diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3194716
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.settings
+.project
+.classpath
+target
+velocity.log
+derby.log
diff --git a/openjpa-all/pom.xml b/openjpa-all/pom.xml
index b59c5f2..e043206 100644
--- a/openjpa-all/pom.xml
+++ b/openjpa-all/pom.xml
@@ -29,7 +29,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
 
     <build>
diff --git a/openjpa-examples/pom.xml b/openjpa-examples/pom.xml
index 20a3d39..c185453 100644
--- a/openjpa-examples/pom.xml
+++ b/openjpa-examples/pom.xml
@@ -32,7 +32,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/openjpa-integration/examples/pom.xml b/openjpa-integration/examples/pom.xml
index 0768cf7..a2d0026 100644
--- a/openjpa-integration/examples/pom.xml
+++ b/openjpa-integration/examples/pom.xml
@@ -38,7 +38,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-integration</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
 
     <profiles>
diff --git a/openjpa-integration/pom.xml b/openjpa-integration/pom.xml
index c819ab8..e8cd5ea 100644
--- a/openjpa-integration/pom.xml
+++ b/openjpa-integration/pom.xml
@@ -29,7 +29,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <modules>
         <module>examples</module>
diff --git a/openjpa-integration/tck/pom.xml b/openjpa-integration/tck/pom.xml
index 8583f83..a78b9dd 100644
--- a/openjpa-integration/tck/pom.xml
+++ b/openjpa-integration/tck/pom.xml
@@ -61,7 +61,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-integration</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
 
     <profiles>
@@ -269,22 +269,12 @@
     </profile>
     </profiles>
 
-    <repositories>
-        <repository>
-            <id>java.net</id>
-            <name>Java.net Maven Repository</name>
-            <url>https://maven-repository.dev.java.net/nonav/repository</url>
-            <layout>legacy</layout>
-        </repository>
-    </repositories>
-
     <dependencies>
-        <!-- use the authoritative javax.persistence API for testing -->
         <dependency>
-            <groupId>javax.persistence</groupId>
-            <artifactId>persistence-api</artifactId>
-            <version>1.0b</version>
-        </dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jpa_3.0_spec</artifactId>
+            <version>1.1.1</version>
+        </dependency> 
         <dependency>
             <groupId>org.apache.openjpa</groupId>
             <artifactId>openjpa-kernel</artifactId>
diff --git a/openjpa-jdbc/pom.xml b/openjpa-jdbc/pom.xml
index f595afa..a2d8251 100644
--- a/openjpa-jdbc/pom.xml
+++ b/openjpa-jdbc/pom.xml
@@ -31,7 +31,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractJDBCSeq.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractJDBCSeq.java
index 5064c3c..110d17e 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractJDBCSeq.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractJDBCSeq.java
@@ -57,8 +57,9 @@
     public Object next(StoreContext ctx, ClassMetaData meta) {
         JDBCStore store = getStore(ctx);
         try {
-            current = nextInternal(store, (ClassMapping) meta);
-            return current;
+            Object currentLocal = nextInternal(store, (ClassMapping) meta);
+            current = currentLocal;
+            return currentLocal;
         } catch (OpenJPAException ke) {
             throw ke;
         } catch (SQLException se) {
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ConstraintUpdateManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ConstraintUpdateManager.java
index 8b869da..c445fdb 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ConstraintUpdateManager.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ConstraintUpdateManager.java
@@ -1,546 +1,546 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.ForeignKey;
-import org.apache.openjpa.jdbc.schema.Table;
-import org.apache.openjpa.jdbc.sql.PrimaryRow;
-import org.apache.openjpa.jdbc.sql.Row;
-import org.apache.openjpa.jdbc.sql.RowImpl;
-import org.apache.openjpa.jdbc.sql.RowManager;
-import org.apache.openjpa.jdbc.sql.RowManagerImpl;
-import org.apache.openjpa.jdbc.sql.SQLExceptions;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.graph.DepthFirstAnalysis;
-import org.apache.openjpa.lib.graph.Edge;
-import org.apache.openjpa.lib.graph.Graph;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * <p>Standard update manager, capable of foreign key constraint evaluation.</p>
- *
- * @since 1.0.0
- */
-public class ConstraintUpdateManager
-    extends AbstractUpdateManager {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (ConstraintUpdateManager.class);
-
-    public boolean orderDirty() {
-        return true;
-    }
-
-    protected PreparedStatementManager newPreparedStatementManager
-        (JDBCStore store, Connection conn) {
-        return new PreparedStatementManagerImpl(store, conn);
-    }
-
-    protected RowManager newRowManager() {
-        return new RowManagerImpl(false);
-    }
-
-    protected Collection flush(RowManager rowMgr,
-        PreparedStatementManager psMgr, Collection exceps) {
-        RowManagerImpl rmimpl = (RowManagerImpl) rowMgr;
-
-        // first take care of all secondary table deletes and 'all row' deletes
-        // (which are probably secondary table deletes), since no foreign
-        // keys ever rely on secondary table pks
-        flush(rmimpl.getAllRowDeletes(), psMgr);
-        flush(rmimpl.getSecondaryDeletes(), psMgr);
-
-        // now do any 'all row' updates
-        flush(rmimpl.getAllRowUpdates(), psMgr);
-
-        // analyze foreign keys
-        Collection inserts = rmimpl.getInserts();
-        Collection updates = rmimpl.getUpdates();
-        Collection deletes = rmimpl.getDeletes();
-        Graph[] graphs = new Graph[2];    // insert graph, delete graph
-        analyzeForeignKeys(inserts, updates, deletes, rmimpl, graphs);
-
-        // flush insert graph, if any
-        boolean autoAssign = rmimpl.hasAutoAssignConstraints();
-        try {
-            flushGraph(graphs[0], psMgr, autoAssign);
-        } catch (SQLException se) {
-            exceps = addException(exceps, SQLExceptions.getStore(se, dict));
-        } catch (OpenJPAException ke) {
-            exceps = addException(exceps, ke);
-        }
-
-        // flush the rest of the inserts and updates; inserts before updates
-        // because some update fks might reference pks that have to be inserted
-        flush(inserts, psMgr);
-        flush(updates, psMgr);
-
-        // flush the delete graph, if any
-        try {
-            flushGraph(graphs[1], psMgr, autoAssign);
-        } catch (SQLException se) {
-            exceps = addException(exceps, SQLExceptions.getStore(se, dict));
-        } catch (OpenJPAException ke) {
-            exceps = addException(exceps, ke);
-        }
-
-        // put the remainder of the deletes after updates because some updates
-        // may be nulling fks to rows that are going to be deleted
-        flush(deletes, psMgr);
-
-        // take care of all secondary table inserts and updates last, since
-        // they may rely on previous inserts or updates, but nothing relies
-        // on them
-        flush(rmimpl.getSecondaryUpdates(), psMgr);
-
-        // flush any left over prepared statements
-        psMgr.flush();
-        return exceps;
-    }
-
-    /**
-     * Analyze foreign key dependencies on the given rows
-     * and create an insert and a delete graph to execute.  The insert
-     * graph will be flushed before all other rows, and the delete graph will
-     * be flushed after them.
-     */
-    private void analyzeForeignKeys(Collection inserts, Collection updates,
-        Collection deletes, RowManagerImpl rowMgr, Graph[] graphs) {
-        // if there are any deletes, we have to map the insert objects on their
-        // oids so we'll be able to detect delete-then-insert-same-pk cases
-        Map insertMap = null;
-        OpenJPAStateManager sm;
-        if (!deletes.isEmpty() && !inserts.isEmpty()) {
-            insertMap = new HashMap((int) (inserts.size() * 1.33 + 1));
-            for (Iterator itr = inserts.iterator(); itr.hasNext();) {
-                sm = ((Row) itr.next()).getPrimaryKey();
-                if (sm != null && sm.getObjectId() != null)
-                    insertMap.put(sm.getObjectId(), sm);
-            }
-        }
-
-        // first construct the graph for deletes; this may expand to include
-        // inserts and updates as well if there are any inserts that rely on
-        // deletes (delete-then-insert-same-pk cases)
-        PrimaryRow row;
-        Row row2;
-        ForeignKey[] fks;
-        OpenJPAStateManager fkVal;
-        boolean ignoreUpdates = true;
-        for (Iterator itr = deletes.iterator(); itr.hasNext();) {
-            row = (PrimaryRow) itr.next();
-            if (!row.isValid())
-                continue;
-
-            row2 = getInsertRow(insertMap, rowMgr, row);
-            if (row2 != null) {
-                ignoreUpdates = false;
-                graphs[1] = addEdge(graphs[1], (PrimaryRow) row2, row, null);
-            }
-
-            // now check this row's fks against other deletes
-            fks = row.getTable().getForeignKeys();
-            for (int j = 0; j < fks.length; j++) {
-                // when deleting ref fks they'll just set a where value, so
-                // check both for fk updates (relation fks) and wheres (ref fks)
-                fkVal = row.getForeignKeySet(fks[j]);
-                if (fkVal == null)
-                    fkVal = row.getForeignKeyWhere(fks[j]);
-                if (fkVal == null)
-                    continue;
-
-                row2 = rowMgr.getRow(fks[j].getPrimaryKeyTable(),
-                    Row.ACTION_DELETE, fkVal, false);
-                if (row2 != null && row2.isValid() && row2 != row)
-                    graphs[1] = addEdge(graphs[1], (PrimaryRow) row2, row,
-                        fks[j]);
-            }
-        }
-
-        if (ignoreUpdates)
-            graphs[0] = analyzeAgainstInserts(inserts, rowMgr, graphs[0]);
-        else {
-            // put inserts *and updates* in the delete graph; they all rely
-            // on each other
-            graphs[1] = analyzeAgainstInserts(updates, rowMgr, graphs[1]);
-            graphs[1] = analyzeAgainstInserts(inserts, rowMgr, graphs[1]);
-        }
-    }
-
-    /**
-     * Check to see if there is an insert for for the same table and primary
-     * key values as the given delete row.
-     */
-    private Row getInsertRow(Map insertMap, RowManagerImpl rowMgr, Row row) {
-        if (insertMap == null)
-            return null;
-
-        OpenJPAStateManager sm = row.getPrimaryKey();
-        if (sm == null)
-            return null;
-
-        // look for a new object whose insert id is the same as this delete one
-        Object oid = sm.getObjectId();
-        OpenJPAStateManager nsm = (OpenJPAStateManager) insertMap.get(oid);
-        if (nsm == null)
-            return null;
-
-        // found new object; get its row
-        row = rowMgr.getRow(row.getTable(), Row.ACTION_INSERT, nsm, false);
-        return (row == null || row.isValid()) ? row : null;
-    }
-
-    /**
-     * Analyze the given rows against the inserts, placing dependencies
-     * in the given graph.
-     */
-    private Graph analyzeAgainstInserts(Collection rows, RowManagerImpl rowMgr,
-        Graph graph) {
-        PrimaryRow row;
-        Row row2;
-        ForeignKey[] fks;
-        Column[] cols;
-        for (Iterator itr = rows.iterator(); itr.hasNext();) {
-            row = (PrimaryRow) itr.next();
-            if (!row.isValid())
-                continue;
-
-            // check this row's fks against inserts; a logical fk to an auto-inc
-            // column is treated just as actual database fk because the result
-            // is the same: the pk row has to be inserted before the fk row
-            fks = row.getTable().getForeignKeys();
-            for (int j = 0; j < fks.length; j++) {
-                if (row.getForeignKeySet(fks[j]) == null)
-                    continue;
-
-                // see if this row is dependent on another.  if it's only
-                // depenent on itself, see if the fk is logical or deferred, in
-                // which case it must be an auto-inc because otherwise we
-                // wouldn't have recorded it
-                row2 = rowMgr.getRow(fks[j].getPrimaryKeyTable(),
-                    Row.ACTION_INSERT, row.getForeignKeySet(fks[j]), false);
-                if (row2 != null && row2.isValid() && (row2 != row
-                    || fks[j].isDeferred() || fks[j].isLogical()))
-                    graph = addEdge(graph, row, (PrimaryRow) row2, fks[j]);
-            }
-
-            // see if there are any relation id columns dependent on
-            // auto-inc objects
-            cols = row.getTable().getRelationIdColumns();
-            for (int j = 0; j < cols.length; j++) {
-                OpenJPAStateManager sm = row.getRelationIdSet(cols[j]);
-                if (sm == null)
-                    continue;
-
-                row2 = rowMgr.getRow(getBaseTable(sm), Row.ACTION_INSERT,
-                    sm, false);
-                if (row2 != null && row2.isValid())
-                    graph = addEdge(graph, row, (PrimaryRow) row2, cols[j]);
-            }
-        }
-        return graph;
-    }
-
-    /**
-     * Return the base table for the given instance.
-     */
-    private static Table getBaseTable(OpenJPAStateManager sm) {
-        ClassMapping cls = (ClassMapping) sm.getMetaData();
-        while (cls.getJoinablePCSuperclassMapping() != null)
-            cls = cls.getJoinablePCSuperclassMapping();
-        return cls.getTable();
-    }
-
-    /**
-     * Add an edge between the given rows in the given foreign key graph.
-     */
-    private Graph addEdge(Graph graph, PrimaryRow row1, PrimaryRow row2,
-        Object fk) {
-        // delay creation of the graph
-        if (graph == null)
-            graph = new Graph();
-
-        row1.setDependent(true);
-        row2.setDependent(true);
-        graph.addNode(row1);
-        graph.addNode(row2);
-
-        // add an edge from row1 to row2, and set the fk causing the
-        // dependency as the user object so we can retrieve it when resolving
-        // circular constraints
-        Edge edge = new Edge(row1, row2, true);
-        edge.setUserObject(fk);
-        graph.addEdge(edge);
-
-        return graph;
-    }
-
-    /**
-     * Flush the given graph of rows in the proper order.
-     * @param graph The graph of statements to be walked
-     * @param psMgr The prepared statement manager to use to issue the
-     * statements
-     * @param autoAssign Whether any of the rows in the graph have any
-     * auto-assign constraints
-     */
-    protected void flushGraph(Graph graph, PreparedStatementManager psMgr,
-        boolean autoAssign)
-        throws SQLException {
-        if (graph == null)
-            return;
-
-        DepthFirstAnalysis dfa = newDepthFirstAnalysis(graph, autoAssign);
-        Collection insertUpdates = new LinkedList();
-        Collection deleteUpdates = new LinkedList();
-        boolean recalculate;
-
-        // Handle circular constraints:
-        // - if deleted row A has a ciricular fk to deleted row B, 
-        //   then use an update statement to null A's fk to B before flushing, 
-        //   and then flush
-        // - if inserted row A has a circular fk to updated/inserted row B,
-        //   then null the fk in the B row object, then flush,
-        //   and after flushing, use an update to set the fk back to A
-        // Depending on where circular dependencies are broken, the  
-        // topological order of the graph nodes has to be re-calculated.
-        recalculate = resolveCycles(graph, dfa.getEdges(Edge.TYPE_BACK),
-                deleteUpdates, insertUpdates);
-        recalculate |= resolveCycles(graph, dfa.getEdges(Edge.TYPE_FORWARD),
-                deleteUpdates, insertUpdates);
-
-        if (recalculate) {
-            dfa = recalculateDepthFirstAnalysis(graph, autoAssign);
-        }
-
-        // flush delete updates to null fks, then all rows in order, then
-        // the insert updates to set circular fk values
-        flush(deleteUpdates, psMgr);
-        Collection nodes = dfa.getSortedNodes();
-        for (Iterator itr = nodes.iterator(); itr.hasNext();)
-            psMgr.flush((RowImpl) itr.next());
-        flush(insertUpdates, psMgr);
-    }
-
-    /**
-     * Break a circular dependency caused by delete operations.
-     * If deleted row A has a ciricular fk to deleted row B, then use an update 
-     * statement to null A's fk to B before deleting B, then delete A.
-     * @param edge Edge in the dependency graph corresponding to a foreign key
-     * constraint. This dependency is broken by nullifying the foreign key.
-     * @param deleteUpdates Collection of update statements that are executed
-     * before the delete operations are flushed 
-     */
-    private void addDeleteUpdate(Edge edge, Collection deleteUpdates)
-        throws SQLException {
-        PrimaryRow row;
-        RowImpl update;
-        ForeignKey fk;
-
-        // copy where conditions into new update that nulls the fk
-        row = (PrimaryRow) edge.getTo();
-        update = new PrimaryRow(row.getTable(), Row.ACTION_UPDATE, null);
-        row.copyInto(update, true);
-        if (edge.getUserObject() instanceof ForeignKey) {
-            fk = (ForeignKey) edge.getUserObject();
-            update.setForeignKey(fk, row.getForeignKeyIO(fk), null);
-        } else
-            update.setNull((Column) edge.getUserObject());
-
-        deleteUpdates.add(update);
-    }
-
-    /**
-     * Break a circular dependency caused by insert operations.
-     * If inserted row A has a circular fk to updated/inserted row B,
-     * then null the fk in the B row object, then flush,
-     * and after flushing, use an update to set the fk back to A.
-     * @param row Row to be flushed
-     * @param edge Edge in the dependency graph corresponding to a foreign key
-     * constraint. This dependency is broken by nullifying the foreign key.
-     * @param insertUpdates Collection of update statements that are executed
-     * after the insert/update operations are flushed 
-     */
-    private void addInsertUpdate(PrimaryRow row, Edge edge,
-        Collection insertUpdates) throws SQLException {
-        RowImpl update;
-        ForeignKey fk;
-        Column col;
-
-        // copy where conditions into new update that sets the fk
-        update = new PrimaryRow(row.getTable(), Row.ACTION_UPDATE, null);
-        if (row.getAction() == Row.ACTION_INSERT) {
-            if (row.getPrimaryKey() == null)
-                throw new InternalException(_loc.get("ref-cycle"));
-            update.wherePrimaryKey(row.getPrimaryKey());
-        } else {
-            // Row.ACTION_UPDATE
-            row.copyInto(update, true);
-        }
-        if (edge.getUserObject() instanceof ForeignKey) {
-            fk = (ForeignKey) edge.getUserObject();
-            update.setForeignKey(fk, row.getForeignKeyIO(fk),
-                row.getForeignKeySet(fk));
-            row.clearForeignKey(fk);
-        } else {
-            col = (Column) edge.getUserObject();
-            update.setRelationId(col, row.getRelationIdSet(col),
-                row.getRelationIdCallback(col));
-            row.clearRelationId(col);
-        }
-
-        insertUpdates.add(update);
-    }
-
-    /**
-     * Finds a nullable foreign key by walking the dependency cycle. 
-     * Circular dependencies can be broken at this point.
-     * @param cycle Cycle in the dependency graph.
-     * @return Edge corresponding to a nullable foreign key.
-     */
-    private Edge findBreakableLink(List cycle) {
-        Edge breakableLink = null;
-        for (Iterator iter = cycle.iterator(); iter.hasNext(); ) {
-            Edge edge = (Edge) iter.next();
-            Object userObject = edge.getUserObject();
-            if (userObject instanceof ForeignKey) {
-                 if (!((ForeignKey) userObject).hasNotNullColumns()) {
-                     breakableLink = edge;
-                     break;
-                 }
-            } else if (userObject instanceof Column) {
-                if (!((Column) userObject).isNotNull()) {
-                    breakableLink = edge;
-                    break;
-                }
-            }
-        }
-        return breakableLink;
-    }
-
-    /**
-     * Re-calculates the DepthFirstSearch analysis of the graph 
-     * after some of the edges have been removed. Ensures
-     * that the dependency graph is cycle free.
-     * @param graph The graph of statements to be walked
-     * @param autoAssign Whether any of the rows in the graph have any
-     * auto-assign constraints
-     */
-    private DepthFirstAnalysis recalculateDepthFirstAnalysis(Graph graph,
-        boolean autoAssign) {
-        DepthFirstAnalysis dfa;
-        // clear previous traversal data
-        graph.clearTraversal();
-        dfa = newDepthFirstAnalysis(graph, autoAssign);
-        // make sure that the graph is non-cyclic now
-        assert (dfa.hasNoCycles()): _loc.get("graph-not-cycle-free");
-        return dfa;
-    }
-
-    /**
-     * Resolve circular dependencies by identifying and breaking
-     * a nullable foreign key.
-     * @param graph Dependency graph.
-     * @param edges Collection of edges. Each edge indicates a possible 
-     * circular dependency
-     * @param deleteUpdates Collection of update operations (nullifying 
-     * foreign keys) to be filled. These updates will be executed before 
-     * the rows in the dependency graph are flushed
-     * @param insertUpdates CCollection of update operations (nullifying 
-     * foreign keys) to be filled. These updates will be executed after 
-     * the rows in the dependency graph are flushed
-     * @return Depending on where circular dependencies are broken, the  
-     * topological order of the graph nodes has to be re-calculated.
-     */
-    private boolean resolveCycles(Graph graph, Collection edges,
-        Collection deleteUpdates, Collection insertUpdates)
-        throws SQLException {
-        boolean recalculate = false;
-        for (Iterator itr = edges.iterator(); itr.hasNext();) {
-            Edge edge = (Edge) itr.next();
-            List cycle = edge.getCycle();
-
-            if (cycle != null) {
-                // find a nullable foreign key
-                Edge breakableLink = findBreakableLink(cycle);
-                if (breakableLink == null) {
-                    throw new UserException(_loc.get("no-nullable-fk"));
-                }
-
-                // topologic node order must be re-calculated,  if the
-                // breakable link is different from the edge where
-                // the circular dependency was originally detected
-                if (edge != breakableLink) {
-                    recalculate = true;
-                }
-
-                if (!breakableLink.isRemovedFromGraph()) {
-
-                    // use a primary row update to prevent setting pk and fk values
-                    // until after flush, to get latest auto-increment values
-                    PrimaryRow row = (PrimaryRow) breakableLink.getFrom();
-                    if (row.getAction() == Row.ACTION_DELETE) {
-                        addDeleteUpdate(breakableLink, deleteUpdates);
-                    } else {
-                        addInsertUpdate(row, breakableLink, insertUpdates);
-                    }
-                    graph.removeEdge(breakableLink);
-                }
-            }
-        }
-        return recalculate;
-    }
-
-    /**
-     * Create a new {@link DepthFirstAnalysis} suitable for the given graph
-     * and auto-assign settings.
-     */
-    protected DepthFirstAnalysis newDepthFirstAnalysis(Graph graph,
-        boolean autoAssign) {
-        return new DepthFirstAnalysis(graph);
-    }
-
-    /**
-     * Flush the given collection of secondary rows.
-     */
-    protected void flush(Collection rows, PreparedStatementManager psMgr) {
-        if (rows.size() == 0)
-            return;
-
-        RowImpl row;
-        for (Iterator itr = rows.iterator(); itr.hasNext(); ) {
-            row = (RowImpl) itr.next();
-            if (row.isValid() && !row.isDependent())
-                psMgr.flush(row);
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.PrimaryRow;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowImpl;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.RowManagerImpl;
+import org.apache.openjpa.jdbc.sql.SQLExceptions;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.graph.DepthFirstAnalysis;
+import org.apache.openjpa.lib.graph.Edge;
+import org.apache.openjpa.lib.graph.Graph;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * <p>Standard update manager, capable of foreign key constraint evaluation.</p>
+ *
+ * @since 1.0.0
+ */
+public class ConstraintUpdateManager
+    extends AbstractUpdateManager {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (ConstraintUpdateManager.class);
+
+    public boolean orderDirty() {
+        return true;
+    }
+
+    protected PreparedStatementManager newPreparedStatementManager
+        (JDBCStore store, Connection conn) {
+        return new PreparedStatementManagerImpl(store, conn);
+    }
+
+    protected RowManager newRowManager() {
+        return new RowManagerImpl(false);
+    }
+
+    protected Collection flush(RowManager rowMgr,
+        PreparedStatementManager psMgr, Collection exceps) {
+        RowManagerImpl rmimpl = (RowManagerImpl) rowMgr;
+
+        // first take care of all secondary table deletes and 'all row' deletes
+        // (which are probably secondary table deletes), since no foreign
+        // keys ever rely on secondary table pks
+        flush(rmimpl.getAllRowDeletes(), psMgr);
+        flush(rmimpl.getSecondaryDeletes(), psMgr);
+
+        // now do any 'all row' updates
+        flush(rmimpl.getAllRowUpdates(), psMgr);
+
+        // analyze foreign keys
+        Collection inserts = rmimpl.getInserts();
+        Collection updates = rmimpl.getUpdates();
+        Collection deletes = rmimpl.getDeletes();
+        Graph[] graphs = new Graph[2];    // insert graph, delete graph
+        analyzeForeignKeys(inserts, updates, deletes, rmimpl, graphs);
+
+        // flush insert graph, if any
+        boolean autoAssign = rmimpl.hasAutoAssignConstraints();
+        try {
+            flushGraph(graphs[0], psMgr, autoAssign);
+        } catch (SQLException se) {
+            exceps = addException(exceps, SQLExceptions.getStore(se, dict));
+        } catch (OpenJPAException ke) {
+            exceps = addException(exceps, ke);
+        }
+
+        // flush the rest of the inserts and updates; inserts before updates
+        // because some update fks might reference pks that have to be inserted
+        flush(inserts, psMgr);
+        flush(updates, psMgr);
+
+        // flush the delete graph, if any
+        try {
+            flushGraph(graphs[1], psMgr, autoAssign);
+        } catch (SQLException se) {
+            exceps = addException(exceps, SQLExceptions.getStore(se, dict));
+        } catch (OpenJPAException ke) {
+            exceps = addException(exceps, ke);
+        }
+
+        // put the remainder of the deletes after updates because some updates
+        // may be nulling fks to rows that are going to be deleted
+        flush(deletes, psMgr);
+
+        // take care of all secondary table inserts and updates last, since
+        // they may rely on previous inserts or updates, but nothing relies
+        // on them
+        flush(rmimpl.getSecondaryUpdates(), psMgr);
+
+        // flush any left over prepared statements
+        psMgr.flush();
+        return exceps;
+    }
+
+    /**
+     * Analyze foreign key dependencies on the given rows
+     * and create an insert and a delete graph to execute.  The insert
+     * graph will be flushed before all other rows, and the delete graph will
+     * be flushed after them.
+     */
+    private void analyzeForeignKeys(Collection inserts, Collection updates,
+        Collection deletes, RowManagerImpl rowMgr, Graph[] graphs) {
+        // if there are any deletes, we have to map the insert objects on their
+        // oids so we'll be able to detect delete-then-insert-same-pk cases
+        Map insertMap = null;
+        OpenJPAStateManager sm;
+        if (!deletes.isEmpty() && !inserts.isEmpty()) {
+            insertMap = new HashMap((int) (inserts.size() * 1.33 + 1));
+            for (Iterator itr = inserts.iterator(); itr.hasNext();) {
+                sm = ((Row) itr.next()).getPrimaryKey();
+                if (sm != null && sm.getObjectId() != null)
+                    insertMap.put(sm.getObjectId(), sm);
+            }
+        }
+
+        // first construct the graph for deletes; this may expand to include
+        // inserts and updates as well if there are any inserts that rely on
+        // deletes (delete-then-insert-same-pk cases)
+        PrimaryRow row;
+        Row row2;
+        ForeignKey[] fks;
+        OpenJPAStateManager fkVal;
+        boolean ignoreUpdates = true;
+        for (Iterator itr = deletes.iterator(); itr.hasNext();) {
+            row = (PrimaryRow) itr.next();
+            if (!row.isValid())
+                continue;
+
+            row2 = getInsertRow(insertMap, rowMgr, row);
+            if (row2 != null) {
+                ignoreUpdates = false;
+                graphs[1] = addEdge(graphs[1], (PrimaryRow) row2, row, null);
+            }
+
+            // now check this row's fks against other deletes
+            fks = row.getTable().getForeignKeys();
+            for (int j = 0; j < fks.length; j++) {
+                // when deleting ref fks they'll just set a where value, so
+                // check both for fk updates (relation fks) and wheres (ref fks)
+                fkVal = row.getForeignKeySet(fks[j]);
+                if (fkVal == null)
+                    fkVal = row.getForeignKeyWhere(fks[j]);
+                if (fkVal == null)
+                    continue;
+
+                row2 = rowMgr.getRow(fks[j].getPrimaryKeyTable(),
+                    Row.ACTION_DELETE, fkVal, false);
+                if (row2 != null && row2.isValid() && row2 != row)
+                    graphs[1] = addEdge(graphs[1], (PrimaryRow) row2, row,
+                        fks[j]);
+            }
+        }
+
+        if (ignoreUpdates)
+            graphs[0] = analyzeAgainstInserts(inserts, rowMgr, graphs[0]);
+        else {
+            // put inserts *and updates* in the delete graph; they all rely
+            // on each other
+            graphs[1] = analyzeAgainstInserts(updates, rowMgr, graphs[1]);
+            graphs[1] = analyzeAgainstInserts(inserts, rowMgr, graphs[1]);
+        }
+    }
+
+    /**
+     * Check to see if there is an insert for for the same table and primary
+     * key values as the given delete row.
+     */
+    private Row getInsertRow(Map insertMap, RowManagerImpl rowMgr, Row row) {
+        if (insertMap == null)
+            return null;
+
+        OpenJPAStateManager sm = row.getPrimaryKey();
+        if (sm == null)
+            return null;
+
+        // look for a new object whose insert id is the same as this delete one
+        Object oid = sm.getObjectId();
+        OpenJPAStateManager nsm = (OpenJPAStateManager) insertMap.get(oid);
+        if (nsm == null)
+            return null;
+
+        // found new object; get its row
+        row = rowMgr.getRow(row.getTable(), Row.ACTION_INSERT, nsm, false);
+        return (row == null || row.isValid()) ? row : null;
+    }
+
+    /**
+     * Analyze the given rows against the inserts, placing dependencies
+     * in the given graph.
+     */
+    private Graph analyzeAgainstInserts(Collection rows, RowManagerImpl rowMgr,
+        Graph graph) {
+        PrimaryRow row;
+        Row row2;
+        ForeignKey[] fks;
+        Column[] cols;
+        for (Iterator itr = rows.iterator(); itr.hasNext();) {
+            row = (PrimaryRow) itr.next();
+            if (!row.isValid())
+                continue;
+
+            // check this row's fks against inserts; a logical fk to an auto-inc
+            // column is treated just as actual database fk because the result
+            // is the same: the pk row has to be inserted before the fk row
+            fks = row.getTable().getForeignKeys();
+            for (int j = 0; j < fks.length; j++) {
+                if (row.getForeignKeySet(fks[j]) == null)
+                    continue;
+
+                // see if this row is dependent on another.  if it's only
+                // depenent on itself, see if the fk is logical or deferred, in
+                // which case it must be an auto-inc because otherwise we
+                // wouldn't have recorded it
+                row2 = rowMgr.getRow(fks[j].getPrimaryKeyTable(),
+                    Row.ACTION_INSERT, row.getForeignKeySet(fks[j]), false);
+                if (row2 != null && row2.isValid() && (row2 != row
+                    || fks[j].isDeferred() || fks[j].isLogical()))
+                    graph = addEdge(graph, row, (PrimaryRow) row2, fks[j]);
+            }
+
+            // see if there are any relation id columns dependent on
+            // auto-inc objects
+            cols = row.getTable().getRelationIdColumns();
+            for (int j = 0; j < cols.length; j++) {
+                OpenJPAStateManager sm = row.getRelationIdSet(cols[j]);
+                if (sm == null)
+                    continue;
+
+                row2 = rowMgr.getRow(getBaseTable(sm), Row.ACTION_INSERT,
+                    sm, false);
+                if (row2 != null && row2.isValid())
+                    graph = addEdge(graph, row, (PrimaryRow) row2, cols[j]);
+            }
+        }
+        return graph;
+    }
+
+    /**
+     * Return the base table for the given instance.
+     */
+    private static Table getBaseTable(OpenJPAStateManager sm) {
+        ClassMapping cls = (ClassMapping) sm.getMetaData();
+        while (cls.getJoinablePCSuperclassMapping() != null)
+            cls = cls.getJoinablePCSuperclassMapping();
+        return cls.getTable();
+    }
+
+    /**
+     * Add an edge between the given rows in the given foreign key graph.
+     */
+    private Graph addEdge(Graph graph, PrimaryRow row1, PrimaryRow row2,
+        Object fk) {
+        // delay creation of the graph
+        if (graph == null)
+            graph = new Graph();
+
+        row1.setDependent(true);
+        row2.setDependent(true);
+        graph.addNode(row1);
+        graph.addNode(row2);
+
+        // add an edge from row1 to row2, and set the fk causing the
+        // dependency as the user object so we can retrieve it when resolving
+        // circular constraints
+        Edge edge = new Edge(row1, row2, true);
+        edge.setUserObject(fk);
+        graph.addEdge(edge);
+
+        return graph;
+    }
+
+    /**
+     * Flush the given graph of rows in the proper order.
+     * @param graph The graph of statements to be walked
+     * @param psMgr The prepared statement manager to use to issue the
+     * statements
+     * @param autoAssign Whether any of the rows in the graph have any
+     * auto-assign constraints
+     */
+    protected void flushGraph(Graph graph, PreparedStatementManager psMgr,
+        boolean autoAssign)
+        throws SQLException {
+        if (graph == null)
+            return;
+
+        DepthFirstAnalysis dfa = newDepthFirstAnalysis(graph, autoAssign);
+        Collection insertUpdates = new LinkedList();
+        Collection deleteUpdates = new LinkedList();
+        boolean recalculate;
+
+        // Handle circular constraints:
+        // - if deleted row A has a ciricular fk to deleted row B, 
+        //   then use an update statement to null A's fk to B before flushing, 
+        //   and then flush
+        // - if inserted row A has a circular fk to updated/inserted row B,
+        //   then null the fk in the B row object, then flush,
+        //   and after flushing, use an update to set the fk back to A
+        // Depending on where circular dependencies are broken, the  
+        // topological order of the graph nodes has to be re-calculated.
+        recalculate = resolveCycles(graph, dfa.getEdges(Edge.TYPE_BACK),
+                deleteUpdates, insertUpdates);
+        recalculate |= resolveCycles(graph, dfa.getEdges(Edge.TYPE_FORWARD),
+                deleteUpdates, insertUpdates);
+
+        if (recalculate) {
+            dfa = recalculateDepthFirstAnalysis(graph, autoAssign);
+        }
+
+        // flush delete updates to null fks, then all rows in order, then
+        // the insert updates to set circular fk values
+        flush(deleteUpdates, psMgr);
+        Collection nodes = dfa.getSortedNodes();
+        for (Iterator itr = nodes.iterator(); itr.hasNext();)
+            psMgr.flush((RowImpl) itr.next());
+        flush(insertUpdates, psMgr);
+    }
+
+    /**
+     * Break a circular dependency caused by delete operations.
+     * If deleted row A has a ciricular fk to deleted row B, then use an update 
+     * statement to null A's fk to B before deleting B, then delete A.
+     * @param edge Edge in the dependency graph corresponding to a foreign key
+     * constraint. This dependency is broken by nullifying the foreign key.
+     * @param deleteUpdates Collection of update statements that are executed
+     * before the delete operations are flushed 
+     */
+    private void addDeleteUpdate(Edge edge, Collection deleteUpdates)
+        throws SQLException {
+        PrimaryRow row;
+        RowImpl update;
+        ForeignKey fk;
+
+        // copy where conditions into new update that nulls the fk
+        row = (PrimaryRow) edge.getTo();
+        update = new PrimaryRow(row.getTable(), Row.ACTION_UPDATE, null);
+        row.copyInto(update, true);
+        if (edge.getUserObject() instanceof ForeignKey) {
+            fk = (ForeignKey) edge.getUserObject();
+            update.setForeignKey(fk, row.getForeignKeyIO(fk), null);
+        } else
+            update.setNull((Column) edge.getUserObject());
+
+        deleteUpdates.add(update);
+    }
+
+    /**
+     * Break a circular dependency caused by insert operations.
+     * If inserted row A has a circular fk to updated/inserted row B,
+     * then null the fk in the B row object, then flush,
+     * and after flushing, use an update to set the fk back to A.
+     * @param row Row to be flushed
+     * @param edge Edge in the dependency graph corresponding to a foreign key
+     * constraint. This dependency is broken by nullifying the foreign key.
+     * @param insertUpdates Collection of update statements that are executed
+     * after the insert/update operations are flushed 
+     */
+    private void addInsertUpdate(PrimaryRow row, Edge edge,
+        Collection insertUpdates) throws SQLException {
+        RowImpl update;
+        ForeignKey fk;
+        Column col;
+
+        // copy where conditions into new update that sets the fk
+        update = new PrimaryRow(row.getTable(), Row.ACTION_UPDATE, null);
+        if (row.getAction() == Row.ACTION_INSERT) {
+            if (row.getPrimaryKey() == null)
+                throw new InternalException(_loc.get("ref-cycle"));
+            update.wherePrimaryKey(row.getPrimaryKey());
+        } else {
+            // Row.ACTION_UPDATE
+            row.copyInto(update, true);
+        }
+        if (edge.getUserObject() instanceof ForeignKey) {
+            fk = (ForeignKey) edge.getUserObject();
+            update.setForeignKey(fk, row.getForeignKeyIO(fk),
+                row.getForeignKeySet(fk));
+            row.clearForeignKey(fk);
+        } else {
+            col = (Column) edge.getUserObject();
+            update.setRelationId(col, row.getRelationIdSet(col),
+                row.getRelationIdCallback(col));
+            row.clearRelationId(col);
+        }
+
+        insertUpdates.add(update);
+    }
+
+    /**
+     * Finds a nullable foreign key by walking the dependency cycle. 
+     * Circular dependencies can be broken at this point.
+     * @param cycle Cycle in the dependency graph.
+     * @return Edge corresponding to a nullable foreign key.
+     */
+    private Edge findBreakableLink(List cycle) {
+        Edge breakableLink = null;
+        for (Iterator iter = cycle.iterator(); iter.hasNext(); ) {
+            Edge edge = (Edge) iter.next();
+            Object userObject = edge.getUserObject();
+            if (userObject instanceof ForeignKey) {
+                 if (!((ForeignKey) userObject).hasNotNullColumns()) {
+                     breakableLink = edge;
+                     break;
+                 }
+            } else if (userObject instanceof Column) {
+                if (!((Column) userObject).isNotNull()) {
+                    breakableLink = edge;
+                    break;
+                }
+            }
+        }
+        return breakableLink;
+    }
+
+    /**
+     * Re-calculates the DepthFirstSearch analysis of the graph 
+     * after some of the edges have been removed. Ensures
+     * that the dependency graph is cycle free.
+     * @param graph The graph of statements to be walked
+     * @param autoAssign Whether any of the rows in the graph have any
+     * auto-assign constraints
+     */
+    private DepthFirstAnalysis recalculateDepthFirstAnalysis(Graph graph,
+        boolean autoAssign) {
+        DepthFirstAnalysis dfa;
+        // clear previous traversal data
+        graph.clearTraversal();
+        dfa = newDepthFirstAnalysis(graph, autoAssign);
+        // make sure that the graph is non-cyclic now
+        assert (dfa.hasNoCycles()): _loc.get("graph-not-cycle-free");
+        return dfa;
+    }
+
+    /**
+     * Resolve circular dependencies by identifying and breaking
+     * a nullable foreign key.
+     * @param graph Dependency graph.
+     * @param edges Collection of edges. Each edge indicates a possible 
+     * circular dependency
+     * @param deleteUpdates Collection of update operations (nullifying 
+     * foreign keys) to be filled. These updates will be executed before 
+     * the rows in the dependency graph are flushed
+     * @param insertUpdates CCollection of update operations (nullifying 
+     * foreign keys) to be filled. These updates will be executed after 
+     * the rows in the dependency graph are flushed
+     * @return Depending on where circular dependencies are broken, the  
+     * topological order of the graph nodes has to be re-calculated.
+     */
+    private boolean resolveCycles(Graph graph, Collection edges,
+        Collection deleteUpdates, Collection insertUpdates)
+        throws SQLException {
+        boolean recalculate = false;
+        for (Iterator itr = edges.iterator(); itr.hasNext();) {
+            Edge edge = (Edge) itr.next();
+            List cycle = edge.getCycle();
+
+            if (cycle != null) {
+                // find a nullable foreign key
+                Edge breakableLink = findBreakableLink(cycle);
+                if (breakableLink == null) {
+                    throw new UserException(_loc.get("no-nullable-fk"));
+                }
+
+                // topologic node order must be re-calculated,  if the
+                // breakable link is different from the edge where
+                // the circular dependency was originally detected
+                if (edge != breakableLink) {
+                    recalculate = true;
+                }
+
+                if (!breakableLink.isRemovedFromGraph()) {
+
+                    // use a primary row update to prevent setting pk and fk values
+                    // until after flush, to get latest auto-increment values
+                    PrimaryRow row = (PrimaryRow) breakableLink.getFrom();
+                    if (row.getAction() == Row.ACTION_DELETE) {
+                        addDeleteUpdate(breakableLink, deleteUpdates);
+                    } else {
+                        addInsertUpdate(row, breakableLink, insertUpdates);
+                    }
+                    graph.removeEdge(breakableLink);
+                }
+            }
+        }
+        return recalculate;
+    }
+
+    /**
+     * Create a new {@link DepthFirstAnalysis} suitable for the given graph
+     * and auto-assign settings.
+     */
+    protected DepthFirstAnalysis newDepthFirstAnalysis(Graph graph,
+        boolean autoAssign) {
+        return new DepthFirstAnalysis(graph);
+    }
+
+    /**
+     * Flush the given collection of secondary rows.
+     */
+    protected void flush(Collection rows, PreparedStatementManager psMgr) {
+        if (rows.size() == 0)
+            return;
+
+        RowImpl row;
+        for (Iterator itr = rows.iterator(); itr.hasNext(); ) {
+            row = (RowImpl) itr.next();
+            if (row.isValid() && !row.isDependent())
+                psMgr.flush(row);
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
index 29b7ec1..d1eda4e 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
@@ -502,15 +502,19 @@
         if (sel == null) return null;
         return sel.execute(this, fetch, params);
     }
-
+    
+    Map<SelectKey, Select> selectImplCacheMap = null;
     private Select newSelect(OpenJPAStateManager sm,
         ClassMapping mapping, JDBCFetchConfiguration fetch, int subs,
         List params) {
         if (!_isQuerySQLCache) 
             return newSelect(sm, mapping, fetch, subs);       
            
-        Map<SelectKey, Select> selectImplCacheMap = 
-            getCacheMapFromQuerySQLCache(JDBCStoreManager.class);
+        if (selectImplCacheMap == null) {
+            selectImplCacheMap =
+                getCacheMapFromQuerySQLCache(JDBCStoreManager.class);
+        }
+         
         JDBCFetchConfiguration fetchClone = new JDBCFetchConfigurationImpl();
         fetchClone.copy(fetch);
         SelectKey selKey = new SelectKey(mapping, null, fetchClone);
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java
index 9ed5e5e..8c2d39b 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java
@@ -281,7 +281,9 @@
         ResultSet rs = null;
         try {
             stmnt = conn.prepareStatement(_select);
-            rs = stmnt.executeQuery();
+            synchronized(this) {
+                rs = stmnt.executeQuery();
+            }
             if (rs.next())
                 return rs.getLong(1);
 
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
index e08fbde..8a5bef5 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
@@ -187,7 +187,20 @@
                 if (log.isWarnEnabled())
                     log.warn(_loc.get("millis-query-timeout"));
             }
-            stmnt.setQueryTimeout(timeout / 1000);
+            try { 
+                stmnt.setQueryTimeout(timeout / 1000);
+            }
+            catch(SQLException e) { 
+                if(! dict.ignoreSQLExceptionOnSetQueryTimeout) { 
+                    throw e;
+                }
+                else { 
+                    if (log.isTraceEnabled()) {
+                        log.trace(_loc.get("error-setting-query-timeout",
+                            timeout, e.getMessage()), e);
+                    }
+                }
+            }
         }
     }
     
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
index d3f760a..6a44425 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
@@ -218,9 +218,12 @@
         String single, String multi, String esc) {
         if (!(v2 instanceof Const))
             throw new UserException(_loc.get("const-only", "matches"));
-        return new MatchesExpression((Val) v1, (Const) v2, single, multi,
-            esc != null ? esc : _type.getMappingRepository().
-                getDBDictionary().searchStringEscape);
+        if (esc == null && _type.getMappingRepository().
+                getDBDictionary().requiresSearchStringEscapeForLike == true) { 
+            esc = _type.getMappingRepository().
+                getDBDictionary().searchStringEscape;
+        }        
+        return new MatchesExpression((Val) v1, (Const) v2, single, multi, esc);
     }
 
     public Subquery newSubquery(ClassMetaData candidate, boolean subs,
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java
index 6c1dbfc..82fce72 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java
@@ -43,7 +43,11 @@
         DBDictionary dict = ctx.store.getDBDictionary();
         String func = dict.toLowerCaseFunction;
         dict.assertSupport(func != null, "ToLowerCaseFunction");
-        func = dict.getCastFunction(getValue(), func);
+        if (getValue() instanceof PCPath) {
+            func = dict.getCastFunction(getValue(), func, ((PCPath) getValue()).getFieldMapping(state).getColumns()[0]);
+        } else {
+            func = dict.getCastFunction(getValue(), func);
+        }
 
         int idx = func.indexOf("{0}");
         buf.append(func.substring(0, idx));
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java
index 8c176c7..3914ff1 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java
@@ -43,7 +43,11 @@
         DBDictionary dict = ctx.store.getDBDictionary();
         String func = dict.toUpperCaseFunction;
         dict.assertSupport(func != null, "ToUpperCaseFunction");
-        func = dict.getCastFunction(getValue(), func);
+        if (getValue() instanceof PCPath) {
+            func = dict.getCastFunction(getValue(), func, ((PCPath) getValue()).getFieldMapping(state).getColumns()[0]);
+        } else {
+            func = dict.getCastFunction(getValue(), func);
+        }
 
         int idx = func.indexOf("{0}");
         buf.append(func.substring(0, idx));
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
index fd93444..84e8a6e 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
@@ -22,13 +22,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.enhance.Reflection;
@@ -88,7 +87,7 @@
     private ClassMapping[] _assignMaps = null;
 
     // maps columns to joinables
-    private final Map _joinables = Collections.synchronizedMap(new HashMap());
+    private final Map _joinables = new ConcurrentHashMap();
 
     /**
      * Constructor. Supply described type and owning repository.
@@ -173,6 +172,7 @@
         FieldMapping fm;
         Joinable join;
         int pkIdx;
+        boolean isNullPK = true;
         for (int i = 0; i < pks.length; i++) {
             // we know that all pk column join mappings use primary key fields,
             // cause this mapping uses the oid as its primary key (we recursed
@@ -187,10 +187,12 @@
                 vals[pkIdx] = join.getPrimaryKeyValue(res, join.getColumns(),
                     fk, store, joins);
                 res.endDataRequest();
-                if (vals[pkIdx] == null)
-                    return null;
+                isNullPK = isNullPK && vals[pkIdx] == null;
             }
         }
+        if (isNullPK) {
+            return null;
+        }
 
         // the oid data is loaded by the base type, but if discriminator data
         // is present, make sure to use it to construct the actual oid instance
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
index bbd7ef5..72f633a 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
@@ -143,7 +143,15 @@
     /**
      * Representation of the database schema.
      */
-    public synchronized SchemaGroup getSchemaGroup() {
+    public SchemaGroup getSchemaGroup() {
+        if(_locking){
+            synchronized(this){
+                if (_schema == null)
+                    _schema = ((JDBCConfiguration) getConfiguration()).
+                        getSchemaFactoryInstance().readSchema();
+                return _schema;                
+            }
+        }
         if (_schema == null)
             _schema = ((JDBCConfiguration) getConfiguration()).
                 getSchemaFactoryInstance().readSchema();
@@ -153,33 +161,59 @@
     /**
      * Representation of the database schema.
      */
-    public synchronized void setSchemaGroup(SchemaGroup schema) {
-        _schema = schema;
+    public void setSchemaGroup(SchemaGroup schema) {
+        if (_locking) {
+            synchronized (this) {
+                _schema = schema;
+            }
+        } else {
+            _schema = schema;
+        }
     }
 
     /**
      * Installs mapping strategies on components.
      */
-    public synchronized StrategyInstaller getStrategyInstaller() {
-        if (_installer == null)
-            _installer = new RuntimeStrategyInstaller(this);
-        return _installer;
+    public StrategyInstaller getStrategyInstaller() {
+        if (_locking) {
+            synchronized (this) {
+                if (_installer == null)
+                    _installer = new RuntimeStrategyInstaller(this);
+                return _installer;
+            }
+        } else {
+            if (_installer == null)
+                _installer = new RuntimeStrategyInstaller(this);
+            return _installer;
+        }
     }
 
     /**
      * Installs mapping strategies on components.
      */
-    public synchronized void setStrategyInstaller(StrategyInstaller installer) {
-        _installer = installer;
+    public void setStrategyInstaller(StrategyInstaller installer) {
+        if (_locking) {
+            synchronized (this) {
+                _installer = installer;
+            }
+        } else {
+            _installer = installer;
+        }
     }
 
     /**
      * Return the query result mapping for the given name.
      */
-    public synchronized QueryResultMapping getQueryResultMapping(Class cls,
+    public QueryResultMapping getQueryResultMapping(Class cls,
         String name, ClassLoader envLoader, boolean mustExist) {
-        QueryResultMapping res = getQueryResultMappingInternal(cls, name,
-            envLoader);
+        QueryResultMapping res = null;
+        if (_locking) {
+            synchronized (this) {
+                res = getQueryResultMappingInternal(cls, name, envLoader);
+            }
+        } else {
+            res = getQueryResultMappingInternal(cls, name, envLoader);
+        }
         if (res == null && mustExist)
             throw new MetaDataException(_loc.get("no-query-res", cls, name));
         return res;
@@ -219,26 +253,49 @@
     /**
      * Return all cached query result mappings.
      */
-    public synchronized QueryResultMapping[] getQueryResultMappings() {
-        Collection values = _results.values();
-        return (QueryResultMapping[]) values.toArray
-            (new QueryResultMapping[values.size()]);
+    public QueryResultMapping[] getQueryResultMappings() {
+        if (_locking) {
+            synchronized (this) {
+                Collection values = _results.values();
+                return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+            }
+        } else {
+            Collection values = _results.values();
+            return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+        }
     }
 
     /**
      * Return the cached query result mapping with the given name, or null if
      * none.
      */
-    public synchronized QueryResultMapping getCachedQueryResultMapping
+    public QueryResultMapping getCachedQueryResultMapping
         (Class cls, String name) {
-        return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+        if (_locking) {
+            synchronized (this) {
+                return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+            }
+        } else {
+            return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+        }
     }
 
     /**
      * Add a query result mapping.
      */
-    public synchronized QueryResultMapping addQueryResultMapping(Class cls,
+    public QueryResultMapping addQueryResultMapping(Class cls,
         String name) {
+        if (_locking) {
+            return addQueryResultMappingLocking(cls, name);
+        } else {
+            return addQueryResultMappingInternal(cls, name);
+        }
+    }
+    private synchronized QueryResultMapping addQueryResultMappingLocking(Class cls, String name) {
+        return addQueryResultMappingInternal(cls, name);
+    }
+
+    private QueryResultMapping addQueryResultMappingInternal(Class cls, String name) {
         QueryResultMapping res = new QueryResultMapping(name, this);
         res.setDefiningType(cls);
         _results.put(getQueryResultKey(res), res);
@@ -248,19 +305,33 @@
     /**
      * Remove a query result mapping.
      */
-    public synchronized boolean removeQueryResultMapping
+    public boolean removeQueryResultMapping
         (QueryResultMapping res) {
-        return _results.remove(getQueryResultKey(res)) != null;
+        if (_locking) {
+            synchronized (this) {
+                return _results.remove(getQueryResultKey(res)) != null;
+            }
+        } else {
+            return _results.remove(getQueryResultKey(res)) != null;
+        }
     }
 
     /**
      * Remove a query result mapping.
      */
-    public synchronized boolean removeQueryResultMapping(Class cls,
+    public boolean removeQueryResultMapping(Class cls,
         String name) {
-        if (name == null)
-            return false;
-        return _results.remove(getQueryResultKey(cls, name)) != null;
+        if (_locking) {
+            synchronized (this) {
+                if (name == null)
+                    return false;
+                return _results.remove(getQueryResultKey(cls, name)) != null;
+            }
+        } else {
+            if (name == null)
+                return false;
+            return _results.remove(getQueryResultKey(cls, name)) != null;
+        }
     }
 
     /**
@@ -300,10 +371,18 @@
             mustExist);
     }
 
-    public synchronized void clear() {
-        super.clear();
-        _schema = null;
-        _results.clear();
+    public void clear() {
+        if (_locking) {
+            synchronized (this) {
+                super.clear();
+                _schema = null;
+                _results.clear();
+            }
+        } else {
+            super.clear();
+            _schema = null;
+            _results.clear();
+        }
     }
 
     protected void prepareMapping(ClassMetaData meta) {
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ElementEmbedValueHandler.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ElementEmbedValueHandler.java
index be14494..0559d61 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ElementEmbedValueHandler.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ElementEmbedValueHandler.java
@@ -1,183 +1,183 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.lib.util.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.util.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.schema.*;
-
-/**
- * <p>Handler for embedded objects as elements of a collection or map.  For
- * embedded objects as fields, use the more powerful
- * {@link EmbedFieldStrategy}.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- * @nojavadoc
- */
-public class ElementEmbedValueHandler
-    extends EmbedValueHandler
-    implements RelationId {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (ElementEmbedValueHandler.class);
-
-    private ValueMapping _vm = null;
-    private Column[] _cols = null;
-    private Object[] _args = null;
-    private int _nullIdx = -1;
-    private boolean _synthetic = false;
-
-    public Column[] map(ValueMapping vm, String name, ColumnIO io,
-        boolean adapt) {
-        LinkedList cols = new LinkedList();
-        LinkedList args = new LinkedList();
-        super.map(vm, name, io, adapt, cols, args);
-
-        ValueMappingInfo vinfo = vm.getValueInfo();
-        Column nullInd = vinfo.getNullIndicatorColumn(vm, name,
-            vm.getFieldMapping().getTable(), adapt);
-        if (nullInd != null)
-            vm.setColumns(new Column[]{ nullInd });
-
-        // record index of null indicator column and whether it is synthetic
-        if (nullInd != null) {
-            _nullIdx = cols.indexOf(nullInd);
-            if (_nullIdx == -1) {
-                cols.addFirst(nullInd);
-                args.addFirst(null);
-                _nullIdx = 0;
-                _synthetic = true;
-            }
-        }
-
-        _vm = vm;
-        _cols = (Column[]) cols.toArray(new Column[cols.size()]);
-        _args = args.toArray();
-        return _cols;
-    }
-
-    public boolean objectValueRequiresLoad(ValueMapping vm) {
-        return true;
-    }
-
-    public Object getResultArgument(ValueMapping vm) {
-        return _args;
-    }
-
-    public Object toDataStoreValue(ValueMapping vm, Object val,
-        JDBCStore store) {
-        OpenJPAStateManager em = store.getContext().getStateManager(val);
-        Object rval = null;
-        if (_cols.length > 1)
-            rval = new Object[_cols.length];
-
-        // set null indicator column
-        int idx = 0;
-        if (_synthetic) {
-            Object cval = ((EmbeddedClassStrategy) vm.getEmbeddedMapping().
-                getStrategy()).getNullIndicatorValue(em);
-            if (_cols.length == 1)
-                return cval;
-            ((Object[]) rval)[idx++] = cval;
-        }
-
-        return super.toDataStoreValue(em, vm, store, _cols, rval, idx);
-    }
-
-    public Object toObjectValue(ValueMapping vm, Object val,
-        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch)
-        throws SQLException {
-        if (sm == null)
-            throw new InvalidStateException(_loc.get("cant-project-owned",
-                vm));
-
-        // check null indicator first
-        if (_nullIdx != -1) {
-            Object nval;
-            if (_cols.length == 1)
-                nval = val;
-            else
-                nval = ((Object[]) val)[_nullIdx];
-            if (((EmbeddedClassStrategy) vm.getEmbeddedMapping().
-                getStrategy()).indicatesNull(nval))
-                return null;
-        }
-
-        // create embedded instance
-        OpenJPAStateManager em = store.getContext().embed(null, null, sm, vm);
-        int idx = (_synthetic) ? 1 : 0;
-        super.toObjectValue(em, vm, val, store, fetch, _cols, idx);
-
-        // after loading everything from result, load the rest of the
-        // configured fields
-        em.load(fetch);
-        return em.getManagedInstance();
-    }
-
-    /////////////////////////////
-    // RelationId implementation
-    /////////////////////////////
-
-    public Object toRelationDataStoreValue(OpenJPAStateManager sm, Column col) {
-        return toRelationDataStoreValue(sm, col, 0);
-    }
-
-    /**
-     * Recursive helper.
-     */
-    private Object toRelationDataStoreValue(OpenJPAStateManager sm, Column col,
-        int idx) {
-        FieldMapping field = findField(col, idx);
-        if (field == null)
-            throw new InternalException();
-
-        if (field.getHandler() instanceof RelationId)
-            return ((RelationId) field.getStrategy()).
-                toRelationDataStoreValue(sm, col);
-        if (field.getStrategy() instanceof RelationId)
-            return ((RelationId) field.getStrategy()).
-                toRelationDataStoreValue(sm, col);
-        return toRelationDataStoreValue(sm, col, field.getIndex() + 1);
-    }
-
-    /**
-     * Find the first field mapping that uses the given column starting with
-     * the given field index.
-     */
-    private FieldMapping findField(Column col, int idx) {
-        FieldMapping[] fms = _vm.getEmbeddedMapping().getFieldMappings();
-        Column[] cols;
-        for (int i = idx; i < fms.length; i++) {
-            if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT)
-                continue;
-            cols = ((Embeddable) fms[i]).getColumns();
-            for (int j = 0; j < cols.length; j++)
-                if (cols[j] == col)
-                    return fms[i];
-        }
-        return null;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.util.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.schema.*;
+
+/**
+ * <p>Handler for embedded objects as elements of a collection or map.  For
+ * embedded objects as fields, use the more powerful
+ * {@link EmbedFieldStrategy}.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ * @nojavadoc
+ */
+public class ElementEmbedValueHandler
+    extends EmbedValueHandler
+    implements RelationId {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (ElementEmbedValueHandler.class);
+
+    private ValueMapping _vm = null;
+    private Column[] _cols = null;
+    private Object[] _args = null;
+    private int _nullIdx = -1;
+    private boolean _synthetic = false;
+
+    public Column[] map(ValueMapping vm, String name, ColumnIO io,
+        boolean adapt) {
+        LinkedList cols = new LinkedList();
+        LinkedList args = new LinkedList();
+        super.map(vm, name, io, adapt, cols, args);
+
+        ValueMappingInfo vinfo = vm.getValueInfo();
+        Column nullInd = vinfo.getNullIndicatorColumn(vm, name,
+            vm.getFieldMapping().getTable(), adapt);
+        if (nullInd != null)
+            vm.setColumns(new Column[]{ nullInd });
+
+        // record index of null indicator column and whether it is synthetic
+        if (nullInd != null) {
+            _nullIdx = cols.indexOf(nullInd);
+            if (_nullIdx == -1) {
+                cols.addFirst(nullInd);
+                args.addFirst(null);
+                _nullIdx = 0;
+                _synthetic = true;
+            }
+        }
+
+        _vm = vm;
+        _cols = (Column[]) cols.toArray(new Column[cols.size()]);
+        _args = args.toArray();
+        return _cols;
+    }
+
+    public boolean objectValueRequiresLoad(ValueMapping vm) {
+        return true;
+    }
+
+    public Object getResultArgument(ValueMapping vm) {
+        return _args;
+    }
+
+    public Object toDataStoreValue(ValueMapping vm, Object val,
+        JDBCStore store) {
+        OpenJPAStateManager em = store.getContext().getStateManager(val);
+        Object rval = null;
+        if (_cols.length > 1)
+            rval = new Object[_cols.length];
+
+        // set null indicator column
+        int idx = 0;
+        if (_synthetic) {
+            Object cval = ((EmbeddedClassStrategy) vm.getEmbeddedMapping().
+                getStrategy()).getNullIndicatorValue(em);
+            if (_cols.length == 1)
+                return cval;
+            ((Object[]) rval)[idx++] = cval;
+        }
+
+        return super.toDataStoreValue(em, vm, store, _cols, rval, idx);
+    }
+
+    public Object toObjectValue(ValueMapping vm, Object val,
+        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch)
+        throws SQLException {
+        if (sm == null)
+            throw new InvalidStateException(_loc.get("cant-project-owned",
+                vm));
+
+        // check null indicator first
+        if (_nullIdx != -1) {
+            Object nval;
+            if (_cols.length == 1)
+                nval = val;
+            else
+                nval = ((Object[]) val)[_nullIdx];
+            if (((EmbeddedClassStrategy) vm.getEmbeddedMapping().
+                getStrategy()).indicatesNull(nval))
+                return null;
+        }
+
+        // create embedded instance
+        OpenJPAStateManager em = store.getContext().embed(null, null, sm, vm);
+        int idx = (_synthetic) ? 1 : 0;
+        super.toObjectValue(em, vm, val, store, fetch, _cols, idx);
+
+        // after loading everything from result, load the rest of the
+        // configured fields
+        em.load(fetch);
+        return em.getManagedInstance();
+    }
+
+    /////////////////////////////
+    // RelationId implementation
+    /////////////////////////////
+
+    public Object toRelationDataStoreValue(OpenJPAStateManager sm, Column col) {
+        return toRelationDataStoreValue(sm, col, 0);
+    }
+
+    /**
+     * Recursive helper.
+     */
+    private Object toRelationDataStoreValue(OpenJPAStateManager sm, Column col,
+        int idx) {
+        FieldMapping field = findField(col, idx);
+        if (field == null)
+            throw new InternalException();
+
+        if (field.getHandler() instanceof RelationId)
+            return ((RelationId) field.getStrategy()).
+                toRelationDataStoreValue(sm, col);
+        if (field.getStrategy() instanceof RelationId)
+            return ((RelationId) field.getStrategy()).
+                toRelationDataStoreValue(sm, col);
+        return toRelationDataStoreValue(sm, col, field.getIndex() + 1);
+    }
+
+    /**
+     * Find the first field mapping that uses the given column starting with
+     * the given field index.
+     */
+    private FieldMapping findField(Column col, int idx) {
+        FieldMapping[] fms = _vm.getEmbeddedMapping().getFieldMappings();
+        Column[] cols;
+        for (int i = idx; i < fms.length; i++) {
+            if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT)
+                continue;
+            cols = ((Embeddable) fms[i]).getColumns();
+            for (int j = 0; j < cols.length; j++)
+                if (cols[j] == col)
+                    return fms[i];
+        }
+        return null;
+	}
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerCollectionTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerCollectionTableFieldStrategy.java
index 21861e4..dd15e30 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerCollectionTableFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerCollectionTableFieldStrategy.java
@@ -1,250 +1,250 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.lib.util.*;
-
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.util.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.schema.*;
-import org.apache.openjpa.jdbc.sql.*;
-
-/**
- * <p>Mapping for a collection of values in a separate table controlled by a
- * {@link ValueHandler}.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-public class HandlerCollectionTableFieldStrategy
-    extends StoreCollectionFieldStrategy
-    implements LRSCollectionFieldStrategy {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (HandlerCollectionTableFieldStrategy.class);
-
-    private Column[] _cols = null;
-    private ColumnIO _io = null;
-    private boolean _load = false;
-    private boolean _lob = false;
-    private boolean _embed = false;
-
-    public FieldMapping getFieldMapping() {
-        return field;
-    }
-
-    public ClassMapping[] getIndependentElementMappings(boolean traverse) {
-        return ClassMapping.EMPTY_MAPPINGS;
-    }
-
-    public Column[] getElementColumns(ClassMapping elem) {
-        return _cols;
-    }
-
-    public ForeignKey getJoinForeignKey(ClassMapping elem) {
-        return field.getJoinForeignKey();
-    }
-
-    public void selectElement(Select sel, ClassMapping elem, JDBCStore store,
-        JDBCFetchConfiguration fetch, int eagerMode, Joins joins) {
-        sel.select(_cols, joins);
-    }
-
-    public Object loadElement(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        return HandlerStrategies.loadObject(field.getElementMapping(),
-            sm, store, fetch, res, joins, _cols, _load);
-    }
-
-    protected Joins join(Joins joins, ClassMapping elem) {
-        return join(joins, false);
-    }
-
-    public Joins joinElementRelation(Joins joins, ClassMapping elem) {
-        return joinRelation(joins, false, false);
-    }
-
-    protected Proxy newLRSProxy() {
-        return new LRSProxyCollection(this);
-    }
-
-    public void map(boolean adapt) {
-        if (field.getTypeCode() != JavaTypes.COLLECTION
-            && field.getTypeCode() != JavaTypes.ARRAY)
-            throw new MetaDataException(_loc.get("not-coll", field));
-
-        assertNotMappedBy();
-        field.getValueInfo().assertNoSchemaComponents(field, !adapt);
-        field.getKeyMapping().getValueInfo().assertNoSchemaComponents
-            (field.getKey(), !adapt);
-
-        ValueMapping elem = field.getElementMapping();
-        if (elem.getHandler() == null)
-            throw new MetaDataException(_loc.get("no-handler", elem));
-
-        field.mapJoin(adapt, true);
-        _io = new ColumnIO();
-        _cols = HandlerStrategies.map(elem, "element", _io, adapt);
-
-        FieldMappingInfo finfo = field.getMappingInfo();
-        Column orderCol = finfo.getOrderColumn(field, field.getTable(), adapt);
-        field.setOrderColumn(orderCol);
-        field.setOrderColumnIO(finfo.getColumnIO());
-        field.mapPrimaryKey(adapt);
-    }
-
-    public void initialize() {
-        for (int i = 0; !_lob && i < _cols.length; i++)
-            _lob = _cols[i].isLob();
-
-        ValueMapping elem = field.getElementMapping();
-        _embed = elem.getEmbeddedMetaData() != null;
-        _load = elem.getHandler().objectValueRequiresLoad(elem);
-    }
-
-    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        insert(sm, store, rm, sm.fetchObject(field.getIndex()));
-    }
-
-    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
-        Object vals)
-        throws SQLException {
-        Collection coll;
-        if (field.getTypeCode() == JavaTypes.ARRAY)
-            coll = JavaTypes.toList(vals, field.getElement().getType(),
-                false);
-        else
-            coll = (Collection) vals;
-        if (coll == null || coll.isEmpty())
-            return;
-
-        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
-        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
-            sm);
-
-        ValueMapping elem = field.getElementMapping();
-        Column order = field.getOrderColumn();
-        boolean setOrder = field.getOrderColumnIO().isInsertable(order, false);
-        int idx = 0;
-        for (Iterator itr = coll.iterator(); itr.hasNext(); idx++) {
-            HandlerStrategies.set(elem, itr.next(), store, row, _cols,
-                _io, true);
-            if (setOrder)
-                row.setInt(order, idx);
-            rm.flushSecondaryRow(row);
-        }
-    }
-
-    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Object obj = sm.fetchObject(field.getIndex());
-        ChangeTracker ct = null;
-        if (obj instanceof Proxy) {
-            Proxy proxy = (Proxy) obj;
-            if (Proxies.isOwner(proxy, sm, field.getIndex()))
-                ct = proxy.getChangeTracker();
-        }
-
-        // if no fine-grained change tracking then just delete and reinsert
-        if (ct == null || !ct.isTracking()) {
-            delete(sm, store, rm);
-            insert(sm, store, rm, obj);
-            return;
-        }
-
-        // delete the removes
-        ValueMapping elem = field.getElementMapping();
-        Collection rem = ct.getRemoved();
-        if (!rem.isEmpty()) {
-            Row delRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_DELETE);
-            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
-            for (Iterator itr = rem.iterator(); itr.hasNext();) {
-                HandlerStrategies.where(elem, itr.next(), store, delRow,
-                    _cols);
-                rm.flushSecondaryRow(delRow);
-            }
-        }
-
-        // insert the adds
-        Collection add = ct.getAdded();
-        if (!add.isEmpty()) {
-            Row addRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_INSERT);
-            addRow.setForeignKey(field.getJoinForeignKey(),
-                field.getJoinColumnIO(), sm);
-
-            int seq = ct.getNextSequence();
-            Column order = field.getOrderColumn();
-            boolean setOrder = field.getOrderColumnIO().isInsertable(order,
-                false);
-            for (Iterator itr = add.iterator(); itr.hasNext(); seq++) {
-                HandlerStrategies.set(elem, itr.next(), store, addRow, _cols,
-                    _io, true);
-                if (setOrder)
-                    addRow.setInt(order, seq);
-                rm.flushSecondaryRow(addRow);
-            }
-            if (order != null)
-                ct.setNextSequence(seq);
-        }
-    }
-
-    public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Row row = rm.getAllRows(field.getTable(), Row.ACTION_DELETE);
-        row.whereForeignKey(field.getJoinForeignKey(), sm);
-        rm.flushAllRows(row);
-    }
-
-    public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch) {
-        // can't do any combined select with lobs, since they don't allow
-        // select distinct.  cant select eager parallel on embedded, because
-        // during parallel result processing the owning sm won't be available
-        // for each elem
-        if (_lob || (_embed && type == Select.EAGER_PARALLEL))
-            return 0;
-        return super.supportsSelect(sel, type, sm, store, fetch);
-    }
-
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
-            val, _cols, store);
-    }
-
-    public Joins join(Joins joins, boolean forceOuter) {
-        return field.join(joins, forceOuter, true);
-    }
-
-    public Joins joinRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        if (traverse)
-            HandlerStrategies.assertJoinable(field.getElementMapping());
-        return joins;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.lib.util.*;
+
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.util.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.schema.*;
+import org.apache.openjpa.jdbc.sql.*;
+
+/**
+ * <p>Mapping for a collection of values in a separate table controlled by a
+ * {@link ValueHandler}.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+public class HandlerCollectionTableFieldStrategy
+    extends StoreCollectionFieldStrategy
+    implements LRSCollectionFieldStrategy {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (HandlerCollectionTableFieldStrategy.class);
+
+    private Column[] _cols = null;
+    private ColumnIO _io = null;
+    private boolean _load = false;
+    private boolean _lob = false;
+    private boolean _embed = false;
+
+    public FieldMapping getFieldMapping() {
+        return field;
+    }
+
+    public ClassMapping[] getIndependentElementMappings(boolean traverse) {
+        return ClassMapping.EMPTY_MAPPINGS;
+    }
+
+    public Column[] getElementColumns(ClassMapping elem) {
+        return _cols;
+    }
+
+    public ForeignKey getJoinForeignKey(ClassMapping elem) {
+        return field.getJoinForeignKey();
+    }
+
+    public void selectElement(Select sel, ClassMapping elem, JDBCStore store,
+        JDBCFetchConfiguration fetch, int eagerMode, Joins joins) {
+        sel.select(_cols, joins);
+    }
+
+    public Object loadElement(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        return HandlerStrategies.loadObject(field.getElementMapping(),
+            sm, store, fetch, res, joins, _cols, _load);
+    }
+
+    protected Joins join(Joins joins, ClassMapping elem) {
+        return join(joins, false);
+    }
+
+    public Joins joinElementRelation(Joins joins, ClassMapping elem) {
+        return joinRelation(joins, false, false);
+    }
+
+    protected Proxy newLRSProxy() {
+        return new LRSProxyCollection(this);
+    }
+
+    public void map(boolean adapt) {
+        if (field.getTypeCode() != JavaTypes.COLLECTION
+            && field.getTypeCode() != JavaTypes.ARRAY)
+            throw new MetaDataException(_loc.get("not-coll", field));
+
+        assertNotMappedBy();
+        field.getValueInfo().assertNoSchemaComponents(field, !adapt);
+        field.getKeyMapping().getValueInfo().assertNoSchemaComponents
+            (field.getKey(), !adapt);
+
+        ValueMapping elem = field.getElementMapping();
+        if (elem.getHandler() == null)
+            throw new MetaDataException(_loc.get("no-handler", elem));
+
+        field.mapJoin(adapt, true);
+        _io = new ColumnIO();
+        _cols = HandlerStrategies.map(elem, "element", _io, adapt);
+
+        FieldMappingInfo finfo = field.getMappingInfo();
+        Column orderCol = finfo.getOrderColumn(field, field.getTable(), adapt);
+        field.setOrderColumn(orderCol);
+        field.setOrderColumnIO(finfo.getColumnIO());
+        field.mapPrimaryKey(adapt);
+    }
+
+    public void initialize() {
+        for (int i = 0; !_lob && i < _cols.length; i++)
+            _lob = _cols[i].isLob();
+
+        ValueMapping elem = field.getElementMapping();
+        _embed = elem.getEmbeddedMetaData() != null;
+        _load = elem.getHandler().objectValueRequiresLoad(elem);
+    }
+
+    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        insert(sm, store, rm, sm.fetchObject(field.getIndex()));
+    }
+
+    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+        Object vals)
+        throws SQLException {
+        Collection coll;
+        if (field.getTypeCode() == JavaTypes.ARRAY)
+            coll = JavaTypes.toList(vals, field.getElement().getType(),
+                false);
+        else
+            coll = (Collection) vals;
+        if (coll == null || coll.isEmpty())
+            return;
+
+        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+            sm);
+
+        ValueMapping elem = field.getElementMapping();
+        Column order = field.getOrderColumn();
+        boolean setOrder = field.getOrderColumnIO().isInsertable(order, false);
+        int idx = 0;
+        for (Iterator itr = coll.iterator(); itr.hasNext(); idx++) {
+            HandlerStrategies.set(elem, itr.next(), store, row, _cols,
+                _io, true);
+            if (setOrder)
+                row.setInt(order, idx);
+            rm.flushSecondaryRow(row);
+        }
+    }
+
+    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Object obj = sm.fetchObject(field.getIndex());
+        ChangeTracker ct = null;
+        if (obj instanceof Proxy) {
+            Proxy proxy = (Proxy) obj;
+            if (Proxies.isOwner(proxy, sm, field.getIndex()))
+                ct = proxy.getChangeTracker();
+        }
+
+        // if no fine-grained change tracking then just delete and reinsert
+        if (ct == null || !ct.isTracking()) {
+            delete(sm, store, rm);
+            insert(sm, store, rm, obj);
+            return;
+        }
+
+        // delete the removes
+        ValueMapping elem = field.getElementMapping();
+        Collection rem = ct.getRemoved();
+        if (!rem.isEmpty()) {
+            Row delRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_DELETE);
+            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
+            for (Iterator itr = rem.iterator(); itr.hasNext();) {
+                HandlerStrategies.where(elem, itr.next(), store, delRow,
+                    _cols);
+                rm.flushSecondaryRow(delRow);
+            }
+        }
+
+        // insert the adds
+        Collection add = ct.getAdded();
+        if (!add.isEmpty()) {
+            Row addRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_INSERT);
+            addRow.setForeignKey(field.getJoinForeignKey(),
+                field.getJoinColumnIO(), sm);
+
+            int seq = ct.getNextSequence();
+            Column order = field.getOrderColumn();
+            boolean setOrder = field.getOrderColumnIO().isInsertable(order,
+                false);
+            for (Iterator itr = add.iterator(); itr.hasNext(); seq++) {
+                HandlerStrategies.set(elem, itr.next(), store, addRow, _cols,
+                    _io, true);
+                if (setOrder)
+                    addRow.setInt(order, seq);
+                rm.flushSecondaryRow(addRow);
+            }
+            if (order != null)
+                ct.setNextSequence(seq);
+        }
+    }
+
+    public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Row row = rm.getAllRows(field.getTable(), Row.ACTION_DELETE);
+        row.whereForeignKey(field.getJoinForeignKey(), sm);
+        rm.flushAllRows(row);
+    }
+
+    public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch) {
+        // can't do any combined select with lobs, since they don't allow
+        // select distinct.  cant select eager parallel on embedded, because
+        // during parallel result processing the owning sm won't be available
+        // for each elem
+        if (_lob || (_embed && type == Select.EAGER_PARALLEL))
+            return 0;
+        return super.supportsSelect(sel, type, sm, store, fetch);
+    }
+
+    public Object toDataStoreValue(Object val, JDBCStore store) {
+        return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
+            val, _cols, store);
+    }
+
+    public Joins join(Joins joins, boolean forceOuter) {
+        return field.join(joins, forceOuter, true);
+    }
+
+    public Joins joinRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        if (traverse)
+            HandlerStrategies.assertJoinable(field.getElementMapping());
+        return joins;
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
index e7859a2..0fed898 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
@@ -1,246 +1,246 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.schema.*;
-import org.apache.openjpa.jdbc.sql.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.lib.util.*;
-import org.apache.openjpa.util.*;
-
-/**
- * Mapping for a map of keys and values both controlled by
- * {@link ValueHandler}s.
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-public class HandlerHandlerMapTableFieldStrategy
-    extends MapTableFieldStrategy {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (HandlerHandlerMapTableFieldStrategy.class);
-
-    private Column[] _kcols = null;
-    private ColumnIO _kio = null;
-    private boolean _kload = false;
-    private Column[] _vcols = null;
-    private ColumnIO _vio = null;
-    private boolean _vload = false;
-
-    public Column[] getKeyColumns(ClassMapping cls) {
-        return _kcols;
-    }
-
-    public Column[] getValueColumns(ClassMapping cls) {
-        return _vcols;
-    }
-
-    public void selectKey(Select sel, ClassMapping cls, OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
-        sel.select(_kcols, joins);
-    }
-
-    public void selectValue(Select sel, ClassMapping cls,
-        OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
-        sel.select(_vcols, joins);
-    }
-
-    public Result[] getResults(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, int eagerMode, Joins[] joins, boolean lrs)
-        throws SQLException {
-        Select sel = store.getSQLFactory().newSelect();
-        sel.setLRS(lrs);
-        sel.select(_kcols);
-        sel.select(_vcols);
-        sel.whereForeignKey(field.getJoinForeignKey(), sm.getObjectId(),
-            field.getDefiningMapping(), store);
-        Result res = sel.execute(store, fetch);
-        return new Result[]{ res, res };
-    }
-
-    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        return HandlerStrategies.loadObject(field.getKeyMapping(),
-            sm, store, fetch, res, joins, _kcols, _kload);
-    }
-
-    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        return HandlerStrategies.loadObject(field.getElementMapping(),
-            sm, store, fetch, res, joins, _vcols, _vload);
-    }
-
-    public void map(boolean adapt) {
-        super.map(adapt);
-
-        ValueMapping key = field.getKeyMapping();
-        if (key.getHandler() == null)
-            throw new MetaDataException(_loc.get("no-handler", key));
-        ValueMapping val = field.getElementMapping();
-        if (val.getHandler() == null)
-            throw new MetaDataException(_loc.get("no-handler", val));
-        assertNotMappedBy();
-
-        field.mapJoin(adapt, true);
-        _kio = new ColumnIO();
-        DBDictionary dict = field.getMappingRepository().getDBDictionary();
-        _kcols = HandlerStrategies.map(key, 
-            dict.getValidColumnName("key", field.getTable()), _kio, adapt);
-
-        _vio = new ColumnIO();
-        _vcols = HandlerStrategies.map(val, "value", _vio, adapt);
-        field.mapPrimaryKey(adapt);
-    }
-
-    public void initialize() {
-        _kload = field.getKeyMapping().getHandler().
-            objectValueRequiresLoad(field.getKeyMapping());
-        _vload = field.getElementMapping().getHandler().
-            objectValueRequiresLoad(field.getElementMapping());
-    }
-
-    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
-    }
-
-    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
-        Map map)
-        throws SQLException {
-        if (map == null || map.isEmpty())
-            return;
-
-        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
-        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
-            sm);
-
-        ValueMapping key = field.getKeyMapping();
-        ValueMapping val = field.getElementMapping();
-        Map.Entry entry;
-        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
-                _kio, true);
-            HandlerStrategies.set(val, entry.getValue(), store, row, _vcols,
-                _vio, true);
-            rm.flushSecondaryRow(row);
-        }
-    }
-
-    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Map map = (Map) sm.fetchObject(field.getIndex());
-        ChangeTracker ct = null;
-        if (map instanceof Proxy) {
-            Proxy proxy = (Proxy) map;
-            if (Proxies.isOwner(proxy, sm, field.getIndex()))
-                ct = proxy.getChangeTracker();
-        }
-
-        // if no fine-grained change tracking then just delete and reinsert
-        if (ct == null || !ct.isTracking()) {
-            delete(sm, store, rm);
-            insert(sm, store, rm, map);
-            return;
-        }
-
-        // delete the removes
-        ValueMapping key = field.getKeyMapping();
-        Collection rem = ct.getRemoved();
-        if (!rem.isEmpty()) {
-            Row delRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_DELETE);
-            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
-            for (Iterator itr = rem.iterator(); itr.hasNext();) {
-                HandlerStrategies.where(key, itr.next(), store, delRow,
-                    _kcols);
-                rm.flushSecondaryRow(delRow);
-            }
-        }
-
-        // insert the adds
-        ValueMapping val = field.getElementMapping();
-        Collection add = ct.getAdded();
-        Object mkey;
-        if (!add.isEmpty()) {
-            Row addRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_INSERT);
-            addRow.setForeignKey(field.getJoinForeignKey(),
-                field.getJoinColumnIO(), sm);
-
-            for (Iterator itr = add.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                HandlerStrategies.set(key, mkey, store, addRow, _kcols,
-                    _kio, true);
-                HandlerStrategies.set(val, map.get(mkey), store, addRow,
-                    _vcols, _vio, true);
-                rm.flushSecondaryRow(addRow);
-            }
-        }
-
-        // update the changes
-        Collection change = ct.getChanged();
-        if (!change.isEmpty()) {
-            Row changeRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_UPDATE);
-            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
-            for (Iterator itr = change.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
-                HandlerStrategies.set(val, map.get(mkey), store, changeRow,
-                    _vcols, _vio, true);
-                rm.flushSecondaryRow(changeRow);
-            }
-        }
-    }
-
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
-            val, _vcols, store);
-    }
-
-    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
-        return HandlerStrategies.toDataStoreValue(field.getKeyMapping(), val,
-            _kcols, store);
-    }
-
-    public Joins joinRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        if (traverse)
-            HandlerStrategies.assertJoinable(field.getElementMapping());
-        return joins;
-    }
-
-    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        if (traverse)
-            HandlerStrategies.assertJoinable(field.getKeyMapping());
-        return joins;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.schema.*;
+import org.apache.openjpa.jdbc.sql.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.util.*;
+
+/**
+ * Mapping for a map of keys and values both controlled by
+ * {@link ValueHandler}s.
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+public class HandlerHandlerMapTableFieldStrategy
+    extends MapTableFieldStrategy {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (HandlerHandlerMapTableFieldStrategy.class);
+
+    private Column[] _kcols = null;
+    private ColumnIO _kio = null;
+    private boolean _kload = false;
+    private Column[] _vcols = null;
+    private ColumnIO _vio = null;
+    private boolean _vload = false;
+
+    public Column[] getKeyColumns(ClassMapping cls) {
+        return _kcols;
+    }
+
+    public Column[] getValueColumns(ClassMapping cls) {
+        return _vcols;
+    }
+
+    public void selectKey(Select sel, ClassMapping cls, OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
+        sel.select(_kcols, joins);
+    }
+
+    public void selectValue(Select sel, ClassMapping cls,
+        OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
+        sel.select(_vcols, joins);
+    }
+
+    public Result[] getResults(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, int eagerMode, Joins[] joins, boolean lrs)
+        throws SQLException {
+        Select sel = store.getSQLFactory().newSelect();
+        sel.setLRS(lrs);
+        sel.select(_kcols);
+        sel.select(_vcols);
+        sel.whereForeignKey(field.getJoinForeignKey(), sm.getObjectId(),
+            field.getDefiningMapping(), store);
+        Result res = sel.execute(store, fetch);
+        return new Result[]{ res, res };
+    }
+
+    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        return HandlerStrategies.loadObject(field.getKeyMapping(),
+            sm, store, fetch, res, joins, _kcols, _kload);
+    }
+
+    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        return HandlerStrategies.loadObject(field.getElementMapping(),
+            sm, store, fetch, res, joins, _vcols, _vload);
+    }
+
+    public void map(boolean adapt) {
+        super.map(adapt);
+
+        ValueMapping key = field.getKeyMapping();
+        if (key.getHandler() == null)
+            throw new MetaDataException(_loc.get("no-handler", key));
+        ValueMapping val = field.getElementMapping();
+        if (val.getHandler() == null)
+            throw new MetaDataException(_loc.get("no-handler", val));
+        assertNotMappedBy();
+
+        field.mapJoin(adapt, true);
+        _kio = new ColumnIO();
+        DBDictionary dict = field.getMappingRepository().getDBDictionary();
+        _kcols = HandlerStrategies.map(key, 
+            dict.getValidColumnName("key", field.getTable()), _kio, adapt);
+
+        _vio = new ColumnIO();
+        _vcols = HandlerStrategies.map(val, "value", _vio, adapt);
+        field.mapPrimaryKey(adapt);
+    }
+
+    public void initialize() {
+        _kload = field.getKeyMapping().getHandler().
+            objectValueRequiresLoad(field.getKeyMapping());
+        _vload = field.getElementMapping().getHandler().
+            objectValueRequiresLoad(field.getElementMapping());
+    }
+
+    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
+    }
+
+    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+        Map map)
+        throws SQLException {
+        if (map == null || map.isEmpty())
+            return;
+
+        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+            sm);
+
+        ValueMapping key = field.getKeyMapping();
+        ValueMapping val = field.getElementMapping();
+        Map.Entry entry;
+        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
+                _kio, true);
+            HandlerStrategies.set(val, entry.getValue(), store, row, _vcols,
+                _vio, true);
+            rm.flushSecondaryRow(row);
+        }
+    }
+
+    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Map map = (Map) sm.fetchObject(field.getIndex());
+        ChangeTracker ct = null;
+        if (map instanceof Proxy) {
+            Proxy proxy = (Proxy) map;
+            if (Proxies.isOwner(proxy, sm, field.getIndex()))
+                ct = proxy.getChangeTracker();
+        }
+
+        // if no fine-grained change tracking then just delete and reinsert
+        if (ct == null || !ct.isTracking()) {
+            delete(sm, store, rm);
+            insert(sm, store, rm, map);
+            return;
+        }
+
+        // delete the removes
+        ValueMapping key = field.getKeyMapping();
+        Collection rem = ct.getRemoved();
+        if (!rem.isEmpty()) {
+            Row delRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_DELETE);
+            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
+            for (Iterator itr = rem.iterator(); itr.hasNext();) {
+                HandlerStrategies.where(key, itr.next(), store, delRow,
+                    _kcols);
+                rm.flushSecondaryRow(delRow);
+            }
+        }
+
+        // insert the adds
+        ValueMapping val = field.getElementMapping();
+        Collection add = ct.getAdded();
+        Object mkey;
+        if (!add.isEmpty()) {
+            Row addRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_INSERT);
+            addRow.setForeignKey(field.getJoinForeignKey(),
+                field.getJoinColumnIO(), sm);
+
+            for (Iterator itr = add.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                HandlerStrategies.set(key, mkey, store, addRow, _kcols,
+                    _kio, true);
+                HandlerStrategies.set(val, map.get(mkey), store, addRow,
+                    _vcols, _vio, true);
+                rm.flushSecondaryRow(addRow);
+            }
+        }
+
+        // update the changes
+        Collection change = ct.getChanged();
+        if (!change.isEmpty()) {
+            Row changeRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_UPDATE);
+            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+            for (Iterator itr = change.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
+                HandlerStrategies.set(val, map.get(mkey), store, changeRow,
+                    _vcols, _vio, true);
+                rm.flushSecondaryRow(changeRow);
+            }
+        }
+    }
+
+    public Object toDataStoreValue(Object val, JDBCStore store) {
+        return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
+            val, _vcols, store);
+    }
+
+    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
+        return HandlerStrategies.toDataStoreValue(field.getKeyMapping(), val,
+            _kcols, store);
+    }
+
+    public Joins joinRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        if (traverse)
+            HandlerStrategies.assertJoinable(field.getElementMapping());
+        return joins;
+    }
+
+    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        if (traverse)
+            HandlerStrategies.assertJoinable(field.getKeyMapping());
+        return joins;
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java
index a931b4c..3731c06 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java
@@ -1,315 +1,315 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.lib.util.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.util.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.schema.*;
-import org.apache.openjpa.jdbc.sql.*;
-
-/**
- * <p>Mapping for a map whose keys are controlled by a {@link ValueHandler}
- * and whose values are relations to other persistent objects.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-public class HandlerRelationMapTableFieldStrategy
-    extends MapTableFieldStrategy {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (HandlerRelationMapTableFieldStrategy.class);
-
-    private Column[] _kcols = null;
-    private ColumnIO _kio = null;
-    private boolean _kload = false;
-
-    public Column[] getKeyColumns(ClassMapping cls) {
-        return _kcols;
-    }
-
-    public Column[] getValueColumns(ClassMapping cls) {
-        return field.getElementMapping().getColumns();
-    }
-
-    public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
-        sel.select(_kcols, joins);
-    }
-
-    public void selectValue(Select sel, ClassMapping val,
-        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, 
-        Joins joins) {
-        sel.select(val, field.getElementMapping().getSelectSubclasses(),
-            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
-    }
-
-    public Result[] getResults(final OpenJPAStateManager sm,
-        final JDBCStore store, final JDBCFetchConfiguration fetch,
-        final int eagerMode, final Joins[] resJoins, boolean lrs)
-        throws SQLException {
-        ValueMapping elem = field.getElementMapping();
-        final ClassMapping[] vals = elem.getIndependentTypeMappings();
-        Union union = store.getSQLFactory().newUnion(vals.length);
-        if (fetch.getSubclassFetchMode(elem.getTypeMapping())
-            != JDBCFetchConfiguration.EAGER_JOIN)
-            union.abortUnion();
-        union.setLRS(lrs);
-        union.select(new Union.Selector() {
-            public void select(Select sel, int idx) {
-                sel.select(_kcols);
-                sel.whereForeignKey(field.getJoinForeignKey(),
-                    sm.getObjectId(), field.getDefiningMapping(), store);
-
-                Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
-                sel.select(vals[idx], field.getElementMapping().
-                    getSelectSubclasses(), store, fetch, eagerMode, joins);
-
-                //### cheat: result joins only care about the relation path;
-                //### thus we can use first mapping of union only
-                if (idx == 0)
-                    resJoins[1] = joins;
-            }
-        });
-        Result res = union.execute(store, fetch);
-        return new Result[]{ res, res };
-    }
-
-    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        return HandlerStrategies.loadObject(field.getKeyMapping(),
-            sm, store, fetch, res, joins, _kcols, _kload);
-    }
-
-    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        ClassMapping val = res.getBaseMapping();
-        if (val == null)
-            val = field.getElementMapping().getIndependentTypeMappings()[0];
-        return res.load(val, store, fetch, joins);
-    }
-
-    public Joins joinValueRelation(Joins joins, ClassMapping val) {
-        ValueMapping vm = field.getElementMapping();
-        return joins.joinRelation(field.getName(), vm.getForeignKey(val), val,
-            vm.getSelectSubclasses(), false, false);
-    }
-
-    public void map(boolean adapt) {
-        super.map(adapt);
-
-        ValueMapping key = field.getKeyMapping();
-        if (key.getHandler() == null)
-            throw new MetaDataException(_loc.get("no-handler", key));
-        ValueMapping val = field.getElementMapping();
-        if (val.getTypeCode() != JavaTypes.PC || val.isEmbeddedPC())
-            throw new MetaDataException(_loc.get("not-relation", val));
-        assertNotMappedBy();
-
-        field.mapJoin(adapt, true);
-        _kio = new ColumnIO();
-        DBDictionary dict = field.getMappingRepository().getDBDictionary();
-        _kcols = HandlerStrategies.map(key, 
-            dict.getValidColumnName("key", field.getTable()), _kio, adapt);
-
-        if (val.getTypeMapping().isMapped()) {
-            ValueMappingInfo vinfo = val.getValueInfo();
-            ForeignKey fk = vinfo.getTypeJoin(val, "value", false, adapt);
-            val.setForeignKey(fk);
-            val.setColumnIO(vinfo.getColumnIO());
-        } else
-            RelationStrategies.mapRelationToUnmappedPC(val, "value", adapt);
-
-        val.mapConstraints("value", adapt);
-        field.mapPrimaryKey(adapt);
-    }
-
-    public void initialize() {
-        _kload = field.getKeyMapping().getHandler().
-            objectValueRequiresLoad(field.getKeyMapping());
-    }
-
-    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
-    }
-
-    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
-        Map map)
-        throws SQLException {
-        if (map == null || map.isEmpty())
-            return;
-
-        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
-        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
-            sm);
-
-        ValueMapping key = field.getKeyMapping();
-        ValueMapping val = field.getElementMapping();
-        StoreContext ctx = store.getContext();
-        OpenJPAStateManager valsm;
-        Map.Entry entry;
-        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
-                _kio, true);
-            valsm = RelationStrategies.getStateManager(entry.getValue(),
-                ctx);
-            val.setForeignKey(row, valsm);
-            rm.flushSecondaryRow(row);
-        }
-    }
-
-    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Map map = (Map) sm.fetchObject(field.getIndex());
-        ChangeTracker ct = null;
-        if (map instanceof Proxy) {
-            Proxy proxy = (Proxy) map;
-            if (Proxies.isOwner(proxy, sm, field.getIndex()))
-                ct = proxy.getChangeTracker();
-        }
-
-        // if no fine-grained change tracking then just delete and reinsert
-        if (ct == null || !ct.isTracking()) {
-            delete(sm, store, rm);
-            insert(sm, store, rm, map);
-            return;
-        }
-
-        ValueMapping key = field.getKeyMapping();
-        ValueMapping val = field.getElementMapping();
-        StoreContext ctx = store.getContext();
-        OpenJPAStateManager valsm;
-
-        // update the changes; note that we have to model changes as
-        // delete-then-insert if we have a foreign key action, because
-        // secondary row updates aren't part of the constraint graph
-        Collection change = ct.getChanged();
-        boolean canChange = val.getForeignKey().isLogical();
-        Object mkey;
-        if (canChange && !change.isEmpty()) {
-            Row changeRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_UPDATE);
-            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
-            for (Iterator itr = change.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
-                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
-                val.setForeignKey(changeRow, valsm);
-                rm.flushSecondaryRow(changeRow);
-            }
-        }
-
-        // delete the removes
-        Collection rem = ct.getRemoved();
-        if (!rem.isEmpty() || (!canChange && !change.isEmpty())) {
-            Row delRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_DELETE);
-            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
-            for (Iterator itr = rem.iterator(); itr.hasNext();) {
-                HandlerStrategies.where(key, itr.next(), store, delRow,
-                    _kcols);
-                rm.flushSecondaryRow(delRow);
-            }
-            if (!canChange && !change.isEmpty()) {
-                for (Iterator itr = change.iterator(); itr.hasNext();) {
-                    HandlerStrategies.where(key, itr.next(), store, delRow,
-                        _kcols);
-                    rm.flushSecondaryRow(delRow);
-                }
-            }
-        }
-
-        // insert the adds
-        Collection add = ct.getAdded();
-        if (!add.isEmpty() || (!canChange && !change.isEmpty())) {
-            Row addRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_INSERT);
-            addRow.setForeignKey(field.getJoinForeignKey(),
-                field.getJoinColumnIO(), sm);
-
-            for (Iterator itr = add.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                HandlerStrategies.set(key, mkey, store, addRow, _kcols,
-                    _kio, true);
-                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
-                val.setForeignKey(addRow, valsm);
-                rm.flushSecondaryRow(addRow);
-            }
-            if (!canChange && !change.isEmpty()) {
-                for (Iterator itr = change.iterator(); itr.hasNext();) {
-                    mkey = itr.next();
-                    HandlerStrategies.set(key, mkey, store, addRow, _kcols,
-                        _kio, true);
-                    valsm = RelationStrategies.getStateManager(map.get(mkey),
-                        ctx);
-                    val.setForeignKey(addRow, valsm);
-                    rm.flushSecondaryRow(addRow);
-                }
-            }
-        }
-    }
-
-    public Joins joinRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        ValueMapping val = field.getElementMapping();
-        ClassMapping[] clss = val.getIndependentTypeMappings();
-        if (clss.length != 1) {
-            if (traverse)
-                throw RelationStrategies.unjoinable(val);
-            return joins;
-        }
-        if (forceOuter)
-            return joins.outerJoinRelation(field.getName(),
-                val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(),
-                false, false);
-        return joins.joinRelation(field.getName(),
-            val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(), 
-            false, false);
-    }
-
-    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        if (traverse)
-            HandlerStrategies.assertJoinable(field.getKeyMapping());
-        return joins;
-    }
-
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return RelationStrategies.toDataStoreValue(field.getElementMapping(),
-            val, store);
-    }
-
-    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
-        return HandlerStrategies.toDataStoreValue(field.getKeyMapping(), val,
-            _kcols, store);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.util.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.schema.*;
+import org.apache.openjpa.jdbc.sql.*;
+
+/**
+ * <p>Mapping for a map whose keys are controlled by a {@link ValueHandler}
+ * and whose values are relations to other persistent objects.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+public class HandlerRelationMapTableFieldStrategy
+    extends MapTableFieldStrategy {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (HandlerRelationMapTableFieldStrategy.class);
+
+    private Column[] _kcols = null;
+    private ColumnIO _kio = null;
+    private boolean _kload = false;
+
+    public Column[] getKeyColumns(ClassMapping cls) {
+        return _kcols;
+    }
+
+    public Column[] getValueColumns(ClassMapping cls) {
+        return field.getElementMapping().getColumns();
+    }
+
+    public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
+        sel.select(_kcols, joins);
+    }
+
+    public void selectValue(Select sel, ClassMapping val,
+        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, 
+        Joins joins) {
+        sel.select(val, field.getElementMapping().getSelectSubclasses(),
+            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
+    }
+
+    public Result[] getResults(final OpenJPAStateManager sm,
+        final JDBCStore store, final JDBCFetchConfiguration fetch,
+        final int eagerMode, final Joins[] resJoins, boolean lrs)
+        throws SQLException {
+        ValueMapping elem = field.getElementMapping();
+        final ClassMapping[] vals = elem.getIndependentTypeMappings();
+        Union union = store.getSQLFactory().newUnion(vals.length);
+        if (fetch.getSubclassFetchMode(elem.getTypeMapping())
+            != JDBCFetchConfiguration.EAGER_JOIN)
+            union.abortUnion();
+        union.setLRS(lrs);
+        union.select(new Union.Selector() {
+            public void select(Select sel, int idx) {
+                sel.select(_kcols);
+                sel.whereForeignKey(field.getJoinForeignKey(),
+                    sm.getObjectId(), field.getDefiningMapping(), store);
+
+                Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
+                sel.select(vals[idx], field.getElementMapping().
+                    getSelectSubclasses(), store, fetch, eagerMode, joins);
+
+                //### cheat: result joins only care about the relation path;
+                //### thus we can use first mapping of union only
+                if (idx == 0)
+                    resJoins[1] = joins;
+            }
+        });
+        Result res = union.execute(store, fetch);
+        return new Result[]{ res, res };
+    }
+
+    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        return HandlerStrategies.loadObject(field.getKeyMapping(),
+            sm, store, fetch, res, joins, _kcols, _kload);
+    }
+
+    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        ClassMapping val = res.getBaseMapping();
+        if (val == null)
+            val = field.getElementMapping().getIndependentTypeMappings()[0];
+        return res.load(val, store, fetch, joins);
+    }
+
+    public Joins joinValueRelation(Joins joins, ClassMapping val) {
+        ValueMapping vm = field.getElementMapping();
+        return joins.joinRelation(field.getName(), vm.getForeignKey(val), val,
+            vm.getSelectSubclasses(), false, false);
+    }
+
+    public void map(boolean adapt) {
+        super.map(adapt);
+
+        ValueMapping key = field.getKeyMapping();
+        if (key.getHandler() == null)
+            throw new MetaDataException(_loc.get("no-handler", key));
+        ValueMapping val = field.getElementMapping();
+        if (val.getTypeCode() != JavaTypes.PC || val.isEmbeddedPC())
+            throw new MetaDataException(_loc.get("not-relation", val));
+        assertNotMappedBy();
+
+        field.mapJoin(adapt, true);
+        _kio = new ColumnIO();
+        DBDictionary dict = field.getMappingRepository().getDBDictionary();
+        _kcols = HandlerStrategies.map(key, 
+            dict.getValidColumnName("key", field.getTable()), _kio, adapt);
+
+        if (val.getTypeMapping().isMapped()) {
+            ValueMappingInfo vinfo = val.getValueInfo();
+            ForeignKey fk = vinfo.getTypeJoin(val, "value", false, adapt);
+            val.setForeignKey(fk);
+            val.setColumnIO(vinfo.getColumnIO());
+        } else
+            RelationStrategies.mapRelationToUnmappedPC(val, "value", adapt);
+
+        val.mapConstraints("value", adapt);
+        field.mapPrimaryKey(adapt);
+    }
+
+    public void initialize() {
+        _kload = field.getKeyMapping().getHandler().
+            objectValueRequiresLoad(field.getKeyMapping());
+    }
+
+    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
+    }
+
+    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+        Map map)
+        throws SQLException {
+        if (map == null || map.isEmpty())
+            return;
+
+        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+            sm);
+
+        ValueMapping key = field.getKeyMapping();
+        ValueMapping val = field.getElementMapping();
+        StoreContext ctx = store.getContext();
+        OpenJPAStateManager valsm;
+        Map.Entry entry;
+        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
+                _kio, true);
+            valsm = RelationStrategies.getStateManager(entry.getValue(),
+                ctx);
+            val.setForeignKey(row, valsm);
+            rm.flushSecondaryRow(row);
+        }
+    }
+
+    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Map map = (Map) sm.fetchObject(field.getIndex());
+        ChangeTracker ct = null;
+        if (map instanceof Proxy) {
+            Proxy proxy = (Proxy) map;
+            if (Proxies.isOwner(proxy, sm, field.getIndex()))
+                ct = proxy.getChangeTracker();
+        }
+
+        // if no fine-grained change tracking then just delete and reinsert
+        if (ct == null || !ct.isTracking()) {
+            delete(sm, store, rm);
+            insert(sm, store, rm, map);
+            return;
+        }
+
+        ValueMapping key = field.getKeyMapping();
+        ValueMapping val = field.getElementMapping();
+        StoreContext ctx = store.getContext();
+        OpenJPAStateManager valsm;
+
+        // update the changes; note that we have to model changes as
+        // delete-then-insert if we have a foreign key action, because
+        // secondary row updates aren't part of the constraint graph
+        Collection change = ct.getChanged();
+        boolean canChange = val.getForeignKey().isLogical();
+        Object mkey;
+        if (canChange && !change.isEmpty()) {
+            Row changeRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_UPDATE);
+            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+            for (Iterator itr = change.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
+                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
+                val.setForeignKey(changeRow, valsm);
+                rm.flushSecondaryRow(changeRow);
+            }
+        }
+
+        // delete the removes
+        Collection rem = ct.getRemoved();
+        if (!rem.isEmpty() || (!canChange && !change.isEmpty())) {
+            Row delRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_DELETE);
+            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+            for (Iterator itr = rem.iterator(); itr.hasNext();) {
+                HandlerStrategies.where(key, itr.next(), store, delRow,
+                    _kcols);
+                rm.flushSecondaryRow(delRow);
+            }
+            if (!canChange && !change.isEmpty()) {
+                for (Iterator itr = change.iterator(); itr.hasNext();) {
+                    HandlerStrategies.where(key, itr.next(), store, delRow,
+                        _kcols);
+                    rm.flushSecondaryRow(delRow);
+                }
+            }
+        }
+
+        // insert the adds
+        Collection add = ct.getAdded();
+        if (!add.isEmpty() || (!canChange && !change.isEmpty())) {
+            Row addRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_INSERT);
+            addRow.setForeignKey(field.getJoinForeignKey(),
+                field.getJoinColumnIO(), sm);
+
+            for (Iterator itr = add.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                HandlerStrategies.set(key, mkey, store, addRow, _kcols,
+                    _kio, true);
+                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
+                val.setForeignKey(addRow, valsm);
+                rm.flushSecondaryRow(addRow);
+            }
+            if (!canChange && !change.isEmpty()) {
+                for (Iterator itr = change.iterator(); itr.hasNext();) {
+                    mkey = itr.next();
+                    HandlerStrategies.set(key, mkey, store, addRow, _kcols,
+                        _kio, true);
+                    valsm = RelationStrategies.getStateManager(map.get(mkey),
+                        ctx);
+                    val.setForeignKey(addRow, valsm);
+                    rm.flushSecondaryRow(addRow);
+                }
+            }
+        }
+    }
+
+    public Joins joinRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        ValueMapping val = field.getElementMapping();
+        ClassMapping[] clss = val.getIndependentTypeMappings();
+        if (clss.length != 1) {
+            if (traverse)
+                throw RelationStrategies.unjoinable(val);
+            return joins;
+        }
+        if (forceOuter)
+            return joins.outerJoinRelation(field.getName(),
+                val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(),
+                false, false);
+        return joins.joinRelation(field.getName(),
+            val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(), 
+            false, false);
+    }
+
+    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        if (traverse)
+            HandlerStrategies.assertJoinable(field.getKeyMapping());
+        return joins;
+    }
+
+    public Object toDataStoreValue(Object val, JDBCStore store) {
+        return RelationStrategies.toDataStoreValue(field.getElementMapping(),
+            val, store);
+    }
+
+    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
+        return HandlerStrategies.toDataStoreValue(field.getKeyMapping(), val,
+            _kcols, store);
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LobFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LobFieldStrategy.java
index 9a1a0ad..5af8420 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LobFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LobFieldStrategy.java
@@ -1,219 +1,219 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.sql.PostgresDictionary;
-import org.apache.openjpa.jdbc.sql.Result;
-import org.apache.openjpa.jdbc.sql.Row;
-import org.apache.openjpa.jdbc.sql.RowManager;
-import org.apache.openjpa.jdbc.sql.Select;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.JavaTypes;
-
-/**
- * Direct mapping from a stream value to a column.
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-public class LobFieldStrategy extends AbstractFieldStrategy {
-
-    private int fieldType;
-    private boolean isBlob;
-
-    public void map(boolean adapt) {
-        assertNotMappedBy();
-        field.mapJoin(adapt, false);
-        field.getKeyMapping().getValueInfo().assertNoSchemaComponents
-            (field.getKey(), !adapt);
-        field.getElementMapping().getValueInfo().assertNoSchemaComponents
-            (field.getElement(), !adapt);
-        field.setStream(true);
-        ValueMappingInfo vinfo = field.getValueInfo();
-        vinfo.assertNoJoin(field, true);
-        vinfo.assertNoForeignKey(field, !adapt);
-        Column tmpCol = new Column();
-        tmpCol.setName(field.getName());
-        tmpCol.setType(fieldType);
-        tmpCol.setJavaType(field.getTypeCode());
-        
-        tmpCol.setSize(-1);
-
-        Column[] cols = vinfo.getColumns(field, field.getName(),
-            new Column[]{ tmpCol }, field.getTable(), adapt);
-
-        field.setColumns(cols);
-        field.setColumnIO(vinfo.getColumnIO());
-        field.mapConstraints(field.getName(), adapt);
-        field.mapPrimaryKey(adapt);
-    }
-
-    public Boolean isCustomInsert(OpenJPAStateManager sm, JDBCStore store) {
-        return null;
-    }
-
-    public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Select sel = createSelect(sm, store);
-        store.getDBDictionary().deleteStream(store, sel);
-    }
-    
-    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Object ob = toDataStoreValue(sm.fetchObjectField
-            (field.getIndex()), store);
-        Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
-        if (field.getColumnIO().isInsertable(0, ob == null)) {
-            Select sel = createSelect(sm, store);
-            if (isBlob) {
-                store.getDBDictionary().insertBlobForStreamingLoad
-                    (row, field.getColumns()[0], store, ob, sel);
-            } else {
-                store.getDBDictionary().insertClobForStreamingLoad
-                    (row, field.getColumns()[0], ob);
-            }
-        }
-    }
-
-    public void customInsert(OpenJPAStateManager sm, JDBCStore store)
-        throws SQLException {
-        Object ob = toDataStoreValue(sm.fetchObjectField
-            (field.getIndex()), store);
-        if (field.getColumnIO().isInsertable(0, ob == null)) {
-            if (ob != null) {
-                Select sel = createSelect(sm, store);
-                if (isBlob) {
-                    store.getDBDictionary().updateBlob
-                        (sel, store, (InputStream)ob);
-                } else {
-                    store.getDBDictionary().updateClob
-                        (sel, store, (Reader)ob);
-                }
-            }
-        }
-    }
-    
-    public Boolean isCustomUpdate(OpenJPAStateManager sm, JDBCStore store) {
-        return null;
-    }
-
-    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Object ob = toDataStoreValue(sm.fetchObjectField
-            (field.getIndex()), store);
-        if (field.getColumnIO().isUpdatable(0, ob == null)) {
-            Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
-            Select sel = createSelect(sm, store);
-            if (isBlob) {
-                store.getDBDictionary().insertBlobForStreamingLoad
-                    (row, field.getColumns()[0], store, ob, sel);
-            } else {
-                store.getDBDictionary().insertClobForStreamingLoad
-                    (row, field.getColumns()[0], sel);
-            }
-        }
-    }
-
-    public void customUpdate(OpenJPAStateManager sm, JDBCStore store)
-        throws SQLException {
-        Object ob = toDataStoreValue(sm.fetchObjectField
-                (field.getIndex()), store);
-        if (field.getColumnIO().isUpdatable(0, ob == null)) {
-            if (ob != null) {
-                Select sel = createSelect(sm, store);
-                if (isBlob) {
-                    store.getDBDictionary().updateBlob
-                        (sel, store, (InputStream)ob);
-                } else {
-                    store.getDBDictionary().updateClob
-                        (sel, store, (Reader)ob);
-                }
-            }
-        }
-    }
-
-    public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch) {
-        if (type == Select.TYPE_JOINLESS && sel.isSelected(field.getTable()))
-            return 1;
-        return 0;
-    }
-
-    public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, int eagerMode) {
-        sel.select(field.getColumns()[0], field.join(sel));
-        return 1;
-    }
-
-    public void load(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res) throws SQLException {
-        Column col = field.getColumns()[0];
-        if (res.contains(col)) {
-            if (isBlob) {
-                sm.storeObject(field.getIndex(), res.getLOBStream(store, col));
-            } else {
-                sm.storeObject(field.getIndex(), res.getCharacterStream(col));
-            }
-        }
-    }
-
-    protected void assertNotMappedBy() {
-        if (field != null && field.getMappedBy() != null)
-            throw new UnsupportedOperationException();
-    }
-
-    public void setFieldMapping(FieldMapping owner) {
-        field = owner;
-        if (owner.getElementMapping().getMappingRepository().getDBDictionary()
-            instanceof PostgresDictionary) {
-            fieldType = Types.INTEGER;
-            isBlob = true;
-            field.setTypeCode(JavaTypes.INT);
-        } else {
-            if (owner.getType().isAssignableFrom(InputStream.class)) {
-                isBlob = true;
-                fieldType = Types.BLOB;
-            } else if (owner.getType().isAssignableFrom(Reader.class)) {
-                isBlob = false;
-                fieldType = Types.CLOB;
-            }
-        }
-    }
-
-    private Select createSelect(OpenJPAStateManager sm, JDBCStore store) {
-        Select sel = store.getSQLFactory().newSelect();
-        sel.select(field.getColumns()[0]);
-        sel.selectPrimaryKey(field.getDefiningMapping());
-        sel.wherePrimaryKey
-            (sm.getObjectId(), field.getDefiningMapping(), store);
-        sel.setLob(true);
-        return sel;
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.PostgresDictionary;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.JavaTypes;
+
+/**
+ * Direct mapping from a stream value to a column.
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+public class LobFieldStrategy extends AbstractFieldStrategy {
+
+    private int fieldType;
+    private boolean isBlob;
+
+    public void map(boolean adapt) {
+        assertNotMappedBy();
+        field.mapJoin(adapt, false);
+        field.getKeyMapping().getValueInfo().assertNoSchemaComponents
+            (field.getKey(), !adapt);
+        field.getElementMapping().getValueInfo().assertNoSchemaComponents
+            (field.getElement(), !adapt);
+        field.setStream(true);
+        ValueMappingInfo vinfo = field.getValueInfo();
+        vinfo.assertNoJoin(field, true);
+        vinfo.assertNoForeignKey(field, !adapt);
+        Column tmpCol = new Column();
+        tmpCol.setName(field.getName());
+        tmpCol.setType(fieldType);
+        tmpCol.setJavaType(field.getTypeCode());
+        
+        tmpCol.setSize(-1);
+
+        Column[] cols = vinfo.getColumns(field, field.getName(),
+            new Column[]{ tmpCol }, field.getTable(), adapt);
+
+        field.setColumns(cols);
+        field.setColumnIO(vinfo.getColumnIO());
+        field.mapConstraints(field.getName(), adapt);
+        field.mapPrimaryKey(adapt);
+    }
+
+    public Boolean isCustomInsert(OpenJPAStateManager sm, JDBCStore store) {
+        return null;
+    }
+
+    public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Select sel = createSelect(sm, store);
+        store.getDBDictionary().deleteStream(store, sel);
+    }
+    
+    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Object ob = toDataStoreValue(sm.fetchObjectField
+            (field.getIndex()), store);
+        Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
+        if (field.getColumnIO().isInsertable(0, ob == null)) {
+            Select sel = createSelect(sm, store);
+            if (isBlob) {
+                store.getDBDictionary().insertBlobForStreamingLoad
+                    (row, field.getColumns()[0], store, ob, sel);
+            } else {
+                store.getDBDictionary().insertClobForStreamingLoad
+                    (row, field.getColumns()[0], ob);
+            }
+        }
+    }
+
+    public void customInsert(OpenJPAStateManager sm, JDBCStore store)
+        throws SQLException {
+        Object ob = toDataStoreValue(sm.fetchObjectField
+            (field.getIndex()), store);
+        if (field.getColumnIO().isInsertable(0, ob == null)) {
+            if (ob != null) {
+                Select sel = createSelect(sm, store);
+                if (isBlob) {
+                    store.getDBDictionary().updateBlob
+                        (sel, store, (InputStream)ob);
+                } else {
+                    store.getDBDictionary().updateClob
+                        (sel, store, (Reader)ob);
+                }
+            }
+        }
+    }
+    
+    public Boolean isCustomUpdate(OpenJPAStateManager sm, JDBCStore store) {
+        return null;
+    }
+
+    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Object ob = toDataStoreValue(sm.fetchObjectField
+            (field.getIndex()), store);
+        if (field.getColumnIO().isUpdatable(0, ob == null)) {
+            Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
+            Select sel = createSelect(sm, store);
+            if (isBlob) {
+                store.getDBDictionary().insertBlobForStreamingLoad
+                    (row, field.getColumns()[0], store, ob, sel);
+            } else {
+                store.getDBDictionary().insertClobForStreamingLoad
+                    (row, field.getColumns()[0], sel);
+            }
+        }
+    }
+
+    public void customUpdate(OpenJPAStateManager sm, JDBCStore store)
+        throws SQLException {
+        Object ob = toDataStoreValue(sm.fetchObjectField
+                (field.getIndex()), store);
+        if (field.getColumnIO().isUpdatable(0, ob == null)) {
+            if (ob != null) {
+                Select sel = createSelect(sm, store);
+                if (isBlob) {
+                    store.getDBDictionary().updateBlob
+                        (sel, store, (InputStream)ob);
+                } else {
+                    store.getDBDictionary().updateClob
+                        (sel, store, (Reader)ob);
+                }
+            }
+        }
+    }
+
+    public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch) {
+        if (type == Select.TYPE_JOINLESS && sel.isSelected(field.getTable()))
+            return 1;
+        return 0;
+    }
+
+    public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, int eagerMode) {
+        sel.select(field.getColumns()[0], field.join(sel));
+        return 1;
+    }
+
+    public void load(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res) throws SQLException {
+        Column col = field.getColumns()[0];
+        if (res.contains(col)) {
+            if (isBlob) {
+                sm.storeObject(field.getIndex(), res.getLOBStream(store, col));
+            } else {
+                sm.storeObject(field.getIndex(), res.getCharacterStream(col));
+            }
+        }
+    }
+
+    protected void assertNotMappedBy() {
+        if (field != null && field.getMappedBy() != null)
+            throw new UnsupportedOperationException();
+    }
+
+    public void setFieldMapping(FieldMapping owner) {
+        field = owner;
+        if (owner.getElementMapping().getMappingRepository().getDBDictionary()
+            instanceof PostgresDictionary) {
+            fieldType = Types.INTEGER;
+            isBlob = true;
+            field.setTypeCode(JavaTypes.INT);
+        } else {
+            if (owner.getType().isAssignableFrom(InputStream.class)) {
+                isBlob = true;
+                fieldType = Types.BLOB;
+            } else if (owner.getType().isAssignableFrom(Reader.class)) {
+                isBlob = false;
+                fieldType = Types.CLOB;
+            }
+        }
+    }
+
+    private Select createSelect(OpenJPAStateManager sm, JDBCStore store) {
+        Select sel = store.getSQLFactory().newSelect();
+        sel.select(field.getColumns()[0]);
+        sel.selectPrimaryKey(field.getDefiningMapping());
+        sel.wherePrimaryKey
+            (sm.getObjectId(), field.getDefiningMapping(), store);
+        sel.setLob(true);
+        return sel;
+    }
+    
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/NanoPrecisionTimestampVersionStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/NanoPrecisionTimestampVersionStrategy.java
index 89ba3c5..de51ad5 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/NanoPrecisionTimestampVersionStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/NanoPrecisionTimestampVersionStrategy.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import org.apache.openjpa.lib.util.TimestampHelper;
-
-/**
- * Uses a timestamp for optimistic versioning with nanosecond
- * precision.
- *
- * @author Albert Lee
- */
-public class NanoPrecisionTimestampVersionStrategy
-    extends TimestampVersionStrategy {
-
-    public static final String ALIAS = "nano-timestamp";
-
-    public String getAlias() {
-        return ALIAS;
-    }
-
-    protected Object nextVersion(Object version) {
-        return TimestampHelper.getNanoPrecisionTimestamp();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import org.apache.openjpa.lib.util.TimestampHelper;
+
+/**
+ * Uses a timestamp for optimistic versioning with nanosecond
+ * precision.
+ *
+ * @author Albert Lee
+ */
+public class NanoPrecisionTimestampVersionStrategy
+    extends TimestampVersionStrategy {
+
+    public static final String ALIAS = "nano-timestamp";
+
+    public String getAlias() {
+        return ALIAS;
+    }
+
+    protected Object nextVersion(Object version) {
+        return TimestampHelper.getNanoPrecisionTimestamp();
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
index 5980871..2ef9aa2 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
@@ -598,7 +598,8 @@
         else
             sm.setIntermediate(field.getIndex(), oid);
     }
-
+    
+    Map<JDBCStoreManager.SelectKey, Object[]> relationFieldUnionCache = null;
     public void load(final OpenJPAStateManager sm, final JDBCStore store,
         final JDBCFetchConfiguration fetch)
         throws SQLException {
@@ -625,9 +626,11 @@
         if (!((JDBCStoreManager)store).isQuerySQLCacheOn())
             union = newUnion(sm, store, fetch, rels, subs, resJoins);
         else {
-            Map<JDBCStoreManager.SelectKey, Object[]> relationFieldUnionCache = 
-                ((JDBCStoreManager)store).getCacheMapFromQuerySQLCache(
-                RelationFieldStrategy.class);
+            if (relationFieldUnionCache == null) {
+                relationFieldUnionCache =
+                    ((JDBCStoreManager) store)
+                        .getCacheMapFromQuerySQLCache(RelationFieldStrategy.class);
+            }
             boolean found = true;
             JDBCFetchConfiguration fetchClone = new JDBCFetchConfigurationImpl();
             fetchClone.copy(fetch);
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationHandlerMapTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationHandlerMapTableFieldStrategy.java
index cc2c1eb..35a3a1c 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationHandlerMapTableFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationHandlerMapTableFieldStrategy.java
@@ -1,290 +1,290 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.lib.util.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.util.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.schema.*;
-import org.apache.openjpa.jdbc.sql.*;
-
-/**
- * <p>Mapping for a map whose keys are relations to other persistent objects
- * and whose values are controlled by a {@link ValueHandler}.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-public class RelationHandlerMapTableFieldStrategy
-    extends MapTableFieldStrategy {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (RelationHandlerMapTableFieldStrategy.class);
-
-    private Column[] _vcols = null;
-    private ColumnIO _vio = null;
-    private boolean _vload = false;
-
-    public Column[] getKeyColumns(ClassMapping cls) {
-        return field.getKeyMapping().getColumns();
-    }
-
-    public Column[] getValueColumns(ClassMapping cls) {
-        return _vcols;
-    }
-
-    public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
-        sel.select(key, field.getKeyMapping().getSelectSubclasses(),
-            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
-    }
-
-    public void selectValue(Select sel, ClassMapping val,
-        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, 
-        Joins joins) {
-        sel.select(_vcols, joins);
-    }
-
-    public Result[] getResults(final OpenJPAStateManager sm,
-        final JDBCStore store, final JDBCFetchConfiguration fetch,
-        final int eagerMode, final Joins[] resJoins, boolean lrs)
-        throws SQLException {
-        ValueMapping key = field.getKeyMapping();
-        final ClassMapping[] keys = key.getIndependentTypeMappings();
-        Union union = store.getSQLFactory().newUnion(keys.length);
-        if (fetch.getSubclassFetchMode(key.getTypeMapping()) 
-            != JDBCFetchConfiguration.EAGER_JOIN)
-            union.abortUnion();
-        union.setLRS(lrs);
-        union.select(new Union.Selector() {
-            public void select(Select sel, int idx) {
-                sel.select(_vcols);
-                sel.whereForeignKey(field.getJoinForeignKey(),
-                    sm.getObjectId(), field.getDefiningMapping(), store);
-
-                Joins joins = joinKeyRelation(sel.newJoins(), keys[idx]);
-                sel.select(keys[idx], field.getKeyMapping().
-                    getSelectSubclasses(), store, fetch, eagerMode, joins);
-
-                //### cheat: result joins only care about the relation path;
-                //### thus we can use first mapping of union only
-                if (idx == 0)
-                    resJoins[0] = joins;
-            }
-        });
-        Result res = union.execute(store, fetch);
-        return new Result[]{ res, res };
-    }
-
-    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        ClassMapping key = res.getBaseMapping();
-        if (key == null)
-            key = field.getKeyMapping().getIndependentTypeMappings()[0];
-        return res.load(key, store, fetch, joins);
-    }
-
-    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        return HandlerStrategies.loadObject(field.getElementMapping(),
-            sm, store, fetch, res, joins, _vcols, _vload);
-    }
-
-    public Joins joinKeyRelation(Joins joins, ClassMapping key) {
-        ValueMapping vm = field.getKeyMapping();
-        return joins.joinRelation(field.getName(), vm.getForeignKey(key), key,
-            vm.getSelectSubclasses(), false, false);
-    }
-
-    public void map(boolean adapt) {
-        super.map(adapt);
-
-        ValueMapping key = field.getKeyMapping();
-        if (key.getTypeCode() != JavaTypes.PC || key.isEmbeddedPC())
-            throw new MetaDataException(_loc.get("not-relation", key));
-        ValueMapping val = field.getElementMapping();
-        if (val.getHandler() == null)
-            throw new MetaDataException(_loc.get("no-handler", val));
-        assertNotMappedBy();
-
-        field.mapJoin(adapt, true);
-        _vio = new ColumnIO();
-        _vcols = HandlerStrategies.map(val, "value", _vio, adapt);
-
-        if (key.getTypeMapping().isMapped()) {
-            ValueMappingInfo vinfo = key.getValueInfo();
-            ForeignKey fk = vinfo.getTypeJoin(key, "key", false, adapt);
-            key.setForeignKey(fk);
-            key.setColumnIO(vinfo.getColumnIO());
-        } else
-            RelationStrategies.mapRelationToUnmappedPC(key, "key", adapt);
-
-        key.mapConstraints("key", adapt);
-        field.mapPrimaryKey(adapt);
-    }
-
-    public void initialize() {
-        _vload = field.getElementMapping().getHandler().
-            objectValueRequiresLoad(field.getElementMapping());
-    }
-
-    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
-    }
-
-    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
-        Map map)
-        throws SQLException {
-        if (map == null || map.isEmpty())
-            return;
-
-        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
-        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
-            sm);
-
-        ValueMapping val = field.getElementMapping();
-        ValueMapping key = field.getKeyMapping();
-        StoreContext ctx = store.getContext();
-        OpenJPAStateManager keysm;
-        Map.Entry entry;
-        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            keysm = RelationStrategies.getStateManager(entry.getKey(), ctx);
-            key.setForeignKey(row, keysm);
-            HandlerStrategies.set(val, entry.getValue(), store, row, _vcols,
-                _vio, true);
-            rm.flushSecondaryRow(row);
-        }
-    }
-
-    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Map map = (Map) sm.fetchObject(field.getIndex());
-        ChangeTracker ct = null;
-        if (map instanceof Proxy) {
-            Proxy proxy = (Proxy) map;
-            if (Proxies.isOwner(proxy, sm, field.getIndex()))
-                ct = proxy.getChangeTracker();
-        }
-
-        // if no fine-grained change tracking then just delete and reinsert
-        if (ct == null || !ct.isTracking()) {
-            delete(sm, store, rm);
-            insert(sm, store, rm, map);
-            return;
-        }
-
-        // delete the removes
-        ValueMapping key = field.getKeyMapping();
-        StoreContext ctx = store.getContext();
-        Collection rem = ct.getRemoved();
-        OpenJPAStateManager keysm;
-        if (!rem.isEmpty()) {
-            Row delRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_DELETE);
-            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
-            for (Iterator itr = rem.iterator(); itr.hasNext();) {
-                keysm = RelationStrategies.getStateManager(itr.next(), ctx);
-                key.whereForeignKey(delRow, keysm);
-                rm.flushSecondaryRow(delRow);
-            }
-        }
-
-        // insert the adds
-        ValueMapping val = field.getElementMapping();
-        Collection add = ct.getAdded();
-        Object mkey;
-        if (!add.isEmpty()) {
-            Row addRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_INSERT);
-            addRow.setForeignKey(field.getJoinForeignKey(),
-                field.getJoinColumnIO(), sm);
-
-            for (Iterator itr = add.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                keysm = RelationStrategies.getStateManager(mkey, ctx);
-                key.setForeignKey(addRow, keysm);
-                HandlerStrategies.set(val, map.get(mkey), store, addRow,
-                    _vcols, _vio, true);
-                rm.flushSecondaryRow(addRow);
-            }
-        }
-
-        // update the changes
-        Collection change = ct.getChanged();
-        if (!change.isEmpty()) {
-            Row changeRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_UPDATE);
-            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
-            for (Iterator itr = change.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                keysm = RelationStrategies.getStateManager(mkey, ctx);
-                key.whereForeignKey(changeRow, keysm);
-                HandlerStrategies.set(val, map.get(mkey), store, changeRow,
-                    _vcols, _vio, true);
-                rm.flushSecondaryRow(changeRow);
-            }
-        }
-    }
-
-    public Joins joinRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        if (traverse)
-            HandlerStrategies.assertJoinable(field.getElementMapping());
-        return joins;
-    }
-
-    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        ValueMapping key = field.getKeyMapping();
-        ClassMapping[] clss = key.getIndependentTypeMappings();
-        if (clss.length != 1) {
-            if (traverse)
-                throw RelationStrategies.unjoinable(field.getKeyMapping());
-            return joins;
-        }
-        if (forceOuter)
-            return joins.outerJoinRelation(field.getName(),
-                key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(),
-                false, false);
-        return joins.joinRelation(field.getName(),
-            key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(),
-            false, false);
-    }
-
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
-            val, _vcols, store);
-    }
-
-    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
-        return RelationStrategies.toDataStoreValue(field.getKeyMapping(), val,
-            store);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.util.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.schema.*;
+import org.apache.openjpa.jdbc.sql.*;
+
+/**
+ * <p>Mapping for a map whose keys are relations to other persistent objects
+ * and whose values are controlled by a {@link ValueHandler}.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+public class RelationHandlerMapTableFieldStrategy
+    extends MapTableFieldStrategy {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (RelationHandlerMapTableFieldStrategy.class);
+
+    private Column[] _vcols = null;
+    private ColumnIO _vio = null;
+    private boolean _vload = false;
+
+    public Column[] getKeyColumns(ClassMapping cls) {
+        return field.getKeyMapping().getColumns();
+    }
+
+    public Column[] getValueColumns(ClassMapping cls) {
+        return _vcols;
+    }
+
+    public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
+        sel.select(key, field.getKeyMapping().getSelectSubclasses(),
+            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
+    }
+
+    public void selectValue(Select sel, ClassMapping val,
+        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, 
+        Joins joins) {
+        sel.select(_vcols, joins);
+    }
+
+    public Result[] getResults(final OpenJPAStateManager sm,
+        final JDBCStore store, final JDBCFetchConfiguration fetch,
+        final int eagerMode, final Joins[] resJoins, boolean lrs)
+        throws SQLException {
+        ValueMapping key = field.getKeyMapping();
+        final ClassMapping[] keys = key.getIndependentTypeMappings();
+        Union union = store.getSQLFactory().newUnion(keys.length);
+        if (fetch.getSubclassFetchMode(key.getTypeMapping()) 
+            != JDBCFetchConfiguration.EAGER_JOIN)
+            union.abortUnion();
+        union.setLRS(lrs);
+        union.select(new Union.Selector() {
+            public void select(Select sel, int idx) {
+                sel.select(_vcols);
+                sel.whereForeignKey(field.getJoinForeignKey(),
+                    sm.getObjectId(), field.getDefiningMapping(), store);
+
+                Joins joins = joinKeyRelation(sel.newJoins(), keys[idx]);
+                sel.select(keys[idx], field.getKeyMapping().
+                    getSelectSubclasses(), store, fetch, eagerMode, joins);
+
+                //### cheat: result joins only care about the relation path;
+                //### thus we can use first mapping of union only
+                if (idx == 0)
+                    resJoins[0] = joins;
+            }
+        });
+        Result res = union.execute(store, fetch);
+        return new Result[]{ res, res };
+    }
+
+    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        ClassMapping key = res.getBaseMapping();
+        if (key == null)
+            key = field.getKeyMapping().getIndependentTypeMappings()[0];
+        return res.load(key, store, fetch, joins);
+    }
+
+    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        return HandlerStrategies.loadObject(field.getElementMapping(),
+            sm, store, fetch, res, joins, _vcols, _vload);
+    }
+
+    public Joins joinKeyRelation(Joins joins, ClassMapping key) {
+        ValueMapping vm = field.getKeyMapping();
+        return joins.joinRelation(field.getName(), vm.getForeignKey(key), key,
+            vm.getSelectSubclasses(), false, false);
+    }
+
+    public void map(boolean adapt) {
+        super.map(adapt);
+
+        ValueMapping key = field.getKeyMapping();
+        if (key.getTypeCode() != JavaTypes.PC || key.isEmbeddedPC())
+            throw new MetaDataException(_loc.get("not-relation", key));
+        ValueMapping val = field.getElementMapping();
+        if (val.getHandler() == null)
+            throw new MetaDataException(_loc.get("no-handler", val));
+        assertNotMappedBy();
+
+        field.mapJoin(adapt, true);
+        _vio = new ColumnIO();
+        _vcols = HandlerStrategies.map(val, "value", _vio, adapt);
+
+        if (key.getTypeMapping().isMapped()) {
+            ValueMappingInfo vinfo = key.getValueInfo();
+            ForeignKey fk = vinfo.getTypeJoin(key, "key", false, adapt);
+            key.setForeignKey(fk);
+            key.setColumnIO(vinfo.getColumnIO());
+        } else
+            RelationStrategies.mapRelationToUnmappedPC(key, "key", adapt);
+
+        key.mapConstraints("key", adapt);
+        field.mapPrimaryKey(adapt);
+    }
+
+    public void initialize() {
+        _vload = field.getElementMapping().getHandler().
+            objectValueRequiresLoad(field.getElementMapping());
+    }
+
+    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
+    }
+
+    private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+        Map map)
+        throws SQLException {
+        if (map == null || map.isEmpty())
+            return;
+
+        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+            sm);
+
+        ValueMapping val = field.getElementMapping();
+        ValueMapping key = field.getKeyMapping();
+        StoreContext ctx = store.getContext();
+        OpenJPAStateManager keysm;
+        Map.Entry entry;
+        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            keysm = RelationStrategies.getStateManager(entry.getKey(), ctx);
+            key.setForeignKey(row, keysm);
+            HandlerStrategies.set(val, entry.getValue(), store, row, _vcols,
+                _vio, true);
+            rm.flushSecondaryRow(row);
+        }
+    }
+
+    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Map map = (Map) sm.fetchObject(field.getIndex());
+        ChangeTracker ct = null;
+        if (map instanceof Proxy) {
+            Proxy proxy = (Proxy) map;
+            if (Proxies.isOwner(proxy, sm, field.getIndex()))
+                ct = proxy.getChangeTracker();
+        }
+
+        // if no fine-grained change tracking then just delete and reinsert
+        if (ct == null || !ct.isTracking()) {
+            delete(sm, store, rm);
+            insert(sm, store, rm, map);
+            return;
+        }
+
+        // delete the removes
+        ValueMapping key = field.getKeyMapping();
+        StoreContext ctx = store.getContext();
+        Collection rem = ct.getRemoved();
+        OpenJPAStateManager keysm;
+        if (!rem.isEmpty()) {
+            Row delRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_DELETE);
+            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
+            for (Iterator itr = rem.iterator(); itr.hasNext();) {
+                keysm = RelationStrategies.getStateManager(itr.next(), ctx);
+                key.whereForeignKey(delRow, keysm);
+                rm.flushSecondaryRow(delRow);
+            }
+        }
+
+        // insert the adds
+        ValueMapping val = field.getElementMapping();
+        Collection add = ct.getAdded();
+        Object mkey;
+        if (!add.isEmpty()) {
+            Row addRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_INSERT);
+            addRow.setForeignKey(field.getJoinForeignKey(),
+                field.getJoinColumnIO(), sm);
+
+            for (Iterator itr = add.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                keysm = RelationStrategies.getStateManager(mkey, ctx);
+                key.setForeignKey(addRow, keysm);
+                HandlerStrategies.set(val, map.get(mkey), store, addRow,
+                    _vcols, _vio, true);
+                rm.flushSecondaryRow(addRow);
+            }
+        }
+
+        // update the changes
+        Collection change = ct.getChanged();
+        if (!change.isEmpty()) {
+            Row changeRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_UPDATE);
+            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+            for (Iterator itr = change.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                keysm = RelationStrategies.getStateManager(mkey, ctx);
+                key.whereForeignKey(changeRow, keysm);
+                HandlerStrategies.set(val, map.get(mkey), store, changeRow,
+                    _vcols, _vio, true);
+                rm.flushSecondaryRow(changeRow);
+            }
+        }
+    }
+
+    public Joins joinRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        if (traverse)
+            HandlerStrategies.assertJoinable(field.getElementMapping());
+        return joins;
+    }
+
+    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        ValueMapping key = field.getKeyMapping();
+        ClassMapping[] clss = key.getIndependentTypeMappings();
+        if (clss.length != 1) {
+            if (traverse)
+                throw RelationStrategies.unjoinable(field.getKeyMapping());
+            return joins;
+        }
+        if (forceOuter)
+            return joins.outerJoinRelation(field.getName(),
+                key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(),
+                false, false);
+        return joins.joinRelation(field.getName(),
+            key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(),
+            false, false);
+    }
+
+    public Object toDataStoreValue(Object val, JDBCStore store) {
+        return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
+            val, _vcols, store);
+    }
+
+    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
+        return RelationStrategies.toDataStoreValue(field.getKeyMapping(), val,
+            store);
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java
index 60770b6..14a15da 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java
@@ -1,375 +1,375 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.lib.util.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.util.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.schema.*;
-import org.apache.openjpa.jdbc.sql.*;
-
-/**
- * <p>Mapping for a map whose keys and values are both relations to other
- * persistent objects.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-public class RelationRelationMapTableFieldStrategy
-    extends MapTableFieldStrategy {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (RelationRelationMapTableFieldStrategy.class);
-
-    private String _keyRelationName = null;
-
-    public Column[] getKeyColumns(ClassMapping cls) {
-        return field.getKeyMapping().getColumns();
-    }
-
-    public Column[] getValueColumns(ClassMapping cls) {
-        return field.getElementMapping().getColumns();
-    }
-
-    public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
-        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
-        sel.select(key, field.getKeyMapping().getSelectSubclasses(),
-            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
-    }
-
-    public void selectValue(Select sel, ClassMapping val,
-        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, 
-        Joins joins) {
-        sel.select(val, field.getElementMapping().getSelectSubclasses(),
-            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
-    }
-
-    public Result[] getResults(final OpenJPAStateManager sm,
-        final JDBCStore store, final JDBCFetchConfiguration fetch,
-        final int eagerMode, final Joins[] resJoins, boolean lrs)
-        throws SQLException {
-        ValueMapping key = field.getKeyMapping();
-        final ClassMapping[] keys = key.getIndependentTypeMappings();
-        Union kunion = store.getSQLFactory().newUnion(keys.length);
-        if (fetch.getSubclassFetchMode(key.getTypeMapping())
-            != JDBCFetchConfiguration.EAGER_JOIN)
-            kunion.abortUnion();
-        kunion.setLRS(lrs);
-        kunion.select(new Union.Selector() {
-            public void select(Select sel, int idx) {
-                sel.whereForeignKey(field.getJoinForeignKey(),
-                    sm.getObjectId(), field.getDefiningMapping(), store);
-
-                // order before select in case we're faking union with
-                // multiple selects; order vals used to merge results
-                Joins joins = joinKeyRelation(sel.newJoins(), keys[idx]);
-                sel.orderBy(field.getKeyMapping().getColumns(), true, true);
-                sel.select(keys[idx], field.getKeyMapping().
-                    getSelectSubclasses(), store, fetch, eagerMode, joins);
-
-                //### cheat: result joins only care about the relation path;
-                //### thus we can use first mapping of union only
-                if (idx == 0)
-                    resJoins[0] = joins;
-            }
-        });
-
-        ValueMapping val = field.getElementMapping();
-        final ClassMapping[] vals = val.getIndependentTypeMappings();
-        Union vunion = store.getSQLFactory().newUnion(vals.length);
-        if (fetch.getSubclassFetchMode(val.getTypeMapping())
-            != JDBCFetchConfiguration.EAGER_JOIN)
-            vunion.abortUnion();
-        vunion.setLRS(lrs);
-        vunion.select(new Union.Selector() {
-            public void select(Select sel, int idx) {
-                sel.whereForeignKey(field.getJoinForeignKey(),
-                    sm.getObjectId(), field.getDefiningMapping(), store);
-
-                // order before select in case we're faking union with
-                // multiple selects; order vals used to merge results
-                Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
-                sel.orderBy(field.getKeyMapping().getColumns(), true, true);
-                sel.select(vals[idx], field.getElementMapping().
-                    getSelectSubclasses(), store, fetch, eagerMode, joins);
-
-                //### cheat: result joins only care about the relation path;
-                //### thus we can use first mapping of union only
-                if (idx == 0)
-                    resJoins[1] = joins;
-            }
-        });
-
-        Result kres = null;
-        Result vres = null;
-        try {
-            kres = kunion.execute(store, fetch);
-            vres = vunion.execute(store, fetch);
-            return new Result[]{ kres, vres };
-        } catch (SQLException se) {
-            if (kres != null)
-                kres.close();
-            if (vres != null)
-                vres.close();
-            throw se;
-        }
-    }
-
-    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        ClassMapping key = res.getBaseMapping();
-        if (key == null)
-            key = field.getKeyMapping().getIndependentTypeMappings()[0];
-        return res.load(key, store, fetch, joins);
-    }
-
-    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
-        JDBCFetchConfiguration fetch, Result res, Joins joins)
-        throws SQLException {
-        ClassMapping val = res.getBaseMapping();
-        if (val == null)
-            val = field.getElementMapping().getIndependentTypeMappings()[0];
-        return res.load(val, store, fetch, joins);
-    }
-
-    public Joins joinKeyRelation(Joins joins, ClassMapping key) {
-        ValueMapping vm = field.getKeyMapping();
-        return joins.joinRelation(_keyRelationName, vm.getForeignKey(key), key,
-            vm.getSelectSubclasses(), false, false);
-    }
-
-    public Joins joinValueRelation(Joins joins, ClassMapping val) {
-        ValueMapping vm = field.getElementMapping();
-        return joins.joinRelation(field.getName(), vm.getForeignKey(val), val,
-            vm.getSelectSubclasses(), false, false);
-    }
-
-    public void map(boolean adapt) {
-        super.map(adapt);
-
-        ValueMapping key = field.getKeyMapping();
-        if (key.getTypeCode() != JavaTypes.PC || key.isEmbeddedPC())
-            throw new MetaDataException(_loc.get("not-relation", key));
-        ValueMapping val = field.getElementMapping();
-        if (val.getTypeCode() != JavaTypes.PC || val.isEmbeddedPC())
-            throw new MetaDataException(_loc.get("not-relation", val));
-        assertNotMappedBy();
-
-        field.mapJoin(adapt, true);
-        mapTypeJoin(key, "key", adapt);
-        mapTypeJoin(val, "value", adapt);
-
-        field.mapPrimaryKey(adapt);
-    }
-
-    /**
-     * Map the given value's join to its persistent type.
-     */
-    private void mapTypeJoin(ValueMapping vm, String name, boolean adapt) {
-        if (vm.getTypeMapping().isMapped()) {
-            ValueMappingInfo vinfo = vm.getValueInfo();
-            ForeignKey fk = vinfo.getTypeJoin(vm, name, false, adapt);
-            vm.setForeignKey(fk);
-            vm.setColumnIO(vinfo.getColumnIO());
-        } else
-            RelationStrategies.mapRelationToUnmappedPC(vm, name, adapt);
-        vm.mapConstraints(name, adapt);
-    }
-
-    public void initialize() {
-        _keyRelationName = field.getName() + ":key";
-    }
-
-    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        insert(sm, rm, (Map) sm.fetchObject(field.getIndex()));
-    }
-
-    private void insert(OpenJPAStateManager sm, RowManager rm, Map map)
-        throws SQLException {
-        if (map == null || map.isEmpty())
-            return;
-
-        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
-        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
-            sm);
-
-        ValueMapping key = field.getKeyMapping();
-        ValueMapping val = field.getElementMapping();
-        StoreContext ctx = sm.getContext();
-        OpenJPAStateManager keysm, valsm;
-        Map.Entry entry;
-        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            keysm = RelationStrategies.getStateManager(entry.getKey(), ctx);
-            valsm = RelationStrategies.getStateManager(entry.getValue(), ctx);
-            key.setForeignKey(row, keysm);
-            val.setForeignKey(row, valsm);
-            rm.flushSecondaryRow(row);
-        }
-    }
-
-    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
-        throws SQLException {
-        Map map = (Map) sm.fetchObject(field.getIndex());
-        ChangeTracker ct = null;
-        if (map instanceof Proxy) {
-            Proxy proxy = (Proxy) map;
-            if (Proxies.isOwner(proxy, sm, field.getIndex()))
-                ct = proxy.getChangeTracker();
-        }
-
-        // if no fine-grained change tracking then just delete and reinsert
-        if (ct == null || !ct.isTracking()) {
-            delete(sm, store, rm);
-            insert(sm, rm, map);
-            return;
-        }
-
-        ValueMapping key = field.getKeyMapping();
-        ValueMapping val = field.getElementMapping();
-        StoreContext ctx = store.getContext();
-        OpenJPAStateManager keysm, valsm;
-
-        // update the changes; note that we have to model changes as
-        // delete-then-insert if we have a foreign key action, because
-        // secondary row updates aren't part of the constraint graph
-        Collection change = ct.getChanged();
-        boolean canChange = val.getForeignKey().isLogical();
-        Object mkey;
-        if (canChange && !change.isEmpty()) {
-            Row changeRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_UPDATE);
-            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
-            for (Iterator itr = change.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                keysm = RelationStrategies.getStateManager(mkey, ctx);
-                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
-                key.whereForeignKey(changeRow, keysm);
-                val.setForeignKey(changeRow, valsm);
-                rm.flushSecondaryRow(changeRow);
-            }
-        }
-
-        // delete the removes
-        Collection rem = ct.getRemoved();
-        if (!rem.isEmpty() || (!canChange && !change.isEmpty())) {
-            Row delRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_DELETE);
-            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
-
-            for (Iterator itr = rem.iterator(); itr.hasNext();) {
-                keysm = RelationStrategies.getStateManager(itr.next(), ctx);
-                key.whereForeignKey(delRow, keysm);
-                rm.flushSecondaryRow(delRow);
-            }
-            if (!canChange && !change.isEmpty()) {
-                for (Iterator itr = change.iterator(); itr.hasNext();) {
-                    keysm = RelationStrategies.getStateManager(itr.next(),
-                        ctx);
-                    key.whereForeignKey(delRow, keysm);
-                    rm.flushSecondaryRow(delRow);
-                }
-            }
-        }
-
-        // insert the adds
-        Collection add = ct.getAdded();
-        if (!add.isEmpty() || (!canChange && !change.isEmpty())) {
-            Row addRow = rm.getSecondaryRow(field.getTable(),
-                Row.ACTION_INSERT);
-            addRow.setForeignKey(field.getJoinForeignKey(),
-                field.getJoinColumnIO(), sm);
-
-            for (Iterator itr = add.iterator(); itr.hasNext();) {
-                mkey = itr.next();
-                keysm = RelationStrategies.getStateManager(mkey, ctx);
-                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
-                key.setForeignKey(addRow, keysm);
-                val.setForeignKey(addRow, valsm);
-                rm.flushSecondaryRow(addRow);
-            }
-            if (!canChange && !change.isEmpty()) {
-                for (Iterator itr = change.iterator(); itr.hasNext();) {
-                    mkey = itr.next();
-                    keysm = RelationStrategies.getStateManager(mkey, ctx);
-                    valsm = RelationStrategies.getStateManager(map.get(mkey),
-                        ctx);
-                    key.setForeignKey(addRow, keysm);
-                    val.setForeignKey(addRow, valsm);
-                    rm.flushSecondaryRow(addRow);
-                }
-            }
-        }
-    }
-
-    public Joins joinRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        ValueMapping val = field.getElementMapping();
-        ClassMapping[] clss = val.getIndependentTypeMappings();
-        if (clss.length != 1) {
-            if (traverse)
-                throw RelationStrategies.unjoinable(val);
-            return joins;
-        }
-        if (forceOuter)
-            return joins.outerJoinRelation(field.getName(),
-                val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(),
-                false, false);
-        return joins.joinRelation(field.getName(),
-            val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(),
-            false, false);
-    }
-
-    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
-        boolean traverse) {
-        ValueMapping key = field.getKeyMapping();
-        ClassMapping[] clss = key.getIndependentTypeMappings();
-        if (clss.length != 1) {
-            if (traverse)
-                throw RelationStrategies.unjoinable(key);
-            return joins;
-        }
-        if (forceOuter)
-            return joins.outerJoinRelation(field.getName(),
-                key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(),
-                false, false);
-        return joins.joinRelation(_keyRelationName,
-            key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(), 
-            false, false);
-    }
-
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return RelationStrategies.toDataStoreValue(field.getElementMapping(),
-            val, store);
-    }
-
-    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
-        return RelationStrategies.toDataStoreValue(field.getKeyMapping(),
-            val, store);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.util.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.schema.*;
+import org.apache.openjpa.jdbc.sql.*;
+
+/**
+ * <p>Mapping for a map whose keys and values are both relations to other
+ * persistent objects.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+public class RelationRelationMapTableFieldStrategy
+    extends MapTableFieldStrategy {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (RelationRelationMapTableFieldStrategy.class);
+
+    private String _keyRelationName = null;
+
+    public Column[] getKeyColumns(ClassMapping cls) {
+        return field.getKeyMapping().getColumns();
+    }
+
+    public Column[] getValueColumns(ClassMapping cls) {
+        return field.getElementMapping().getColumns();
+    }
+
+    public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
+        JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
+        sel.select(key, field.getKeyMapping().getSelectSubclasses(),
+            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
+    }
+
+    public void selectValue(Select sel, ClassMapping val,
+        OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, 
+        Joins joins) {
+        sel.select(val, field.getElementMapping().getSelectSubclasses(),
+            store, fetch, JDBCFetchConfiguration.EAGER_NONE, joins);
+    }
+
+    public Result[] getResults(final OpenJPAStateManager sm,
+        final JDBCStore store, final JDBCFetchConfiguration fetch,
+        final int eagerMode, final Joins[] resJoins, boolean lrs)
+        throws SQLException {
+        ValueMapping key = field.getKeyMapping();
+        final ClassMapping[] keys = key.getIndependentTypeMappings();
+        Union kunion = store.getSQLFactory().newUnion(keys.length);
+        if (fetch.getSubclassFetchMode(key.getTypeMapping())
+            != JDBCFetchConfiguration.EAGER_JOIN)
+            kunion.abortUnion();
+        kunion.setLRS(lrs);
+        kunion.select(new Union.Selector() {
+            public void select(Select sel, int idx) {
+                sel.whereForeignKey(field.getJoinForeignKey(),
+                    sm.getObjectId(), field.getDefiningMapping(), store);
+
+                // order before select in case we're faking union with
+                // multiple selects; order vals used to merge results
+                Joins joins = joinKeyRelation(sel.newJoins(), keys[idx]);
+                sel.orderBy(field.getKeyMapping().getColumns(), true, true);
+                sel.select(keys[idx], field.getKeyMapping().
+                    getSelectSubclasses(), store, fetch, eagerMode, joins);
+
+                //### cheat: result joins only care about the relation path;
+                //### thus we can use first mapping of union only
+                if (idx == 0)
+                    resJoins[0] = joins;
+            }
+        });
+
+        ValueMapping val = field.getElementMapping();
+        final ClassMapping[] vals = val.getIndependentTypeMappings();
+        Union vunion = store.getSQLFactory().newUnion(vals.length);
+        if (fetch.getSubclassFetchMode(val.getTypeMapping())
+            != JDBCFetchConfiguration.EAGER_JOIN)
+            vunion.abortUnion();
+        vunion.setLRS(lrs);
+        vunion.select(new Union.Selector() {
+            public void select(Select sel, int idx) {
+                sel.whereForeignKey(field.getJoinForeignKey(),
+                    sm.getObjectId(), field.getDefiningMapping(), store);
+
+                // order before select in case we're faking union with
+                // multiple selects; order vals used to merge results
+                Joins joins = joinValueRelation(sel.newJoins(), vals[idx]);
+                sel.orderBy(field.getKeyMapping().getColumns(), true, true);
+                sel.select(vals[idx], field.getElementMapping().
+                    getSelectSubclasses(), store, fetch, eagerMode, joins);
+
+                //### cheat: result joins only care about the relation path;
+                //### thus we can use first mapping of union only
+                if (idx == 0)
+                    resJoins[1] = joins;
+            }
+        });
+
+        Result kres = null;
+        Result vres = null;
+        try {
+            kres = kunion.execute(store, fetch);
+            vres = vunion.execute(store, fetch);
+            return new Result[]{ kres, vres };
+        } catch (SQLException se) {
+            if (kres != null)
+                kres.close();
+            if (vres != null)
+                vres.close();
+            throw se;
+        }
+    }
+
+    public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        ClassMapping key = res.getBaseMapping();
+        if (key == null)
+            key = field.getKeyMapping().getIndependentTypeMappings()[0];
+        return res.load(key, store, fetch, joins);
+    }
+
+    public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res, Joins joins)
+        throws SQLException {
+        ClassMapping val = res.getBaseMapping();
+        if (val == null)
+            val = field.getElementMapping().getIndependentTypeMappings()[0];
+        return res.load(val, store, fetch, joins);
+    }
+
+    public Joins joinKeyRelation(Joins joins, ClassMapping key) {
+        ValueMapping vm = field.getKeyMapping();
+        return joins.joinRelation(_keyRelationName, vm.getForeignKey(key), key,
+            vm.getSelectSubclasses(), false, false);
+    }
+
+    public Joins joinValueRelation(Joins joins, ClassMapping val) {
+        ValueMapping vm = field.getElementMapping();
+        return joins.joinRelation(field.getName(), vm.getForeignKey(val), val,
+            vm.getSelectSubclasses(), false, false);
+    }
+
+    public void map(boolean adapt) {
+        super.map(adapt);
+
+        ValueMapping key = field.getKeyMapping();
+        if (key.getTypeCode() != JavaTypes.PC || key.isEmbeddedPC())
+            throw new MetaDataException(_loc.get("not-relation", key));
+        ValueMapping val = field.getElementMapping();
+        if (val.getTypeCode() != JavaTypes.PC || val.isEmbeddedPC())
+            throw new MetaDataException(_loc.get("not-relation", val));
+        assertNotMappedBy();
+
+        field.mapJoin(adapt, true);
+        mapTypeJoin(key, "key", adapt);
+        mapTypeJoin(val, "value", adapt);
+
+        field.mapPrimaryKey(adapt);
+    }
+
+    /**
+     * Map the given value's join to its persistent type.
+     */
+    private void mapTypeJoin(ValueMapping vm, String name, boolean adapt) {
+        if (vm.getTypeMapping().isMapped()) {
+            ValueMappingInfo vinfo = vm.getValueInfo();
+            ForeignKey fk = vinfo.getTypeJoin(vm, name, false, adapt);
+            vm.setForeignKey(fk);
+            vm.setColumnIO(vinfo.getColumnIO());
+        } else
+            RelationStrategies.mapRelationToUnmappedPC(vm, name, adapt);
+        vm.mapConstraints(name, adapt);
+    }
+
+    public void initialize() {
+        _keyRelationName = field.getName() + ":key";
+    }
+
+    public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        insert(sm, rm, (Map) sm.fetchObject(field.getIndex()));
+    }
+
+    private void insert(OpenJPAStateManager sm, RowManager rm, Map map)
+        throws SQLException {
+        if (map == null || map.isEmpty())
+            return;
+
+        Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+        row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+            sm);
+
+        ValueMapping key = field.getKeyMapping();
+        ValueMapping val = field.getElementMapping();
+        StoreContext ctx = sm.getContext();
+        OpenJPAStateManager keysm, valsm;
+        Map.Entry entry;
+        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            keysm = RelationStrategies.getStateManager(entry.getKey(), ctx);
+            valsm = RelationStrategies.getStateManager(entry.getValue(), ctx);
+            key.setForeignKey(row, keysm);
+            val.setForeignKey(row, valsm);
+            rm.flushSecondaryRow(row);
+        }
+    }
+
+    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+        throws SQLException {
+        Map map = (Map) sm.fetchObject(field.getIndex());
+        ChangeTracker ct = null;
+        if (map instanceof Proxy) {
+            Proxy proxy = (Proxy) map;
+            if (Proxies.isOwner(proxy, sm, field.getIndex()))
+                ct = proxy.getChangeTracker();
+        }
+
+        // if no fine-grained change tracking then just delete and reinsert
+        if (ct == null || !ct.isTracking()) {
+            delete(sm, store, rm);
+            insert(sm, rm, map);
+            return;
+        }
+
+        ValueMapping key = field.getKeyMapping();
+        ValueMapping val = field.getElementMapping();
+        StoreContext ctx = store.getContext();
+        OpenJPAStateManager keysm, valsm;
+
+        // update the changes; note that we have to model changes as
+        // delete-then-insert if we have a foreign key action, because
+        // secondary row updates aren't part of the constraint graph
+        Collection change = ct.getChanged();
+        boolean canChange = val.getForeignKey().isLogical();
+        Object mkey;
+        if (canChange && !change.isEmpty()) {
+            Row changeRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_UPDATE);
+            changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+            for (Iterator itr = change.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                keysm = RelationStrategies.getStateManager(mkey, ctx);
+                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
+                key.whereForeignKey(changeRow, keysm);
+                val.setForeignKey(changeRow, valsm);
+                rm.flushSecondaryRow(changeRow);
+            }
+        }
+
+        // delete the removes
+        Collection rem = ct.getRemoved();
+        if (!rem.isEmpty() || (!canChange && !change.isEmpty())) {
+            Row delRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_DELETE);
+            delRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+            for (Iterator itr = rem.iterator(); itr.hasNext();) {
+                keysm = RelationStrategies.getStateManager(itr.next(), ctx);
+                key.whereForeignKey(delRow, keysm);
+                rm.flushSecondaryRow(delRow);
+            }
+            if (!canChange && !change.isEmpty()) {
+                for (Iterator itr = change.iterator(); itr.hasNext();) {
+                    keysm = RelationStrategies.getStateManager(itr.next(),
+                        ctx);
+                    key.whereForeignKey(delRow, keysm);
+                    rm.flushSecondaryRow(delRow);
+                }
+            }
+        }
+
+        // insert the adds
+        Collection add = ct.getAdded();
+        if (!add.isEmpty() || (!canChange && !change.isEmpty())) {
+            Row addRow = rm.getSecondaryRow(field.getTable(),
+                Row.ACTION_INSERT);
+            addRow.setForeignKey(field.getJoinForeignKey(),
+                field.getJoinColumnIO(), sm);
+
+            for (Iterator itr = add.iterator(); itr.hasNext();) {
+                mkey = itr.next();
+                keysm = RelationStrategies.getStateManager(mkey, ctx);
+                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
+                key.setForeignKey(addRow, keysm);
+                val.setForeignKey(addRow, valsm);
+                rm.flushSecondaryRow(addRow);
+            }
+            if (!canChange && !change.isEmpty()) {
+                for (Iterator itr = change.iterator(); itr.hasNext();) {
+                    mkey = itr.next();
+                    keysm = RelationStrategies.getStateManager(mkey, ctx);
+                    valsm = RelationStrategies.getStateManager(map.get(mkey),
+                        ctx);
+                    key.setForeignKey(addRow, keysm);
+                    val.setForeignKey(addRow, valsm);
+                    rm.flushSecondaryRow(addRow);
+                }
+            }
+        }
+    }
+
+    public Joins joinRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        ValueMapping val = field.getElementMapping();
+        ClassMapping[] clss = val.getIndependentTypeMappings();
+        if (clss.length != 1) {
+            if (traverse)
+                throw RelationStrategies.unjoinable(val);
+            return joins;
+        }
+        if (forceOuter)
+            return joins.outerJoinRelation(field.getName(),
+                val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(),
+                false, false);
+        return joins.joinRelation(field.getName(),
+            val.getForeignKey(clss[0]), clss[0], val.getSelectSubclasses(),
+            false, false);
+    }
+
+    public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+        boolean traverse) {
+        ValueMapping key = field.getKeyMapping();
+        ClassMapping[] clss = key.getIndependentTypeMappings();
+        if (clss.length != 1) {
+            if (traverse)
+                throw RelationStrategies.unjoinable(key);
+            return joins;
+        }
+        if (forceOuter)
+            return joins.outerJoinRelation(field.getName(),
+                key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(),
+                false, false);
+        return joins.joinRelation(_keyRelationName,
+            key.getForeignKey(clss[0]), clss[0], key.getSelectSubclasses(), 
+            false, false);
+    }
+
+    public Object toDataStoreValue(Object val, JDBCStore store) {
+        return RelationStrategies.toDataStoreValue(field.getElementMapping(),
+            val, store);
+    }
+
+    public Object toKeyDataStoreValue(Object val, JDBCStore store) {
+        return RelationStrategies.toDataStoreValue(field.getKeyMapping(),
+            val, store);
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
index af138d5..49ff908 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
@@ -38,13 +38,9 @@
 
         // DB2-based databases have restrictions on having uncast parameters
         // in string functions
-        toUpperCaseFunction = "UPPER(CAST({0} AS VARCHAR(" + varcharCastLength
-            + ")))";
-        toLowerCaseFunction = "LOWER(CAST({0} AS VARCHAR(" + varcharCastLength
-            + ")))";
         stringLengthFunction = "LENGTH({0})";
         concatenateFunction = "(CAST({0} AS VARCHAR(" + varcharCastLength
-            + ")))||(CAST({1} AS VARCHAR(1000)))";
+            + ")))||(CAST({1} AS VARCHAR(" + varcharCastLength + ")))";
 
         trimLeadingFunction = "LTRIM({0})";
         trimTrailingFunction = "RTRIM({0})";
@@ -60,6 +56,7 @@
         supportsLockingWithOuterJoin = false;
         supportsLockingWithInnerJoin = false;
         supportsLockingWithSelectRange = true;
+        supportsCaseConversionForLob = true;
 
         requiresAutoCommitForMetaData = true;
         requiresAliasForSubselect = true;
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
index 6909141..6e2bcb1 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
@@ -1,831 +1,859 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.sql;
-
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Arrays;
-import java.util.StringTokenizer;
-
-import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
-import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
-import org.apache.openjpa.jdbc.kernel.exps.Lit;
-import org.apache.openjpa.jdbc.kernel.exps.Param;
-import org.apache.openjpa.jdbc.kernel.exps.Val;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.Index;
-import org.apache.openjpa.jdbc.schema.Schema;
-import org.apache.openjpa.jdbc.schema.Sequence;
-import org.apache.openjpa.jdbc.schema.Table;
-import org.apache.openjpa.kernel.Filters;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.UnsupportedException;
-
-import serp.util.Strings;
-
-/**
- * Dictionary for IBM DB2 database.
- */
-public class DB2Dictionary
-    extends AbstractDB2Dictionary {
-    private static final Localizer _loc = Localizer.forPackage
-        (DB2Dictionary.class);
-
-    public String optimizeClause = "optimize for";
-    public String rowClause = "row";
-    protected int db2ServerType = 0;
-    public static final int db2ISeriesV5R3OrEarlier = 1;
-    public static final int db2UDBV81OrEarlier = 2;
-    public static final int db2ZOSV8xOrLater = 3;
-    public static final int db2UDBV82OrLater = 4;
-    public static final int db2ISeriesV5R4OrLater = 5;
-	protected static final String forUpdate = "FOR UPDATE";
-    protected static final String withURClause = "WITH UR";
-    protected static final String withCSClause = "WITH CS";
-    protected static final String withRSClause = "WITH RS";
-    protected static final String withRRClause = "WITH RR";
-    protected static final String useKeepShareLockClause
-        = "USE AND KEEP SHARE LOCKS";
-    protected static final String useKeepUpdateLockClause
-        = "USE AND KEEP UPDATE LOCKS";
-    protected static final String useKeepExclusiveLockClause
-        = "USE AND KEEP EXCLUSIVE LOCKS";
-    protected static final String forReadOnlyClause = "FOR READ ONLY";
-    protected String databaseProductName = "";
-    protected String databaseProductVersion = "";
-    protected int maj = 0;
-    protected int min = 0;
-    
-    private int defaultBatchLimit = 100;
-
-    public DB2Dictionary() {
-        platform = "DB2";
-        validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
-            + "SYSIBM.SYSTABLES";
-        supportsSelectEndIndex = true;
-
-        nextSequenceQuery = "VALUES NEXTVAL FOR {0}";
-
-        sequenceSQL = "SELECT SEQSCHEMA AS SEQUENCE_SCHEMA, "
-            + "SEQNAME AS SEQUENCE_NAME FROM SYSCAT.SEQUENCES";
-        sequenceSchemaSQL = "SEQSCHEMA = ?";
-        sequenceNameSQL = "SEQNAME = ?";
-        characterColumnSize = 254;
-
-        binaryTypeName = "BLOB(1M)";
-        longVarbinaryTypeName = "BLOB(1M)";
-        varbinaryTypeName = "BLOB(1M)";
-        clobTypeName = "CLOB(1M)";
-        longVarcharTypeName = "LONG VARCHAR";
-        datePrecision = MICRO;
-        storeCharsAsNumbers = false;
-
-        fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
-            "LONG VARCHAR FOR BIT DATA", "LONG VARCHAR", "LONG VARGRAPHIC",
-        }));
-        systemSchemas = new String(
-                "SYSCAT,SYSIBM,SYSSTAT,SYSIBMADM,SYSTOOLS");
-        maxConstraintNameLength = 18;
-        maxIndexNameLength = 18;
-        maxColumnNameLength = 30;
-        supportsDeferredConstraints = false;
-        supportsDefaultDeleteAction = false;
-        supportsAlterTableWithDropColumn = false;
-
-        supportsNullTableForGetColumns = false;
-        requiresCastForMathFunctions = true;
-        requiresCastForComparisons = true;
-
-        reservedWordSet.addAll(Arrays.asList(new String[]{
-            "AFTER", "ALIAS", "ALLOW", "APPLICATION", "ASSOCIATE", "ASUTIME",
-            "AUDIT", "AUX", "AUXILIARY", "BEFORE", "BINARY", "BUFFERPOOL",
-            "CACHE", "CALL", "CALLED", "CAPTURE", "CARDINALITY", "CCSID",
-            "CLUSTER", "COLLECTION", "COLLID", "COMMENT", "CONCAT",
-            "CONDITION", "CONTAINS", "COUNT_BIG", "CURRENT_LC_CTYPE",
-            "CURRENT_PATH", "CURRENT_SERVER", "CURRENT_TIMEZONE", "CYCLE",
-            "DATA", "DATABASE", "DAYS", "DB2GENERAL", "DB2GENRL", "DB2SQL",
-            "DBINFO", "DEFAULTS", "DEFINITION", "DETERMINISTIC", "DISALLOW",
-            "DO", "DSNHATTR", "DSSIZE", "DYNAMIC", "EACH", "EDITPROC", "ELSEIF",
-            "ENCODING", "END-EXEC1", "ERASE", "EXCLUDING", "EXIT", "FENCED",
-            "FIELDPROC", "FILE", "FINAL", "FREE", "FUNCTION", "GENERAL",
-            "GENERATED", "GRAPHIC", "HANDLER", "HOLD", "HOURS", "IF",
-            "INCLUDING", "INCREMENT", "INDEX", "INHERIT", "INOUT", "INTEGRITY",
-            "ISOBID", "ITERATE", "JAR", "JAVA", "LABEL", "LC_CTYPE", "LEAVE",
-            "LINKTYPE", "LOCALE", "LOCATOR", "LOCATORS", "LOCK", "LOCKMAX",
-            "LOCKSIZE", "LONG", "LOOP", "MAXVALUE", "MICROSECOND",
-            "MICROSECONDS", "MINUTES", "MINVALUE", "MODE", "MODIFIES", "MONTHS",
-            "NEW", "NEW_TABLE", "NOCACHE", "NOCYCLE", "NODENAME", "NODENUMBER",
-            "NOMAXVALUE", "NOMINVALUE", "NOORDER", "NULLS", "NUMPARTS", "OBID",
-            "OLD", "OLD_TABLE", "OPTIMIZATION", "OPTIMIZE", "OUT", "OVERRIDING",
-            "PACKAGE", "PARAMETER", "PART", "PARTITION", "PATH", "PIECESIZE",
-            "PLAN", "PRIQTY", "PROGRAM", "PSID", "QUERYNO", "READS", "RECOVERY",
-            "REFERENCING", "RELEASE", "RENAME", "REPEAT", "RESET", "RESIGNAL",
-            "RESTART", "RESULT", "RESULT_SET_LOCATOR", "RETURN", "RETURNS",
-            "ROUTINE", "ROW", "RRN", "RUN", "SAVEPOINT", "SCRATCHPAD",
-            "SECONDS", "SECQTY", "SECURITY", "SENSITIVE", "SIGNAL", "SIMPLE",
-            "SOURCE", "SPECIFIC", "SQLID", "STANDARD", "START", "STATIC",
-            "STAY", "STOGROUP", "STORES", "STYLE", "SUBPAGES", "SYNONYM",
-            "SYSFUN", "SYSIBM", "SYSPROC", "SYSTEM", "TABLESPACE", "TRIGGER",
-            "TYPE", "UNDO", "UNTIL", "VALIDPROC", "VARIABLE", "VARIANT", "VCAT",
-            "VOLUMES", "WHILE", "WLM", "YEARS",
-        }));
-        
-        super.setBatchLimit(defaultBatchLimit);
-        
-        selectWordSet.add("WITH");
-    }
-
-    public boolean supportsRandomAccessResultSet(Select sel,
-        boolean forUpdate) {
-        return !forUpdate
-            && super.supportsRandomAccessResultSet(sel, forUpdate);
-    }
-
-    protected void appendSelectRange(SQLBuffer buf, long start, long end,
-        boolean subselect) {
-        // appends the literal range string, since DB2 is unable to handle
-        // a bound parameter for it
-        // do not generate FETCH FIRST clause for subselect
-        if (!subselect)
-            buf.append(" FETCH FIRST ").append(Long.toString(end)).
-                append(" ROWS ONLY");
-    }
-
-    protected void appendSelect(SQLBuffer selectSQL, Object alias, Select sel,
-        int idx) {
-        // if this is a literal value, add a cast...
-        Object val = sel.getSelects().get(idx);
-        if (val instanceof Lit)
-            selectSQL.append("CAST(");
-
-        // ... and add the select per super's behavior...
-        super.appendSelect(selectSQL, alias, sel, idx);
-
-        // ... and finish the cast
-        if (val instanceof Lit) {
-            Class c = ((Lit) val).getType();
-            int javaTypeCode = JavaTypes.getTypeCode(c);
-            int jdbcTypeCode = getJDBCType(javaTypeCode, false);
-            String typeName = getTypeName(jdbcTypeCode);
-            selectSQL.append(" AS " + typeName);
-
-            // if the literal is a string, use the default char col size
-            // in the cast statement.
-            if (String.class.equals(c))
-                selectSQL.append("(" + characterColumnSize + ")");
-
-            selectSQL.append(")");
-        }
-    }
-
-    public String[] getCreateSequenceSQL(Sequence seq) {
-        String[] sql = super.getCreateSequenceSQL(seq);
-        if (seq.getAllocate() > 1)
-            sql[0] += " CACHE " + seq.getAllocate();
-        return sql;
-    }
-
-    protected String getSequencesSQL(String schemaName, String sequenceName) {
-        StringBuffer buf = new StringBuffer();
-        buf.append(sequenceSQL);
-        if (schemaName != null || sequenceName != null)
-            buf.append(" WHERE ");
-        if (schemaName != null) {
-            buf.append(sequenceSchemaSQL);
-            if (sequenceName != null)
-                buf.append(" AND ");
-        }
-        if (sequenceName != null)
-            buf.append(sequenceNameSQL);
-        return buf.toString();
-    }
-
-    public Connection decorate(Connection conn)
-        throws SQLException {
-        // some versions of the DB2 driver seem to default to
-        // READ_UNCOMMITTED, which will prevent locking from working
-        // (multiple SELECT ... FOR UPDATE statements are allowed on
-        // the same instance); if we have not overridden the
-        // transaction isolation in the configuration, default to
-        // TRANSACTION_READ_COMMITTED
-        conn = super.decorate(conn);
-
-        if (conf.getTransactionIsolationConstant() == -1
-            && conn.getTransactionIsolation() < conn.TRANSACTION_READ_COMMITTED)
-            conn.setTransactionIsolation(conn.TRANSACTION_READ_COMMITTED);
-
-        return conn;
-    }
-
-    public void connectedConfiguration(Connection conn) throws SQLException {
-    	super.connectedConfiguration(conn);
-
-    	DatabaseMetaData metaData = conn.getMetaData();
-        databaseProductName = nullSafe(metaData.getDatabaseProductName());
-        databaseProductVersion = nullSafe(metaData.getDatabaseProductVersion());
-        
-        // Determine the type of DB2 database
-        // First check for AS/400
-        getProductVersionMajorMinorForISeries();
-
-        if (maj > 0) {
-            if (isDB2ISeriesV5R3OrEarlier())
-                db2ServerType = db2ISeriesV5R3OrEarlier;
-            else if (isDB2ISeriesV5R4OrLater())
-                db2ServerType = db2ISeriesV5R4OrLater;
-        }
-        
-    	if (db2ServerType == 0) {
-    	    if (isJDBC3) {
-    	        maj = metaData.getDatabaseMajorVersion();
-    	        min = metaData.getDatabaseMinorVersion();
-    	    }
-    	    else
-    	        getProductVersionMajorMinor();
-
-    	    // Determine the type of DB2 database for ZOS & UDB
-    	    if (isDB2UDBV81OrEarlier())
-    	        db2ServerType = db2UDBV81OrEarlier;
-    	    else if (isDB2ZOSV8xOrLater())
-    	        db2ServerType = db2ZOSV8xOrLater;
-    	    else if (isDB2UDBV82OrLater())
-    	        db2ServerType = db2UDBV82OrLater;
-        }
-
-        // verify that databae product is supported
-        if (db2ServerType == 0 || maj == 0)
-            throw new UnsupportedException(_loc.get("db-not-supported",
-                new Object[] {databaseProductName, databaseProductVersion }));                    
-
-    	if (maj >= 9 || (maj == 8 && min >= 2)) {
-    	    supportsLockingWithMultipleTables = true;
-    	    supportsLockingWithInnerJoin = true;
-    	    supportsLockingWithOuterJoin = true;
-    	    forUpdateClause = "WITH RR USE AND KEEP UPDATE LOCKS";
-    	    if (maj >=9)
-    	        supportsXMLColumn = true;
-    	}
-
-        // platform specific settings
-        switch (db2ServerType) {
-        case  db2ZOSV8xOrLater:
-            // DB2 Z/OS 
-            characterColumnSize = 255;
-            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM "
-                + "SYSIBM.SYSDUMMY1";
-            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM "
-                + "SYSIBM.SYSDUMMY1";
-            sequenceSQL = "SELECT SCHEMA AS SEQUENCE_SCHEMA, "
-                + "NAME AS SEQUENCE_NAME FROM SYSIBM.SYSSEQUENCES";
-            sequenceSchemaSQL = "SCHEMA = ?";
-            sequenceNameSQL = "NAME = ?";
-            if (maj == 8)
-                // DB2 Z/OS Version 8: no bigint support, hence map Java
-                // long to decimal
-                bigintTypeName = "DECIMAL(31,0)";
-            break;
-        case db2ISeriesV5R3OrEarlier:
-        case db2ISeriesV5R4OrLater:
-            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM "
-                + "SYSIBM.SYSDUMMY1";
-            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM "
-                + "SYSIBM.SYSDUMMY1";
-            validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
-                + "QSYS2.SYSTABLES";
-            sequenceSQL = "SELECT SEQUENCE_SCHEMA, "
-                + "SEQUENCE_NAME FROM QSYS2.SYSSEQUENCES";
-            sequenceSchemaSQL = "SEQUENCE_SCHEMA = ?";
-            sequenceNameSQL = "SEQUENCE_NAME = ?";
-            break;
-        }
-    }
-
-    /**
-     * Get the update clause for the query based on the
-     * updateClause and isolationLevel hints
-     */
-    protected String getForUpdateClause(JDBCFetchConfiguration fetch,
-        boolean isForUpdate, Select sel) {
-        int isolationLevel;
-        // For db2UDBV81OrEarlier and db2ISeriesV5R3OrEarlier:
-        // "optimize for" clause appears before "for update" clause.
-        StringBuffer forUpdateString = new StringBuffer(
-            getOptimizeClause(sel));
-        try {
-            // Determine the isolationLevel; the fetch
-            // configuration data overrides the persistence.xml value
-            if (fetch != null && fetch.getIsolation() != -1)
-                isolationLevel = fetch.getIsolation();
-            else
-                isolationLevel = conf.getTransactionIsolationConstant();
-
-            if (isForUpdate) {
-                switch(db2ServerType) {
-                case db2ISeriesV5R3OrEarlier:
-                case db2UDBV81OrEarlier:
-                    if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE)
-                        forUpdateString.append(" ").append(forUpdateClause);
-                    else 
-                        forUpdateString.append(" ").append(forUpdate)
-                            .append(" ").append(withRSClause);
-                    break;
-                case db2ZOSV8xOrLater:
-                case db2UDBV82OrLater:
-                    if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
-                        forUpdateString.append(" ").append(forReadOnlyClause)
-                            .append(" ").append(withRRClause)
-                            .append(" ").append(useKeepUpdateLockClause);   
-                    } else {
-                        forUpdateString.append(" ").append(forReadOnlyClause)
-                            .append(" ").append(withRSClause)
-                            .append(" ").append(useKeepUpdateLockClause);                            
-                    }
-                    break;
-                case db2ISeriesV5R4OrLater:
-                    if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
-                        forUpdateString.append(" ").append(forReadOnlyClause)
-                            .append(" ").append(withRRClause)
-                            .append(" ").append(useKeepExclusiveLockClause);       
-                    } else {
-                        forUpdateString.append(" ").append(forReadOnlyClause)
-                            .append(" ").append(withRSClause)
-                            .append(" ").append(useKeepExclusiveLockClause);
-                    }
-                    break;
-                }
-            }
-        }
-        catch (Exception e) {
-            if (log.isTraceEnabled())
-                log.error(e.toString(),e);
-        }
-        return forUpdateString.toString();
-    }
-
-    public boolean isDB2UDBV82OrLater() {
-        return (databaseProductVersion.indexOf("SQL") != -1
-             || databaseProductName.indexOf("DB2/") != -1)
-             && ((maj == 8 && min >= 2) || (maj >= 9));
-    }
-
-    public boolean isDB2ZOSV8xOrLater() {
-       return (databaseProductVersion.indexOf("DSN") != -1
-            || databaseProductName.indexOf("DB2/") == -1)
-            && maj >= 8;
-           
-    }
-
-    public boolean isDB2ISeriesV5R3OrEarlier() {
-       return (databaseProductName.indexOf("AS") != -1
-           && ((maj == 5 && min <=3) || maj < 5));
-    }
-
-    public boolean isDB2ISeriesV5R4OrLater() {
-       return databaseProductName.indexOf("AS") != -1
-           && (maj >=6 || (maj == 5 && min >=4));
-    }
-
-    public boolean isDB2UDBV81OrEarlier() {
-        return (databaseProductVersion.indexOf("SQL") != -1 
-            || databaseProductName.indexOf("DB2/") != -1) 
-            && ((maj == 8 && min <= 1) || maj < 8);
-    }
-
-    /** Get the version Major/Minor for the ISeries
-     */
-    private void getProductVersionMajorMinorForISeries() {
-        // ISeries    DBProdName                 DB2 UDB for AS/400
-        //   (Toolbox)DBProdVersion              05.04.0000 V5R4m0
-        // ISeries                               DB2 UDB for AS/400
-        //   (Native)                            V5R4M0
-        // new jcc    DBProdVersion              QSQ05040 or QSQ06010
-        if (databaseProductName.indexOf("AS") != -1) {
-            // default to V5R4
-            maj = 5;
-            min = 4;
-            int index = databaseProductVersion.indexOf('V');
-            if (index != -1) {
-                String s = databaseProductVersion.substring(index);
-                s = s.toUpperCase();
-
-                StringTokenizer stringtokenizer = new StringTokenizer(s, "VRM"
-                    , false);
-                if (stringtokenizer.countTokens() == 3) {
-                    String s1 = stringtokenizer.nextToken();
-                    maj = Integer.parseInt(s1);
-                    String s2 =  stringtokenizer.nextToken();
-                    min = Integer.parseInt(s2);
-                }
-            } else {
-                index = databaseProductVersion.indexOf('0');
-                if (index != -1) {
-                    String s = databaseProductVersion.substring(index);
-                    s = s.toUpperCase();
-
-                    StringTokenizer stringtokenizer = new StringTokenizer(s, "0"
-                        , false);                    
-                    if (stringtokenizer.countTokens() == 2) {
-                        String s1 = stringtokenizer.nextToken();
-                        maj = Integer.parseInt(s1);
-                        String s2 =  stringtokenizer.nextToken();
-                        min = Integer.parseInt(s2);
-                    }
-                }
-            }
-        }
-    }
-    
-    private void getProductVersionMajorMinor() {
-        // Incase JDBC driver version is lower than 3
-        // use following info to determine Major and Minor 
-        //                        CLI    vs      JCC
-        // ZDBV8 DBProdName       DB2            DB2
-        //       DBProdVersion    08.01.0005     DSN08015
-        // ZDBV9                  DB2            DB2
-        //                        09.01.0005     DSN09015
-        // WinV9                  DB2/NT         DB2/NT
-        //                        09.01.0000     SQL09010
-        // SolarisV9                             DB2/SUN64
-        //                                       SQL0901
-        // Linux                  DB2/LINUX      DB2/LINUX
-        //                        09.01.0000     SQL0901
-        if (databaseProductVersion.indexOf("09") != -1) {
-            maj = 9;
-            if (databaseProductVersion.indexOf("01") != -1) {
-                min = 1;
-            }
-        } else if (databaseProductVersion.indexOf("08") != -1) {
-            maj = 8;
-            min = 2;
-            if (databaseProductVersion.indexOf("01") != -1) {
-                min = 1;
-            }
-        }
-    }
-
-    protected String getOptimizeClause(Select sel) {
-        if (sel != null && sel.getExpectedResultCount() > 0) {
-            StringBuffer buf = new StringBuffer();
-            buf.append(" ").append(optimizeClause).append(" ")
-                .append(String.valueOf(sel.getExpectedResultCount()))
-                .append(" ").append(rowClause);
-            return buf.toString();
-        }
-
-        return "";
-    }
-
-    public OpenJPAException newStoreException(String msg, SQLException[] causes,
-        Object failed) {
-        if (causes != null && causes.length > 0)
-            msg = appendExtendedExceptionMsg(msg, causes[0]);
-        return super.newStoreException(msg, causes, failed);
-    }
-
-    /**
-     *  Append exception information from SQLCA to the exsisting
-     *  exception meassage
-     */
-    private String appendExtendedExceptionMsg(String msg, SQLException sqle){
-       final String GETSQLCA ="getSqlca";
-       String exceptionMsg = new String();
-       try {
-            Method sqlcaM2 = sqle.getNextException().getClass()
-                             .getMethod(GETSQLCA,null);
-            Object sqlca = sqlcaM2.invoke(sqle.getNextException(),
-                                          new Object[] {});
-            Method  getSqlErrpMethd = sqlca.getClass().
-            getMethod("getSqlErrp", null);
-            Method  getSqlWarnMethd = sqlca.getClass().
-            getMethod("getSqlWarn", null);
-            Method  getSqlErrdMethd = sqlca.getClass().
-            getMethod("getSqlErrd", null);
-            StringBuffer errdStr = new StringBuffer();
-
-            int[] errds = (int[]) getSqlErrdMethd.invoke(sqlca, new Object[]{});
-            for (int i = 0; i < errds.length; i++)
-                errdStr.append(errdStr.length() > 0 ? ", " : "").
-                    append(errds[i]);
-            exceptionMsg = exceptionMsg.concat( "SQLCA OUTPUT" +
-                    "[Errp=" + getSqlErrpMethd.invoke(sqlca, new Object[]{})
-                    + ", Errd=" + errdStr);
-
-            String Warn = new String((char[]) getSqlWarnMethd.
-                    invoke(sqlca, new Object[]{}));
-            if (Warn.trim().length() != 0)
-                exceptionMsg = exceptionMsg.concat(", Warn=" +Warn + "]" );
-            else
-                exceptionMsg = exceptionMsg.concat( "]" );
-            msg = msg.concat(exceptionMsg);
-            
-            // for batched execution failures, SQLExceptions are nested
-            SQLException sqle2 = sqle.getNextException();
-            while (sqle2 != null) {                
-                msg = msg.concat("\n" + sqle2.getMessage());
-                sqle2 = sqle2.getNextException();
-            }
-            
-            return msg;
-        } catch (Throwable t) {
-            return sqle.getMessage();
-        }
-    }
-
-    public int getDb2ServerType() {
-        return db2ServerType;
-    }
-    
-    protected void appendLength(SQLBuffer buf, int type) {
-        if (type == Types.VARCHAR)
-            buf.append("(").append(Integer.toString(characterColumnSize)).
-                append(")");
-    }
-
-    /**
-     * If this dictionary supports XML type,
-     * use this method to append xml predicate.
-     * 
-     * @param buf the SQL buffer to write the comparison
-     * @param op the comparison operation to perform
-     * @param lhs the left hand side of the comparison
-     * @param rhs the right hand side of the comparison
-     * @param lhsxml indicates whether the left operand maps to xml
-     * @param rhsxml indicates whether the right operand maps to xml
-     */
-    public void appendXmlComparison(SQLBuffer buf, String op, FilterValue lhs,
-        FilterValue rhs, boolean lhsxml, boolean rhsxml) {
-        super.appendXmlComparison(buf, op, lhs, rhs, lhsxml, rhsxml);
-        if (lhsxml && rhsxml)
-            appendXmlComparison2(buf, op, lhs, rhs);
-        else if (lhsxml)
-            appendXmlComparison1(buf, op, lhs, rhs);
-        else 
-            appendXmlComparison1(buf, op, rhs, lhs);
-    }
-
-    /**
-     * Append an xml comparison predicate.
-     *
-     * @param buf the SQL buffer to write the comparison
-     * @param op the comparison operation to perform
-     * @param lhs the left hand side of the comparison (maps to xml column)
-     * @param rhs the right hand side of the comparison
-     */
-    private void appendXmlComparison1(SQLBuffer buf, String op, 
-            FilterValue lhs, FilterValue rhs) {
-        boolean castrhs = false;
-        Class rc = Filters.wrap(rhs.getType());
-        int type = 0;
-        if (rhs.isConstant()) {
-            type = getJDBCType(JavaTypes.getTypeCode(rc), false);
-            castrhs = true;
-        }
-        
-        appendXmlExists(buf, lhs);
-
-        buf.append(" ").append(op).append(" ");
-        
-        buf.append("$");
-        if (castrhs)
-            buf.append("Parm");
-        else
-            rhs.appendTo(buf);
-        
-        buf.append("]' PASSING ");
-        appendXmlVar(buf, lhs);
-        buf.append(", ");
-        
-        if (castrhs)
-            appendCast(buf, rhs, type);
-        else
-            rhs.appendTo(buf);
-        
-        buf.append(" AS \"");
-        if (castrhs)
-            buf.append("Parm");
-        else
-            rhs.appendTo(buf);
-        buf.append("\")");
-    }
-    
-    /**
-     * Append an xml comparison predicate. (both operands map to xml column)
-     *
-     * @param buf the SQL buffer to write the comparison
-     * @param op the comparison operation to perform
-     * @param lhs the left hand side of the comparison (maps to xml column)
-     * @param rhs the right hand side of the comparison (maps to xml column)
-     */
-    private void appendXmlComparison2(SQLBuffer buf, String op, 
-            FilterValue lhs, FilterValue rhs) {
-        appendXmlExists(buf, lhs);
-        
-        buf.append(" ").append(op).append(" ");
-        
-        buf.append("$").append(rhs.getColumnAlias(
-            rhs.getFieldMapping().getColumns()[0])).
-            append("/*/");
-        rhs.appendTo(buf);
-        
-        buf.append("]' PASSING ");
-        appendXmlVar(buf, lhs);
-        buf.append(", ");
-        appendXmlVar(buf, rhs);
-        buf.append(")");
-    }
-    
-    private void appendXmlVar(SQLBuffer buf, FilterValue val) {
-        buf.append(val.getColumnAlias(
-            val.getFieldMapping().getColumns()[0])).
-            append(" AS ").
-            append("\"").append(val.getColumnAlias(
-            val.getFieldMapping().getColumns()[0])).
-            append("\"");        
-    }
-    
-    private void appendXmlExists(SQLBuffer buf, FilterValue val) {
-        buf.append("XMLEXISTS('");
-        buf.append("$").append(val.getColumnAlias(
-            val.getFieldMapping().getColumns()[0])).
-            append("/*[");
-        val.appendTo(buf);        
-    }
-    
-    /**
-     * add CAST for a scalar function where operand is a param
-     * 
-     * @param func original string
-     * @param target substring to look for
-     * @param asString 
-     * @return updated string (func)
-     */
-    private String addCastAsString(String func, String target, 
-            String asString) {
-        String fstring = func;
-        if (func.indexOf(target) != -1)
-            fstring = Strings.replace(
-                func, target, "CAST(" + target + asString + ")");
-        return fstring;
-    }
-
-    /**
-     * add CAST for a function operator where operand is a param
-     * 
-     * @param func function name
-     * @param val type
-     * @return updated string (func)
-     */
-    public String addCastAsType(String func, Val val) {
-        String fstring = null;
-        String type = getTypeName(getJDBCType(JavaTypes.getTypeCode(val
-            .getType()), false));
-        if (String.class.equals(val.getType()))
-            type = type + "(" + characterColumnSize + ")";
-        fstring = "CAST(? AS " + type + ")";
-        return fstring;
-    }
-
-    /**
-     * Return the batch limit. If the batchLimit is -1, change it to 100 for
-     * best performance
-     */
-    public int getBatchLimit() {
-        int limit = super.getBatchLimit();
-        if (limit == UNLIMITED) {
-            limit = defaultBatchLimit;
-            if (log.isTraceEnabled())
-                log.trace(_loc.get("batch_unlimit", String.valueOf(limit)));
-        }
-        return limit;
-    }
-
-    /**
-     * Return the correct CAST function syntax
-     * 
-     * @param val operand of cast
-     * @param func original string
-     * @return a String with the correct CAST function syntax
-     */
-    public String getCastFunction(Val val, String func) {
-        if (val instanceof Lit || val instanceof Param)
-            if (func.indexOf("VARCHAR") == -1)
-                func = addCastAsString(func, "{0}", " AS VARCHAR(1000)");
-        return func;
-    }
-
-    public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
-            FilterValue start) {
-        if (find.getValue() != null) { // non constants
-            buf.append("(LOCATE(CAST((");
-            find.appendTo(buf);
-            buf.append(") AS VARCHAR(1000)), ");
-        } else {
-            // this is a constant
-            buf.append("(LOCATE(");
-            find.appendTo(buf);
-            buf.append(", ");
-        }
-        if (str.getValue() != null) {
-            buf.append("CAST((");
-            str.appendTo(buf);
-            buf.append(") AS VARCHAR(1000))");
-        } else {
-            str.appendTo(buf);
-        }
-        if (start != null) {
-            if (start.getValue() == null) {
-                buf.append(", CAST((");
-                start.appendTo(buf);
-                buf.append(") AS INTEGER) + 1");
-            } else {
-                buf.append(", ");
-                start.appendTo(buf);
-            }
-        }
-        buf.append(") - 1)");
-    }
-    
-    /** 
-     * Cast the specified value to the specified type.
-     *
-     * @param buf the buffer to append the cast to
-     * @param val the value to cast
-     * @param type the type of the case, e.g. {@link Types#NUMERIC}
-     */
-    public void appendCast(SQLBuffer buf, FilterValue val, int type) {
-
-        // Convert the cast function: "CAST({0} AS {1})"
-        int firstParam = castFunction.indexOf("{0}");
-        String pre = castFunction.substring(0, firstParam); // "CAST("
-        String mid = castFunction.substring(firstParam + 3);
-        int secondParam = mid.indexOf("{1}");
-        String post;
-        if (secondParam > -1) {
-            post = mid.substring(secondParam + 3); // ")"
-            mid = mid.substring(0, secondParam); // " AS "
-        } else
-            post = "";
-
-        // No need to add CAST if the value is a constant
-        if (val instanceof Lit || val instanceof Param) {
-            buf.append(pre);
-            val.appendTo(buf);
-            buf.append(mid);
-            buf.append(getTypeName(type));
-            appendLength(buf, type);
-            buf.append(post);
-        } else {
-            val.appendTo(buf);
-            String sqlString = buf.getSQL(false);
-            if (sqlString.endsWith("?")) {
-                // case "(?" - convert to "CAST(? AS type"
-                String typeName = getTypeName(type);
-                if (String.class.equals(val.getType()))
-                    typeName = typeName + "(" + characterColumnSize + ")";
-                String str = "CAST(? AS " + typeName + ")";
-                buf.replaceSqlString(sqlString.length() - 1,
-                        sqlString.length(), str);
-            }
-        }
-    }
-
-    /**
-     * Create an index if necessary for some database tables
-     */
-    public void createIndexIfNecessary(Schema schema, String table,
-            Column pkColumn) {
-        if (isDB2ZOSV8xOrLater()) {
-            // build the index for the sequence tables
-            // the index name will the fully qualified table name + _IDX
-            Table tab = schema.getTable(table);
-            Index idx = tab.addIndex(tab.getFullName() + "_IDX");
-            idx.setUnique(true);
-            idx.addColumn(pkColumn);
-        }
-    }
-    
-    String nullSafe(String s) {
-    	return s == null ? "" : s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.jdbc.kernel.exps.Lit;
+import org.apache.openjpa.jdbc.kernel.exps.Param;
+import org.apache.openjpa.jdbc.kernel.exps.Val;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.Schema;
+import org.apache.openjpa.jdbc.schema.Sequence;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.UnsupportedException;
+
+import serp.util.Strings;
+
+/**
+ * Dictionary for IBM DB2 database.
+ */
+public class DB2Dictionary
+    extends AbstractDB2Dictionary {
+    private static final Localizer _loc = Localizer.forPackage
+        (DB2Dictionary.class);
+
+    public String optimizeClause = "optimize for";
+    public String rowClause = "row";
+    protected int db2ServerType = 0;
+    public static final int db2ISeriesV5R3OrEarlier = 1;
+    public static final int db2UDBV81OrEarlier = 2;
+    public static final int db2ZOSV8xOrLater = 3;
+    public static final int db2UDBV82OrLater = 4;
+    public static final int db2ISeriesV5R4OrLater = 5;
+	protected static final String forUpdate = "FOR UPDATE";
+    protected static final String withURClause = "WITH UR";
+    protected static final String withCSClause = "WITH CS";
+    protected static final String withRSClause = "WITH RS";
+    protected static final String withRRClause = "WITH RR";
+    protected static final String useKeepShareLockClause
+        = "USE AND KEEP SHARE LOCKS";
+    protected static final String useKeepUpdateLockClause
+        = "USE AND KEEP UPDATE LOCKS";
+    protected static final String useKeepExclusiveLockClause
+        = "USE AND KEEP EXCLUSIVE LOCKS";
+    protected static final String forReadOnlyClause = "FOR READ ONLY";
+    protected String databaseProductName = "";
+    protected String databaseProductVersion = "";
+    protected int maj = 0;
+    protected int min = 0;
+    
+    private int defaultBatchLimit = 100;
+
+    public DB2Dictionary() {
+        platform = "DB2";
+        validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
+            + "SYSIBM.SYSTABLES";
+        supportsSelectEndIndex = true;
+
+        nextSequenceQuery = "VALUES NEXTVAL FOR {0}";
+
+        sequenceSQL = "SELECT SEQSCHEMA AS SEQUENCE_SCHEMA, "
+            + "SEQNAME AS SEQUENCE_NAME FROM SYSCAT.SEQUENCES";
+        sequenceSchemaSQL = "SEQSCHEMA = ?";
+        sequenceNameSQL = "SEQNAME = ?";
+        characterColumnSize = 254;
+
+        binaryTypeName = "BLOB(1M)";
+        longVarbinaryTypeName = "BLOB(1M)";
+        varbinaryTypeName = "BLOB(1M)";
+        clobTypeName = "CLOB(1M)";
+        longVarcharTypeName = "LONG VARCHAR";
+        datePrecision = MICRO;
+        storeCharsAsNumbers = false;
+
+        fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
+            "LONG VARCHAR FOR BIT DATA", "LONG VARCHAR", "LONG VARGRAPHIC",
+        }));
+        systemSchemas = new String(
+                "SYSCAT,SYSIBM,SYSSTAT,SYSIBMADM,SYSTOOLS");
+        maxConstraintNameLength = 18;
+        maxIndexNameLength = 18;
+        maxColumnNameLength = 30;
+        supportsDeferredConstraints = false;
+        supportsDefaultDeleteAction = false;
+        supportsAlterTableWithDropColumn = false;
+
+        supportsNullTableForGetColumns = false;
+        requiresCastForMathFunctions = true;
+        requiresCastForComparisons = true;
+
+        reservedWordSet.addAll(Arrays.asList(new String[]{
+            "AFTER", "ALIAS", "ALLOW", "APPLICATION", "ASSOCIATE", "ASUTIME",
+            "AUDIT", "AUX", "AUXILIARY", "BEFORE", "BINARY", "BUFFERPOOL",
+            "CACHE", "CALL", "CALLED", "CAPTURE", "CARDINALITY", "CCSID",
+            "CLUSTER", "COLLECTION", "COLLID", "COMMENT", "CONCAT",
+            "CONDITION", "CONTAINS", "COUNT_BIG", "CURRENT_LC_CTYPE",
+            "CURRENT_PATH", "CURRENT_SERVER", "CURRENT_TIMEZONE", "CYCLE",
+            "DATA", "DATABASE", "DAYS", "DB2GENERAL", "DB2GENRL", "DB2SQL",
+            "DBINFO", "DEFAULTS", "DEFINITION", "DETERMINISTIC", "DISALLOW",
+            "DO", "DSNHATTR", "DSSIZE", "DYNAMIC", "EACH", "EDITPROC", "ELSEIF",
+            "ENCODING", "END-EXEC1", "ERASE", "EXCLUDING", "EXIT", "FENCED",
+            "FIELDPROC", "FILE", "FINAL", "FREE", "FUNCTION", "GENERAL",
+            "GENERATED", "GRAPHIC", "HANDLER", "HOLD", "HOURS", "IF",
+            "INCLUDING", "INCREMENT", "INDEX", "INHERIT", "INOUT", "INTEGRITY",
+            "ISOBID", "ITERATE", "JAR", "JAVA", "LABEL", "LC_CTYPE", "LEAVE",
+            "LINKTYPE", "LOCALE", "LOCATOR", "LOCATORS", "LOCK", "LOCKMAX",
+            "LOCKSIZE", "LONG", "LOOP", "MAXVALUE", "MICROSECOND",
+            "MICROSECONDS", "MINUTES", "MINVALUE", "MODE", "MODIFIES", "MONTHS",
+            "NEW", "NEW_TABLE", "NOCACHE", "NOCYCLE", "NODENAME", "NODENUMBER",
+            "NOMAXVALUE", "NOMINVALUE", "NOORDER", "NULLS", "NUMPARTS", "OBID",
+            "OLD", "OLD_TABLE", "OPTIMIZATION", "OPTIMIZE", "OUT", "OVERRIDING",
+            "PACKAGE", "PARAMETER", "PART", "PARTITION", "PATH", "PIECESIZE",
+            "PLAN", "PRIQTY", "PROGRAM", "PSID", "QUERYNO", "READS", "RECOVERY",
+            "REFERENCING", "RELEASE", "RENAME", "REPEAT", "RESET", "RESIGNAL",
+            "RESTART", "RESULT", "RESULT_SET_LOCATOR", "RETURN", "RETURNS",
+            "ROUTINE", "ROW", "RRN", "RUN", "SAVEPOINT", "SCRATCHPAD",
+            "SECONDS", "SECQTY", "SECURITY", "SENSITIVE", "SIGNAL", "SIMPLE",
+            "SOURCE", "SPECIFIC", "SQLID", "STANDARD", "START", "STATIC",
+            "STAY", "STOGROUP", "STORES", "STYLE", "SUBPAGES", "SYNONYM",
+            "SYSFUN", "SYSIBM", "SYSPROC", "SYSTEM", "TABLESPACE", "TRIGGER",
+            "TYPE", "UNDO", "UNTIL", "VALIDPROC", "VARIABLE", "VARIANT", "VCAT",
+            "VOLUMES", "WHILE", "WLM", "YEARS",
+        }));
+        
+        super.setBatchLimit(defaultBatchLimit);
+        
+        selectWordSet.add("WITH");
+    }
+
+    public boolean supportsRandomAccessResultSet(Select sel,
+        boolean forUpdate) {
+        return !forUpdate
+            && super.supportsRandomAccessResultSet(sel, forUpdate);
+    }
+
+    protected void appendSelectRange(SQLBuffer buf, long start, long end,
+        boolean subselect) {
+        // appends the literal range string, since DB2 is unable to handle
+        // a bound parameter for it
+        // do not generate FETCH FIRST clause for subselect
+        if (!subselect)
+            buf.append(" FETCH FIRST ").append(Long.toString(end)).
+                append(" ROWS ONLY");
+    }
+
+    protected void appendSelect(SQLBuffer selectSQL, Object alias, Select sel,
+        int idx) {
+        // if this is a literal value, add a cast...
+        Object val = sel.getSelects().get(idx);
+        if (val instanceof Lit)
+            selectSQL.append("CAST(");
+
+        // ... and add the select per super's behavior...
+        super.appendSelect(selectSQL, alias, sel, idx);
+
+        // ... and finish the cast
+        if (val instanceof Lit) {
+            Class c = ((Lit) val).getType();
+            int javaTypeCode = JavaTypes.getTypeCode(c);
+            int jdbcTypeCode = getJDBCType(javaTypeCode, false);
+            String typeName = getTypeName(jdbcTypeCode);
+            selectSQL.append(" AS " + typeName);
+
+            // if the literal is a string, use the default char col size
+            // in the cast statement.
+            if (String.class.equals(c))
+                selectSQL.append("(" + characterColumnSize + ")");
+
+            selectSQL.append(")");
+        }
+    }
+
+    public String[] getCreateSequenceSQL(Sequence seq) {
+        String[] sql = super.getCreateSequenceSQL(seq);
+        if (seq.getAllocate() > 1)
+            sql[0] += " CACHE " + seq.getAllocate();
+        return sql;
+    }
+
+    protected String getSequencesSQL(String schemaName, String sequenceName) {
+        StringBuffer buf = new StringBuffer();
+        buf.append(sequenceSQL);
+        if (schemaName != null || sequenceName != null)
+            buf.append(" WHERE ");
+        if (schemaName != null) {
+            buf.append(sequenceSchemaSQL);
+            if (sequenceName != null)
+                buf.append(" AND ");
+        }
+        if (sequenceName != null)
+            buf.append(sequenceNameSQL);
+        return buf.toString();
+    }
+
+    public Connection decorate(Connection conn)
+        throws SQLException {
+        // some versions of the DB2 driver seem to default to
+        // READ_UNCOMMITTED, which will prevent locking from working
+        // (multiple SELECT ... FOR UPDATE statements are allowed on
+        // the same instance); if we have not overridden the
+        // transaction isolation in the configuration, default to
+        // TRANSACTION_READ_COMMITTED
+        conn = super.decorate(conn);
+
+        if (conf.getTransactionIsolationConstant() == -1
+            && conn.getTransactionIsolation() < conn.TRANSACTION_READ_COMMITTED)
+            conn.setTransactionIsolation(conn.TRANSACTION_READ_COMMITTED);
+
+        return conn;
+    }
+
+    public void connectedConfiguration(Connection conn) throws SQLException {
+    	super.connectedConfiguration(conn);
+
+    	DatabaseMetaData metaData = conn.getMetaData();
+        databaseProductName = nullSafe(metaData.getDatabaseProductName());
+        databaseProductVersion = nullSafe(metaData.getDatabaseProductVersion());
+        
+        // Determine the type of DB2 database
+        // First check for AS/400
+        getProductVersionMajorMinorForISeries();
+
+        if (maj > 0) {
+            if (isDB2ISeriesV5R3OrEarlier())
+                db2ServerType = db2ISeriesV5R3OrEarlier;
+            else if (isDB2ISeriesV5R4OrLater())
+                db2ServerType = db2ISeriesV5R4OrLater;
+        }
+        
+    	if (db2ServerType == 0) {
+    	    if (isJDBC3) {
+    	        maj = metaData.getDatabaseMajorVersion();
+    	        min = metaData.getDatabaseMinorVersion();
+    	    }
+    	    else
+    	        getProductVersionMajorMinor();
+
+    	    // Determine the type of DB2 database for ZOS & UDB
+    	    if (isDB2UDBV81OrEarlier())
+    	        db2ServerType = db2UDBV81OrEarlier;
+    	    else if (isDB2ZOSV8xOrLater())
+    	        db2ServerType = db2ZOSV8xOrLater;
+    	    else if (isDB2UDBV82OrLater())
+    	        db2ServerType = db2UDBV82OrLater;
+        }
+
+        // verify that databae product is supported
+        if (db2ServerType == 0 || maj == 0)
+            throw new UnsupportedException(_loc.get("db-not-supported",
+                new Object[] {databaseProductName, databaseProductVersion }));                    
+
+    	if (maj >= 9 || (maj == 8 && min >= 2)) {
+    	    supportsLockingWithMultipleTables = true;
+    	    supportsLockingWithInnerJoin = true;
+    	    supportsLockingWithOuterJoin = true;
+    	    forUpdateClause = "WITH RR USE AND KEEP UPDATE LOCKS";
+    	    if (maj >=9)
+    	        supportsXMLColumn = true;
+    	}
+
+        // platform specific settings
+        switch (db2ServerType) {
+        case  db2ZOSV8xOrLater:
+            // DB2 Z/OS 
+            characterColumnSize = 255;
+            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM "
+                + "SYSIBM.SYSDUMMY1";
+            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM "
+                + "SYSIBM.SYSDUMMY1";
+            sequenceSQL = "SELECT SCHEMA AS SEQUENCE_SCHEMA, "
+                + "NAME AS SEQUENCE_NAME FROM SYSIBM.SYSSEQUENCES";
+            sequenceSchemaSQL = "SCHEMA = ?";
+            sequenceNameSQL = "NAME = ?";
+            if (maj == 8) {
+                // DB2 Z/OS Version 8: no bigint support, hence map Java
+                // long to decimal
+                bigintTypeName = "DECIMAL(31,0)";
+            }
+            ignoreSQLExceptionOnSetQueryTimeout = true; 
+            break;
+        case db2ISeriesV5R3OrEarlier:
+        case db2ISeriesV5R4OrLater:
+            lastGeneratedKeyQuery = "SELECT IDENTITY_VAL_LOCAL() FROM "
+                + "SYSIBM.SYSDUMMY1";
+            nextSequenceQuery = "SELECT NEXTVAL FOR {0} FROM "
+                + "SYSIBM.SYSDUMMY1";
+            validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
+                + "QSYS2.SYSTABLES";
+            sequenceSQL = "SELECT SEQUENCE_SCHEMA, "
+                + "SEQUENCE_NAME FROM QSYS2.SYSSEQUENCES";
+            sequenceSchemaSQL = "SEQUENCE_SCHEMA = ?";
+            sequenceNameSQL = "SEQUENCE_NAME = ?";
+            break;
+        }
+    }
+
+    /**
+     * Get the update clause for the query based on the
+     * updateClause and isolationLevel hints
+     */
+    protected String getForUpdateClause(JDBCFetchConfiguration fetch,
+        boolean isForUpdate, Select sel) {
+        int isolationLevel;
+        // For db2UDBV81OrEarlier and db2ISeriesV5R3OrEarlier:
+        // "optimize for" clause appears before "for update" clause.
+        StringBuffer forUpdateString = new StringBuffer(
+            getOptimizeClause(sel));
+        try {
+            // Determine the isolationLevel; the fetch
+            // configuration data overrides the persistence.xml value
+            if (fetch != null && fetch.getIsolation() != -1)
+                isolationLevel = fetch.getIsolation();
+            else
+                isolationLevel = conf.getTransactionIsolationConstant();
+
+            if (isForUpdate) {
+                switch(db2ServerType) {
+                case db2ISeriesV5R3OrEarlier:
+                case db2UDBV81OrEarlier:
+                    if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE)
+                        forUpdateString.append(" ").append(forUpdateClause);
+                    else 
+                        forUpdateString.append(" ").append(forUpdate)
+                            .append(" ").append(withRSClause);
+                    break;
+                case db2ZOSV8xOrLater:
+                case db2UDBV82OrLater:
+                    if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
+                        forUpdateString.append(" ").append(forReadOnlyClause)
+                            .append(" ").append(withRRClause)
+                            .append(" ").append(useKeepUpdateLockClause);   
+                    } else {
+                        forUpdateString.append(" ").append(forReadOnlyClause)
+                            .append(" ").append(withRSClause)
+                            .append(" ").append(useKeepUpdateLockClause);                            
+                    }
+                    break;
+                case db2ISeriesV5R4OrLater:
+                    if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
+                        forUpdateString.append(" ").append(forReadOnlyClause)
+                            .append(" ").append(withRRClause)
+                            .append(" ").append(useKeepExclusiveLockClause);       
+                    } else {
+                        forUpdateString.append(" ").append(forReadOnlyClause)
+                            .append(" ").append(withRSClause)
+                            .append(" ").append(useKeepExclusiveLockClause);
+                    }
+                    break;
+                }
+            }
+        }
+        catch (Exception e) {
+            if (log.isTraceEnabled())
+                log.error(e.toString(),e);
+        }
+        return forUpdateString.toString();
+    }
+
+    public boolean isDB2UDBV82OrLater() {
+        return (databaseProductVersion.indexOf("SQL") != -1
+             || databaseProductName.indexOf("DB2/") != -1)
+             && ((maj == 8 && min >= 2) || (maj >= 9));
+    }
+
+    public boolean isDB2ZOSV8xOrLater() {
+       return (databaseProductVersion.indexOf("DSN") != -1
+            || databaseProductName.indexOf("DB2/") == -1)
+            && maj >= 8;
+    }
+
+    public boolean isDB2ISeriesV5R3OrEarlier() {
+       return (databaseProductName.indexOf("AS") != -1
+           && ((maj == 5 && min <=3) || maj < 5));
+    }
+
+    public boolean isDB2ISeriesV5R4OrLater() {
+       return databaseProductName.indexOf("AS") != -1
+           && (maj >=6 || (maj == 5 && min >=4));
+    }
+
+    public boolean isDB2UDBV81OrEarlier() {
+        return (databaseProductVersion.indexOf("SQL") != -1 
+            || databaseProductName.indexOf("DB2/") != -1) 
+            && ((maj == 8 && min <= 1) || maj < 8);
+    }
+
+    /** Get the version Major/Minor for the ISeries
+     */
+    private void getProductVersionMajorMinorForISeries() {
+        // ISeries    DBProdName                 DB2 UDB for AS/400
+        //   (Toolbox)DBProdVersion              05.04.0000 V5R4m0
+        // ISeries                               DB2 UDB for AS/400
+        //   (Native)                            V5R4M0
+        // new jcc    DBProdVersion              QSQ05040 or QSQ06010
+        if (databaseProductName.indexOf("AS") != -1) {
+            // default to V5R4
+            maj = 5;
+            min = 4;
+            int index = databaseProductVersion.indexOf('V');
+            if (index != -1) {
+                String s = databaseProductVersion.substring(index);
+                s = s.toUpperCase();
+
+                StringTokenizer stringtokenizer = new StringTokenizer(s, "VRM"
+                    , false);
+                if (stringtokenizer.countTokens() == 3) {
+                    String s1 = stringtokenizer.nextToken();
+                    maj = Integer.parseInt(s1);
+                    String s2 =  stringtokenizer.nextToken();
+                    min = Integer.parseInt(s2);
+                }
+            } else {
+                index = databaseProductVersion.indexOf('0');
+                if (index != -1) {
+                    String s = databaseProductVersion.substring(index);
+                    s = s.toUpperCase();
+
+                    StringTokenizer stringtokenizer = new StringTokenizer(s, "0"
+                        , false);                    
+                    if (stringtokenizer.countTokens() == 2) {
+                        String s1 = stringtokenizer.nextToken();
+                        maj = Integer.parseInt(s1);
+                        String s2 =  stringtokenizer.nextToken();
+                        min = Integer.parseInt(s2);
+                    }
+                }
+            }
+        }
+    }
+    
+    private void getProductVersionMajorMinor() {
+        // Incase JDBC driver version is lower than 3
+        // use following info to determine Major and Minor 
+        //                        CLI    vs      JCC
+        // ZDBV8 DBProdName       DB2            DB2
+        //       DBProdVersion    08.01.0005     DSN08015
+        // ZDBV9                  DB2            DB2
+        //                        09.01.0005     DSN09015
+        // WinV9                  DB2/NT         DB2/NT
+        //                        09.01.0000     SQL09010
+        // SolarisV9                             DB2/SUN64
+        //                                       SQL0901
+        // Linux                  DB2/LINUX      DB2/LINUX
+        //                        09.01.0000     SQL0901
+        if (databaseProductVersion.indexOf("09") != -1) {
+            maj = 9;
+            if (databaseProductVersion.indexOf("01") != -1) {
+                min = 1;
+            }
+        } else if (databaseProductVersion.indexOf("08") != -1) {
+            maj = 8;
+            min = 2;
+            if (databaseProductVersion.indexOf("01") != -1) {
+                min = 1;
+            }
+        }
+    }
+
+    protected String getOptimizeClause(Select sel) {
+        if (sel != null && sel.getExpectedResultCount() > 0) {
+            StringBuffer buf = new StringBuffer();
+            buf.append(" ").append(optimizeClause).append(" ")
+                .append(String.valueOf(sel.getExpectedResultCount()))
+                .append(" ").append(rowClause);
+            return buf.toString();
+        }
+
+        return "";
+    }
+
+    public OpenJPAException newStoreException(String msg, SQLException[] causes,
+        Object failed) {
+        if (causes != null && causes.length > 0)
+            msg = appendExtendedExceptionMsg(msg, causes[0]);
+        return super.newStoreException(msg, causes, failed);
+    }
+
+    /**
+     *  Append exception information from SQLCA to the exsisting
+     *  exception meassage
+     */
+    private String appendExtendedExceptionMsg(String msg, SQLException sqle){
+       final String GETSQLCA ="getSqlca";
+       String exceptionMsg = new String();
+       try {
+            Method sqlcaM2 = sqle.getNextException().getClass()
+                             .getMethod(GETSQLCA,null);
+            Object sqlca = sqlcaM2.invoke(sqle.getNextException(),
+                                          new Object[] {});
+            Method  getSqlErrpMethd = sqlca.getClass().
+            getMethod("getSqlErrp", null);
+            Method  getSqlWarnMethd = sqlca.getClass().
+            getMethod("getSqlWarn", null);
+            Method  getSqlErrdMethd = sqlca.getClass().
+            getMethod("getSqlErrd", null);
+            StringBuffer errdStr = new StringBuffer();
+
+            int[] errds = (int[]) getSqlErrdMethd.invoke(sqlca, new Object[]{});
+            for (int i = 0; i < errds.length; i++)
+                errdStr.append(errdStr.length() > 0 ? ", " : "").
+                    append(errds[i]);
+            exceptionMsg = exceptionMsg.concat( "SQLCA OUTPUT" +
+                    "[Errp=" + getSqlErrpMethd.invoke(sqlca, new Object[]{})
+                    + ", Errd=" + errdStr);
+
+            String Warn = new String((char[]) getSqlWarnMethd.
+                    invoke(sqlca, new Object[]{}));
+            if (Warn.trim().length() != 0)
+                exceptionMsg = exceptionMsg.concat(", Warn=" +Warn + "]" );
+            else
+                exceptionMsg = exceptionMsg.concat( "]" );
+            msg = msg.concat(exceptionMsg);
+            
+            // for batched execution failures, SQLExceptions are nested
+            SQLException sqle2 = sqle.getNextException();
+            while (sqle2 != null) {                
+                msg = msg.concat("\n" + sqle2.getMessage());
+                sqle2 = sqle2.getNextException();
+            }
+            
+            return msg;
+        } catch (Throwable t) {
+            return sqle.getMessage();
+        }
+    }
+
+    public int getDb2ServerType() {
+        return db2ServerType;
+    }
+    
+    protected void appendLength(SQLBuffer buf, int type) {
+        if (type == Types.VARCHAR)
+            buf.append("(").append(Integer.toString(characterColumnSize)).
+                append(")");
+    }
+
+    /**
+     * If this dictionary supports XML type,
+     * use this method to append xml predicate.
+     * 
+     * @param buf the SQL buffer to write the comparison
+     * @param op the comparison operation to perform
+     * @param lhs the left hand side of the comparison
+     * @param rhs the right hand side of the comparison
+     * @param lhsxml indicates whether the left operand maps to xml
+     * @param rhsxml indicates whether the right operand maps to xml
+     */
+    public void appendXmlComparison(SQLBuffer buf, String op, FilterValue lhs,
+        FilterValue rhs, boolean lhsxml, boolean rhsxml) {
+        super.appendXmlComparison(buf, op, lhs, rhs, lhsxml, rhsxml);
+        if (lhsxml && rhsxml)
+            appendXmlComparison2(buf, op, lhs, rhs);
+        else if (lhsxml)
+            appendXmlComparison1(buf, op, lhs, rhs);
+        else 
+            appendXmlComparison1(buf, op, rhs, lhs);
+    }
+
+    /**
+     * Append an xml comparison predicate.
+     *
+     * @param buf the SQL buffer to write the comparison
+     * @param op the comparison operation to perform
+     * @param lhs the left hand side of the comparison (maps to xml column)
+     * @param rhs the right hand side of the comparison
+     */
+    private void appendXmlComparison1(SQLBuffer buf, String op, 
+            FilterValue lhs, FilterValue rhs) {
+        boolean castrhs = false;
+        Class rc = Filters.wrap(rhs.getType());
+        int type = 0;
+        if (rhs.isConstant()) {
+            type = getJDBCType(JavaTypes.getTypeCode(rc), false);
+            castrhs = true;
+        }
+        
+        appendXmlExists(buf, lhs);
+
+        buf.append(" ").append(op).append(" ");
+        
+        buf.append("$");
+        if (castrhs)
+            buf.append("Parm");
+        else
+            rhs.appendTo(buf);
+        
+        buf.append("]' PASSING ");
+        appendXmlVar(buf, lhs);
+        buf.append(", ");
+        
+        if (castrhs)
+            appendCast(buf, rhs, type);
+        else
+            rhs.appendTo(buf);
+        
+        buf.append(" AS \"");
+        if (castrhs)
+            buf.append("Parm");
+        else
+            rhs.appendTo(buf);
+        buf.append("\")");
+    }
+    
+    /**
+     * Append an xml comparison predicate. (both operands map to xml column)
+     *
+     * @param buf the SQL buffer to write the comparison
+     * @param op the comparison operation to perform
+     * @param lhs the left hand side of the comparison (maps to xml column)
+     * @param rhs the right hand side of the comparison (maps to xml column)
+     */
+    private void appendXmlComparison2(SQLBuffer buf, String op, 
+            FilterValue lhs, FilterValue rhs) {
+        appendXmlExists(buf, lhs);
+        
+        buf.append(" ").append(op).append(" ");
+        
+        buf.append("$").append(rhs.getColumnAlias(
+            rhs.getFieldMapping().getColumns()[0])).
+            append("/*/");
+        rhs.appendTo(buf);
+        
+        buf.append("]' PASSING ");
+        appendXmlVar(buf, lhs);
+        buf.append(", ");
+        appendXmlVar(buf, rhs);
+        buf.append(")");
+    }
+    
+    private void appendXmlVar(SQLBuffer buf, FilterValue val) {
+        buf.append(val.getColumnAlias(
+            val.getFieldMapping().getColumns()[0])).
+            append(" AS ").
+            append("\"").append(val.getColumnAlias(
+            val.getFieldMapping().getColumns()[0])).
+            append("\"");        
+    }
+    
+    private void appendXmlExists(SQLBuffer buf, FilterValue val) {
+        buf.append("XMLEXISTS('");
+        buf.append("$").append(val.getColumnAlias(
+            val.getFieldMapping().getColumns()[0])).
+            append("/*[");
+        val.appendTo(buf);        
+    }
+    
+    /**
+     * add CAST for a scalar function where operand is a param
+     * 
+     * @param func original string
+     * @param target substring to look for
+     * @param asString 
+     * @return updated string (func)
+     */
+    private String addCastAsString(String func, String target, 
+            String asString) {
+        String fstring = func;
+        if (func.indexOf(target) != -1)
+            fstring = Strings.replace(
+                func, target, "CAST(" + target + asString + ")");
+        return fstring;
+    }
+
+    /**
+     * add CAST for a function operator where operand is a param
+     * 
+     * @param func function name
+     * @param val type
+     * @return updated string (func)
+     */
+    public String addCastAsType(String func, Val val) {
+        String fstring = null;
+        String type = getTypeName(getJDBCType(JavaTypes.getTypeCode(val
+            .getType()), false));
+        if (String.class.equals(val.getType()))
+            type = type + "(" + characterColumnSize + ")";
+        fstring = "CAST(? AS " + type + ")";
+        return fstring;
+    }
+
+    /**
+     * Return the batch limit. If the batchLimit is -1, change it to 100 for
+     * best performance
+     */
+    public int getBatchLimit() {
+        int limit = super.getBatchLimit();
+        if (limit == UNLIMITED) {
+            limit = defaultBatchLimit;
+            if (log.isTraceEnabled())
+                log.trace(_loc.get("batch_unlimit", String.valueOf(limit)));
+        }
+        return limit;
+    }
+
+    /**
+     * Return the correct CAST function syntax
+     * 
+     * @param val operand of cast
+     * @param func original string
+     * @return a String with the correct CAST function syntax
+     */
+    public String getCastFunction(Val val, String func) {
+        if (val instanceof Lit || val instanceof Param) {
+            if (func.indexOf("VARCHAR") == -1) {
+                func = addCastAsString(func, "{0}", " AS VARCHAR(" + varcharCastLength + ")");
+            }
+        }
+        return func;
+    }
+    
+    /**
+     * Return the correct CAST function syntax
+     * 
+     * @param val operand of cast
+     * @param func original string
+     * @param col database column
+     * @return a String with the correct CAST function syntax
+     */
+    public String getCastFunction(Val val, String func, Column col) {
+        boolean doCast = false;
+        if (val instanceof Lit || val instanceof Param) {
+        	doCast = true;
+        }
+        // cast anything not already a VARCHAR to VARCHAR
+        if (col.getType() != Types.VARCHAR) {
+            doCast = true;
+        }
+        if (doCast == true) {
+            if (func.indexOf("VARCHAR") == -1) {
+                func = addCastAsString(func, "{0}", " AS VARCHAR(" + varcharCastLength + ")");
+            }
+        }
+        return func;
+    }
+
+    public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
+            FilterValue start) {
+        if (find.getValue() != null) { // non constants
+            buf.append("(LOCATE(CAST((");
+            find.appendTo(buf);
+            buf.append(") AS VARCHAR(1000)), ");
+        } else {
+            // this is a constant
+            buf.append("(LOCATE(");
+            find.appendTo(buf);
+            buf.append(", ");
+        }
+        if (str.getValue() != null) {
+            buf.append("CAST((");
+            str.appendTo(buf);
+            buf.append(") AS VARCHAR(1000))");
+        } else {
+            str.appendTo(buf);
+        }
+        if (start != null) {
+            if (start.getValue() == null) {
+                buf.append(", CAST((");
+                start.appendTo(buf);
+                buf.append(") AS INTEGER) + 1");
+            } else {
+                buf.append(", ");
+                start.appendTo(buf);
+            }
+        }
+        buf.append(") - 1)");
+    }
+    
+    /** 
+     * Cast the specified value to the specified type.
+     *
+     * @param buf the buffer to append the cast to
+     * @param val the value to cast
+     * @param type the type of the case, e.g. {@link Types#NUMERIC}
+     */
+    public void appendCast(SQLBuffer buf, FilterValue val, int type) {
+
+        // Convert the cast function: "CAST({0} AS {1})"
+        int firstParam = castFunction.indexOf("{0}");
+        String pre = castFunction.substring(0, firstParam); // "CAST("
+        String mid = castFunction.substring(firstParam + 3);
+        int secondParam = mid.indexOf("{1}");
+        String post;
+        if (secondParam > -1) {
+            post = mid.substring(secondParam + 3); // ")"
+            mid = mid.substring(0, secondParam); // " AS "
+        } else
+            post = "";
+
+        // No need to add CAST if the value is a constant
+        if (val instanceof Lit || val instanceof Param) {
+            buf.append(pre);
+            val.appendTo(buf);
+            buf.append(mid);
+            buf.append(getTypeName(type));
+            appendLength(buf, type);
+            buf.append(post);
+        } else {
+            val.appendTo(buf);
+            String sqlString = buf.getSQL(false);
+            if (sqlString.endsWith("?")) {
+                // case "(?" - convert to "CAST(? AS type"
+                String typeName = getTypeName(type);
+                if (String.class.equals(val.getType()))
+                    typeName = typeName + "(" + characterColumnSize + ")";
+                String str = "CAST(? AS " + typeName + ")";
+                buf.replaceSqlString(sqlString.length() - 1,
+                        sqlString.length(), str);
+            }
+        }
+    }
+
+    /**
+     * Create an index if necessary for some database tables
+     */
+    public void createIndexIfNecessary(Schema schema, String table,
+            Column pkColumn) {
+        if (isDB2ZOSV8xOrLater()) {
+            // build the index for the sequence tables
+            // the index name will the fully qualified table name + _IDX
+            Table tab = schema.getTable(table);
+            Index idx = tab.addIndex(tab.getFullName() + "_IDX");
+            idx.setUnique(true);
+            idx.addColumn(pkColumn);
+        }
+    }
+    
+    String nullSafe(String s) {
+    	return s == null ? "" : s;
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
index ce8f050..96cf76f 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
@@ -232,12 +232,14 @@
     public boolean requiresTargetForDelete = false;
     public boolean allowsAliasInBulkClause = true;
     public boolean supportsMultipleNontransactionalResultSets = true;
+    public boolean requiresSearchStringEscapeForLike = true;
     public String searchStringEscape = "\\";
     public boolean requiresCastForMathFunctions = false;
     public boolean requiresCastForComparisons = false;
     public boolean supportsModOperator = false;
     public boolean supportsXMLColumn = false;
     public boolean reportsSuccessNoInfoOnBatchUpdates = false;
+    public boolean supportsCaseConversionForLob = false;
     
     /**
      * Some Databases append whitespace after the schema name 
@@ -341,6 +343,18 @@
     protected final Set systemTableSet = new HashSet();
     protected final Set fixedSizeTypeNameSet = new HashSet();
     protected final Set typeModifierSet = new HashSet();
+    
+    /**
+     * Some JDBC drivers - ie DB2 type 2 on Z/OS throw exceptions on
+     * setQueryTimeout when provided specific input values.
+     * To remain consistent with earlier versions of the driver we should ignore
+     * the exception.
+     * 
+     * This variable will be removed in future releases when we can handle the
+     * exception properly.
+     */ 
+    @Deprecated
+    public boolean ignoreSQLExceptionOnSetQueryTimeout = false; 
 
     /**
      * If a native query begins with any of the values found here then it will
@@ -4387,6 +4401,19 @@
     public String getCastFunction(Val val, String func) {
         return func;
     }
+
+    /**
+     * Return the correct CAST function syntax.  This should be overriden by subclasses
+     * that need access to the Column information.
+     * 
+     * @param val operand of cast
+     * @param func original string
+     * @param col database column
+     * @return a String with the correct CAST function syntax
+     */
+    public String getCastFunction(Val val, String func, Column col) {
+    	return getCastFunction (val, func);
+    }
     
     /**
      * Create an index if necessary for some database tables
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
index aa67411..aab3ed7 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
@@ -122,6 +122,18 @@
                         DBDictionary.class)));
             dict = (DBDictionary) AccessController.doPrivileged(
                 J2DoPrivHelper.newInstanceAction(c));
+        } catch (ClassNotFoundException cnfe) {
+            // if the dictionary was not found, make another attempt
+            // at loading the dictionary using the current thread.
+            try {
+                Class c = Thread.currentThread().getContextClassLoader().loadClass(dclass);
+                dict = (DBDictionary) AccessController.doPrivileged(
+                        J2DoPrivHelper.newInstanceAction(c));
+            } catch (Exception e) {
+                if (e instanceof PrivilegedActionException)
+                    e = ((PrivilegedActionException) e).getException();
+                throw new UserException(e).setFatal(true);
+            }
         } catch (Exception e) {
             if (e instanceof PrivilegedActionException)
                 e = ((PrivilegedActionException) e).getException();
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
index 8453fe0..3dee559 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
@@ -45,6 +45,8 @@
         validationSQL = "VALUES(1)";
         stringLengthFunction = "LENGTH({0})";
         substringFunctionName = "SUBSTR";
+        toUpperCaseFunction = "UPPER(CAST({0} AS VARCHAR(" + varcharCastLength + ")))";
+        toLowerCaseFunction = "LOWER(CAST({0} AS VARCHAR(" + varcharCastLength + ")))";
 
         maxConstraintNameLength = 18;
         maxIndexNameLength = 128;
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
index 2714a84..14a011c 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
@@ -167,6 +167,7 @@
         super.setBatchLimit(defaultBatchLimit);
         selectWordSet.add("WITH");
         reportsSuccessNoInfoOnBatchUpdates = true;
+        requiresSearchStringEscapeForLike = false;
     }
 
     public void endConfiguration() {
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
index a4d4c22..307194c 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
@@ -52,7 +52,7 @@
     private static final String PARAMETER_TOKEN = "?";
 
     private final DBDictionary _dict;
-    private final StringBuffer _sql = new StringBuffer();
+    private final StringBuilder _sql = new StringBuilder();
     private List _subsels = null;
     private List _params = null;
     private List _cols = null;
@@ -407,7 +407,7 @@
         if (!replaceParams || _params == null || _params.isEmpty())
             return sql;
 
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         Iterator pi = _params.iterator();
         for (int i = 0; i < sql.length(); i++) {
             if (sql.charAt(i) != '?') {
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java
index 5ed844a..dece0a3 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java
@@ -1,155 +1,155 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.sql;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.xml.XMLFactory;
-import org.apache.openjpa.util.StoreException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Parses XML content of SQL Error State codes to populate errro codes for
- * a given Database Dictionary.
- * 
- * @author Pinaki Poddar
- * 
- */
-public class SQLErrorCodeReader {
-	private Log log = null;
-	public static final String ERROR_CODE_DELIMITER = ",";
-	public static final Map<String, Integer> storeErrorTypes = 
-		new HashMap<String, Integer>();
-	static {
-		storeErrorTypes.put("lock", StoreException.LOCK);
-		storeErrorTypes.put("object-exists", StoreException.OBJECT_EXISTS);
-		storeErrorTypes
-				.put("object-not-found", StoreException.OBJECT_NOT_FOUND);
-		storeErrorTypes.put("optimistic", StoreException.OPTIMISTIC);
-		storeErrorTypes.put("referential-integrity",
-				StoreException.REFERENTIAL_INTEGRITY);
-
-	}
-	
-	private static final Localizer _loc = 
-		Localizer.forPackage(SQLErrorCodeReader.class);
-	
-	public List<String> getDictionaries(InputStream in) {
-		List<String> result = new ArrayList<String>();
-		DocumentBuilder builder = XMLFactory.getDOMParser(false, false);
-		try {
-			Document doc = builder.parse(in);
-			Element root = doc.getDocumentElement();
-			NodeList nodes = root.getElementsByTagName("dictionary");
-			for (int i = 0; i < nodes.getLength(); i++) {
-				Node node = nodes.item(i);
-				NamedNodeMap attrs = node.getAttributes();
-				Node dictionary = attrs.getNamedItem("class");
-				if (dictionary != null) {
-				   result.add(dictionary.getNodeValue());
-				}
-			}
-		} catch (Throwable e) {
-			if (log.isWarnEnabled()) {
-				log.error(_loc.get("error-code-parse-error"));
-			}
-		} finally {
-			try {
-				in.close();
-			} catch (IOException e) {
-				// ignore
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Parses given stream of XML content for error codes of the given database
-	 * dictionary name. Populates the given dictionary with the error codes.
-	 * 
-	 */
-	public void parse(InputStream in, String dictName, DBDictionary dict) {
-		if (in == null || dict == null)
-			return;
-		log = dict.conf.getLog(JDBCConfiguration.LOG_JDBC);
-		DocumentBuilder builder = XMLFactory.getDOMParser(false, false);
-		try {
-			Document doc = builder.parse(in);
-			Element root = doc.getDocumentElement();
-			NodeList nodes = root.getElementsByTagName("dictionary");
-			for (int i = 0; i < nodes.getLength(); i++) {
-				Node node = nodes.item(i);
-				NamedNodeMap attrs = node.getAttributes();
-				Node dictionary = attrs.getNamedItem("class");
-				if (dictionary != null 
-				 && dictionary.getNodeValue().equals(dictName)) {
-					readErrorCodes(node, dict);
-				}
-			}
-		} catch (Throwable e) {
-			if (log.isWarnEnabled()) {
-				log.error(_loc.get("error-code-parse-error"));
-			}
-		} finally {
-			try {
-				in.close();
-			} catch (IOException e) {
-				// ignore
-			}
-		}
-	}
-
-	static void readErrorCodes(Node node, DBDictionary dict) {
-		NodeList children = node.getChildNodes();
-		for (int i = 0; i < children.getLength(); i++) {
-			Node child = children.item(i);
-			short nodeType = child.getNodeType();
-			if (nodeType == Node.ELEMENT_NODE) {
-				String errorType = child.getNodeName();
-				Node textNode = child.getFirstChild();
-				if (storeErrorTypes.containsKey(errorType) && textNode != null){
-					String errorCodes = textNode.getNodeValue();
-					if (!StringUtils.isEmpty(errorCodes)) {
-						String[] codes = errorCodes.split(ERROR_CODE_DELIMITER);
-						for (String code : codes) {
-							dict.addErrorCode(storeErrorTypes.get(errorType),
-									code.trim());
-						}
-					}
-				}
-			}
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.xml.XMLFactory;
+import org.apache.openjpa.util.StoreException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Parses XML content of SQL Error State codes to populate errro codes for
+ * a given Database Dictionary.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class SQLErrorCodeReader {
+	private Log log = null;
+	public static final String ERROR_CODE_DELIMITER = ",";
+	public static final Map<String, Integer> storeErrorTypes = 
+		new HashMap<String, Integer>();
+	static {
+		storeErrorTypes.put("lock", StoreException.LOCK);
+		storeErrorTypes.put("object-exists", StoreException.OBJECT_EXISTS);
+		storeErrorTypes
+				.put("object-not-found", StoreException.OBJECT_NOT_FOUND);
+		storeErrorTypes.put("optimistic", StoreException.OPTIMISTIC);
+		storeErrorTypes.put("referential-integrity",
+				StoreException.REFERENTIAL_INTEGRITY);
+
+	}
+	
+	private static final Localizer _loc = 
+		Localizer.forPackage(SQLErrorCodeReader.class);
+	
+	public List<String> getDictionaries(InputStream in) {
+		List<String> result = new ArrayList<String>();
+		DocumentBuilder builder = XMLFactory.getDOMParser(false, false);
+		try {
+			Document doc = builder.parse(in);
+			Element root = doc.getDocumentElement();
+			NodeList nodes = root.getElementsByTagName("dictionary");
+			for (int i = 0; i < nodes.getLength(); i++) {
+				Node node = nodes.item(i);
+				NamedNodeMap attrs = node.getAttributes();
+				Node dictionary = attrs.getNamedItem("class");
+				if (dictionary != null) {
+				   result.add(dictionary.getNodeValue());
+				}
+			}
+		} catch (Throwable e) {
+			if (log.isWarnEnabled()) {
+				log.error(_loc.get("error-code-parse-error"));
+			}
+		} finally {
+			try {
+				in.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Parses given stream of XML content for error codes of the given database
+	 * dictionary name. Populates the given dictionary with the error codes.
+	 * 
+	 */
+	public void parse(InputStream in, String dictName, DBDictionary dict) {
+		if (in == null || dict == null)
+			return;
+		log = dict.conf.getLog(JDBCConfiguration.LOG_JDBC);
+		DocumentBuilder builder = XMLFactory.getDOMParser(false, false);
+		try {
+			Document doc = builder.parse(in);
+			Element root = doc.getDocumentElement();
+			NodeList nodes = root.getElementsByTagName("dictionary");
+			for (int i = 0; i < nodes.getLength(); i++) {
+				Node node = nodes.item(i);
+				NamedNodeMap attrs = node.getAttributes();
+				Node dictionary = attrs.getNamedItem("class");
+				if (dictionary != null 
+				 && dictionary.getNodeValue().equals(dictName)) {
+					readErrorCodes(node, dict);
+				}
+			}
+		} catch (Throwable e) {
+			if (log.isWarnEnabled()) {
+				log.error(_loc.get("error-code-parse-error"));
+			}
+		} finally {
+			try {
+				in.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+
+	static void readErrorCodes(Node node, DBDictionary dict) {
+		NodeList children = node.getChildNodes();
+		for (int i = 0; i < children.getLength(); i++) {
+			Node child = children.item(i);
+			short nodeType = child.getNodeType();
+			if (nodeType == Node.ELEMENT_NODE) {
+				String errorType = child.getNodeName();
+				Node textNode = child.getFirstChild();
+				if (storeErrorTypes.containsKey(errorType) && textNode != null){
+					String errorCodes = textNode.getNodeValue();
+					if (!StringUtils.isEmpty(errorCodes)) {
+						String[] codes = errorCodes.split(ERROR_CODE_DELIMITER);
+						for (String code : codes) {
+							dict.addErrorCode(storeErrorTypes.get(errorType),
+									code.trim());
+						}
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
index 18ac7cc..7f9a4bd 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
@@ -64,49 +64,73 @@
     public void connectedConfiguration(Connection conn)
         throws SQLException {
         super.connectedConfiguration(conn);
-
+        boolean requiresWarnings = true;
         DatabaseMetaData meta = conn.getMetaData();
         String driverName = meta.getDriverName();
         String url = meta.getURL();
         if (driverVendor == null) {
-            if ("NetDirect JSQLConnect".equals(driverName))
-                driverVendor = VENDOR_NETDIRECT;
-            else if (driverName != null && driverName.startsWith("jTDS"))
-                driverVendor = VENDOR_JTDS;
-            else if ("SQLServer".equals(driverName)) {
-                if (url != null && url.startsWith("jdbc:microsoft:sqlserver:"))
-                    driverVendor = VENDOR_MICROSOFT;
-                else if (url != null
-                    && url.startsWith("jdbc:datadirect:sqlserver:"))
-                    driverVendor = VENDOR_DATADIRECT;
-                else
-                    driverVendor = VENDOR_OTHER;
-            } else
+            if (driverName != null) {
+                if (driverName.startsWith("Microsoft SQL Server")) {
+                    // v1.1, 1.2 or 2.0 driver
+                    driverVendor = VENDOR_MICROSOFT;                
+                    // serverMajorVersion of 8==2000, 9==2005, 10==2008
+                    if (meta.getDatabaseMajorVersion() >= 9)
+                        supportsXMLColumn = true;
+                    if (meta.getDriverMajorVersion() >= 2) {
+                        // see http://blogs.msdn.com/jdbcteam/archive/2007/05/\
+                        // 02/what-is-adaptive-response-buffering-and-why-\
+                        // should-i-use-it.aspx
+                        // 2.0 driver connectURL automatically includes 
+                        // responseBuffering=adaptive
+                        // and disableStatementPooling=true
+                        requiresWarnings = false;
+                    }
+                } else {
+                    if ("NetDirect JSQLConnect".equals(driverName))
+                        driverVendor = VENDOR_NETDIRECT;
+                    else if (driverName.startsWith("jTDS"))
+                        driverVendor = VENDOR_JTDS;
+                    else if ("SQLServer".equals(driverName)) {
+                        if (url != null &&
+                            url.startsWith("jdbc:microsoft:sqlserver:"))
+                            driverVendor = VENDOR_MICROSOFT;
+                        else if (url != null
+                            && url.startsWith("jdbc:datadirect:sqlserver:"))
+                            driverVendor = VENDOR_DATADIRECT;
+                        else
+                            driverVendor = VENDOR_OTHER;
+                    }
+                    // old way of determining xml support
+                    if (driverName.indexOf(platform) != -1) {
+                        String versionString = driverName.
+                            substring(platform.length() + 1);
+                        if (versionString.indexOf(" ") != -1)
+                            versionString = versionString.substring(0,
+                                versionString.indexOf(" "));
+                        int version = Integer.parseInt(versionString);
+                        if (version >= 2005)
+                            supportsXMLColumn = true;
+                    }
+                }
+            } else {
                 driverVendor = VENDOR_OTHER;
-            if (driverName.indexOf(platform) != -1) {
-                String versionString = driverName.
-                    substring(platform.length() + 1);
-                if (versionString.indexOf(" ") != -1)
-                    versionString = versionString.substring(0,
-                        versionString.indexOf(" "));
-                int version = Integer.parseInt(versionString);
-                if (version >= 2005)
-                    supportsXMLColumn = true;
             }
         }
 
-        // warn about using cursors
-        if ((VENDOR_MICROSOFT.equalsIgnoreCase(driverVendor)
+        // warn about not using cursors for pre-2.0 MS driver
+        // as connectURL includes selectMethod=direct
+        if (((VENDOR_MICROSOFT.equalsIgnoreCase(driverVendor)
+            && requiresWarnings) 
             || VENDOR_DATADIRECT.equalsIgnoreCase(driverVendor))
-            && url.toLowerCase().indexOf("selectmethod=cursor") == -1)
+            && (url.toLowerCase().indexOf("selectmethod=cursor") == -1))
             log.warn(_loc.get("sqlserver-cursor", url));
 
-        // warn about prepared statement caching if using ms driver
+        // warn about prepared statement caching if using pre-2.0 MS drivers
+        // as connectURL includes responseBuffering=full
         String props = conf.getConnectionFactoryProperties();
-        if (props == null)
-            props = "";
-        if (VENDOR_MICROSOFT.equalsIgnoreCase(driverVendor)
-            && props.toLowerCase().indexOf("maxcachedstatements=0") == -1)
+        if ((props != null) && 
+            VENDOR_MICROSOFT.equalsIgnoreCase(driverVendor) && requiresWarnings
+            && (props.toLowerCase().indexOf("maxcachedstatements=0") == -1))
             log.warn(_loc.get("sqlserver-cachedstmnts"));
     }
 
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
index 3237a97..3c492d3 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
@@ -476,13 +476,26 @@
         if (forUpdate && _dict.supportsQueryTimeout && fetch != null 
             && fetch.getLockTimeout() > stmnt.getQueryTimeout() * 1000) {
             int timeout = fetch.getLockTimeout();
+            Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC);
             if (timeout < 1000) {
                 timeout = 1000; 
-                Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC);
                 if (log.isWarnEnabled())
                     log.warn(_loc.get("millis-query-timeout"));
             }
-            stmnt.setQueryTimeout(timeout / 1000);
+            try { 
+                stmnt.setQueryTimeout(fetch.getLockTimeout() / 1000);
+            }
+            catch(SQLException e) { 
+                if(_dict.ignoreSQLExceptionOnSetQueryTimeout) { 
+                    if (log.isTraceEnabled()) {
+                        log.trace(_loc.get("error-setting-query-timeout",
+                            new Integer(timeout), e.getMessage()), e);
+                    }   
+                }
+                else { 
+                    throw e;
+                }
+            }
         }
     }
 
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SybaseDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SybaseDictionary.java
index 81464d5..7c59d7f 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SybaseDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SybaseDictionary.java
@@ -22,6 +22,7 @@
 import java.math.BigInteger;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
 import java.util.Arrays;
@@ -29,6 +30,7 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.jdbc.schema.Column;
 import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Index;
 import org.apache.openjpa.jdbc.schema.PrimaryKey;
 import org.apache.openjpa.jdbc.schema.Table;
 import org.apache.openjpa.jdbc.schema.Unique;
@@ -281,6 +283,33 @@
     }
 
     /**
+     * Create a new primary key from the information in the schema metadata.
+     */
+    protected PrimaryKey newPrimaryKey(ResultSet pkMeta)
+        throws SQLException {
+        PrimaryKey pk = new PrimaryKey();
+        pk.setSchemaName(pkMeta.getString("table_owner"));
+        pk.setTableName(pkMeta.getString("table_name"));
+        pk.setColumnName(pkMeta.getString("column_name"));
+        pk.setName(pkMeta.getString("index_name"));
+        return pk;
+    }
+
+    /**
+     * Create a new index from the information in the index metadata.
+     */
+    protected Index newIndex(ResultSet idxMeta)
+        throws SQLException {
+        Index idx = new Index();
+        idx.setSchemaName(idxMeta.getString("table_owner"));
+        idx.setTableName(idxMeta.getString("table_name"));
+        idx.setColumnName(idxMeta.getString("column_name"));
+        idx.setName(idxMeta.getString("index_name"));
+        idx.setUnique(!idxMeta.getBoolean("non_unique"));
+        return idx;
+    }
+
+    /**
      * Connection wrapper to cache the {@link Connection#getCatalog} result,
      * which takes a very long time with the Sybase Connection (and
      * which we frequently invoke).
diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
index 5c918cd..337655f 100644
--- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
+++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
@@ -114,4 +114,9 @@
 batch_update_info: ExecuteBatch command returns update count {0} for \
 	statement {1}.
 cache-hit: SQL Cache hit with key: {0} in {1}
-cache-missed: SQL Cache missed with key: {0} in {1}    
+cache-missed: SQL Cache missed with key: {0} in {1}  
+error-setting-query-timeout: A SQLException was thrown when trying to set the \
+	queryTimeout to {0}. We believe the exception is not fatal and will \
+    continue processing. If this is a benign error you may disable it entirely \
+	by setting the supportsQueryTimeout attribute on the DBDictionary to false.\
+	The exception thrown was {1}.
diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties
index 1c8b9f7..efd7747 100644
--- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties
+++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties
@@ -176,4 +176,10 @@
 connection-defaults: Initial connection autoCommit: {0}, holdability: {1}, \
     TransactionIsolation: {2}
 null-blob-in-not-nullable: Can not set null value on column "{0}" \
-	because the corresponding field is set to be non-nullable.
\ No newline at end of file
+	because the corresponding field is set to be non-nullable.
+error-setting-query-timeout: A SQLException was thrown when trying to set the \
+	queryTimeout to {0}. We believe the exception is not fatal and will \
+    continue processing. If this is a benign error you may disable it entirely \
+	by setting the supportsQueryTimeout attribute on the DBDictionary to false.\
+	The exception thrown was {1}.
+	
\ No newline at end of file
diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
index 5a53277..cb3f2c8 100644
--- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
+++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
@@ -1,146 +1,146 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<!-- ======================================================================= -->
-<!-- Lists SQL Error State codes for specific type of faults per database    -->
-<!-- dictionary.                                                             -->
-<!-- SQL Exceptions raised by JDBC should carry standard error state code    -->
-<!-- but they hardly do. Hence, the error state codes for specific type of   -->
-<!-- database error can be listed here. These codes help to narrow down the  -->
-<!-- cause of failure at JDBC layer and bubbles up as more intelligible      -->
-<!-- exception to the application.                                           -->
-<!-- ======================================================================= -->
-<sql-state-codes>
-
-	<dictionary class="org.apache.openjpa.jdbc.sql.DB2Dictionary">
-		<lock>-911,-913</lock>
-		<referential-integrity>-407,-530,-531,-532,-543,-544,-545,-603,-667,-803</referential-integrity>
-		<object-exists></object-exists>
-		<object-not-found></object-not-found>
-		<optimistic></optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.DerbyDictionary">
-		<lock>40001</lock>
-		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
-		<object-exists>23505</object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>40XL1,40001</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.SQLServerDictionary">
-		<lock>1205</lock>
-		<referential-integrity>544,2601,2627,8114,8115</referential-integrity>
-		<optimistic>1205</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.SybaseDictionary">
-		<lock>1205</lock>
-		<referential-integrity>423,511,515,530,547,2601,2615,2714</referential-integrity>
-		<object-exists></object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>1205</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.AccessDictionary">
-		<lock>40001</lock>
-		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
-		<object-exists>23505,456c</object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>40XL1,40001</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.CacheDictionary">
-		<lock>40001</lock>
-		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
-		<object-exists>23505,456c</object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>40XL1,40001</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.EmpressDictionary">
-		<lock>40001</lock>
-		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
-		<object-exists>23505,456c</object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>40XL1,40001</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.FoxProDictionary">
-		<lock>40001</lock>
-		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
-		<object-exists>23505,456c</object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>40XL1,40001</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.H2Dictionary">
-		<referential-integrity>22003,22012,22025,23000,23001</referential-integrity>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.HSQLDictionary">
-		<referential-integrity>-9</referential-integrity>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.InformixDictionary">
-		<referential-integrity>-239,-268,-692,-11030</referential-integrity>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.InterbaseDictionary">
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.FirebirdDictionary">
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.JDataStoreDictionary">
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.MySQLDictionary">
-		<lock>1213</lock>
-		<referential-integrity>630,839,840,893,1062,1169,1215,1216,1217,1451,1452,1557</referential-integrity>
-		<object-exists>23000</object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>41000,1205,1213</optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.OracleDictionary">
-		<lock></lock>
-		<referential-integrity>1,1400,1722,2291,2292</referential-integrity>
-		<object-exists></object-exists>
-		<object-not-found></object-not-found>
-		<optimistic></optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.PointbaseDictionary">
-		<lock></lock>
-		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
-		<object-exists></object-exists>
-		<object-not-found></object-not-found>
-		<optimistic></optimistic>
-	</dictionary>
-	
-	<dictionary class="org.apache.openjpa.jdbc.sql.PostgresDictionary">
-		<lock>55P03,40P01</lock>
-		<referential-integrity>23000,23502,23503,23505,23514</referential-integrity>
-		<object-exists></object-exists>
-		<object-not-found></object-not-found>
-		<optimistic>55P03</optimistic>
-	</dictionary>
-	
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<!-- ======================================================================= -->
+<!-- Lists SQL Error State codes for specific type of faults per database    -->
+<!-- dictionary.                                                             -->
+<!-- SQL Exceptions raised by JDBC should carry standard error state code    -->
+<!-- but they hardly do. Hence, the error state codes for specific type of   -->
+<!-- database error can be listed here. These codes help to narrow down the  -->
+<!-- cause of failure at JDBC layer and bubbles up as more intelligible      -->
+<!-- exception to the application.                                           -->
+<!-- ======================================================================= -->
+<sql-state-codes>
+
+	<dictionary class="org.apache.openjpa.jdbc.sql.DB2Dictionary">
+		<lock>-911,-913</lock>
+		<referential-integrity>-407,-530,-531,-532,-543,-544,-545,-603,-667,-803</referential-integrity>
+		<object-exists></object-exists>
+		<object-not-found></object-not-found>
+		<optimistic></optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.DerbyDictionary">
+		<lock>40001</lock>
+		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
+		<object-exists>23505</object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>40XL1,40001</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.SQLServerDictionary">
+		<lock>1205</lock>
+		<referential-integrity>544,2601,2627,8114,8115</referential-integrity>
+		<optimistic>1205</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.SybaseDictionary">
+		<lock>1205</lock>
+		<referential-integrity>423,511,515,530,547,2601,2615,2714</referential-integrity>
+		<object-exists></object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>1205</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.AccessDictionary">
+		<lock>40001</lock>
+		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
+		<object-exists>23505,456c</object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>40XL1,40001</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.CacheDictionary">
+		<lock>40001</lock>
+		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
+		<object-exists>23505,456c</object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>40XL1,40001</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.EmpressDictionary">
+		<lock>40001</lock>
+		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
+		<object-exists>23505,456c</object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>40XL1,40001</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.FoxProDictionary">
+		<lock>40001</lock>
+		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
+		<object-exists>23505,456c</object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>40XL1,40001</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.H2Dictionary">
+		<referential-integrity>22003,22012,22025,23000,23001</referential-integrity>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.HSQLDictionary">
+		<referential-integrity>-9</referential-integrity>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.InformixDictionary">
+		<referential-integrity>-239,-268,-692,-11030</referential-integrity>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.InterbaseDictionary">
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.FirebirdDictionary">
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.JDataStoreDictionary">
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.MySQLDictionary">
+		<lock>1213</lock>
+		<referential-integrity>630,839,840,893,1062,1169,1215,1216,1217,1451,1452,1557</referential-integrity>
+		<object-exists>23000</object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>41000,1205,1213</optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.OracleDictionary">
+		<lock></lock>
+		<referential-integrity>1,1400,1722,2291,2292</referential-integrity>
+		<object-exists></object-exists>
+		<object-not-found></object-not-found>
+		<optimistic></optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.PointbaseDictionary">
+		<lock></lock>
+		<referential-integrity>22001,22005,23502,23503,23513,X0Y32</referential-integrity>
+		<object-exists></object-exists>
+		<object-not-found></object-not-found>
+		<optimistic></optimistic>
+	</dictionary>
+	
+	<dictionary class="org.apache.openjpa.jdbc.sql.PostgresDictionary">
+		<lock>55P03,40P01</lock>
+		<referential-integrity>23000,23502,23503,23505,23514</referential-integrity>
+		<object-exists></object-exists>
+		<object-not-found></object-not-found>
+		<optimistic>55P03</optimistic>
+	</dictionary>
+	
 </sql-state-codes>
\ No newline at end of file
diff --git a/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java b/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java
index d35d9f7..c6f7250 100644
--- a/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java
+++ b/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java
@@ -1,882 +1,882 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import java.io.IOException;
-import java.io.ObjectOutput;
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.StateManager;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.Strategy;
-import org.apache.openjpa.jdbc.meta.ValueMapping;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.jdbc.sql.RowManager;
-import org.apache.openjpa.jdbc.sql.SQLFactory;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.util.Id;
-
-/**
- * <p>
- * Tests AbstractUpdateManager flush's method exception return behavior.
- * </p>
- * 
- * @author Albert Lee
- */
-public class TestUpdateManagerFlushException extends /* Abstract */TestCase {
-
-    private TestUpdateManager updMgr;
-
-    public void setUp() {
-        updMgr = new TestUpdateManager();
-    }
-
-    /**
-     * Tests exception collection returns from UpdateManager flush method is in
-     * the order the original exceptions are thrown.
-     */
-    public void testAddRetrieve() {
-        
-        Collection states = new ArrayList<OpenJPAStateManager>();
-        states.add(new TestOpenJPAStateManager());
-
-        Collection exceps = updMgr.flush(states, new TestJDBCStore());
-
-        assertEquals(3, exceps.size());
-        
-        Iterator<Exception> itr = exceps.iterator();
-        assertEquals(itr.next().getMessage(),
-            "TestUpdateManager.populateRowManager");
-        assertEquals(itr.next().getMessage(),
-            "TestUpdateManager.flush");
-        assertEquals(itr.next().getMessage(),
-            "TestUpdateManager.customInsert");
-    }
-
-    /*
-     * Scaffolding test update manager.
-     */
-    class TestUpdateManager extends AbstractUpdateManager {
-
-        protected Collection flush(RowManager rowMgr,
-            PreparedStatementManager psMgr, Collection exceps) {
-
-            exceps.add(new SQLException("TestUpdateManager.flush"));
-
-            return exceps;
-        }
-
-        protected PreparedStatementManager newPreparedStatementManager(
-            JDBCStore store, Connection conn) {
-            return new PreparedStatementManagerImpl(store, conn);
-        }
-
-        protected RowManager newRowManager() {
-            return null;
-        }
-
-        public boolean orderDirty() {
-            return false;
-        }
-
-        protected Collection populateRowManager(OpenJPAStateManager sm,
-            RowManager rowMgr, JDBCStore store, Collection exceps,
-            Collection customs) {
-            
-            exceps.add(new SQLException(
-                "TestUpdateManager.populateRowManager"));
-            customs.add(new CustomMapping(CustomMapping.INSERT, sm,
-                new Strategy() {
-                    public void customDelete(OpenJPAStateManager sm,
-                        JDBCStore store) throws SQLException {
-                    }
-
-                    public void customInsert(OpenJPAStateManager sm,
-                        JDBCStore store) throws SQLException {
-                        throw new SQLException(
-                            "TestUpdateManager.customInsert");
-                    }
-
-                    public void customUpdate(OpenJPAStateManager sm,
-                        JDBCStore store) throws SQLException {
-                    }
-
-                    public void delete(OpenJPAStateManager sm, JDBCStore store,
-                        RowManager rm) throws SQLException {
-                    }
-
-                    public String getAlias() {
-                        return null;
-                    }
-
-                    public void initialize() {
-                    }
-
-                    public void insert(OpenJPAStateManager sm, JDBCStore store,
-                        RowManager rm) throws SQLException {
-
-                    }
-
-                    public Boolean isCustomDelete(OpenJPAStateManager sm,
-                        JDBCStore store) {
-                        return null;
-                    }
-
-                    public Boolean isCustomInsert(OpenJPAStateManager sm,
-                        JDBCStore store) {
-                        return null;
-                    }
-
-                    public Boolean isCustomUpdate(OpenJPAStateManager sm,
-                        JDBCStore store) {
-                        return null;
-                    }
-
-                    public void map(boolean adapt) {
-                    }
-
-                    public void update(OpenJPAStateManager sm, JDBCStore store,
-                        RowManager rm) throws SQLException {
-                    }
-                }));
-            return exceps;
-        }
-    }
-
-    /*
-     * Scaffolding test state manager.
-     */
-    class TestOpenJPAStateManager implements OpenJPAStateManager {
-
-        public boolean assignObjectId(boolean flush) {
-            return false;
-        }
-
-        public boolean beforeRefresh(boolean refreshAll) {
-            return false;
-        }
-
-        public void dirty(int field) {
-        }
-
-        public Object fetch(int field) {
-            return null;
-        }
-
-        public boolean fetchBoolean(int field) {
-            return false;
-        }
-
-        public byte fetchByte(int field) {
-            return 0;
-        }
-
-        public char fetchChar(int field) {
-            return 0;
-        }
-
-        public double fetchDouble(int field) {
-            return 0;
-        }
-
-        public Object fetchField(int field, boolean transitions) {
-            return null;
-        }
-
-        public float fetchFloat(int field) {
-            return 0;
-        }
-
-        public Object fetchInitialField(int field) {
-            return null;
-        }
-
-        public int fetchInt(int field) {
-            return 0;
-        }
-
-        public long fetchLong(int field) {
-            return 0;
-        }
-
-        public Object fetchObject(int field) {
-            return null;
-        }
-
-        public short fetchShort(int field) {
-            return 0;
-        }
-
-        public String fetchString(int field) {
-            return null;
-        }
-
-        public StoreContext getContext() {
-            return null;
-        }
-
-        public BitSet getDirty() {
-            return null;
-        }
-
-        public BitSet getFlushed() {
-            return null;
-        }
-
-        public Object getId() {
-            return null;
-        }
-
-        public Object getImplData() {
-            return null;
-        }
-
-        public Object getImplData(int field) {
-            return null;
-        }
-
-        public Object getIntermediate(int field) {
-            return null;
-        }
-
-        public BitSet getLoaded() {
-            return null;
-        }
-
-        public Object getLock() {
-            return null;
-        }
-
-        public Object getManagedInstance() {
-            return null;
-        }
-
-        public ClassMetaData getMetaData() {
-            return null;
-        }
-
-        public Object getObjectId() {
-            return null;
-        }
-
-        public OpenJPAStateManager getOwner() {
-            return null;
-        }
-
-        public int getOwnerIndex() {
-            return 0;
-        }
-
-        public PCState getPCState() {
-            return null;
-        }
-
-        public PersistenceCapable getPersistenceCapable() {
-            return null;
-        }
-
-        public BitSet getUnloaded(FetchConfiguration fetch) {
-            return null;
-        }
-
-        public Object getVersion() {
-            return null;
-        }
-
-        public void initialize(Class forType, PCState state) {
-        }
-
-        public boolean isDefaultValue(int field) {
-            return false;
-        }
-
-        public boolean isEmbedded() {
-            return false;
-        }
-
-        public boolean isFlushed() {
-            return false;
-        }
-
-        public boolean isFlushedDirty() {
-            return false;
-        }
-
-        public boolean isImplDataCacheable() {
-            return false;
-        }
-
-        public boolean isImplDataCacheable(int field) {
-            return false;
-        }
-
-        public boolean isProvisional() {
-            return false;
-        }
-
-        public boolean isVersionCheckRequired() {
-            return false;
-        }
-
-        public boolean isVersionUpdateRequired() {
-            return false;
-        }
-
-        public void load(FetchConfiguration fetch) {
-        }
-
-        public Object newFieldProxy(int field) {
-            return null;
-        }
-
-        public Object newProxy(int field) {
-            return null;
-        }
-
-        public void removed(int field, Object removed, boolean key) {
-        }
-
-        public Object setImplData(Object data, boolean cacheable) {
-            return null;
-        }
-
-        public Object setImplData(int field, Object data) {
-            return null;
-        }
-
-        public void setIntermediate(int field, Object value) {
-        }
-
-        public void setLock(Object lock) {
-        }
-
-        public void setNextVersion(Object version) {
-        }
-
-        public void setObjectId(Object oid) {
-        }
-
-        public void setRemote(int field, Object value) {
-        }
-
-        public void setVersion(Object version) {
-        }
-
-        public void store(int field, Object value) {
-        }
-
-        public void storeBoolean(int field, boolean externalVal) {
-        }
-
-        public void storeByte(int field, byte externalVal) {
-        }
-
-        public void storeChar(int field, char externalVal) {
-        }
-
-        public void storeDouble(int field, double externalVal) {
-        }
-
-        public void storeField(int field, Object value) {
-        }
-
-        public void storeFloat(int field, float externalVal) {
-        }
-
-        public void storeInt(int field, int externalVal) {
-        }
-
-        public void storeLong(int field, long externalVal) {
-        }
-
-        public void storeObject(int field, Object externalVal) {
-        }
-
-        public void storeShort(int field, short externalVal) {
-        }
-
-        public void storeString(int field, String externalVal) {
-        }
-
-        public void accessingField(int idx) {
-        }
-
-        public void dirty(String field) {
-        }
-
-        public Object fetchObjectId() {
-            return null;
-        }
-
-        public Object getGenericContext() {
-            return null;
-        }
-
-        public Object getPCPrimaryKey(Object oid, int field) {
-            return null;
-        }
-
-        public boolean isDeleted() {
-            return false;
-        }
-
-        public boolean isDetached() {
-            return false;
-        }
-
-        public boolean isDirty() {
-            return false;
-        }
-
-        public boolean isNew() {
-            return false;
-        }
-
-        public boolean isPersistent() {
-            return false;
-        }
-
-        public boolean isTransactional() {
-            return false;
-        }
-
-        public void providedBooleanField(PersistenceCapable pc, int idx,
-            boolean cur) {
-        }
-
-        public void providedByteField(PersistenceCapable pc, int idx,
-            byte cur) {
-        }
-
-        public void providedCharField(PersistenceCapable pc, int idx, 
-            char cur) {
-        }
-
-        public void providedDoubleField(PersistenceCapable pc, int idx,
-            double cur) {
-        }
-
-        public void providedFloatField(PersistenceCapable pc, int idx,
-            float cur) {
-        }
-
-        public void providedIntField(PersistenceCapable pc, int idx, 
-            int cur) {
-        }
-
-        public void providedLongField(PersistenceCapable pc, int idx, 
-            long cur) {
-        }
-
-        public void providedObjectField(PersistenceCapable pc, int idx,
-            Object cur) {
-        }
-
-        public void providedShortField(PersistenceCapable pc, int idx, 
-            short cur) {
-        }
-
-        public void providedStringField(PersistenceCapable pc, int idx,
-            String cur) {
-        }
-
-        public void proxyDetachedDeserialized(int idx) {
-        }
-
-        public boolean replaceBooleanField(PersistenceCapable pc, int idx) {
-            return false;
-        }
-
-        public byte replaceByteField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public char replaceCharField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public double replaceDoubleField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public float replaceFloatField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public int replaceIntField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public long replaceLongField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public Object replaceObjectField(PersistenceCapable pc, int idx) {
-            return null;
-        }
-
-        public short replaceShortField(PersistenceCapable pc, int idx) {
-            return 0;
-        }
-
-        public StateManager replaceStateManager(StateManager sm) {
-            return null;
-        }
-
-        public String replaceStringField(PersistenceCapable pc, int idx) {
-            return null;
-        }
-
-        public boolean serializing() {
-            return false;
-        }
-
-        public void settingBooleanField(PersistenceCapable pc, int idx,
-            boolean cur, boolean next, int set) {
-        }
-
-        public void settingByteField(PersistenceCapable pc, int idx, byte cur,
-            byte next, int set) {
-        }
-
-        public void settingCharField(PersistenceCapable pc, int idx, char cur,
-            char next, int set) {
-        }
-
-        public void settingDoubleField(PersistenceCapable pc, int idx,
-            double cur, double next, int set) {
-        }
-
-        public void settingFloatField(PersistenceCapable pc, int idx,
-            float cur, float next, int set) {
-        }
-
-        public void settingIntField(PersistenceCapable pc, int idx, int cur,
-            int next, int set) {
-        }
-
-        public void settingLongField(PersistenceCapable pc, int idx, long cur,
-            long next, int set) {
-        }
-
-        public void settingObjectField(PersistenceCapable pc, int idx,
-            Object cur, Object next, int set) {
-        }
-
-        public void settingShortField(PersistenceCapable pc, int idx,
-            short cur, short next, int set) {
-        }
-
-        public void settingStringField(PersistenceCapable pc, int idx,
-            String cur, String next, int set) {
-        }
-
-        public boolean writeDetached(ObjectOutput out) throws IOException {
-            return false;
-        }
-
-        public void storeBooleanField(int fieldIndex, boolean value) {
-        }
-
-        public void storeByteField(int fieldIndex, byte value) {
-        }
-
-        public void storeCharField(int fieldIndex, char value) {
-        }
-
-        public void storeDoubleField(int fieldIndex, double value) {
-        }
-
-        public void storeFloatField(int fieldIndex, float value) {
-        }
-
-        public void storeIntField(int fieldIndex, int value) {
-        }
-
-        public void storeLongField(int fieldIndex, long value) {
-        }
-
-        public void storeObjectField(int fieldIndex, Object value) {
-        }
-
-        public void storeShortField(int fieldIndex, short value) {
-        }
-
-        public void storeStringField(int fieldIndex, String value) {
-        }
-
-        public boolean fetchBooleanField(int fieldIndex) {
-            return false;
-        }
-
-        public byte fetchByteField(int fieldIndex) {
-            return 0;
-        }
-
-        public char fetchCharField(int fieldIndex) {
-            return 0;
-        }
-
-        public double fetchDoubleField(int fieldIndex) {
-            return 0;
-        }
-
-        public float fetchFloatField(int fieldIndex) {
-            return 0;
-        }
-
-        public int fetchIntField(int fieldIndex) {
-            return 0;
-        }
-
-        public long fetchLongField(int fieldIndex) {
-            return 0;
-        }
-
-        public Object fetchObjectField(int fieldIndex) {
-            return null;
-        }
-
-        public short fetchShortField(int fieldIndex) {
-            return 0;
-        }
-
-        public String fetchStringField(int fieldIndex) {
-            return null;
-        }
-    }
-
-    /*
-     * Scaffolding test connection.
-     */
-    class TestConnection implements Connection {
-
-        public void clearWarnings() throws SQLException {
-        }
-
-        public void close() throws SQLException {
-        }
-
-        public void commit() throws SQLException {
-        }
-
-        public Statement createStatement() throws SQLException {
-            return null;
-        }
-
-        public Statement createStatement(int resultSetType,
-            int resultSetConcurrency) throws SQLException {
-            return null;
-        }
-
-        public Statement createStatement(int resultSetType,
-            int resultSetConcurrency, int resultSetHoldability)
-            throws SQLException {
-            return null;
-        }
-
-        public boolean getAutoCommit() throws SQLException {
-            return false;
-        }
-
-        public String getCatalog() throws SQLException {
-            return null;
-        }
-
-        public int getHoldability() throws SQLException {
-            return 0;
-        }
-
-        public DatabaseMetaData getMetaData() throws SQLException {
-            return null;
-        }
-
-        public int getTransactionIsolation() throws SQLException {
-            return 0;
-        }
-
-        public Map<String, Class<?>> getTypeMap() throws SQLException {
-            return null;
-        }
-
-        public SQLWarning getWarnings() throws SQLException {
-            return null;
-        }
-
-        public boolean isClosed() throws SQLException {
-            return false;
-        }
-
-        public boolean isReadOnly() throws SQLException {
-            return false;
-        }
-
-        public String nativeSQL(String sql) throws SQLException {
-            return null;
-        }
-
-        public CallableStatement prepareCall(String sql) throws SQLException {
-            return null;
-        }
-
-        public CallableStatement prepareCall(String sql, int resultSetType,
-            int resultSetConcurrency) throws SQLException {
-            return null;
-        }
-
-        public CallableStatement prepareCall(String sql, int resultSetType,
-            int resultSetConcurrency, int resultSetHoldability)
-            throws SQLException {
-            return null;
-        }
-
-        public PreparedStatement prepareStatement(String sql)
-            throws SQLException {
-            return null;
-        }
-
-        public PreparedStatement prepareStatement(String sql,
-            int autoGeneratedKeys) throws SQLException {
-            return null;
-        }
-
-        public PreparedStatement prepareStatement(String sql,
-            int[] columnIndexes) throws SQLException {
-            return null;
-        }
-
-        public PreparedStatement prepareStatement(String sql,
-            String[] columnNames) throws SQLException {
-            return null;
-        }
-
-        public PreparedStatement prepareStatement(String sql,
-            int resultSetType, int resultSetConcurrency) throws SQLException {
-            return null;
-        }
-
-        public PreparedStatement prepareStatement(String sql,
-            int resultSetType, int resultSetConcurrency,
-            int resultSetHoldability) throws SQLException {
-            return null;
-        }
-
-        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-        }
-
-        public void rollback() throws SQLException {
-        }
-
-        public void rollback(Savepoint savepoint) throws SQLException {
-        }
-
-        public void setAutoCommit(boolean autoCommit) throws SQLException {
-        }
-
-        public void setCatalog(String catalog) throws SQLException {
-        }
-
-        public void setHoldability(int holdability) throws SQLException {
-        }
-
-        public void setReadOnly(boolean readOnly) throws SQLException {
-        }
-
-        public Savepoint setSavepoint() throws SQLException {
-            return null;
-        }
-
-        public Savepoint setSavepoint(String name) throws SQLException {
-            return null;
-        }
-
-        public void setTransactionIsolation(int level) throws SQLException {
-        }
-
-        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
-        }
-    }
-
-    /*
-     * Scaffolding test store manager.
-     */
-    class TestJDBCStore implements JDBCStore {
-
-        public Object find(Object oid, ValueMapping vm,
-            JDBCFetchConfiguration fetch) {
-            return null;
-        }
-
-        public JDBCConfiguration getConfiguration() {
-            return null;
-        }
-
-        public Connection getConnection() {
-            return new TestConnection();
-        }
-
-        public StoreContext getContext() {
-            return null;
-        }
-
-        public DBDictionary getDBDictionary() {
-            return null;
-        }
-
-        public JDBCFetchConfiguration getFetchConfiguration() {
-            return null;
-        }
-
-        public JDBCLockManager getLockManager() {
-            return null;
-        }
-
-        public SQLFactory getSQLFactory() {
-            return null;
-        }
-
-        public void loadSubclasses(ClassMapping mapping) {
-
-        }
-
-        public Id newDataStoreId(long id, ClassMapping mapping, boolean subs) {
-            return null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Strategy;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.SQLFactory;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.Id;
+
+/**
+ * <p>
+ * Tests AbstractUpdateManager flush's method exception return behavior.
+ * </p>
+ * 
+ * @author Albert Lee
+ */
+public class TestUpdateManagerFlushException extends /* Abstract */TestCase {
+
+    private TestUpdateManager updMgr;
+
+    public void setUp() {
+        updMgr = new TestUpdateManager();
+    }
+
+    /**
+     * Tests exception collection returns from UpdateManager flush method is in
+     * the order the original exceptions are thrown.
+     */
+    public void testAddRetrieve() {
+        
+        Collection states = new ArrayList<OpenJPAStateManager>();
+        states.add(new TestOpenJPAStateManager());
+
+        Collection exceps = updMgr.flush(states, new TestJDBCStore());
+
+        assertEquals(3, exceps.size());
+        
+        Iterator<Exception> itr = exceps.iterator();
+        assertEquals(itr.next().getMessage(),
+            "TestUpdateManager.populateRowManager");
+        assertEquals(itr.next().getMessage(),
+            "TestUpdateManager.flush");
+        assertEquals(itr.next().getMessage(),
+            "TestUpdateManager.customInsert");
+    }
+
+    /*
+     * Scaffolding test update manager.
+     */
+    class TestUpdateManager extends AbstractUpdateManager {
+
+        protected Collection flush(RowManager rowMgr,
+            PreparedStatementManager psMgr, Collection exceps) {
+
+            exceps.add(new SQLException("TestUpdateManager.flush"));
+
+            return exceps;
+        }
+
+        protected PreparedStatementManager newPreparedStatementManager(
+            JDBCStore store, Connection conn) {
+            return new PreparedStatementManagerImpl(store, conn);
+        }
+
+        protected RowManager newRowManager() {
+            return null;
+        }
+
+        public boolean orderDirty() {
+            return false;
+        }
+
+        protected Collection populateRowManager(OpenJPAStateManager sm,
+            RowManager rowMgr, JDBCStore store, Collection exceps,
+            Collection customs) {
+            
+            exceps.add(new SQLException(
+                "TestUpdateManager.populateRowManager"));
+            customs.add(new CustomMapping(CustomMapping.INSERT, sm,
+                new Strategy() {
+                    public void customDelete(OpenJPAStateManager sm,
+                        JDBCStore store) throws SQLException {
+                    }
+
+                    public void customInsert(OpenJPAStateManager sm,
+                        JDBCStore store) throws SQLException {
+                        throw new SQLException(
+                            "TestUpdateManager.customInsert");
+                    }
+
+                    public void customUpdate(OpenJPAStateManager sm,
+                        JDBCStore store) throws SQLException {
+                    }
+
+                    public void delete(OpenJPAStateManager sm, JDBCStore store,
+                        RowManager rm) throws SQLException {
+                    }
+
+                    public String getAlias() {
+                        return null;
+                    }
+
+                    public void initialize() {
+                    }
+
+                    public void insert(OpenJPAStateManager sm, JDBCStore store,
+                        RowManager rm) throws SQLException {
+
+                    }
+
+                    public Boolean isCustomDelete(OpenJPAStateManager sm,
+                        JDBCStore store) {
+                        return null;
+                    }
+
+                    public Boolean isCustomInsert(OpenJPAStateManager sm,
+                        JDBCStore store) {
+                        return null;
+                    }
+
+                    public Boolean isCustomUpdate(OpenJPAStateManager sm,
+                        JDBCStore store) {
+                        return null;
+                    }
+
+                    public void map(boolean adapt) {
+                    }
+
+                    public void update(OpenJPAStateManager sm, JDBCStore store,
+                        RowManager rm) throws SQLException {
+                    }
+                }));
+            return exceps;
+        }
+    }
+
+    /*
+     * Scaffolding test state manager.
+     */
+    class TestOpenJPAStateManager implements OpenJPAStateManager {
+
+        public boolean assignObjectId(boolean flush) {
+            return false;
+        }
+
+        public boolean beforeRefresh(boolean refreshAll) {
+            return false;
+        }
+
+        public void dirty(int field) {
+        }
+
+        public Object fetch(int field) {
+            return null;
+        }
+
+        public boolean fetchBoolean(int field) {
+            return false;
+        }
+
+        public byte fetchByte(int field) {
+            return 0;
+        }
+
+        public char fetchChar(int field) {
+            return 0;
+        }
+
+        public double fetchDouble(int field) {
+            return 0;
+        }
+
+        public Object fetchField(int field, boolean transitions) {
+            return null;
+        }
+
+        public float fetchFloat(int field) {
+            return 0;
+        }
+
+        public Object fetchInitialField(int field) {
+            return null;
+        }
+
+        public int fetchInt(int field) {
+            return 0;
+        }
+
+        public long fetchLong(int field) {
+            return 0;
+        }
+
+        public Object fetchObject(int field) {
+            return null;
+        }
+
+        public short fetchShort(int field) {
+            return 0;
+        }
+
+        public String fetchString(int field) {
+            return null;
+        }
+
+        public StoreContext getContext() {
+            return null;
+        }
+
+        public BitSet getDirty() {
+            return null;
+        }
+
+        public BitSet getFlushed() {
+            return null;
+        }
+
+        public Object getId() {
+            return null;
+        }
+
+        public Object getImplData() {
+            return null;
+        }
+
+        public Object getImplData(int field) {
+            return null;
+        }
+
+        public Object getIntermediate(int field) {
+            return null;
+        }
+
+        public BitSet getLoaded() {
+            return null;
+        }
+
+        public Object getLock() {
+            return null;
+        }
+
+        public Object getManagedInstance() {
+            return null;
+        }
+
+        public ClassMetaData getMetaData() {
+            return null;
+        }
+
+        public Object getObjectId() {
+            return null;
+        }
+
+        public OpenJPAStateManager getOwner() {
+            return null;
+        }
+
+        public int getOwnerIndex() {
+            return 0;
+        }
+
+        public PCState getPCState() {
+            return null;
+        }
+
+        public PersistenceCapable getPersistenceCapable() {
+            return null;
+        }
+
+        public BitSet getUnloaded(FetchConfiguration fetch) {
+            return null;
+        }
+
+        public Object getVersion() {
+            return null;
+        }
+
+        public void initialize(Class forType, PCState state) {
+        }
+
+        public boolean isDefaultValue(int field) {
+            return false;
+        }
+
+        public boolean isEmbedded() {
+            return false;
+        }
+
+        public boolean isFlushed() {
+            return false;
+        }
+
+        public boolean isFlushedDirty() {
+            return false;
+        }
+
+        public boolean isImplDataCacheable() {
+            return false;
+        }
+
+        public boolean isImplDataCacheable(int field) {
+            return false;
+        }
+
+        public boolean isProvisional() {
+            return false;
+        }
+
+        public boolean isVersionCheckRequired() {
+            return false;
+        }
+
+        public boolean isVersionUpdateRequired() {
+            return false;
+        }
+
+        public void load(FetchConfiguration fetch) {
+        }
+
+        public Object newFieldProxy(int field) {
+            return null;
+        }
+
+        public Object newProxy(int field) {
+            return null;
+        }
+
+        public void removed(int field, Object removed, boolean key) {
+        }
+
+        public Object setImplData(Object data, boolean cacheable) {
+            return null;
+        }
+
+        public Object setImplData(int field, Object data) {
+            return null;
+        }
+
+        public void setIntermediate(int field, Object value) {
+        }
+
+        public void setLock(Object lock) {
+        }
+
+        public void setNextVersion(Object version) {
+        }
+
+        public void setObjectId(Object oid) {
+        }
+
+        public void setRemote(int field, Object value) {
+        }
+
+        public void setVersion(Object version) {
+        }
+
+        public void store(int field, Object value) {
+        }
+
+        public void storeBoolean(int field, boolean externalVal) {
+        }
+
+        public void storeByte(int field, byte externalVal) {
+        }
+
+        public void storeChar(int field, char externalVal) {
+        }
+
+        public void storeDouble(int field, double externalVal) {
+        }
+
+        public void storeField(int field, Object value) {
+        }
+
+        public void storeFloat(int field, float externalVal) {
+        }
+
+        public void storeInt(int field, int externalVal) {
+        }
+
+        public void storeLong(int field, long externalVal) {
+        }
+
+        public void storeObject(int field, Object externalVal) {
+        }
+
+        public void storeShort(int field, short externalVal) {
+        }
+
+        public void storeString(int field, String externalVal) {
+        }
+
+        public void accessingField(int idx) {
+        }
+
+        public void dirty(String field) {
+        }
+
+        public Object fetchObjectId() {
+            return null;
+        }
+
+        public Object getGenericContext() {
+            return null;
+        }
+
+        public Object getPCPrimaryKey(Object oid, int field) {
+            return null;
+        }
+
+        public boolean isDeleted() {
+            return false;
+        }
+
+        public boolean isDetached() {
+            return false;
+        }
+
+        public boolean isDirty() {
+            return false;
+        }
+
+        public boolean isNew() {
+            return false;
+        }
+
+        public boolean isPersistent() {
+            return false;
+        }
+
+        public boolean isTransactional() {
+            return false;
+        }
+
+        public void providedBooleanField(PersistenceCapable pc, int idx,
+            boolean cur) {
+        }
+
+        public void providedByteField(PersistenceCapable pc, int idx,
+            byte cur) {
+        }
+
+        public void providedCharField(PersistenceCapable pc, int idx, 
+            char cur) {
+        }
+
+        public void providedDoubleField(PersistenceCapable pc, int idx,
+            double cur) {
+        }
+
+        public void providedFloatField(PersistenceCapable pc, int idx,
+            float cur) {
+        }
+
+        public void providedIntField(PersistenceCapable pc, int idx, 
+            int cur) {
+        }
+
+        public void providedLongField(PersistenceCapable pc, int idx, 
+            long cur) {
+        }
+
+        public void providedObjectField(PersistenceCapable pc, int idx,
+            Object cur) {
+        }
+
+        public void providedShortField(PersistenceCapable pc, int idx, 
+            short cur) {
+        }
+
+        public void providedStringField(PersistenceCapable pc, int idx,
+            String cur) {
+        }
+
+        public void proxyDetachedDeserialized(int idx) {
+        }
+
+        public boolean replaceBooleanField(PersistenceCapable pc, int idx) {
+            return false;
+        }
+
+        public byte replaceByteField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public char replaceCharField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public double replaceDoubleField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public float replaceFloatField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public int replaceIntField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public long replaceLongField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public Object replaceObjectField(PersistenceCapable pc, int idx) {
+            return null;
+        }
+
+        public short replaceShortField(PersistenceCapable pc, int idx) {
+            return 0;
+        }
+
+        public StateManager replaceStateManager(StateManager sm) {
+            return null;
+        }
+
+        public String replaceStringField(PersistenceCapable pc, int idx) {
+            return null;
+        }
+
+        public boolean serializing() {
+            return false;
+        }
+
+        public void settingBooleanField(PersistenceCapable pc, int idx,
+            boolean cur, boolean next, int set) {
+        }
+
+        public void settingByteField(PersistenceCapable pc, int idx, byte cur,
+            byte next, int set) {
+        }
+
+        public void settingCharField(PersistenceCapable pc, int idx, char cur,
+            char next, int set) {
+        }
+
+        public void settingDoubleField(PersistenceCapable pc, int idx,
+            double cur, double next, int set) {
+        }
+
+        public void settingFloatField(PersistenceCapable pc, int idx,
+            float cur, float next, int set) {
+        }
+
+        public void settingIntField(PersistenceCapable pc, int idx, int cur,
+            int next, int set) {
+        }
+
+        public void settingLongField(PersistenceCapable pc, int idx, long cur,
+            long next, int set) {
+        }
+
+        public void settingObjectField(PersistenceCapable pc, int idx,
+            Object cur, Object next, int set) {
+        }
+
+        public void settingShortField(PersistenceCapable pc, int idx,
+            short cur, short next, int set) {
+        }
+
+        public void settingStringField(PersistenceCapable pc, int idx,
+            String cur, String next, int set) {
+        }
+
+        public boolean writeDetached(ObjectOutput out) throws IOException {
+            return false;
+        }
+
+        public void storeBooleanField(int fieldIndex, boolean value) {
+        }
+
+        public void storeByteField(int fieldIndex, byte value) {
+        }
+
+        public void storeCharField(int fieldIndex, char value) {
+        }
+
+        public void storeDoubleField(int fieldIndex, double value) {
+        }
+
+        public void storeFloatField(int fieldIndex, float value) {
+        }
+
+        public void storeIntField(int fieldIndex, int value) {
+        }
+
+        public void storeLongField(int fieldIndex, long value) {
+        }
+
+        public void storeObjectField(int fieldIndex, Object value) {
+        }
+
+        public void storeShortField(int fieldIndex, short value) {
+        }
+
+        public void storeStringField(int fieldIndex, String value) {
+        }
+
+        public boolean fetchBooleanField(int fieldIndex) {
+            return false;
+        }
+
+        public byte fetchByteField(int fieldIndex) {
+            return 0;
+        }
+
+        public char fetchCharField(int fieldIndex) {
+            return 0;
+        }
+
+        public double fetchDoubleField(int fieldIndex) {
+            return 0;
+        }
+
+        public float fetchFloatField(int fieldIndex) {
+            return 0;
+        }
+
+        public int fetchIntField(int fieldIndex) {
+            return 0;
+        }
+
+        public long fetchLongField(int fieldIndex) {
+            return 0;
+        }
+
+        public Object fetchObjectField(int fieldIndex) {
+            return null;
+        }
+
+        public short fetchShortField(int fieldIndex) {
+            return 0;
+        }
+
+        public String fetchStringField(int fieldIndex) {
+            return null;
+        }
+    }
+
+    /*
+     * Scaffolding test connection.
+     */
+    class TestConnection implements Connection {
+
+        public void clearWarnings() throws SQLException {
+        }
+
+        public void close() throws SQLException {
+        }
+
+        public void commit() throws SQLException {
+        }
+
+        public Statement createStatement() throws SQLException {
+            return null;
+        }
+
+        public Statement createStatement(int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+            return null;
+        }
+
+        public Statement createStatement(int resultSetType,
+            int resultSetConcurrency, int resultSetHoldability)
+            throws SQLException {
+            return null;
+        }
+
+        public boolean getAutoCommit() throws SQLException {
+            return false;
+        }
+
+        public String getCatalog() throws SQLException {
+            return null;
+        }
+
+        public int getHoldability() throws SQLException {
+            return 0;
+        }
+
+        public DatabaseMetaData getMetaData() throws SQLException {
+            return null;
+        }
+
+        public int getTransactionIsolation() throws SQLException {
+            return 0;
+        }
+
+        public Map<String, Class<?>> getTypeMap() throws SQLException {
+            return null;
+        }
+
+        public SQLWarning getWarnings() throws SQLException {
+            return null;
+        }
+
+        public boolean isClosed() throws SQLException {
+            return false;
+        }
+
+        public boolean isReadOnly() throws SQLException {
+            return false;
+        }
+
+        public String nativeSQL(String sql) throws SQLException {
+            return null;
+        }
+
+        public CallableStatement prepareCall(String sql) throws SQLException {
+            return null;
+        }
+
+        public CallableStatement prepareCall(String sql, int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+            return null;
+        }
+
+        public CallableStatement prepareCall(String sql, int resultSetType,
+            int resultSetConcurrency, int resultSetHoldability)
+            throws SQLException {
+            return null;
+        }
+
+        public PreparedStatement prepareStatement(String sql)
+            throws SQLException {
+            return null;
+        }
+
+        public PreparedStatement prepareStatement(String sql,
+            int autoGeneratedKeys) throws SQLException {
+            return null;
+        }
+
+        public PreparedStatement prepareStatement(String sql,
+            int[] columnIndexes) throws SQLException {
+            return null;
+        }
+
+        public PreparedStatement prepareStatement(String sql,
+            String[] columnNames) throws SQLException {
+            return null;
+        }
+
+        public PreparedStatement prepareStatement(String sql,
+            int resultSetType, int resultSetConcurrency) throws SQLException {
+            return null;
+        }
+
+        public PreparedStatement prepareStatement(String sql,
+            int resultSetType, int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+            return null;
+        }
+
+        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+        }
+
+        public void rollback() throws SQLException {
+        }
+
+        public void rollback(Savepoint savepoint) throws SQLException {
+        }
+
+        public void setAutoCommit(boolean autoCommit) throws SQLException {
+        }
+
+        public void setCatalog(String catalog) throws SQLException {
+        }
+
+        public void setHoldability(int holdability) throws SQLException {
+        }
+
+        public void setReadOnly(boolean readOnly) throws SQLException {
+        }
+
+        public Savepoint setSavepoint() throws SQLException {
+            return null;
+        }
+
+        public Savepoint setSavepoint(String name) throws SQLException {
+            return null;
+        }
+
+        public void setTransactionIsolation(int level) throws SQLException {
+        }
+
+        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+        }
+    }
+
+    /*
+     * Scaffolding test store manager.
+     */
+    class TestJDBCStore implements JDBCStore {
+
+        public Object find(Object oid, ValueMapping vm,
+            JDBCFetchConfiguration fetch) {
+            return null;
+        }
+
+        public JDBCConfiguration getConfiguration() {
+            return null;
+        }
+
+        public Connection getConnection() {
+            return new TestConnection();
+        }
+
+        public StoreContext getContext() {
+            return null;
+        }
+
+        public DBDictionary getDBDictionary() {
+            return null;
+        }
+
+        public JDBCFetchConfiguration getFetchConfiguration() {
+            return null;
+        }
+
+        public JDBCLockManager getLockManager() {
+            return null;
+        }
+
+        public SQLFactory getSQLFactory() {
+            return null;
+        }
+
+        public void loadSubclasses(ClassMapping mapping) {
+
+        }
+
+        public Id newDataStoreId(long id, ClassMapping mapping, boolean subs) {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-kernel/pom.xml b/openjpa-kernel/pom.xml
index c42a685..03d21d6 100644
--- a/openjpa-kernel/pom.xml
+++ b/openjpa-kernel/pom.xml
@@ -31,7 +31,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshaller.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshaller.java
index 7d6c43d..8d1bf94 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshaller.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshaller.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.conf.Configuration;
-
-/**
- * Responsible for marshalling and unmarshalling objects between memory and
- * durable cache.
- *
- * @since 1.1.0
- */
-public interface CacheMarshaller {
-
-    /**
-     * Load and return an instance of the type handled by this marshaller.
-     * If the type implements {@link Configurable}, then this method will invoke
-     * {@link Configurable#setConfiguration}, 
-     * {@link Configurable#startConfiguration()}, and
-     * {@link Configurable#endConfiguration()} on the instance before returning.
-     */
-    public Object load();
-
-    /**
-     * Store <code>o</code> into the cache.
-     */
-    public void store(Object o);
-
-    /**
-     * The id that this marshaller is responsible for.
-     * A value for this parameter is required.
-     */
-    public void setId(String id);
-
-    /**
-     * The id that this marshaller is responsible for.
-     */
-    public String getId();
-
-    /**
-     * The {@link ValidationPolicy} that this marshaller should use.
-     * A value for this parameter is required. The class will be instantiated
-     * via the {@link org.apache.openjpa.lib.conf.Configurations} mechanism, ensuring that if the class
-     * implements {@link Configurable} or {@link org.apache.openjpa.lib.conf.GenericConfigurable}, it will
-     * be taken through the appropriate lifecycle.
-     */
-    public void setValidationPolicy(String policy)
-        throws InstantiationException, IllegalAccessException;
-
-    /**
-     * Validation policies are responsible for computing whether or not a
-     * cached data structure is valid for the current context.
-     * <p/>
-     * <code>getValidCachedData(getCacheableData(o), conf)</code> should
-     * return an object equivalent to <code>o</code> in the expected case.
-     * <p/>
-     * Implementations of this class will often also implement
-     * {@link Configurable} in order to receive the current
-     * {@link Configuration}.
-     */
-    public interface ValidationPolicy {
-        /**
-         * Returns an object that this policy considers to be valid, based
-         * on <code>o</code>. If <code>o</code> is not valid, this method
-         * will return <code>null</code>.
-         */
-        public Object getValidData(Object o);
-
-        /**
-         * Return an object that the {@link CacheMarshaller} should store.
-         */
-        public Object getCacheableData(Object o);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+
+/**
+ * Responsible for marshalling and unmarshalling objects between memory and
+ * durable cache.
+ *
+ * @since 1.1.0
+ */
+public interface CacheMarshaller {
+
+    /**
+     * Load and return an instance of the type handled by this marshaller.
+     * If the type implements {@link Configurable}, then this method will invoke
+     * {@link Configurable#setConfiguration}, 
+     * {@link Configurable#startConfiguration()}, and
+     * {@link Configurable#endConfiguration()} on the instance before returning.
+     */
+    public Object load();
+
+    /**
+     * Store <code>o</code> into the cache.
+     */
+    public void store(Object o);
+
+    /**
+     * The id that this marshaller is responsible for.
+     * A value for this parameter is required.
+     */
+    public void setId(String id);
+
+    /**
+     * The id that this marshaller is responsible for.
+     */
+    public String getId();
+
+    /**
+     * The {@link ValidationPolicy} that this marshaller should use.
+     * A value for this parameter is required. The class will be instantiated
+     * via the {@link org.apache.openjpa.lib.conf.Configurations} mechanism, ensuring that if the class
+     * implements {@link Configurable} or {@link org.apache.openjpa.lib.conf.GenericConfigurable}, it will
+     * be taken through the appropriate lifecycle.
+     */
+    public void setValidationPolicy(String policy)
+        throws InstantiationException, IllegalAccessException;
+
+    /**
+     * Validation policies are responsible for computing whether or not a
+     * cached data structure is valid for the current context.
+     * <p/>
+     * <code>getValidCachedData(getCacheableData(o), conf)</code> should
+     * return an object equivalent to <code>o</code> in the expected case.
+     * <p/>
+     * Implementations of this class will often also implement
+     * {@link Configurable} in order to receive the current
+     * {@link Configuration}.
+     */
+    public interface ValidationPolicy {
+        /**
+         * Returns an object that this policy considers to be valid, based
+         * on <code>o</code>. If <code>o</code> is not valid, this method
+         * will return <code>null</code>.
+         */
+        public Object getValidData(Object o);
+
+        /**
+         * Return an object that the {@link CacheMarshaller} should store.
+         */
+        public Object getCacheableData(Object o);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallerImpl.java
index c552ccd..40684bb 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallerImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallerImpl.java
@@ -1,253 +1,253 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.InternalException;
-
-/**
- * Default {@link CacheMarshaller} implementation that writes data
- * to a specified file and reads data from a specified file or URL.
- *
- * @since 1.1.0
- */
-public class CacheMarshallerImpl
-    implements CacheMarshaller, Configurable {
-
-    private static final Localizer _loc =
-        Localizer.forPackage(CacheMarshallerImpl.class);
-
-    private String _id;
-    private ValidationPolicy _validationPolicy;
-    private OpenJPAConfiguration _conf;
-    private Log _log;
-    private File _outputFile;
-    private URL _inputURL;
-
-    // temporary storage for resource location specification
-    private String _inputResourceLocation;
-    
-    private boolean _consumeErrors = true;
-
-    public Object load() {
-        if (_inputURL == null) {
-            _log.trace(_loc.get("cache-marshaller-no-inputs", getId()));
-            return null;
-        }
-
-        Object o = null;
-        ObjectInputStream in = null;
-        try {
-            in = new ObjectInputStream(new BufferedInputStream(
-                _inputURL.openStream()));
-
-            o = in.readObject();
-            o = _validationPolicy.getValidData(o);
-
-            if (o != null && o.getClass().isArray()) {
-                Object[] array = (Object[]) o;
-                for (int i = 0; i < array.length; i++)
-                    configure(array[i]);
-            } else {
-                configure(o);
-            }
-
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("cache-marshaller-loaded",
-                    o == null ? null : o.getClass().getName(), _inputURL));
-        } catch (Exception e) {
-            if (_consumeErrors) {
-                if (_log.isWarnEnabled())
-                    _log.warn(_loc.get("cache-marshaller-load-exception-ignore",
-                        _inputURL), e);
-            } else {
-                throw new InternalException(
-                    _loc.get("cache-marshaller-load-exception-fatal",
-                        _inputURL),
-                    e);
-            }
-        } finally {
-            if (in != null)
-                try { in.close(); } catch (IOException e) { }
-        }
-
-        return o;
-    }
-
-    private void configure(Object o) {
-        if (o instanceof Configurable) {
-            ((Configurable) o).setConfiguration(_conf);
-            ((Configurable) o).startConfiguration();
-            ((Configurable) o).endConfiguration();
-        }
-    }
-
-    public void store(Object o) {
-        if (_outputFile == null) {
-            _log.trace(_loc.get("cache-marshaller-no-output-file", getId()));
-            return;
-        }
-        OutputStream out = null;
-        try {
-            out = new FileOutputStream(_outputFile);
-            ObjectOutputStream oos =
-                new ObjectOutputStream(new BufferedOutputStream(out));
-            Object toStore = _validationPolicy.getCacheableData(o);
-            oos.writeObject(toStore);
-            oos.flush();
-            out.flush();
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("cache-marshaller-stored",
-                    o.getClass().getName(), _outputFile));
-        } catch (Exception e) {
-            if (_consumeErrors) {
-                if (_log.isWarnEnabled())
-                    _log.warn(_loc.get("cache-marshaller-store-exception",
-                        o.getClass().getName(), _outputFile), e);
-            } else {
-                throw new InternalException(
-                    _loc.get("cache-marshaller-store-exception",
-                        o.getClass().getName(), _outputFile),
-                    e);
-            }
-        } finally {
-            if (out != null) {
-                try { out.close(); } catch (IOException ioe) { }
-            }
-        }
-    }
-
-    public void setOutputFile(File file) {
-        _outputFile = file;
-    }
-
-    public File getOutputFile() {
-        return _outputFile;
-    }
-
-    public void setInputURL(URL url) {
-        _inputURL = url;
-    }
-
-    public void setInputResource(String resource) {
-        _inputResourceLocation = resource;
-    }
-
-    public void setConsumeSerializationErrors(boolean consume) {
-        _consumeErrors = consume;
-    }
-
-    public String getId() {
-        return _id;
-    }
-
-    public void setId(String id) {
-        _id = id;
-    }
-
-    public void setValidationPolicy(String policy)
-        throws InstantiationException, IllegalAccessException {
-        String name = Configurations.getClassName(policy);
-        String props = Configurations.getProperties(policy);
-        _validationPolicy = (ValidationPolicy)
-            Configurations.newInstance(name, _conf, props, null);
-    }
-
-    public ValidationPolicy getValidationPolicy() {
-        return _validationPolicy;
-    }
-
-    public void setConfiguration(Configuration conf) {
-        _conf = (OpenJPAConfiguration) conf;
-        _log = conf.getConfigurationLog();
-    }
-
-    public void startConfiguration() {
-    }
-
-    public void endConfiguration() {
-        if (_inputResourceLocation != null && _inputURL != null)
-            throw new IllegalStateException(
-                _loc.get("cache-marshaller-input-url-and-resource-specified")
-                    .getMessage());
-        if (_inputResourceLocation != null)
-            setInputUrlFromResourceLocation();
-
-        if (_validationPolicy == null)
-            throw new IllegalStateException(
-                _loc.get("cache-marshaller-null-validation-policy",
-                    getClass().getName()).getMessage());
-        if (_id == null)
-            throw new IllegalStateException(
-                _loc.get("cache-marshaller-null-id",
-                    getClass().getName()).getMessage());
-    }
-
-    private void setInputUrlFromResourceLocation() {
-        try {
-            ClassLoader cl = _conf.getClassResolverInstance()
-                .getClassLoader(getClass(), null);
-            List list = new ArrayList();
-            for (Enumeration e = cl.getResources(_inputResourceLocation);
-                e.hasMoreElements(); )
-                list.add(e);
-
-            if (list.size() > 1) {
-                if (_consumeErrors) {
-                    if (_log.isWarnEnabled())
-                        _log.warn(_loc.get(
-                            "cache-marshaller-multiple-resources-warn",
-                            getId(), _inputResourceLocation, list)
-                            .getMessage());
-                } else {
-                    throw new IllegalStateException(
-                        _loc.get("cache-marshaller-multiple-resources",
-                            getId(), _inputResourceLocation, list)
-                            .getMessage());
-                }
-            }
-
-            if (!list.isEmpty())
-                _inputURL = (URL) list.get(0);
-        } catch (IOException ioe) {
-            IllegalStateException ise = new IllegalStateException(
-                _loc.get("cache-marshaller-bad-url", getId(),
-                    _inputResourceLocation).getMessage());
-            ise.initCause(ioe);
-            throw ise;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Default {@link CacheMarshaller} implementation that writes data
+ * to a specified file and reads data from a specified file or URL.
+ *
+ * @since 1.1.0
+ */
+public class CacheMarshallerImpl
+    implements CacheMarshaller, Configurable {
+
+    private static final Localizer _loc =
+        Localizer.forPackage(CacheMarshallerImpl.class);
+
+    private String _id;
+    private ValidationPolicy _validationPolicy;
+    private OpenJPAConfiguration _conf;
+    private Log _log;
+    private File _outputFile;
+    private URL _inputURL;
+
+    // temporary storage for resource location specification
+    private String _inputResourceLocation;
+    
+    private boolean _consumeErrors = true;
+
+    public Object load() {
+        if (_inputURL == null) {
+            _log.trace(_loc.get("cache-marshaller-no-inputs", getId()));
+            return null;
+        }
+
+        Object o = null;
+        ObjectInputStream in = null;
+        try {
+            in = new ObjectInputStream(new BufferedInputStream(
+                _inputURL.openStream()));
+
+            o = in.readObject();
+            o = _validationPolicy.getValidData(o);
+
+            if (o != null && o.getClass().isArray()) {
+                Object[] array = (Object[]) o;
+                for (int i = 0; i < array.length; i++)
+                    configure(array[i]);
+            } else {
+                configure(o);
+            }
+
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("cache-marshaller-loaded",
+                    o == null ? null : o.getClass().getName(), _inputURL));
+        } catch (Exception e) {
+            if (_consumeErrors) {
+                if (_log.isWarnEnabled())
+                    _log.warn(_loc.get("cache-marshaller-load-exception-ignore",
+                        _inputURL), e);
+            } else {
+                throw new InternalException(
+                    _loc.get("cache-marshaller-load-exception-fatal",
+                        _inputURL),
+                    e);
+            }
+        } finally {
+            if (in != null)
+                try { in.close(); } catch (IOException e) { }
+        }
+
+        return o;
+    }
+
+    private void configure(Object o) {
+        if (o instanceof Configurable) {
+            ((Configurable) o).setConfiguration(_conf);
+            ((Configurable) o).startConfiguration();
+            ((Configurable) o).endConfiguration();
+        }
+    }
+
+    public void store(Object o) {
+        if (_outputFile == null) {
+            _log.trace(_loc.get("cache-marshaller-no-output-file", getId()));
+            return;
+        }
+        OutputStream out = null;
+        try {
+            out = new FileOutputStream(_outputFile);
+            ObjectOutputStream oos =
+                new ObjectOutputStream(new BufferedOutputStream(out));
+            Object toStore = _validationPolicy.getCacheableData(o);
+            oos.writeObject(toStore);
+            oos.flush();
+            out.flush();
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("cache-marshaller-stored",
+                    o.getClass().getName(), _outputFile));
+        } catch (Exception e) {
+            if (_consumeErrors) {
+                if (_log.isWarnEnabled())
+                    _log.warn(_loc.get("cache-marshaller-store-exception",
+                        o.getClass().getName(), _outputFile), e);
+            } else {
+                throw new InternalException(
+                    _loc.get("cache-marshaller-store-exception",
+                        o.getClass().getName(), _outputFile),
+                    e);
+            }
+        } finally {
+            if (out != null) {
+                try { out.close(); } catch (IOException ioe) { }
+            }
+        }
+    }
+
+    public void setOutputFile(File file) {
+        _outputFile = file;
+    }
+
+    public File getOutputFile() {
+        return _outputFile;
+    }
+
+    public void setInputURL(URL url) {
+        _inputURL = url;
+    }
+
+    public void setInputResource(String resource) {
+        _inputResourceLocation = resource;
+    }
+
+    public void setConsumeSerializationErrors(boolean consume) {
+        _consumeErrors = consume;
+    }
+
+    public String getId() {
+        return _id;
+    }
+
+    public void setId(String id) {
+        _id = id;
+    }
+
+    public void setValidationPolicy(String policy)
+        throws InstantiationException, IllegalAccessException {
+        String name = Configurations.getClassName(policy);
+        String props = Configurations.getProperties(policy);
+        _validationPolicy = (ValidationPolicy)
+            Configurations.newInstance(name, _conf, props, null);
+    }
+
+    public ValidationPolicy getValidationPolicy() {
+        return _validationPolicy;
+    }
+
+    public void setConfiguration(Configuration conf) {
+        _conf = (OpenJPAConfiguration) conf;
+        _log = conf.getConfigurationLog();
+    }
+
+    public void startConfiguration() {
+    }
+
+    public void endConfiguration() {
+        if (_inputResourceLocation != null && _inputURL != null)
+            throw new IllegalStateException(
+                _loc.get("cache-marshaller-input-url-and-resource-specified")
+                    .getMessage());
+        if (_inputResourceLocation != null)
+            setInputUrlFromResourceLocation();
+
+        if (_validationPolicy == null)
+            throw new IllegalStateException(
+                _loc.get("cache-marshaller-null-validation-policy",
+                    getClass().getName()).getMessage());
+        if (_id == null)
+            throw new IllegalStateException(
+                _loc.get("cache-marshaller-null-id",
+                    getClass().getName()).getMessage());
+    }
+
+    private void setInputUrlFromResourceLocation() {
+        try {
+            ClassLoader cl = _conf.getClassResolverInstance()
+                .getClassLoader(getClass(), null);
+            List list = new ArrayList();
+            for (Enumeration e = cl.getResources(_inputResourceLocation);
+                e.hasMoreElements(); )
+                list.add(e);
+
+            if (list.size() > 1) {
+                if (_consumeErrors) {
+                    if (_log.isWarnEnabled())
+                        _log.warn(_loc.get(
+                            "cache-marshaller-multiple-resources-warn",
+                            getId(), _inputResourceLocation, list)
+                            .getMessage());
+                } else {
+                    throw new IllegalStateException(
+                        _loc.get("cache-marshaller-multiple-resources",
+                            getId(), _inputResourceLocation, list)
+                            .getMessage());
+                }
+            }
+
+            if (!list.isEmpty())
+                _inputURL = (URL) list.get(0);
+        } catch (IOException ioe) {
+            IllegalStateException ise = new IllegalStateException(
+                _loc.get("cache-marshaller-bad-url", getId(),
+                    _inputResourceLocation).getMessage());
+            ise.initCause(ioe);
+            throw ise;
+        }
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallersValue.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallersValue.java
index c1276f9..e0efef0 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallersValue.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/CacheMarshallersValue.java
@@ -1,121 +1,121 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.conf.PluginListValue;
-import org.apache.openjpa.conf.NoOpCacheMarshaller;
-import org.apache.openjpa.lib.conf.Configuration;
-
-/**
- * A configuration value for handling and accessing cache marshallers.
- *
- * @since 1.1.0
- */
-public class CacheMarshallersValue
-    extends PluginListValue {
-
-    private static final String KEY = "CacheMarshallers";
-    private static final CacheMarshaller NO_OP_CACHE_MARSHALLER
-        = new NoOpCacheMarshaller();
-    private static final Localizer _loc =
-        Localizer.forPackage(CacheMarshallersValue.class);
-
-    private Configuration _conf;
-    private Map _marshallers;
-    private boolean _initialized;
-
-    public CacheMarshallersValue(Configuration conf) {
-        super(KEY);
-        _conf = conf;
-        setAlias("default", CacheMarshallerImpl.class.getName());
-        setAlias("none", null);
-        setDefault("none");
-        setString("none");
-        setScope(getClass());
-    }
-
-    public Object instantiate(Class elemType, Configuration conf,
-        boolean fatal) {
-        CacheMarshaller[] ms = (CacheMarshaller[])
-            super.instantiate(elemType, conf, fatal);
-        if (ms != null) {
-            _marshallers = new HashMap();
-            for (int i = 0; i < ms.length; i++) {
-                String mid = ms[i].getId();
-                if (mid != null)
-                    _marshallers.put(mid, ms[i]);
-            }
-        } else {
-            _marshallers = null;
-        }
-        return ms;
-    }
-
-    /**
-     * Return the {@link CacheMarshaller} to use for caching metadata of id
-     * <code>id</code>. If no marshaller exists for the id, returns
-     * {@link NoOpCacheMarshaller}.
-     */
-    public CacheMarshaller getMarshallerById(String id) {
-        initialize();
-
-        CacheMarshaller cm = (CacheMarshaller) _marshallers.get(id);
-        if (cm == null) {
-            if (getLog().isTraceEnabled())
-                getLog().trace(_loc.get("cache-marshaller-not-found", id));
-            return NO_OP_CACHE_MARSHALLER;
-        } else {
-            if (getLog().isTraceEnabled())
-                getLog().trace(_loc.get("cache-marshaller-found", id,
-                    cm.getClass().getName()));
-            return cm;
-        }
-    }
-
-    private Log getLog() {
-        return _conf.getConfigurationLog();
-    }
-
-    /**
-     * Return the {@link CacheMarshaller} to use for caching metadata of id
-     * <code>id</code>. If no marshaller exists for the id, returns
-     * {@link NoOpCacheMarshaller}.
-     */
-    public static CacheMarshaller getMarshallerById(Configuration c, String id){
-        CacheMarshallersValue v =
-            ((OpenJPAConfigurationImpl) c).cacheMarshallerPlugins;
-        return v.getMarshallerById(id);
-    }
-
-    public Map getInstancesAsMap() {
-        return _marshallers;
-    }
-
-    protected synchronized void initialize() {
-        if (!_initialized) {
-            instantiate(CacheMarshaller.class, _conf);
-            _initialized = true;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.conf.PluginListValue;
+import org.apache.openjpa.conf.NoOpCacheMarshaller;
+import org.apache.openjpa.lib.conf.Configuration;
+
+/**
+ * A configuration value for handling and accessing cache marshallers.
+ *
+ * @since 1.1.0
+ */
+public class CacheMarshallersValue
+    extends PluginListValue {
+
+    private static final String KEY = "CacheMarshallers";
+    private static final CacheMarshaller NO_OP_CACHE_MARSHALLER
+        = new NoOpCacheMarshaller();
+    private static final Localizer _loc =
+        Localizer.forPackage(CacheMarshallersValue.class);
+
+    private Configuration _conf;
+    private Map _marshallers;
+    private boolean _initialized;
+
+    public CacheMarshallersValue(Configuration conf) {
+        super(KEY);
+        _conf = conf;
+        setAlias("default", CacheMarshallerImpl.class.getName());
+        setAlias("none", null);
+        setDefault("none");
+        setString("none");
+        setScope(getClass());
+    }
+
+    public Object instantiate(Class elemType, Configuration conf,
+        boolean fatal) {
+        CacheMarshaller[] ms = (CacheMarshaller[])
+            super.instantiate(elemType, conf, fatal);
+        if (ms != null) {
+            _marshallers = new HashMap();
+            for (int i = 0; i < ms.length; i++) {
+                String mid = ms[i].getId();
+                if (mid != null)
+                    _marshallers.put(mid, ms[i]);
+            }
+        } else {
+            _marshallers = null;
+        }
+        return ms;
+    }
+
+    /**
+     * Return the {@link CacheMarshaller} to use for caching metadata of id
+     * <code>id</code>. If no marshaller exists for the id, returns
+     * {@link NoOpCacheMarshaller}.
+     */
+    public CacheMarshaller getMarshallerById(String id) {
+        initialize();
+
+        CacheMarshaller cm = (CacheMarshaller) _marshallers.get(id);
+        if (cm == null) {
+            if (getLog().isTraceEnabled())
+                getLog().trace(_loc.get("cache-marshaller-not-found", id));
+            return NO_OP_CACHE_MARSHALLER;
+        } else {
+            if (getLog().isTraceEnabled())
+                getLog().trace(_loc.get("cache-marshaller-found", id,
+                    cm.getClass().getName()));
+            return cm;
+        }
+    }
+
+    private Log getLog() {
+        return _conf.getConfigurationLog();
+    }
+
+    /**
+     * Return the {@link CacheMarshaller} to use for caching metadata of id
+     * <code>id</code>. If no marshaller exists for the id, returns
+     * {@link NoOpCacheMarshaller}.
+     */
+    public static CacheMarshaller getMarshallerById(Configuration c, String id){
+        CacheMarshallersValue v =
+            ((OpenJPAConfigurationImpl) c).cacheMarshallerPlugins;
+        return v.getMarshallerById(id);
+    }
+
+    public Map getInstancesAsMap() {
+        return _marshallers;
+    }
+
+    protected synchronized void initialize() {
+        if (!_initialized) {
+            instantiate(CacheMarshaller.class, _conf);
+            _initialized = true;
+        }
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
index c054895..1ba0aef 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
@@ -55,7 +55,9 @@
     private boolean _nonOptimisticVersionCheck = false;
     private int _jpql = JPQL_WARN;
     private boolean _storeMapCollectionInEntityAsBlob = false;
-    private boolean _flushBeforeDetach = true; 
+    private boolean _flushBeforeDetach = true;
+    private boolean _reorderMetaDataResolution = false;
+    private boolean _reloadOnDetach = true;
 
     /**
      * Whether to require exact identity value types when creating object
@@ -268,5 +270,54 @@
     public void setFlushBeforeDetach(boolean beforeDetach) {
         _flushBeforeDetach = beforeDetach;
     }
+    
+    
+    /**
+     * Whether OpenJPA should reorder entities in MetaDataRepository.processBuffer() to ensure that the MetaData for 
+     * entities with foreign keys in their identity are processed after the entities they depend on.
+     * 
+     * @return true if the reordering should be performed, false if not.
+     */
+    public boolean getReorderMetaDataResolution() {
+    	return _reorderMetaDataResolution;
+    }
+    
+    /**
+     * Whether OpenJPA should reorder entities in MetaDataRepository.processBuffer() to ensure that the MetaData for 
+     * entities with foreign keys in their identity are processed after the entities they depend on.
+     * 
+     * @param reorderProcessBuffer true if the reordering should be performed, false if not.
+     */
+    public void setReorderMetaDataResolution(boolean reorderProcessBuffer) {
+        _reorderMetaDataResolution = reorderProcessBuffer;
+    }
+
+    /**
+     * Whether OpenJPA should attempt to load fields when the DetachState
+     * option is set to loaded. This also determines whether a
+     * redundant copy of the version field is made. Defaults to true.
+     * 
+     * @return the _reloadOnDetach
+     * 
+     * @since 1.2.2
+     */
+    public boolean getReloadOnDetach() {
+        return _reloadOnDetach;
+    }
+
+    /**
+     * Whether OpenJPA should attempt to load fields when the DetachState
+     * option is set to loaded. This also determines whether a
+     * redundant copy of the version field is made. Defaults to true.
+     * 
+     * @param reloadOnDetach the _reloadOnDetach to set
+     * 
+     * @since 1.2.2
+     */
+    public void setReloadOnDetach(boolean reloadOnDetach) {
+        _reloadOnDetach = reloadOnDetach;
+    }   
+
+    
 
 }
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataCacheMaintenance.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataCacheMaintenance.java
index 6762bd9..854f1a6 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataCacheMaintenance.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataCacheMaintenance.java
@@ -1,202 +1,202 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.openjpa.kernel.Bootstrap;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.conf.MapConfigurationProvider;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.meta.QueryMetaData;
-import org.apache.openjpa.meta.SequenceMetaData;
-
-/**
- * Performs maintenance tasks on the metadata caches accessible via the
- * {@link CacheMarshaller} architecture.
- *
- * @since 1.1.0
- */
-public class MetaDataCacheMaintenance {
-
-    private final BrokerFactory factory;
-    private final OpenJPAConfiguration conf;
-    private final boolean devpath;
-    private Log log;
-
-    public static void main(String[] args) {
-        Options opts = new Options();
-        args = opts.setFromCmdLine(args);
-        boolean devpath = opts.getBooleanProperty("scanDevPath", "ScanDevPath",
-            true);
-
-        ConfigurationProvider cp = new MapConfigurationProvider(opts);
-        BrokerFactory factory = Bootstrap.newBrokerFactory(cp, null);
-        try {
-            MetaDataCacheMaintenance maint = new MetaDataCacheMaintenance(
-                factory, devpath);
-
-            if (args.length != 1) {
-                usage();
-                return;
-            }
-
-            if ("store".equals(args[0]))
-                maint.store();
-            else if ("dump".equals(args[0]))
-                maint.dump();
-            else
-                usage();
-        } finally {
-            factory.close();
-        }
-    }
-
-    /**
-     * @deprecated logging is routed to the logging system now.
-     */
-    public MetaDataCacheMaintenance(BrokerFactory factory, boolean devpath,
-        boolean verbose) {
-        this(factory, devpath);
-    }
-
-    /**
-     * @param factory The {@link BrokerFactory} for which cached metadata
-     * should be built.
-     * @param devpath Whether or not to scan the development environment paths
-     * to find persistent types to store.
-     */
-    public MetaDataCacheMaintenance(BrokerFactory factory, boolean devpath) {
-        this.factory = factory;
-        this.conf = factory.getConfiguration();
-        this.devpath = devpath;
-        this.log = conf.getLog(OpenJPAConfiguration.LOG_TOOL);
-    }
-
-    public void setLog(Log log) {
-        this.log = log;
-    }
-
-    private static int usage() {
-        System.err.println("Usage: java MetaDataCacheMaintenance " +
-            "[-scanDevPath t|f] [-<openjpa.PropertyName> value] store | dump");
-        return -1;
-    }
-
-    /**
-     * The metadata repository for the factory that this instance was
-     * constructed with will be serialized, along with any query
-     * compilations etc. that have been created for the factory.
-     */
-    public void store() {
-        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
-        repos.setSourceMode(MetaDataRepository.MODE_ALL);
-        Collection types = repos.loadPersistentTypes(devpath, null);
-        for (Iterator iter = types.iterator(); iter.hasNext(); )
-            repos.getMetaData((Class) iter.next(), null, true);
-
-        loadQueries();
-
-        log.info("The following data will be stored: ");
-        log(repos, conf.getQueryCompilationCacheInstance());
-
-        CacheMarshallersValue.getMarshallerById(conf, getClass().getName())
-            .store(new Object[] {
-                repos, conf.getQueryCompilationCacheInstance()
-            });
-    }
-
-    private void loadQueries() {
-        Broker broker = factory.newBroker();
-        try {
-            QueryMetaData[] qmds =
-                conf.getMetaDataRepositoryInstance().getQueryMetaDatas();
-            for (int i = 0; i < qmds.length; i++)
-                loadQuery(broker, qmds[i]);
-        } finally {
-            broker.close();
-        }
-    }
-
-    private void loadQuery(Broker broker, QueryMetaData qmd) {
-        try {
-            Query q = broker.newQuery(qmd.getLanguage(), null);
-            qmd.setInto(q);
-            q.compile();
-        } catch (Exception e) {
-            if (log.isTraceEnabled()) {
-                log.warn("Skipping named query " + qmd.getName() + ": "
-                    + e.getMessage(), e);
-            } else {
-                log.warn("Skipping named query " + qmd.getName() + ": "
-                    + e.getMessage());
-            }
-        }
-    }
-
-    public void dump() {
-        Object[] os = (Object[])
-            CacheMarshallersValue.getMarshallerById(conf, getClass().getName())
-            .load();
-        if (os == null) {
-            log.info("No cached data was found");
-            return;
-        }
-        MetaDataRepository repos = (MetaDataRepository) os[0];
-        Map qcc = (Map) os[1];
-
-        log.info("The following data was found: ");
-        log(repos, qcc);
-    }
-
-    private void log(MetaDataRepository repos, Map qcc) {
-        ClassMetaData[] metas = repos.getMetaDatas();
-        log.info("  Types: " + metas.length);
-        if (log.isTraceEnabled())
-            for (int i = 0; i < metas.length; i++)
-                log.trace("    " + metas[i].getDescribedType().getName());
-
-        QueryMetaData[] qmds = repos.getQueryMetaDatas();
-        log.info("  Queries: " + qmds.length);
-        if (log.isTraceEnabled())
-            for (int i = 0; i < qmds.length; i++)
-                log.trace("    " + qmds[i].getName() + ": "
-                    + qmds[i].getQueryString());
-
-        SequenceMetaData[] smds = repos.getSequenceMetaDatas();
-        log.info("  Sequences: " + smds.length);
-        if (log.isTraceEnabled())
-            for (int i = 0; i < smds.length; i++)
-                log.trace("    " + smds[i].getName());
-
-        log.info("  Compiled queries: "
-            + (qcc == null ? "0" : "" + qcc.size()));
-        if (log.isTraceEnabled() && qcc != null)
-            for (Iterator iter = qcc.keySet().iterator(); iter.hasNext(); )
-                log.trace("    " + iter.next());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.openjpa.kernel.Bootstrap;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.conf.MapConfigurationProvider;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.QueryMetaData;
+import org.apache.openjpa.meta.SequenceMetaData;
+
+/**
+ * Performs maintenance tasks on the metadata caches accessible via the
+ * {@link CacheMarshaller} architecture.
+ *
+ * @since 1.1.0
+ */
+public class MetaDataCacheMaintenance {
+
+    private final BrokerFactory factory;
+    private final OpenJPAConfiguration conf;
+    private final boolean devpath;
+    private Log log;
+
+    public static void main(String[] args) {
+        Options opts = new Options();
+        args = opts.setFromCmdLine(args);
+        boolean devpath = opts.getBooleanProperty("scanDevPath", "ScanDevPath",
+            true);
+
+        ConfigurationProvider cp = new MapConfigurationProvider(opts);
+        BrokerFactory factory = Bootstrap.newBrokerFactory(cp, null);
+        try {
+            MetaDataCacheMaintenance maint = new MetaDataCacheMaintenance(
+                factory, devpath);
+
+            if (args.length != 1) {
+                usage();
+                return;
+            }
+
+            if ("store".equals(args[0]))
+                maint.store();
+            else if ("dump".equals(args[0]))
+                maint.dump();
+            else
+                usage();
+        } finally {
+            factory.close();
+        }
+    }
+
+    /**
+     * @deprecated logging is routed to the logging system now.
+     */
+    public MetaDataCacheMaintenance(BrokerFactory factory, boolean devpath,
+        boolean verbose) {
+        this(factory, devpath);
+    }
+
+    /**
+     * @param factory The {@link BrokerFactory} for which cached metadata
+     * should be built.
+     * @param devpath Whether or not to scan the development environment paths
+     * to find persistent types to store.
+     */
+    public MetaDataCacheMaintenance(BrokerFactory factory, boolean devpath) {
+        this.factory = factory;
+        this.conf = factory.getConfiguration();
+        this.devpath = devpath;
+        this.log = conf.getLog(OpenJPAConfiguration.LOG_TOOL);
+    }
+
+    public void setLog(Log log) {
+        this.log = log;
+    }
+
+    private static int usage() {
+        System.err.println("Usage: java MetaDataCacheMaintenance " +
+            "[-scanDevPath t|f] [-<openjpa.PropertyName> value] store | dump");
+        return -1;
+    }
+
+    /**
+     * The metadata repository for the factory that this instance was
+     * constructed with will be serialized, along with any query
+     * compilations etc. that have been created for the factory.
+     */
+    public void store() {
+        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
+        repos.setSourceMode(MetaDataRepository.MODE_ALL);
+        Collection types = repos.loadPersistentTypes(devpath, null);
+        for (Iterator iter = types.iterator(); iter.hasNext(); )
+            repos.getMetaData((Class) iter.next(), null, true);
+
+        loadQueries();
+
+        log.info("The following data will be stored: ");
+        log(repos, conf.getQueryCompilationCacheInstance());
+
+        CacheMarshallersValue.getMarshallerById(conf, getClass().getName())
+            .store(new Object[] {
+                repos, conf.getQueryCompilationCacheInstance()
+            });
+    }
+
+    private void loadQueries() {
+        Broker broker = factory.newBroker();
+        try {
+            QueryMetaData[] qmds =
+                conf.getMetaDataRepositoryInstance().getQueryMetaDatas();
+            for (int i = 0; i < qmds.length; i++)
+                loadQuery(broker, qmds[i]);
+        } finally {
+            broker.close();
+        }
+    }
+
+    private void loadQuery(Broker broker, QueryMetaData qmd) {
+        try {
+            Query q = broker.newQuery(qmd.getLanguage(), null);
+            qmd.setInto(q);
+            q.compile();
+        } catch (Exception e) {
+            if (log.isTraceEnabled()) {
+                log.warn("Skipping named query " + qmd.getName() + ": "
+                    + e.getMessage(), e);
+            } else {
+                log.warn("Skipping named query " + qmd.getName() + ": "
+                    + e.getMessage());
+            }
+        }
+    }
+
+    public void dump() {
+        Object[] os = (Object[])
+            CacheMarshallersValue.getMarshallerById(conf, getClass().getName())
+            .load();
+        if (os == null) {
+            log.info("No cached data was found");
+            return;
+        }
+        MetaDataRepository repos = (MetaDataRepository) os[0];
+        Map qcc = (Map) os[1];
+
+        log.info("The following data was found: ");
+        log(repos, qcc);
+    }
+
+    private void log(MetaDataRepository repos, Map qcc) {
+        ClassMetaData[] metas = repos.getMetaDatas();
+        log.info("  Types: " + metas.length);
+        if (log.isTraceEnabled())
+            for (int i = 0; i < metas.length; i++)
+                log.trace("    " + metas[i].getDescribedType().getName());
+
+        QueryMetaData[] qmds = repos.getQueryMetaDatas();
+        log.info("  Queries: " + qmds.length);
+        if (log.isTraceEnabled())
+            for (int i = 0; i < qmds.length; i++)
+                log.trace("    " + qmds[i].getName() + ": "
+                    + qmds[i].getQueryString());
+
+        SequenceMetaData[] smds = repos.getSequenceMetaDatas();
+        log.info("  Sequences: " + smds.length);
+        if (log.isTraceEnabled())
+            for (int i = 0; i < smds.length; i++)
+                log.trace("    " + smds[i].getName());
+
+        log.info("  Compiled queries: "
+            + (qcc == null ? "0" : "" + qcc.size()));
+        if (log.isTraceEnabled() && qcc != null)
+            for (Iterator iter = qcc.keySet().iterator(); iter.hasNext(); )
+                log.trace("    " + iter.next());
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataRepositoryValue.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataRepositoryValue.java
index 10f6a21..c027a52 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataRepositoryValue.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/MetaDataRepositoryValue.java
@@ -1,74 +1,74 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import java.util.Map;
-
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.PluginValue;
-import org.apache.openjpa.conf.CacheMarshallersValue;
-import org.apache.openjpa.meta.MetaDataRepository;
-
-/**
- * A {@link PluginValue} that interacts with the {@link CacheMarshaller}
- * to cache the metadata repository between executions.
- *
- * @since 1.1.0
- */
-public class MetaDataRepositoryValue
-    extends PluginValue {
-
-    private static final String KEY = "MetaDataRepository";
-
-    public MetaDataRepositoryValue() {
-        super(KEY, false);
-        String[] aliases = new String[] {
-            "default",
-            MetaDataRepository.class.getName()
-        };
-        setAliases(aliases);
-        setDefault(aliases[0]);
-        setString(aliases[0]);
-    }
-
-    public Object instantiate(Class type, Configuration c, boolean fatal) {
-        MetaDataRepository repos = null;
-        OpenJPAConfiguration conf = (OpenJPAConfiguration) c;
-
-        Object[] os = (Object[]) CacheMarshallersValue.getMarshallerById(
-            conf, MetaDataCacheMaintenance.class.getName())
-            .load();
-        if (os != null) {
-            repos = (MetaDataRepository) os[0];
-            if (os[1] != null)
-                // It's a bit odd that we do this in MetaDataRepositoryValue.
-                // We need to serialize all the various bits of configuration
-                // together; maybe we can move the caching logic somewhere
-                // else?
-                conf.getQueryCompilationCacheInstance().putAll((Map) os[1]);
-        }
-
-        if (repos == null)
-            return super.instantiate(type, c, fatal);
-        else
-            return repos;
-    }
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import java.util.Map;
+
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.conf.CacheMarshallersValue;
+import org.apache.openjpa.meta.MetaDataRepository;
+
+/**
+ * A {@link PluginValue} that interacts with the {@link CacheMarshaller}
+ * to cache the metadata repository between executions.
+ *
+ * @since 1.1.0
+ */
+public class MetaDataRepositoryValue
+    extends PluginValue {
+
+    private static final String KEY = "MetaDataRepository";
+
+    public MetaDataRepositoryValue() {
+        super(KEY, false);
+        String[] aliases = new String[] {
+            "default",
+            MetaDataRepository.class.getName()
+        };
+        setAliases(aliases);
+        setDefault(aliases[0]);
+        setString(aliases[0]);
+    }
+
+    public Object instantiate(Class type, Configuration c, boolean fatal) {
+        MetaDataRepository repos = null;
+        OpenJPAConfiguration conf = (OpenJPAConfiguration) c;
+
+        Object[] os = (Object[]) CacheMarshallersValue.getMarshallerById(
+            conf, MetaDataCacheMaintenance.class.getName())
+            .load();
+        if (os != null) {
+            repos = (MetaDataRepository) os[0];
+            if (os[1] != null)
+                // It's a bit odd that we do this in MetaDataRepositoryValue.
+                // We need to serialize all the various bits of configuration
+                // together; maybe we can move the caching logic somewhere
+                // else?
+                conf.getQueryCompilationCacheInstance().putAll((Map) os[1]);
+        }
+
+        if (repos == null)
+            return super.instantiate(type, c, fatal);
+        else
+            return repos;
+    }
+
+
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/NoOpCacheMarshaller.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/NoOpCacheMarshaller.java
index af9e390..3413add 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/NoOpCacheMarshaller.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/NoOpCacheMarshaller.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-/**
- * Implementation of {@link CacheMarshaller} that does nothing.
- *
- * @since 1.1.0
- */
-public class NoOpCacheMarshaller
-    implements CacheMarshaller {
-
-    private String id;
-
-    public Object load() {
-        return null;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setValidationPolicy(String policy) {
-    }
-
-    public void store(Object o) {
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+/**
+ * Implementation of {@link CacheMarshaller} that does nothing.
+ *
+ * @since 1.1.0
+ */
+public class NoOpCacheMarshaller
+    implements CacheMarshaller {
+
+    private String id;
+
+    public Object load() {
+        return null;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setValidationPolicy(String policy) {
+    }
+
+    public void store(Object o) {
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
index 917d6c4..218ae07 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
@@ -126,7 +126,7 @@
     public BooleanValue multithreaded;
     public StringValue mapping;
     public PluginValue metaFactoryPlugin;
-    public ObjectValue metaRepositoryPlugin;
+    public MetaDataRepositoryValue metaRepositoryPlugin;
     public ObjectValue lockManagerPlugin;
     public ObjectValue inverseManagerPlugin;
     public ObjectValue savepointManagerPlugin;
@@ -303,7 +303,7 @@
         mapping = addString("Mapping");
         metaFactoryPlugin = addPlugin("MetaDataFactory", false);
 
-        metaRepositoryPlugin = (ObjectValue)
+        metaRepositoryPlugin = (MetaDataRepositoryValue)
             addValue(new MetaDataRepositoryValue());
 
         connectionFactory = addObject("ConnectionFactory");
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAProductDerivation.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAProductDerivation.java
index c0676b1..a8e5bb1 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAProductDerivation.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAProductDerivation.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.conf;
-
-import org.apache.openjpa.lib.conf.ProductDerivation;
-import java.util.Map;
-
-/**
- * Adds datastore based extension to ProductDerivation.  
- *
- * @since 0.4.1
- * @author Pinaki Poddar
- */
-public interface OpenJPAProductDerivation extends ProductDerivation {
-
-    public static final int TYPE_SPEC = 0;
-    public static final int TYPE_STORE = 200;
-    public static final int TYPE_SPEC_STORE = 300;
-    public static final int TYPE_PRODUCT_STORE = 400;
-
-    /**
-     * Load default alias options into the given map.  Each entry maps an
-     * alias to a broker factory class name.  Replace anything previously 
-     * under the desired keys.
-     */
-    public void putBrokerFactoryAliases(Map aliases);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.conf;
+
+import org.apache.openjpa.lib.conf.ProductDerivation;
+import java.util.Map;
+
+/**
+ * Adds datastore based extension to ProductDerivation.  
+ *
+ * @since 0.4.1
+ * @author Pinaki Poddar
+ */
+public interface OpenJPAProductDerivation extends ProductDerivation {
+
+    public static final int TYPE_SPEC = 0;
+    public static final int TYPE_STORE = 200;
+    public static final int TYPE_SPEC_STORE = 300;
+    public static final int TYPE_PRODUCT_STORE = 400;
+
+    /**
+     * Load default alias options into the given map.  Each entry maps an
+     * alias to a broker factory class name.  Replace anything previously 
+     * under the desired keys.
+     */
+    public void putBrokerFactoryAliases(Map aliases);
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAVersionAndConfigurationTypeValidationPolicy.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAVersionAndConfigurationTypeValidationPolicy.java
index 6cad968..df3cd84 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAVersionAndConfigurationTypeValidationPolicy.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAVersionAndConfigurationTypeValidationPolicy.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import org.apache.openjpa.conf.CacheMarshaller.ValidationPolicy;
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.conf.Configuration;
-
-/**
- * Compute validity based on whether or not the cached data is from the same
- * version of Kodo as the current install. This also checks OpenJPA version
- * information in case the OpenJPA jars were independently updated.
- *
- * @since 1.1.0
- */
-public class OpenJPAVersionAndConfigurationTypeValidationPolicy
-    implements ValidationPolicy, Configurable {
-
-    private String confClassName;
-
-    public Object getCacheableData(Object o) {
-        return new Object[] {
-            OpenJPAVersion.VERSION_ID,
-            confClassName,
-            o,
-        };
-    }
-
-    public Object getValidData(Object o) {
-        Object[] array = (Object[]) o;
-        if (array.length != 3)
-            return null;
-
-        if (OpenJPAVersion.VERSION_ID.equals(array[0])
-            && confClassName.equals(array[1]))
-            return array[2];
-        else
-            return null;
-    }
-
-    public void setConfiguration(Configuration conf) {
-        confClassName = conf.getClass().getName();
-    }
-
-    public void startConfiguration() {
-    }
-
-    public void endConfiguration() {
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import org.apache.openjpa.conf.CacheMarshaller.ValidationPolicy;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+
+/**
+ * Compute validity based on whether or not the cached data is from the same
+ * version of Kodo as the current install. This also checks OpenJPA version
+ * information in case the OpenJPA jars were independently updated.
+ *
+ * @since 1.1.0
+ */
+public class OpenJPAVersionAndConfigurationTypeValidationPolicy
+    implements ValidationPolicy, Configurable {
+
+    private String confClassName;
+
+    public Object getCacheableData(Object o) {
+        return new Object[] {
+            OpenJPAVersion.VERSION_ID,
+            confClassName,
+            o,
+        };
+    }
+
+    public Object getValidData(Object o) {
+        Object[] array = (Object[]) o;
+        if (array.length != 3)
+            return null;
+
+        if (OpenJPAVersion.VERSION_ID.equals(array[0])
+            && confClassName.equals(array[1]))
+            return array[2];
+        else
+            return null;
+    }
+
+    public void setConfiguration(Configuration conf) {
+        confClassName = conf.getClass().getName();
+    }
+
+    public void startConfiguration() {
+    }
+
+    public void endConfiguration() {
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/QueryCompilationCacheValue.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/QueryCompilationCacheValue.java
index b504a60..c7546b4 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/QueryCompilationCacheValue.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/QueryCompilationCacheValue.java
@@ -1,95 +1,95 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.conf;
-
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.PluginValue;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.openjpa.lib.util.ParseException;
-import org.apache.openjpa.util.CacheMap;
-
-/**
- * A cache of compiled queries.
- *
- * @author Abe White
- * @since 0.9.6 (also existed in prior versions of Kodo)
- * @nojavadoc
- */
-public class QueryCompilationCacheValue
-    extends PluginValue {
-
-    public static final String[] ALIASES = {
-        "true", CacheMap.class.getName(),
-        "all", ConcurrentHashMap.class.getName(),
-        "false", null,
-    };
-
-    public QueryCompilationCacheValue(String prop) {
-        super(prop, true);
-        setAliases(ALIASES);
-        setDefault(ALIASES[0]);
-        setClassName(ALIASES[1]);
-    }
-
-    public Object newInstance(String clsName, Class type,
-        Configuration conf, boolean fatal) {
-        // make sure map handles concurrency
-        Map map;
-        
-        try {
-            map = (Map) super.newInstance(clsName, type, conf, fatal);
-        } catch (ParseException pe) {
-            // OPENJPA256: this class differs from most plugins in that
-            // the plugin type is the standard java interface Map.class (rather
-            // than an openjpa-specific interface), which means that the
-            // ClassLoader used to load the implementation will be the system
-            // class loader; this presents a problem if OpenJPA is not in the
-            // system classpath, so work around the problem by catching
-            // the ParseException (which is what we wrap the
-            // ClassNotFoundException in) and try again, this time using
-            // this class' ClassLoader.
-            map = (Map) super.newInstance(clsName,
-                QueryCompilationCacheValue.class, conf, fatal);
-        } catch (IllegalArgumentException iae) {
-            // OPENJPA256: this class differs from most plugins in that
-            // the plugin type is the standard java interface Map.class (rather
-            // than an openjpa-specific interface), which means that the
-            // ClassLoader used to load the implementation will be the system
-            // class loader; this presents a problem if OpenJPA is not in the
-            // system classpath, so work around the problem by catching
-            // the IllegalArgumentException (which is what we wrap the
-            // ClassNotFoundException in) and try again, this time using
-            // this class' ClassLoader.
-            map = (Map) super.newInstance(clsName,
-                QueryCompilationCacheValue.class, conf, fatal);
-        }
-
-        if (map != null && !(map instanceof Hashtable)
-            && !(map instanceof CacheMap)
-            && !(map instanceof
-                    org.apache.openjpa.lib.util.concurrent.ConcurrentMap)
-            && !(map instanceof java.util.concurrent.ConcurrentMap))
-            map = Collections.synchronizedMap(map);
-        return map;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.conf;
+
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.PluginValue;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.openjpa.lib.util.ParseException;
+import org.apache.openjpa.util.CacheMap;
+
+/**
+ * A cache of compiled queries.
+ *
+ * @author Abe White
+ * @since 0.9.6 (also existed in prior versions of Kodo)
+ * @nojavadoc
+ */
+public class QueryCompilationCacheValue
+    extends PluginValue {
+
+    public static final String[] ALIASES = {
+        "true", CacheMap.class.getName(),
+        "all", ConcurrentHashMap.class.getName(),
+        "false", null,
+    };
+
+    public QueryCompilationCacheValue(String prop) {
+        super(prop, true);
+        setAliases(ALIASES);
+        setDefault(ALIASES[0]);
+        setClassName(ALIASES[1]);
+    }
+
+    public Object newInstance(String clsName, Class type,
+        Configuration conf, boolean fatal) {
+        // make sure map handles concurrency
+        Map map;
+        
+        try {
+            map = (Map) super.newInstance(clsName, type, conf, fatal);
+        } catch (ParseException pe) {
+            // OPENJPA256: this class differs from most plugins in that
+            // the plugin type is the standard java interface Map.class (rather
+            // than an openjpa-specific interface), which means that the
+            // ClassLoader used to load the implementation will be the system
+            // class loader; this presents a problem if OpenJPA is not in the
+            // system classpath, so work around the problem by catching
+            // the ParseException (which is what we wrap the
+            // ClassNotFoundException in) and try again, this time using
+            // this class' ClassLoader.
+            map = (Map) super.newInstance(clsName,
+                QueryCompilationCacheValue.class, conf, fatal);
+        } catch (IllegalArgumentException iae) {
+            // OPENJPA256: this class differs from most plugins in that
+            // the plugin type is the standard java interface Map.class (rather
+            // than an openjpa-specific interface), which means that the
+            // ClassLoader used to load the implementation will be the system
+            // class loader; this presents a problem if OpenJPA is not in the
+            // system classpath, so work around the problem by catching
+            // the IllegalArgumentException (which is what we wrap the
+            // ClassNotFoundException in) and try again, this time using
+            // this class' ClassLoader.
+            map = (Map) super.newInstance(clsName,
+                QueryCompilationCacheValue.class, conf, fatal);
+        }
+
+        if (map != null && !(map instanceof Hashtable)
+            && !(map instanceof CacheMap)
+            && !(map instanceof
+                    org.apache.openjpa.lib.util.concurrent.ConcurrentMap)
+            && !(map instanceof java.util.concurrent.ConcurrentMap))
+            map = Collections.synchronizedMap(map);
+        return map;
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
index 9e7c732..1627d11 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
@@ -1,455 +1,492 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.datacache;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-
-/**
- * Abstract {@link DataCache} implementation that provides various
- * statistics, logging, and timeout functionality common across cache
- * implementations.
- *
- * @author Patrick Linskey
- * @author Abe White
- */
-public abstract class AbstractDataCache
-    extends AbstractConcurrentEventManager
-    implements DataCache, Configurable {
-
-    private static final BitSet EMPTY_BITSET = new BitSet(0);
-
-    private static final Localizer s_loc =
-        Localizer.forPackage(AbstractDataCache.class);
-
-    /**
-     * The configuration set by the system.
-     */
-    protected OpenJPAConfiguration conf;
-
-    /**
-     * The log to use.
-     */
-    protected Log log;
-
-    private String _name = null;
-    private boolean _closed = false;
-    private String _schedule = null;
-
-    public String getName() {
-        return _name;
-    }
-
-    public void setName(String name) {
-        _name = name;
-    }
-
-    public String getEvictionSchedule() {
-        return _schedule;
-    }
-
-    public void setEvictionSchedule(String s) {
-        _schedule = s;
-    }
-
-    public void initialize(DataCacheManager manager) {
-        if (_schedule != null && !"".equals(_schedule)) {
-            DataCacheScheduler scheduler = manager.getDataCacheScheduler();
-            if (scheduler != null)
-                scheduler.scheduleEviction(this, _schedule);
-        }
-    }
-
-    public void commit(Collection additions, Collection newUpdates,
-        Collection existingUpdates, Collection deletes) {
-        // remove all objects in deletes list
-        removeAllInternal(deletes);
-
-        // next, add all the new additions
-        putAllInternal(additions);
-        putAllInternal(newUpdates);
-
-        // possibly add the existing updates, depending on the
-        // semantics of the cache, as dictated by recacheUpdates()
-        if (recacheUpdates())
-            putAllInternal(existingUpdates);
-
-        if (log.isTraceEnabled()) {
-            Collection addIds = new ArrayList(additions.size());
-            Collection upIds = new ArrayList(newUpdates.size());
-            Collection exIds = new ArrayList(existingUpdates.size());
-
-            for (Iterator iter = additions.iterator(); iter.hasNext();)
-                addIds.add(((DataCachePCData) iter.next()).getId());
-            for (Iterator iter = newUpdates.iterator(); iter.hasNext();)
-                upIds.add(((DataCachePCData) iter.next()).getId());
-            for (Iterator iter = existingUpdates.iterator(); iter.hasNext();)
-                exIds.add(((DataCachePCData) iter.next()).getId());
-
-            log.trace(s_loc.get("cache-commit",
-                new Object[]{ addIds, upIds, exIds, deletes }));
-        }
-    }
-
-    public boolean contains(Object key) {
-        DataCachePCData o = getInternal(key);
-        if (o != null && o.isTimedOut()) {
-            o = null;
-            removeInternal(key);
-            if (log.isTraceEnabled())
-                log.trace(s_loc.get("cache-timeout", key));
-        }
-        return o != null;
-    }
-
-    public BitSet containsAll(Collection keys) {
-        if (keys.isEmpty())
-            return EMPTY_BITSET;
-
-        BitSet set = new BitSet(keys.size());
-        int i = 0;
-        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
-            if (contains(iter.next()))
-                set.set(i);
-        return set;
-    }
-
-    public DataCachePCData get(Object key) {
-        DataCachePCData o = getInternal(key);
-        if (o != null && o.isTimedOut()) {
-            o = null;
-            removeInternal(key);
-            if (log.isTraceEnabled())
-                log.trace(s_loc.get("cache-timeout", key));
-        }
-
-        if (log.isTraceEnabled()) {
-            if (o == null)
-                log.trace(s_loc.get("cache-miss", key));
-            else
-                log.trace(s_loc.get("cache-hit", key));
-        }
-
-        return o;
-    }
-
-    public DataCachePCData put(DataCachePCData data) {
-        DataCachePCData o = putInternal(data.getId(), data);
-        if (log.isTraceEnabled())
-            log.trace(s_loc.get("cache-put", data.getId()));
-        return (o == null || o.isTimedOut()) ? null : o;
-    }
-
-    public void update(DataCachePCData data) {
-        if (recacheUpdates())
-            putInternal(data.getId(), data);
-    }
-
-    public DataCachePCData remove(Object key) {
-        DataCachePCData o = removeInternal(key);
-        if (o != null && o.isTimedOut())
-            o = null;
-        if (log.isTraceEnabled()) {
-            if (o == null)
-                log.trace(s_loc.get("cache-remove-miss", key));
-            else
-                log.trace(s_loc.get("cache-remove-hit", key));
-        }
-        return o;
-    }
-
-    public BitSet removeAll(Collection keys) {
-        if (keys.isEmpty())
-            return EMPTY_BITSET;
-
-        BitSet set = new BitSet(keys.size());
-        int i = 0;
-        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
-            if (remove(iter.next()) != null)
-                set.set(i);
-        return set;
-    }
-
-    /**
-     * Remove the objects of the given class from the cache.
-     */
-    public void removeAll(Class cls, boolean subClasses) {
-        removeAllInternal(cls, subClasses);
-    }
-
-    public boolean pin(Object key) {
-        boolean bool = pinInternal(key);
-        if (log.isTraceEnabled()) {
-            if (bool)
-                log.trace(s_loc.get("cache-pin-hit", key));
-            else
-                log.trace(s_loc.get("cache-pin-miss", key));
-        }
-        return bool;
-    }
-
-    public BitSet pinAll(Collection keys) {
-        if (keys.isEmpty())
-            return EMPTY_BITSET;
-
-        BitSet set = new BitSet(keys.size());
-        int i = 0;
-        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
-            if (pin(iter.next()))
-                set.set(i);
-        return set;
-    }
-
-    public void pinAll(Class cls, boolean subs) {
-        if (log.isWarnEnabled())
-            log.warn(s_loc.get("cache-class-pin", getName()));
-    }
-
-    public boolean unpin(Object key) {
-        boolean bool = unpinInternal(key);
-        if (log.isTraceEnabled()) {
-            if (bool)
-                log.trace(s_loc.get("cache-unpin-hit", key));
-            else
-                log.trace(s_loc.get("cache-unpin-miss", key));
-        }
-        return bool;
-    }
-
-    public BitSet unpinAll(Collection keys) {
-        if (keys.isEmpty())
-            return EMPTY_BITSET;
-
-        BitSet set = new BitSet(keys.size());
-        int i = 0;
-        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
-            if (unpin(iter.next()))
-                set.set(i);
-        return set;
-    }
-
-    public void unpinAll(Class cls, boolean subs) {
-        if (log.isWarnEnabled())
-            log.warn(s_loc.get("cache-class-unpin", getName()));
-    }
-
-    public void clear() {
-        clearInternal();
-        if (log.isTraceEnabled())
-            log.trace(s_loc.get("cache-clear", getName()));
-    }
-
-    public void close() {
-        close(true);
-    }
-
-    protected void close(boolean clear) {
-        if (!_closed) {
-            if (clear)
-                clearInternal();
-            _closed = true;
-        }
-    }
-
-    public boolean isClosed() {
-        return _closed;
-    }
-
-    public void addExpirationListener(ExpirationListener listen) {
-        addListener(listen);
-    }
-
-    public boolean removeExpirationListener(ExpirationListener listen) {
-        return removeListener(listen);
-    }
-
-    public String toString() {
-        return "[" + super.toString() + ":" + _name + "]";
-    }
-
-    /**
-     * This method is part of the {@link RemoteCommitListener} interface. If
-     * your cache subclass relies on OpenJPA for clustering support, make it
-     * implement <code>RemoteCommitListener</code>. This method will take
-     * care of invalidating entries from remote commits.
-     */
-    public void afterCommit(RemoteCommitEvent event) {
-        if (_closed)
-            return;
-
-        if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
-            removeAllTypeNamesInternal(event.getUpdatedTypeNames());
-            removeAllTypeNamesInternal(event.getDeletedTypeNames());
-        } else {
-            // drop all the committed OIDs, excepting brand
-            // new OIDs. brand new OIDs either won't be in
-            // the cache, or if they are, will be more up to date
-            removeAllInternal(event.getUpdatedObjectIds());
-            removeAllInternal(event.getDeletedObjectIds());
-        }
-    }
-
-    /**
-     * Invoke when a key is removed from this cache. Propagates the
-     * expiration event on to all expiration listeners registered
-     * with this class.
-     */
-    protected void keyRemoved(Object key, boolean expired) {
-        // Notify any expiration listeners of the expiration.
-        if (hasListeners())
-            fireEvent(new ExpirationEvent(this, key, expired));
-
-        if (expired && log.isTraceEnabled())
-            log.trace(s_loc.get("cache-expired", key));
-    }
-
-    /**
-     * Return <code>true</code> if updates to data already in the
-     * cache (either in {@link #commit} or the {@link #update})
-     * should be put back into the cache. Returns false by default.
-     */
-    protected boolean recacheUpdates() {
-        return false;
-    }
-
-    /**
-     * Return the object for the given oid.
-     */
-    protected abstract DataCachePCData getInternal(Object oid);
-
-    /**
-     * Add the given object to the cache, returning the old object under the
-     * given oid.
-     */
-    protected abstract DataCachePCData putInternal(Object oid,
-        DataCachePCData pc);
-
-    /**
-     * All all of the given objects to the cache.
-     */
-    protected void putAllInternal(Collection pcs) {
-        DataCachePCData pc;
-        for (Iterator iter = pcs.iterator(); iter.hasNext();) {
-            pc = (DataCachePCData) iter.next();
-            putInternal(pc.getId(), pc);
-        }
-    }
-
-    /**
-     * Remove the object under the given oid from the cache.
-     */
-    protected abstract DataCachePCData removeInternal(Object oid);
-
-    /**
-     * Evict objects in cache by class.
-     */
-    protected abstract void removeAllInternal(Class cls, boolean subclasses);
-
-    /**
-     * Remove all objects under the given oids from the cache.
-     */
-    protected void removeAllInternal(Collection oids) {
-        for (Iterator iter = oids.iterator(); iter.hasNext();)
-            removeInternal(iter.next());
-    }
-
-    /**
-     * Remove all objects of the given class names from the cache.
-     */
-    protected void removeAllTypeNamesInternal(Collection classNames) {
-        Collection classes = Caches.addTypesByName(conf, classNames, null);
-        if (classes == null)
-            return;
-
-        Class cls;
-        for (Iterator iter = classes.iterator(); iter.hasNext();) {
-            cls = (Class) iter.next();
-            if (log.isTraceEnabled())
-                log.trace(s_loc.get("cache-removeclass", cls.getName()));
-            removeAllInternal(cls, false);
-        }
-    }
-
-    /**
-     * Clear the cache.
-     */
-    protected abstract void clearInternal();
-
-    /**
-     * Pin an object to the cache.
-     */
-    protected abstract boolean pinInternal(Object oid);
-
-    /**
-     * Unpin an object from the cache.
-     */
-    protected abstract boolean unpinInternal(Object oid);
-
-    // ---------- Configurable implementation ----------
-
-    public void setConfiguration(Configuration conf) {
-        this.conf = (OpenJPAConfiguration) conf;
-        this.log = conf.getLog(OpenJPAConfiguration.LOG_DATACACHE);
-    }
-
-    public void startConfiguration() {
-    }
-
-    public void endConfiguration() {
-        if (_name == null)
-            setName(NAME_DEFAULT);
-    }
-
-    // ---------- AbstractEventManager implementation ----------
-
-    protected void fireEvent(Object event, Object listener) {
-        ExpirationListener listen = (ExpirationListener) listener;
-        ExpirationEvent ev = (ExpirationEvent) event;
-        try {
-            listen.onExpire(ev);
-        } catch (Exception e) {
-            if (log.isWarnEnabled())
-                log.warn(s_loc.get("exp-listener-ex"), e);
-		}
-	}
-
-    /**
-     * Returns the objects for the given key List.
-     */
-    public Map getAll(List keys) {
-        Map resultMap = new HashMap(keys.size());
-        for(int i=0; i<keys.size(); i++)
-            resultMap.put(keys.get(i), get(keys.get(i)));
-        return resultMap;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.datacache;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+
+import serp.util.Strings;
+
+/**
+ * Abstract {@link DataCache} implementation that provides various
+ * statistics, logging, and timeout functionality common across cache
+ * implementations.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ */
+public abstract class AbstractDataCache
+    extends AbstractConcurrentEventManager
+    implements DataCache, Configurable {
+
+    private static final BitSet EMPTY_BITSET = new BitSet(0);
+
+    private static final Localizer s_loc =
+        Localizer.forPackage(AbstractDataCache.class);
+
+    /**
+     * The configuration set by the system.
+     */
+    protected OpenJPAConfiguration conf;
+
+    /**
+     * The log to use.
+     */
+    protected Log log;
+
+    private String _name = null;
+    private boolean _closed = false;
+    private String _schedule = null;
+    
+    protected Set<String> _includedTypes;
+    protected Set<String> _excludedTypes;
+
+    public String getName() {
+        return _name;
+    }
+
+    public void setName(String name) {
+        _name = name;
+    }
+
+    public String getEvictionSchedule() {
+        return _schedule;
+    }
+
+    public void setEvictionSchedule(String s) {
+        _schedule = s;
+    }
+
+    public void initialize(DataCacheManager manager) {
+        if (_schedule != null && !"".equals(_schedule)) {
+            DataCacheScheduler scheduler = manager.getDataCacheScheduler();
+            if (scheduler != null)
+                scheduler.scheduleEviction(this, _schedule);
+        }
+    }
+
+    public void commit(Collection additions, Collection newUpdates,
+        Collection existingUpdates, Collection deletes) {
+        // remove all objects in deletes list
+        removeAllInternal(deletes);
+
+        // next, add all the new additions
+        putAllInternal(additions);
+        putAllInternal(newUpdates);
+
+        // possibly add the existing updates, depending on the
+        // semantics of the cache, as dictated by recacheUpdates()
+        if (recacheUpdates())
+            putAllInternal(existingUpdates);
+
+        if (log.isTraceEnabled()) {
+            Collection addIds = new ArrayList(additions.size());
+            Collection upIds = new ArrayList(newUpdates.size());
+            Collection exIds = new ArrayList(existingUpdates.size());
+
+            for (Iterator iter = additions.iterator(); iter.hasNext();)
+                addIds.add(((DataCachePCData) iter.next()).getId());
+            for (Iterator iter = newUpdates.iterator(); iter.hasNext();)
+                upIds.add(((DataCachePCData) iter.next()).getId());
+            for (Iterator iter = existingUpdates.iterator(); iter.hasNext();)
+                exIds.add(((DataCachePCData) iter.next()).getId());
+
+            log.trace(s_loc.get("cache-commit",
+                new Object[]{ addIds, upIds, exIds, deletes }));
+        }
+    }
+
+    public boolean contains(Object key) {
+        DataCachePCData o = getInternal(key);
+        if (o != null && o.isTimedOut()) {
+            o = null;
+            removeInternal(key);
+            if (log.isTraceEnabled())
+                log.trace(s_loc.get("cache-timeout", key));
+        }
+        return o != null;
+    }
+
+    public BitSet containsAll(Collection keys) {
+        if (keys.isEmpty())
+            return EMPTY_BITSET;
+
+        BitSet set = new BitSet(keys.size());
+        int i = 0;
+        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
+            if (contains(iter.next()))
+                set.set(i);
+        return set;
+    }
+
+    public DataCachePCData get(Object key) {
+        DataCachePCData o = getInternal(key);
+        if (o != null && o.isTimedOut()) {
+            o = null;
+            removeInternal(key);
+            if (log.isTraceEnabled())
+                log.trace(s_loc.get("cache-timeout", key));
+        }
+
+        if (log.isTraceEnabled()) {
+            if (o == null)
+                log.trace(s_loc.get("cache-miss", key));
+            else
+                log.trace(s_loc.get("cache-hit", key));
+        }
+
+        return o;
+    }
+
+    public DataCachePCData put(DataCachePCData data) {
+        DataCachePCData o = putInternal(data.getId(), data);
+        if (log.isTraceEnabled())
+            log.trace(s_loc.get("cache-put", data.getId()));
+        return (o == null || o.isTimedOut()) ? null : o;
+    }
+
+    public void update(DataCachePCData data) {
+        if (recacheUpdates())
+            putInternal(data.getId(), data);
+    }
+
+    public DataCachePCData remove(Object key) {
+        DataCachePCData o = removeInternal(key);
+        if (o != null && o.isTimedOut())
+            o = null;
+        if (log.isTraceEnabled()) {
+            if (o == null)
+                log.trace(s_loc.get("cache-remove-miss", key));
+            else
+                log.trace(s_loc.get("cache-remove-hit", key));
+        }
+        return o;
+    }
+
+    public BitSet removeAll(Collection keys) {
+        if (keys.isEmpty())
+            return EMPTY_BITSET;
+
+        BitSet set = new BitSet(keys.size());
+        int i = 0;
+        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
+            if (remove(iter.next()) != null)
+                set.set(i);
+        return set;
+    }
+
+    /**
+     * Remove the objects of the given class from the cache.
+     */
+    public void removeAll(Class cls, boolean subClasses) {
+        removeAllInternal(cls, subClasses);
+    }
+
+    public boolean pin(Object key) {
+        boolean bool = pinInternal(key);
+        if (log.isTraceEnabled()) {
+            if (bool)
+                log.trace(s_loc.get("cache-pin-hit", key));
+            else
+                log.trace(s_loc.get("cache-pin-miss", key));
+        }
+        return bool;
+    }
+
+    public BitSet pinAll(Collection keys) {
+        if (keys.isEmpty())
+            return EMPTY_BITSET;
+
+        BitSet set = new BitSet(keys.size());
+        int i = 0;
+        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
+            if (pin(iter.next()))
+                set.set(i);
+        return set;
+    }
+
+    public void pinAll(Class cls, boolean subs) {
+        if (log.isWarnEnabled())
+            log.warn(s_loc.get("cache-class-pin", getName()));
+    }
+
+    public boolean unpin(Object key) {
+        boolean bool = unpinInternal(key);
+        if (log.isTraceEnabled()) {
+            if (bool)
+                log.trace(s_loc.get("cache-unpin-hit", key));
+            else
+                log.trace(s_loc.get("cache-unpin-miss", key));
+        }
+        return bool;
+    }
+
+    public BitSet unpinAll(Collection keys) {
+        if (keys.isEmpty())
+            return EMPTY_BITSET;
+
+        BitSet set = new BitSet(keys.size());
+        int i = 0;
+        for (Iterator iter = keys.iterator(); iter.hasNext(); i++)
+            if (unpin(iter.next()))
+                set.set(i);
+        return set;
+    }
+
+    public void unpinAll(Class cls, boolean subs) {
+        if (log.isWarnEnabled())
+            log.warn(s_loc.get("cache-class-unpin", getName()));
+    }
+
+    public void clear() {
+        clearInternal();
+        if (log.isTraceEnabled())
+            log.trace(s_loc.get("cache-clear", getName()));
+    }
+
+    public void close() {
+        close(true);
+    }
+
+    protected void close(boolean clear) {
+        if (!_closed) {
+            if (clear)
+                clearInternal();
+            _closed = true;
+        }
+    }
+
+    public boolean isClosed() {
+        return _closed;
+    }
+
+    public void addExpirationListener(ExpirationListener listen) {
+        addListener(listen);
+    }
+
+    public boolean removeExpirationListener(ExpirationListener listen) {
+        return removeListener(listen);
+    }
+
+    public String toString() {
+        return "[" + super.toString() + ":" + _name + "]";
+    }
+
+    /**
+     * This method is part of the {@link RemoteCommitListener} interface. If
+     * your cache subclass relies on OpenJPA for clustering support, make it
+     * implement <code>RemoteCommitListener</code>. This method will take
+     * care of invalidating entries from remote commits.
+     */
+    public void afterCommit(RemoteCommitEvent event) {
+        if (_closed)
+            return;
+
+        if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
+            removeAllTypeNamesInternal(event.getUpdatedTypeNames());
+            removeAllTypeNamesInternal(event.getDeletedTypeNames());
+        } else {
+            // drop all the committed OIDs, excepting brand
+            // new OIDs. brand new OIDs either won't be in
+            // the cache, or if they are, will be more up to date
+            removeAllInternal(event.getUpdatedObjectIds());
+            removeAllInternal(event.getDeletedObjectIds());
+        }
+    }
+
+    /**
+     * Invoke when a key is removed from this cache. Propagates the
+     * expiration event on to all expiration listeners registered
+     * with this class.
+     */
+    protected void keyRemoved(Object key, boolean expired) {
+        // Notify any expiration listeners of the expiration.
+        if (hasListeners())
+            fireEvent(new ExpirationEvent(this, key, expired));
+
+        if (expired && log.isTraceEnabled())
+            log.trace(s_loc.get("cache-expired", key));
+    }
+
+    /**
+     * Return <code>true</code> if updates to data already in the
+     * cache (either in {@link #commit} or the {@link #update})
+     * should be put back into the cache. Returns false by default.
+     */
+    protected boolean recacheUpdates() {
+        return false;
+    }
+
+    /**
+     * Return the object for the given oid.
+     */
+    protected abstract DataCachePCData getInternal(Object oid);
+
+    /**
+     * Add the given object to the cache, returning the old object under the
+     * given oid.
+     */
+    protected abstract DataCachePCData putInternal(Object oid,
+        DataCachePCData pc);
+
+    /**
+     * All all of the given objects to the cache.
+     */
+    protected void putAllInternal(Collection pcs) {
+        DataCachePCData pc;
+        for (Iterator iter = pcs.iterator(); iter.hasNext();) {
+            pc = (DataCachePCData) iter.next();
+            putInternal(pc.getId(), pc);
+        }
+    }
+
+    /**
+     * Remove the object under the given oid from the cache.
+     */
+    protected abstract DataCachePCData removeInternal(Object oid);
+
+    /**
+     * Evict objects in cache by class.
+     */
+    protected abstract void removeAllInternal(Class cls, boolean subclasses);
+
+    /**
+     * Remove all objects under the given oids from the cache.
+     */
+    protected void removeAllInternal(Collection oids) {
+        for (Iterator iter = oids.iterator(); iter.hasNext();)
+            removeInternal(iter.next());
+    }
+
+    /**
+     * Remove all objects of the given class names from the cache.
+     */
+    protected void removeAllTypeNamesInternal(Collection classNames) {
+        Collection classes = Caches.addTypesByName(conf, classNames, null);
+        if (classes == null)
+            return;
+
+        Class cls;
+        for (Iterator iter = classes.iterator(); iter.hasNext();) {
+            cls = (Class) iter.next();
+            if (log.isTraceEnabled())
+                log.trace(s_loc.get("cache-removeclass", cls.getName()));
+            removeAllInternal(cls, false);
+        }
+    }
+
+    /**
+     * Clear the cache.
+     */
+    protected abstract void clearInternal();
+
+    /**
+     * Pin an object to the cache.
+     */
+    protected abstract boolean pinInternal(Object oid);
+
+    /**
+     * Unpin an object from the cache.
+     */
+    protected abstract boolean unpinInternal(Object oid);
+
+    // ---------- Configurable implementation ----------
+
+    public void setConfiguration(Configuration conf) {
+        this.conf = (OpenJPAConfiguration) conf;
+        this.log = conf.getLog(OpenJPAConfiguration.LOG_DATACACHE);
+    }
+
+    public void startConfiguration() {
+    }
+
+    public void endConfiguration() {
+        if (_name == null)
+            setName(NAME_DEFAULT);
+    }
+
+    // ---------- AbstractEventManager implementation ----------
+
+    protected void fireEvent(Object event, Object listener) {
+        ExpirationListener listen = (ExpirationListener) listener;
+        ExpirationEvent ev = (ExpirationEvent) event;
+        try {
+            listen.onExpire(ev);
+        } catch (Exception e) {
+            if (log.isWarnEnabled())
+                log.warn(s_loc.get("exp-listener-ex"), e);
+		}
+	}
+
+    /**
+     * Returns the objects for the given key List.
+     */
+    public Map getAll(List keys) {
+        Map resultMap = new HashMap(keys.size());
+        for(int i=0; i<keys.size(); i++)
+            resultMap.put(keys.get(i), get(keys.get(i)));
+        return resultMap;
+    }
+    
+    public Set<String> getTypes() {
+        return _includedTypes;
+    }
+    
+    public Set<String> getExcludedTypes() {
+        return _excludedTypes;
+    }
+
+    public void setTypes(Set<String> types) {
+        _includedTypes = types;
+    }
+
+    public void setTypes(String types) {
+        _includedTypes =
+            StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays
+                .asList(Strings.split(types, ";", 0)));
+    }
+
+    public void setExcludedTypes(Set<String> types) {
+        _excludedTypes = types;
+    }
+
+    public void setExcludedTypes(String types) {
+        _excludedTypes =
+            StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays
+                .asList(Strings.split(types, ";", 0)));
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
index 6adbd8b..7a6beb9 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
@@ -1,322 +1,322 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.datacache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.Id;
-
-/**
- * Abstract {@link QueryCache} implementation that provides various
- * statistics, logging, and timeout functionality common across cache
- * implementations.
- *
- * @author Patrick Linskey
- * @author Abe White
- */
-public abstract class AbstractQueryCache
-    extends AbstractConcurrentEventManager 
-    implements QueryCache, Configurable {
-
-    private static final Localizer s_loc =
-        Localizer.forPackage(AbstractQueryCache.class);
-
-    /**
-     * The configuration set by the system.
-     */
-    protected OpenJPAConfiguration conf;
-
-    /**
-     * The log to use.
-     */
-    protected Log log;
-
-    private boolean _closed = false;
-
-    public void initialize(DataCacheManager manager) {
-    }
-
-    public void onTypesChanged(TypesChangedEvent ev) {
-        writeLock();
-        Collection keys = null;
-        try {
-            if (hasListeners())
-                fireEvent(ev);
-            keys = keySet();
-        } finally {
-            writeUnlock();
-        }
-
-        QueryKey qk;
-        List removes = null;
-        for (Iterator iter = keys.iterator(); iter.hasNext();) {
-            qk = (QueryKey) iter.next();
-            if (qk.changeInvalidatesQuery(ev.getTypes())) {
-                if (removes == null)
-                    removes = new ArrayList();
-                removes.add(qk);
-            }
-        }
-        if (removes != null)
-            removeAllInternal(removes);
-    }
-
-    public QueryResult get(QueryKey key) {
-        QueryResult o = getInternal(key);
-        if (o != null && o.isTimedOut()) {
-            o = null;
-            removeInternal(key);
-            if (log.isTraceEnabled())
-                log.trace(s_loc.get("cache-timeout", key));
-        }
-
-        if (log.isTraceEnabled()) {
-            if (o == null)
-                log.trace(s_loc.get("cache-miss", key));
-            else
-                log.trace(s_loc.get("cache-hit", key));
-        }
-        return o;
-    }
-
-    public QueryResult put(QueryKey qk, QueryResult oids) {
-        QueryResult o = putInternal(qk, oids);
-        if (log.isTraceEnabled())
-            log.trace(s_loc.get("cache-put", qk));
-        return (o == null || o.isTimedOut()) ? null : o;
-    }
-
-    public QueryResult remove(QueryKey key) {
-        QueryResult o = removeInternal(key);
-        if (o != null && o.isTimedOut())
-            o = null;
-        if (log.isTraceEnabled()) {
-            if (o == null)
-                log.trace(s_loc.get("cache-remove-miss", key));
-            else
-                log.trace(s_loc.get("cache-remove-hit", key));
-        }
-        return o;
-    }
-
-    public boolean pin(QueryKey key) {
-        boolean bool = pinInternal(key);
-        if (log.isTraceEnabled()) {
-            if (bool)
-                log.trace(s_loc.get("cache-pin-hit", key));
-            else
-                log.trace(s_loc.get("cache-pin-miss", key));
-        }
-        return bool;
-    }
-
-    public boolean unpin(QueryKey key) {
-        boolean bool = unpinInternal(key);
-        if (log.isTraceEnabled()) {
-            if (bool)
-                log.trace(s_loc.get("cache-unpin-hit", key));
-            else
-                log.trace(s_loc.get("cache-unpin-miss", key));
-        }
-        return bool;
-    }
-
-    public void clear() {
-        clearInternal();
-        if (log.isTraceEnabled())
-            log.trace(s_loc.get("cache-clear", "<query-cache>"));
-    }
-
-    public void close() {
-        close(true);
-    }
-
-    protected void close(boolean clear) {
-        if (!_closed) {
-            if (clear)
-                clearInternal();
-            _closed = true;
-        }
-    }
-
-    public boolean isClosed() {
-        return _closed;
-    }
-
-    public void addTypesChangedListener(TypesChangedListener listen) {
-        addListener(listen);
-    }
-
-    public boolean removeTypesChangedListener(TypesChangedListener listen) {
-        return removeListener(listen);
-    }
-
-    /**
-     * This method is part of the {@link RemoteCommitListener} interface. If
-     * your cache subclass relies on OpenJPA for clustering support, make it
-     * implement <code>RemoteCommitListener</code>. This method will take
-     * care of invalidating entries from remote commits, by delegating to
-     * {@link #onTypesChanged}.
-     */
-    public void afterCommit(RemoteCommitEvent event) {
-        if (_closed)
-            return;
-
-        // drop all committed classes
-        Set classes = Caches.addTypesByName(conf,
-            event.getPersistedTypeNames(), null);
-        if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
-            classes = Caches.addTypesByName(conf, event.getUpdatedTypeNames(),
-                classes);
-            classes = Caches.addTypesByName(conf, event.getDeletedTypeNames(),
-                classes);
-        } else {
-            classes = addTypes(event.getUpdatedObjectIds(), classes);
-            classes = addTypes(event.getDeletedObjectIds(), classes);
-        }
-        if (classes != null)
-            onTypesChanged(new TypesChangedEvent(this, classes));
-    }
-
-    /**
-     * Build up a set of classes for the given oids.
-     */
-    private Set addTypes(Collection oids, Set classes) {
-        if (oids.isEmpty())
-            return classes;
-        if (classes == null)
-            classes = new HashSet();
-
-        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
-        ClassMetaData meta;
-        Object oid;
-        for (Iterator itr = oids.iterator(); itr.hasNext();) {
-            oid = itr.next();
-            if (oid instanceof Id)
-                classes.add(((Id) oid).getType());
-            else {
-                // ok if no metadata for oid; that just means the pc type
-                // probably hasn't been loaded into this JVM yet, and therefore
-                // there's no chance that it's in the cache anyway
-                meta = repos.getMetaData(oid, null, false);
-                if (meta != null)
-                    classes.add(meta.getDescribedType());
-            }
-        }
-        return classes;
-    }
-
-    /**
-     * Return a threadsafe view of the keys in this cache. This collection
-     * must be iterable without risk of concurrent modification exceptions.
-     * It does not have to implement contains() efficiently or use set
-     * semantics.
-     */
-    protected abstract Collection keySet();
-
-    /**
-     * Return the list for the given key.
-     */
-    protected abstract QueryResult getInternal(QueryKey qk);
-
-    /**
-     * Add the given result to the cache, returning the old result under the
-     * given key.
-     */
-    protected abstract QueryResult putInternal(QueryKey qk, QueryResult oids);
-
-    /**
-     * Remove the result under the given key from the cache.
-     */
-    protected abstract QueryResult removeInternal(QueryKey qk);
-
-    /**
-     * Remove all results under the given keys from the cache.
-     */
-    protected void removeAllInternal(Collection qks) {
-        for (Iterator iter = qks.iterator(); iter.hasNext();)
-            removeInternal((QueryKey) iter.next());
-    }
-
-    /**
-     * Clear the cache.
-     */
-    protected abstract void clearInternal();
-
-    /**
-     * Pin an object to the cache.
-     */
-    protected abstract boolean pinInternal(QueryKey qk);
-
-    /**
-     * Unpin an object from the cache.
-     */
-    protected abstract boolean unpinInternal(QueryKey qk);
-
-    // ---------- Configurable implementation ----------
-
-    public void setConfiguration(Configuration conf) {
-        this.conf = (OpenJPAConfiguration) conf;
-        this.log = conf.getLog(OpenJPAConfiguration.LOG_DATACACHE);
-    }
-
-    public void startConfiguration() {
-    }
-
-    public void endConfiguration() {
-    }
-
-    // ---------- AbstractEventManager implementation ----------
-
-    protected void fireEvent(Object event, Object listener) {
-        TypesChangedListener listen = (TypesChangedListener) listener;
-        TypesChangedEvent ev = (TypesChangedEvent) event;
-        try {
-            listen.onTypesChanged(ev);
-        } catch (Exception e) {
-            if (log.isWarnEnabled())
-                log.warn(s_loc.get("exp-listener-ex"), e);
-        }
-    }
-
-    /**
-     * Individual query results will be registered as types changed
-     * listeners. We want such query results to be gc'd once
-     * the only reference is held by the list of expiration listeners.
-     */
-    protected Collection newListenerCollection() {
-        return new ConcurrentReferenceHashSet (ConcurrentReferenceHashSet.WEAK);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.datacache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.Id;
+
+/**
+ * Abstract {@link QueryCache} implementation that provides various
+ * statistics, logging, and timeout functionality common across cache
+ * implementations.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ */
+public abstract class AbstractQueryCache
+    extends AbstractConcurrentEventManager 
+    implements QueryCache, Configurable {
+
+    private static final Localizer s_loc =
+        Localizer.forPackage(AbstractQueryCache.class);
+
+    /**
+     * The configuration set by the system.
+     */
+    protected OpenJPAConfiguration conf;
+
+    /**
+     * The log to use.
+     */
+    protected Log log;
+
+    private boolean _closed = false;
+
+    public void initialize(DataCacheManager manager) {
+    }
+
+    public void onTypesChanged(TypesChangedEvent ev) {
+        writeLock();
+        Collection keys = null;
+        try {
+            if (hasListeners())
+                fireEvent(ev);
+            keys = keySet();
+        } finally {
+            writeUnlock();
+        }
+
+        QueryKey qk;
+        List removes = null;
+        for (Iterator iter = keys.iterator(); iter.hasNext();) {
+            qk = (QueryKey) iter.next();
+            if (qk.changeInvalidatesQuery(ev.getTypes())) {
+                if (removes == null)
+                    removes = new ArrayList();
+                removes.add(qk);
+            }
+        }
+        if (removes != null)
+            removeAllInternal(removes);
+    }
+
+    public QueryResult get(QueryKey key) {
+        QueryResult o = getInternal(key);
+        if (o != null && o.isTimedOut()) {
+            o = null;
+            removeInternal(key);
+            if (log.isTraceEnabled())
+                log.trace(s_loc.get("cache-timeout", key));
+        }
+
+        if (log.isTraceEnabled()) {
+            if (o == null)
+                log.trace(s_loc.get("cache-miss", key));
+            else
+                log.trace(s_loc.get("cache-hit", key));
+        }
+        return o;
+    }
+
+    public QueryResult put(QueryKey qk, QueryResult oids) {
+        QueryResult o = putInternal(qk, oids);
+        if (log.isTraceEnabled())
+            log.trace(s_loc.get("cache-put", qk));
+        return (o == null || o.isTimedOut()) ? null : o;
+    }
+
+    public QueryResult remove(QueryKey key) {
+        QueryResult o = removeInternal(key);
+        if (o != null && o.isTimedOut())
+            o = null;
+        if (log.isTraceEnabled()) {
+            if (o == null)
+                log.trace(s_loc.get("cache-remove-miss", key));
+            else
+                log.trace(s_loc.get("cache-remove-hit", key));
+        }
+        return o;
+    }
+
+    public boolean pin(QueryKey key) {
+        boolean bool = pinInternal(key);
+        if (log.isTraceEnabled()) {
+            if (bool)
+                log.trace(s_loc.get("cache-pin-hit", key));
+            else
+                log.trace(s_loc.get("cache-pin-miss", key));
+        }
+        return bool;
+    }
+
+    public boolean unpin(QueryKey key) {
+        boolean bool = unpinInternal(key);
+        if (log.isTraceEnabled()) {
+            if (bool)
+                log.trace(s_loc.get("cache-unpin-hit", key));
+            else
+                log.trace(s_loc.get("cache-unpin-miss", key));
+        }
+        return bool;
+    }
+
+    public void clear() {
+        clearInternal();
+        if (log.isTraceEnabled())
+            log.trace(s_loc.get("cache-clear", "<query-cache>"));
+    }
+
+    public void close() {
+        close(true);
+    }
+
+    protected void close(boolean clear) {
+        if (!_closed) {
+            if (clear)
+                clearInternal();
+            _closed = true;
+        }
+    }
+
+    public boolean isClosed() {
+        return _closed;
+    }
+
+    public void addTypesChangedListener(TypesChangedListener listen) {
+        addListener(listen);
+    }
+
+    public boolean removeTypesChangedListener(TypesChangedListener listen) {
+        return removeListener(listen);
+    }
+
+    /**
+     * This method is part of the {@link RemoteCommitListener} interface. If
+     * your cache subclass relies on OpenJPA for clustering support, make it
+     * implement <code>RemoteCommitListener</code>. This method will take
+     * care of invalidating entries from remote commits, by delegating to
+     * {@link #onTypesChanged}.
+     */
+    public void afterCommit(RemoteCommitEvent event) {
+        if (_closed)
+            return;
+
+        // drop all committed classes
+        Set classes = Caches.addTypesByName(conf,
+            event.getPersistedTypeNames(), null);
+        if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
+            classes = Caches.addTypesByName(conf, event.getUpdatedTypeNames(),
+                classes);
+            classes = Caches.addTypesByName(conf, event.getDeletedTypeNames(),
+                classes);
+        } else {
+            classes = addTypes(event.getUpdatedObjectIds(), classes);
+            classes = addTypes(event.getDeletedObjectIds(), classes);
+        }
+        if (classes != null)
+            onTypesChanged(new TypesChangedEvent(this, classes));
+    }
+
+    /**
+     * Build up a set of classes for the given oids.
+     */
+    private Set addTypes(Collection oids, Set classes) {
+        if (oids.isEmpty())
+            return classes;
+        if (classes == null)
+            classes = new HashSet();
+
+        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
+        ClassMetaData meta;
+        Object oid;
+        for (Iterator itr = oids.iterator(); itr.hasNext();) {
+            oid = itr.next();
+            if (oid instanceof Id)
+                classes.add(((Id) oid).getType());
+            else {
+                // ok if no metadata for oid; that just means the pc type
+                // probably hasn't been loaded into this JVM yet, and therefore
+                // there's no chance that it's in the cache anyway
+                meta = repos.getMetaData(oid, null, false);
+                if (meta != null)
+                    classes.add(meta.getDescribedType());
+            }
+        }
+        return classes;
+    }
+
+    /**
+     * Return a threadsafe view of the keys in this cache. This collection
+     * must be iterable without risk of concurrent modification exceptions.
+     * It does not have to implement contains() efficiently or use set
+     * semantics.
+     */
+    protected abstract Collection keySet();
+
+    /**
+     * Return the list for the given key.
+     */
+    protected abstract QueryResult getInternal(QueryKey qk);
+
+    /**
+     * Add the given result to the cache, returning the old result under the
+     * given key.
+     */
+    protected abstract QueryResult putInternal(QueryKey qk, QueryResult oids);
+
+    /**
+     * Remove the result under the given key from the cache.
+     */
+    protected abstract QueryResult removeInternal(QueryKey qk);
+
+    /**
+     * Remove all results under the given keys from the cache.
+     */
+    protected void removeAllInternal(Collection qks) {
+        for (Iterator iter = qks.iterator(); iter.hasNext();)
+            removeInternal((QueryKey) iter.next());
+    }
+
+    /**
+     * Clear the cache.
+     */
+    protected abstract void clearInternal();
+
+    /**
+     * Pin an object to the cache.
+     */
+    protected abstract boolean pinInternal(QueryKey qk);
+
+    /**
+     * Unpin an object from the cache.
+     */
+    protected abstract boolean unpinInternal(QueryKey qk);
+
+    // ---------- Configurable implementation ----------
+
+    public void setConfiguration(Configuration conf) {
+        this.conf = (OpenJPAConfiguration) conf;
+        this.log = conf.getLog(OpenJPAConfiguration.LOG_DATACACHE);
+    }
+
+    public void startConfiguration() {
+    }
+
+    public void endConfiguration() {
+    }
+
+    // ---------- AbstractEventManager implementation ----------
+
+    protected void fireEvent(Object event, Object listener) {
+        TypesChangedListener listen = (TypesChangedListener) listener;
+        TypesChangedEvent ev = (TypesChangedEvent) event;
+        try {
+            listen.onTypesChanged(ev);
+        } catch (Exception e) {
+            if (log.isWarnEnabled())
+                log.warn(s_loc.get("exp-listener-ex"), e);
+        }
+    }
+
+    /**
+     * Individual query results will be registered as types changed
+     * listeners. We want such query results to be gc'd once
+     * the only reference is held by the list of expiration listeners.
+     */
+    protected Collection newListenerCollection() {
+        return new ConcurrentReferenceHashSet (ConcurrentReferenceHashSet.WEAK);
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java
index 6224fe8..28e7e21 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheScheduler.java
@@ -1,248 +1,248 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.datacache;
-
-import java.security.AccessController;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.openjpa.util.InvalidStateException;
-import org.apache.openjpa.util.UserException;
-import serp.util.Strings;
-
-/**
- * Cron-style cache eviction. Understands schedules based on cron format:
- * <code>minute hour mday month wday</code>
- * For example:
- * <code>15,30 6,19 2,10 1 2 </code>
- * Would run at 15 and 30 past the 6AM and 7PM, on the 2nd and 10th
- * of January when its a Monday.
- *
- * @author Steve Kim
- */
-public class DataCacheScheduler
-    implements Runnable {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (DataCacheScheduler.class);
-
-    private Map _caches = new ConcurrentHashMap();
-    private boolean _stop = false;
-    private int _interval = 2;
-    private Log _log;
-    private Thread _thread;
-
-    public DataCacheScheduler(OpenJPAConfiguration conf) {
-        _log = conf.getLogFactory().getLog(OpenJPAConfiguration.LOG_DATACACHE);
-    }
-
-    /**
-     * The interval time in minutes between cache checks. Defaults to 2.
-     */
-    public int getInterval() {
-        return _interval;
-    }
-
-    /**
-     * The interval time in minutes between cache checks. Defaults to 2.
-     */
-    public void setInterval(int interval) {
-        _interval = interval;
-    }
-
-    /**
-     * Stop the associated thread if there and stop the current runnable.
-     */
-    public synchronized void stop() {
-        _stop = true;
-    }
-
-    private boolean isStopped() {
-        return _stop;
-    }
-
-    /**
-     * Schedule the given cache for eviction. Starts the scheduling thread
-     * if not started.
-     */
-    public synchronized void scheduleEviction(DataCache cache, String times) {
-        if (times == null)
-            return;
-
-        Schedule schedule = new Schedule(times);
-        _caches.put(cache, schedule);
-        _stop = false;
-        if (_thread == null) {
-            _thread = (Thread) AccessController.doPrivileged(J2DoPrivHelper
-                .newDaemonThreadAction(this, _loc.get("scheduler-name")
-                    .getMessage()));
-            _thread.start();
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("scheduler-start", _thread.getName()));
-        }
-    }
-
-    /**
-     * Remove the given cache from scheduling.
-     */
-    public synchronized void removeFromSchedule(DataCache cache) {
-        _caches.remove(cache);
-        if (_caches.size() == 0)
-            stop();
-    }
-
-    public void run() {
-        if (_log.isTraceEnabled())
-            _log.trace(_loc.get("scheduler-interval", _interval + ""));
-
-        Date lastRun = new Date();
-        DateFormat fom = new SimpleDateFormat("E HH:mm:ss");
-        while (!isStopped()) {
-            try {
-                Thread.sleep(_interval * 60 * 1000);
-
-                Date now = new Date();
-                DataCache cache;
-                Schedule schedule;
-                Map.Entry entry;
-                for (Iterator i = _caches.entrySet().iterator(); i.hasNext();) {
-                    entry = (Map.Entry) i.next();
-                    cache = (DataCache) entry.getKey();
-                    schedule = (Schedule) entry.getValue();
-                    if (schedule.matches(lastRun, now)) {
-                        if (_log.isTraceEnabled())
-                            _log.trace(_loc.get("scheduler-clear",
-                                cache.getName(), fom.format(now)));
-                        evict(cache);
-                    }
-                }
-                lastRun = now;
-            } catch (Exception e) {
-                throw new InvalidStateException(_loc.get("scheduler-fail"), e).
-                    setFatal(true);
-            }
-        }
-
-        _log.info(_loc.get("scheduler-stop"));
-        synchronized (this) {
-            if (isStopped())
-                _thread = null; // be sure to deref the thread so it can restart
-        }
-    }
-
-    protected void evict(DataCache cache) {
-        cache.clear();
-    }
-
-    /**
-     * Simple class which represents the given time schedule.
-     */
-    private static class Schedule {
-
-        static final int[] WILDCARD = new int[0];
-        static final int[] UNITS = {
-            Calendar.MONTH,
-            Calendar.DAY_OF_MONTH,
-            Calendar.DAY_OF_WEEK,
-            Calendar.HOUR_OF_DAY,
-            Calendar.MINUTE
-        };
-        final int[] month;
-        final int[] dayOfMonth;
-        final int[] dayOfWeek;
-        final int[] hour;
-        final int[] min;
-
-        public Schedule(String date) {
-            StringTokenizer token = new StringTokenizer(date, " \t");
-            if (token.countTokens() != 5)
-                throw new UserException(_loc.get("bad-count", date)).
-                    setFatal(true);
-            try {
-                min = parse(token.nextToken(), 0, 60);
-                hour = parse(token.nextToken(), 0, 24);
-                dayOfMonth = parse(token.nextToken(), 1, 31);
-                month = parse(token.nextToken(), 1, 13);
-                dayOfWeek = parse(token.nextToken(), 1, 8);
-            } catch (Throwable t) {
-                throw new UserException(_loc.get("bad-schedule", date), t).
-                    setFatal(true);
-            }
-        }
-
-        private int[] parse(String token, int min, int max) {
-            if ("*".equals(token.trim()))
-                return WILDCARD;
-            String[] tokens = Strings.split(token, ",", 0);
-            int [] times = new int[tokens.length];
-            for (int i = 0; i < tokens.length; i++) {
-                try {
-                    times[i] = Integer.parseInt(tokens[i]);
-                } catch (Throwable t) {
-                    throw new UserException(_loc.get("not-number", token)).
-                        setFatal(true);
-                }
-                if (times[i] < min || times[i] >= max)
-                    throw new UserException(_loc.get("not-range", token,
-                        String.valueOf(min), String.valueOf(max))).
-                        setFatal(true);
-            }
-            return times;
-        }
-
-        boolean matches(Date last, Date now) {
-            Calendar time = Calendar.getInstance();
-            time.setTime(now);
-            time.set(Calendar.SECOND, 0);
-            time.set(Calendar.MILLISECOND, 0);
-
-            int[][] all =
-                new int[][]{ month, dayOfMonth, dayOfWeek, hour, min };
-            return matches(last, now, time, all, 0);
-        }
-
-        private boolean matches(Date last, Date now, Calendar time,
-            int[][] times, int depth) {
-            if (depth == UNITS.length) {
-                Date compare = time.getTime();
-                return compare.compareTo(last) >= 0 &&
-                    compare.compareTo(now) < 0;
-            }
-
-            if (times[depth] != WILDCARD) {
-                for (int i = 0; i < times[depth].length; i++) {
-                    time.set(UNITS[depth], times[depth][i]);
-                    if (matches(last, now, time, times, depth + 1))
-                        return true;
-                }
-            }
-            return matches(last, now, time, times, depth + 1);
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.datacache;
+
+import java.security.AccessController;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.openjpa.util.InvalidStateException;
+import org.apache.openjpa.util.UserException;
+import serp.util.Strings;
+
+/**
+ * Cron-style cache eviction. Understands schedules based on cron format:
+ * <code>minute hour mday month wday</code>
+ * For example:
+ * <code>15,30 6,19 2,10 1 2 </code>
+ * Would run at 15 and 30 past the 6AM and 7PM, on the 2nd and 10th
+ * of January when its a Monday.
+ *
+ * @author Steve Kim
+ */
+public class DataCacheScheduler
+    implements Runnable {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (DataCacheScheduler.class);
+
+    private Map _caches = new ConcurrentHashMap();
+    private boolean _stop = false;
+    private int _interval = 2;
+    private Log _log;
+    private Thread _thread;
+
+    public DataCacheScheduler(OpenJPAConfiguration conf) {
+        _log = conf.getLogFactory().getLog(OpenJPAConfiguration.LOG_DATACACHE);
+    }
+
+    /**
+     * The interval time in minutes between cache checks. Defaults to 2.
+     */
+    public int getInterval() {
+        return _interval;
+    }
+
+    /**
+     * The interval time in minutes between cache checks. Defaults to 2.
+     */
+    public void setInterval(int interval) {
+        _interval = interval;
+    }
+
+    /**
+     * Stop the associated thread if there and stop the current runnable.
+     */
+    public synchronized void stop() {
+        _stop = true;
+    }
+
+    private boolean isStopped() {
+        return _stop;
+    }
+
+    /**
+     * Schedule the given cache for eviction. Starts the scheduling thread
+     * if not started.
+     */
+    public synchronized void scheduleEviction(DataCache cache, String times) {
+        if (times == null)
+            return;
+
+        Schedule schedule = new Schedule(times);
+        _caches.put(cache, schedule);
+        _stop = false;
+        if (_thread == null) {
+            _thread = (Thread) AccessController.doPrivileged(J2DoPrivHelper
+                .newDaemonThreadAction(this, _loc.get("scheduler-name")
+                    .getMessage()));
+            _thread.start();
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("scheduler-start", _thread.getName()));
+        }
+    }
+
+    /**
+     * Remove the given cache from scheduling.
+     */
+    public synchronized void removeFromSchedule(DataCache cache) {
+        _caches.remove(cache);
+        if (_caches.size() == 0)
+            stop();
+    }
+
+    public void run() {
+        if (_log.isTraceEnabled())
+            _log.trace(_loc.get("scheduler-interval", _interval + ""));
+
+        Date lastRun = new Date();
+        DateFormat fom = new SimpleDateFormat("E HH:mm:ss");
+        while (!isStopped()) {
+            try {
+                Thread.sleep(_interval * 60 * 1000);
+
+                Date now = new Date();
+                DataCache cache;
+                Schedule schedule;
+                Map.Entry entry;
+                for (Iterator i = _caches.entrySet().iterator(); i.hasNext();) {
+                    entry = (Map.Entry) i.next();
+                    cache = (DataCache) entry.getKey();
+                    schedule = (Schedule) entry.getValue();
+                    if (schedule.matches(lastRun, now)) {
+                        if (_log.isTraceEnabled())
+                            _log.trace(_loc.get("scheduler-clear",
+                                cache.getName(), fom.format(now)));
+                        evict(cache);
+                    }
+                }
+                lastRun = now;
+            } catch (Exception e) {
+                throw new InvalidStateException(_loc.get("scheduler-fail"), e).
+                    setFatal(true);
+            }
+        }
+
+        _log.info(_loc.get("scheduler-stop"));
+        synchronized (this) {
+            if (isStopped())
+                _thread = null; // be sure to deref the thread so it can restart
+        }
+    }
+
+    protected void evict(DataCache cache) {
+        cache.clear();
+    }
+
+    /**
+     * Simple class which represents the given time schedule.
+     */
+    private static class Schedule {
+
+        static final int[] WILDCARD = new int[0];
+        static final int[] UNITS = {
+            Calendar.MONTH,
+            Calendar.DAY_OF_MONTH,
+            Calendar.DAY_OF_WEEK,
+            Calendar.HOUR_OF_DAY,
+            Calendar.MINUTE
+        };
+        final int[] month;
+        final int[] dayOfMonth;
+        final int[] dayOfWeek;
+        final int[] hour;
+        final int[] min;
+
+        public Schedule(String date) {
+            StringTokenizer token = new StringTokenizer(date, " \t");
+            if (token.countTokens() != 5)
+                throw new UserException(_loc.get("bad-count", date)).
+                    setFatal(true);
+            try {
+                min = parse(token.nextToken(), 0, 60);
+                hour = parse(token.nextToken(), 0, 24);
+                dayOfMonth = parse(token.nextToken(), 1, 31);
+                month = parse(token.nextToken(), 1, 13);
+                dayOfWeek = parse(token.nextToken(), 1, 8);
+            } catch (Throwable t) {
+                throw new UserException(_loc.get("bad-schedule", date), t).
+                    setFatal(true);
+            }
+        }
+
+        private int[] parse(String token, int min, int max) {
+            if ("*".equals(token.trim()))
+                return WILDCARD;
+            String[] tokens = Strings.split(token, ",", 0);
+            int [] times = new int[tokens.length];
+            for (int i = 0; i < tokens.length; i++) {
+                try {
+                    times[i] = Integer.parseInt(tokens[i]);
+                } catch (Throwable t) {
+                    throw new UserException(_loc.get("not-number", token)).
+                        setFatal(true);
+                }
+                if (times[i] < min || times[i] >= max)
+                    throw new UserException(_loc.get("not-range", token,
+                        String.valueOf(min), String.valueOf(max))).
+                        setFatal(true);
+            }
+            return times;
+        }
+
+        boolean matches(Date last, Date now) {
+            Calendar time = Calendar.getInstance();
+            time.setTime(now);
+            time.set(Calendar.SECOND, 0);
+            time.set(Calendar.MILLISECOND, 0);
+
+            int[][] all =
+                new int[][]{ month, dayOfMonth, dayOfWeek, hour, min };
+            return matches(last, now, time, all, 0);
+        }
+
+        private boolean matches(Date last, Date now, Calendar time,
+            int[][] times, int depth) {
+            if (depth == UNITS.length) {
+                Date compare = time.getTime();
+                return compare.compareTo(last) >= 0 &&
+                    compare.compareTo(now) < 0;
+            }
+
+            if (times[depth] != WILDCARD) {
+                for (int i = 0; i < times[depth].length; i++) {
+                    time.set(UNITS[depth], times[depth][i]);
+                    if (matches(last, now, time, times, depth + 1))
+                        return true;
+                }
+            }
+            return matches(last, now, time, times, depth + 1);
+		}
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
index 4b5722e..6b615df 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
@@ -1,670 +1,670 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.datacache;
-
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.commons.collections.map.LinkedMap;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.LockLevels;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.QueryContext;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.kernel.StoreQuery;
-import org.apache.openjpa.kernel.exps.AggregateListener;
-import org.apache.openjpa.kernel.exps.FilterListener;
-import org.apache.openjpa.lib.rop.ListResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.ObjectNotFoundException;
-
-import serp.util.Numbers;
-
-/**
- * A {@link StoreQuery} implementation that caches the OIDs involved in
- * the query, and can determine whether or not the query has been dirtied.
- *
- * @author Patrick Linskey
- * @since 0.2.5.0
- */
-public class QueryCacheStoreQuery
-    implements StoreQuery {
-
-    private final StoreQuery _query;
-    private final QueryCache _cache;
-    private StoreContext _sctx;
-    private MetaDataRepository _repos;
-
-    /**
-     * Create a new instance that delegates to <code>query</code> if no
-     * cached results are available.
-     */
-    public QueryCacheStoreQuery(StoreQuery query, QueryCache cache) {
-        _query = query;
-        _cache = cache;
-    }
-
-    /**
-     * Return the {@link QueryCache} that this object is associated with.
-     */
-    public QueryCache getCache() {
-        return _cache;
-    }
-
-    /**
-     * Delegate.
-     */
-    public StoreQuery getDelegate() {
-        return _query;
-    }
-
-    /**
-     * Look in the query cache for a result for the given query
-     * key. Only look if this query is being executed outside a
-     * transaction or in a transaction with IgnoreChanges set to true
-     * or in a transaction with IgnoreChanges set to false but in which
-     * none of the classes involved in this query have been touched.
-     *  Caching is not used when using object locking.
-     * This is because we must obtain locks on the
-     * data, and it is likely that making n trips to the database to
-     * make the locks will be slower than running the query against
-     * the database.
-     *  If the fetch configuration has query caching disabled,
-     * then this method returns <code>null</code>.
-     *  Return the list if we meet the above criteria and if a list
-     * is found for <code>qk</code>. Else, return
-     * <code>null</code>.
-     *  This implementation means that queries against the cache
-     * are of READ_COMMITTED isolation level. It'd be nice to support
-     * READ_SERIALIZABLE -- to do so, we'd just return false when in
-     * a transaction.
-     */
-    private List checkCache(QueryKey qk) {
-        if (qk == null)
-            return null;
-        FetchConfiguration fetch = getContext().getFetchConfiguration();
-        if (!fetch.getQueryCacheEnabled())
-            return null;
-        if (fetch.getReadLockLevel() > LockLevels.LOCK_NONE)
-            return null;
-
-        // get the cached data
-        QueryResult res = _cache.get(qk);
-        if (res == null)
-            return null;
-        if (res.isEmpty())
-            return Collections.EMPTY_LIST;
-
-        int projs = getContext().getProjectionAliases().length;
-        if (projs == 0) {
-            // make sure the data cache contains the oids for the query result;
-            // if it doesn't, then using the result could be slower than not
-            // using it because of the individual by-oid lookups
-            ClassMetaData meta = _repos.getMetaData(getContext().
-                getCandidateType(), _sctx.getClassLoader(), true);
-            if (meta.getDataCache() == null)
-                return null;
-
-            BitSet idxs = meta.getDataCache().containsAll(res);
-
-            // eventually we should optimize this to figure out how many objects
-            // the cache is missing and if only a few do a bulk fetch for them
-            int len = idxs.length();
-            if (len < res.size())
-                return null;
-            for (int i = 0; i < len; i++)
-                if (!idxs.get(i))
-                    return null;
-        }
-        return new CachedList(res, projs != 0, _sctx);
-    }
-
-    /**
-     * Wrap the result object provider returned by our delegate in a
-     * caching provider.
-     */
-    private ResultObjectProvider wrapResult(ResultObjectProvider rop,
-        QueryKey key) {
-        if (key == null)
-            return rop;
-        return new CachingResultObjectProvider(rop, getContext().
-            getProjectionAliases().length > 0, key);
-    }
-
-    /**
-     * Copy a projection element for caching / returning.
-     */
-    private static Object copyProjection(Object obj, StoreContext ctx) {
-        if (obj == null)
-            return null;
-        switch (JavaTypes.getTypeCode(obj.getClass())) {
-            case JavaTypes.STRING:
-            case JavaTypes.BOOLEAN_OBJ:
-            case JavaTypes.BYTE_OBJ:
-            case JavaTypes.CHAR_OBJ:
-            case JavaTypes.DOUBLE_OBJ:
-            case JavaTypes.FLOAT_OBJ:
-            case JavaTypes.INT_OBJ:
-            case JavaTypes.LONG_OBJ:
-            case JavaTypes.SHORT_OBJ:
-            case JavaTypes.BIGDECIMAL:
-            case JavaTypes.BIGINTEGER:
-            case JavaTypes.OID:
-                return obj;
-            case JavaTypes.DATE:
-                return ((Date) obj).clone();
-            case JavaTypes.LOCALE:
-                return ((Locale) obj).clone();
-            default:
-                if (obj instanceof CachedObjectId)
-                    return fromObjectId(((CachedObjectId) obj).oid, ctx);
-                Object oid = ctx.getObjectId(obj);
-                if (oid != null)
-                    return new CachedObjectId(oid);
-                return obj;
-        }
-    }
-
-    /**
-     * Return the result object based on its cached oid.
-     */
-    private static Object fromObjectId(Object oid, StoreContext sctx) {
-        if (oid == null)
-            return null;
-
-        Object obj = sctx.find(oid, null, null, null, 0);
-        if (obj == null)
-            throw new ObjectNotFoundException(oid);
-        return obj;
-    }
-
-    public Object writeReplace()
-        throws ObjectStreamException {
-        return _query;
-    }
-
-    public QueryContext getContext() {
-        return _query.getContext();
-    }
-
-    public void setContext(QueryContext qctx) {
-        _query.setContext(qctx);
-        _sctx = qctx.getStoreContext();
-        _repos = _sctx.getConfiguration().getMetaDataRepositoryInstance();
-    }
-
-    public boolean setQuery(Object query) {
-        return _query.setQuery(query);
-    }
-
-    public FilterListener getFilterListener(String tag) {
-        return _query.getFilterListener(tag);
-    }
-
-    public AggregateListener getAggregateListener(String tag) {
-        return _query.getAggregateListener(tag);
-    }
-
-    public Object newCompilationKey() {
-        return _query.newCompilationKey();
-    }
-
-    public Object newCompilation() {
-        return _query.newCompilation();
-    }
-
-    public void populateFromCompilation(Object comp) {
-        _query.populateFromCompilation(comp);
-    }
-
-    public void invalidateCompilation() {
-        _query.invalidateCompilation();
-    }
-
-    public boolean supportsDataStoreExecution() {
-        return _query.supportsDataStoreExecution();
-    }
-
-    public boolean supportsInMemoryExecution() {
-        return _query.supportsInMemoryExecution();
-    }
-
-    public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs) {
-        return _query.newInMemoryExecutor(meta, subs);
-    }
-
-    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
-        Executor ex = _query.newDataStoreExecutor(meta, subs);
-        return new QueryCacheExecutor(ex, meta, subs);
-    }
-
-    public boolean supportsAbstractExecutors() {
-        return _query.supportsAbstractExecutors();
-    }
-
-    public boolean requiresCandidateType() {
-        return _query.requiresCandidateType();
-    }
-
-    public boolean requiresParameterDeclarations() {
-        return _query.requiresParameterDeclarations();
-    }
-
-    public boolean supportsParameterDeclarations() {
-        return _query.supportsParameterDeclarations();
-    }
- 
-    public Object evaluate(Object value, Object ob, Object[] params,
-        OpenJPAStateManager sm) {
-        return _query.evaluate(value, ob, params, sm);         
-    }
-
-    /**
-     * Caching executor.
-     */
-    private static class QueryCacheExecutor
-        implements Executor {
-
-        private final Executor _ex;
-        private final Class _candidate;
-        private final boolean _subs;
-
-        public QueryCacheExecutor(Executor ex, ClassMetaData meta,
-            boolean subs) {
-            _ex = ex;
-            _candidate = (meta == null) ? null : meta.getDescribedType();
-            _subs = subs;
-        }
-
-        public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
-            Range range) {
-            QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
-            QueryKey key = QueryKey.newInstance(cq.getContext(),
-                _ex.isPacking(q), params, _candidate, _subs, range.start, 
-                range.end);
-            List cached = cq.checkCache(key);
-            if (cached != null)
-                return new ListResultObjectProvider(cached);
-
-            ResultObjectProvider rop = _ex.executeQuery(cq.getDelegate(),
-                params, range);
-            return cq.wrapResult(rop, key);
-        }
-
-        /**
-         * Clear the cached queries associated with the access path
-         * classes in the query. This is done when bulk operations
-         * (such as deletes or updates) are performed so that the
-         * cache remains up-to-date.
-         */
-        private void clearAccessPath(StoreQuery q) {
-            if (q == null)
-                return;
-
-            ClassMetaData[] cmd = getAccessPathMetaDatas(q);
-            if (cmd == null || cmd.length == 0)
-                return;
-
-            List classes = new ArrayList(cmd.length);
-            for (int i = 0; i < cmd.length; i++)
-                classes.add(cmd[i].getDescribedType());
-
-            // evict from the query cache
-            QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
-            cq.getCache().onTypesChanged(new TypesChangedEvent
-                (q.getContext(), classes));
-
-            // evict from the data cache
-            for (int i = 0; i < cmd.length; i++) {
-                if (cmd[i].getDataCache() != null)
-                    cmd[i].getDataCache().removeAll(
-                        cmd[i].getDescribedType(), true);
-            }
-        }
-
-        public Number executeDelete(StoreQuery q, Object[] params) {
-            try {
-                return _ex.executeDelete(unwrap(q), params);
-            } finally {
-                clearAccessPath(q);
-            }
-        }
-
-        public Number executeUpdate(StoreQuery q, Object[] params) {
-            try {
-                return _ex.executeUpdate(unwrap(q), params);
-            } finally {
-                clearAccessPath(q);
-            }
-        }
-
-        public String[] getDataStoreActions(StoreQuery q, Object[] params,
-            Range range) {
-            return EMPTY_STRINGS;
-        }
-
-        public void validate(StoreQuery q) {
-            _ex.validate(unwrap(q));
-        }
-        
-        public void getRange(StoreQuery q, Object[] params, Range range) {
-            _ex.getRange(q, params, range); 
-        }
-
-        public Object getOrderingValue(StoreQuery q, Object[] params,
-            Object resultObject, int orderIndex) {
-            return _ex.getOrderingValue(unwrap(q), params, resultObject,
-                orderIndex);
-        }
-
-        public boolean[] getAscending(StoreQuery q) {
-            return _ex.getAscending(unwrap(q));
-        }
-
-        public boolean isPacking(StoreQuery q) {
-            return _ex.isPacking(unwrap(q));
-        }
-
-        public String getAlias(StoreQuery q) {
-            return _ex.getAlias(unwrap(q));
-        }
-
-        public Class getResultClass(StoreQuery q) {
-            return _ex.getResultClass(unwrap(q));
-        }
-
-        public String[] getProjectionAliases(StoreQuery q) {
-            return _ex.getProjectionAliases(unwrap(q));
-        }
-
-        public Class[] getProjectionTypes(StoreQuery q) {
-            return _ex.getProjectionTypes(unwrap(q));
-        }
-
-        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q) {
-            return _ex.getAccessPathMetaDatas(unwrap(q));
-        }
-
-        public int getOperation(StoreQuery q) {
-            return _ex.getOperation(unwrap(q));
-        }
-
-        public boolean isAggregate(StoreQuery q) {
-            return _ex.isAggregate(unwrap(q));
-        }
-
-        public boolean hasGrouping(StoreQuery q) {
-            return _ex.hasGrouping(unwrap(q));
-        }
-
-        public LinkedMap getParameterTypes(StoreQuery q) {
-            return _ex.getParameterTypes(unwrap(q));
-        }
-
-        public Map getUpdates(StoreQuery q) {
-            return _ex.getUpdates(unwrap(q));
-        }
-
-        private static StoreQuery unwrap(StoreQuery q) {
-            return ((QueryCacheStoreQuery) q).getDelegate();
-        }
-    }
-
-    /**
-     * Result list implementation for a cached query result. Package-protected
-     * for testing.
-     */
-    public static class CachedList
-        extends AbstractList
-        implements Serializable {
-
-        private final QueryResult _res;
-        private final boolean _proj;
-        private final StoreContext _sctx;
-
-        public CachedList(QueryResult res, boolean proj, StoreContext ctx) {
-            _res = res;
-            _proj = proj;
-            _sctx = ctx;
-        }
-
-        public Object get(int idx) {
-            if (!_proj)
-                return fromObjectId(_res.get(idx), _sctx);
-
-            Object[] cached = (Object[]) _res.get(idx);
-            if (cached == null)
-                return null;
-            Object[] uncached = new Object[cached.length];
-            for (int i = 0; i < cached.length; i++)
-                uncached[i] = copyProjection(cached[i], _sctx);
-            return uncached;
-        }
-
-        public int size() {
-            return _res.size();
-        }
-
-        public Object writeReplace()
-            throws ObjectStreamException {
-            return new ArrayList(this);
-        }
-    }
-
-    /**
-     * A wrapper around a {@link ResultObjectProvider} that builds up a list of
-     * all the OIDs in this list and registers that list with the
-     * query cache. Abandons monitoring and registering if one of the classes
-     * in the access path is modified while the query results are being loaded.
-     */
-    private class CachingResultObjectProvider
-        implements ResultObjectProvider, TypesChangedListener {
-
-        private final ResultObjectProvider _rop;
-        private final boolean _proj;
-        private final QueryKey _qk;
-        private final TreeMap _data = new TreeMap();
-        private boolean _maintainCache = true;
-        private int _pos = -1;
-
-        // used to determine list size without necessarily calling size(),
-        // which may require a DB trip or return Integer.MAX_VALUE
-        private int _max = -1;
-        private int _size = Integer.MAX_VALUE;
-
-        /**
-         * Constructor. Supply delegate result provider and our query key.
-         */
-        public CachingResultObjectProvider(ResultObjectProvider rop,
-            boolean proj, QueryKey key) {
-            _rop = rop;
-            _proj = proj;
-            _qk = key;
-            _cache.addTypesChangedListener(this);
-        }
-
-        /**
-         * Stop caching.
-         */
-        private void abortCaching() {
-            if (!_maintainCache)
-                return;
-
-            // this can be called via an event from another thread
-            synchronized (this) {
-                // it's important that we set this flag first so that any
-                // subsequent calls to this object are bypassed.
-                _maintainCache = false;
-                _cache.removeTypesChangedListener(this);
-                _data.clear();
-            }
-        }
-
-        /**
-         * Check whether we've buffered all results, while optionally adding
-         * the given result.
-         */
-        private void checkFinished(Object obj, boolean result) {
-            // this can be called at the same time as abortCaching via
-            // a types changed event
-            boolean finished = false;
-            synchronized (this) {
-                if (_maintainCache) {
-                    if (result) {
-                        Integer index = Numbers.valueOf(_pos);
-                        if (!_data.containsKey(index)) {
-                            Object cached;
-                            if (obj == null)
-                                cached = null;
-                            else if (!_proj)
-                                cached = _sctx.getObjectId(obj);
-                            else {
-                                Object[] arr = (Object[]) obj;
-                                Object[] cp = new Object[arr.length];
-                                for (int i = 0; i < arr.length; i++)
-                                    cp[i] = copyProjection(arr[i], _sctx);
-                                cached = cp;
-                            }
-                            if (cached != null)
-                                _data.put(index, cached);
-                        }
-                    }
-                    finished = _size == _data.size();
-                }
-            }
-
-            if (finished) {
-                // an abortCaching call can sneak in here via onExpire; the
-                // cache is locked during event firings, so the lock here will
-                // wait for it (or will force the next firing to wait)
-                _cache.writeLock();
-                try {
-                    // make sure we didn't abort
-                    if (_maintainCache) {
-                        QueryResult res = null;
-                        synchronized (this) {
-                            res = new QueryResult(_qk, _data.values());
-                        }
-                        _cache.put(_qk, res);
-                        abortCaching();
-                    }
-                }
-                finally {
-                    _cache.writeUnlock();
-                }
-            }
-        }
-
-        public boolean supportsRandomAccess() {
-            return _rop.supportsRandomAccess();
-        }
-
-        public void open()
-            throws Exception {
-            _rop.open();
-        }
-
-        public Object getResultObject()
-            throws Exception {
-            Object obj = _rop.getResultObject();
-            checkFinished(obj, true);
-            return obj;
-        }
-
-        public boolean next()
-            throws Exception {
-            _pos++;
-            boolean next = _rop.next();
-            if (!next && _pos == _max + 1) {
-                _size = _pos;
-                checkFinished(null, false);
-            } else if (next && _pos > _max)
-                _max = _pos;
-            return next;
-        }
-
-        public boolean absolute(int pos)
-            throws Exception {
-            _pos = pos;
-            boolean valid = _rop.absolute(pos);
-            if (!valid && _pos == _max + 1) {
-                _size = _pos;
-                checkFinished(null, false);
-            } else if (valid && _pos > _max)
-                _max = _pos;
-            return valid;
-        }
-
-        public int size()
-            throws Exception {
-            if (_size != Integer.MAX_VALUE)
-                return _size;
-            int size = _rop.size();
-            _size = size;
-            checkFinished(null, false);
-            return size;
-        }
-
-        public void reset()
-            throws Exception {
-            _rop.reset();
-            _pos = -1;
-        }
-
-        public void close()
-            throws Exception {
-            abortCaching();
-            _rop.close();
-        }
-
-        public void handleCheckedException(Exception e) {
-            _rop.handleCheckedException(e);
-        }
-
-        public void onTypesChanged(TypesChangedEvent ev) {
-            if (_qk.changeInvalidatesQuery(ev.getTypes()))
-                abortCaching();
-        }
-    }
-
-    /**
-     * Struct to recognize cached oids.
-     */
-    private static class CachedObjectId {
-
-        public final Object oid;
-
-        public CachedObjectId (Object oid)
-		{
-			this.oid = oid;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.datacache;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.LockLevels;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.QueryContext;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.AggregateListener;
+import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.lib.rop.ListResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.ObjectNotFoundException;
+
+import serp.util.Numbers;
+
+/**
+ * A {@link StoreQuery} implementation that caches the OIDs involved in
+ * the query, and can determine whether or not the query has been dirtied.
+ *
+ * @author Patrick Linskey
+ * @since 0.2.5.0
+ */
+public class QueryCacheStoreQuery
+    implements StoreQuery {
+
+    private final StoreQuery _query;
+    private final QueryCache _cache;
+    private StoreContext _sctx;
+    private MetaDataRepository _repos;
+
+    /**
+     * Create a new instance that delegates to <code>query</code> if no
+     * cached results are available.
+     */
+    public QueryCacheStoreQuery(StoreQuery query, QueryCache cache) {
+        _query = query;
+        _cache = cache;
+    }
+
+    /**
+     * Return the {@link QueryCache} that this object is associated with.
+     */
+    public QueryCache getCache() {
+        return _cache;
+    }
+
+    /**
+     * Delegate.
+     */
+    public StoreQuery getDelegate() {
+        return _query;
+    }
+
+    /**
+     * Look in the query cache for a result for the given query
+     * key. Only look if this query is being executed outside a
+     * transaction or in a transaction with IgnoreChanges set to true
+     * or in a transaction with IgnoreChanges set to false but in which
+     * none of the classes involved in this query have been touched.
+     *  Caching is not used when using object locking.
+     * This is because we must obtain locks on the
+     * data, and it is likely that making n trips to the database to
+     * make the locks will be slower than running the query against
+     * the database.
+     *  If the fetch configuration has query caching disabled,
+     * then this method returns <code>null</code>.
+     *  Return the list if we meet the above criteria and if a list
+     * is found for <code>qk</code>. Else, return
+     * <code>null</code>.
+     *  This implementation means that queries against the cache
+     * are of READ_COMMITTED isolation level. It'd be nice to support
+     * READ_SERIALIZABLE -- to do so, we'd just return false when in
+     * a transaction.
+     */
+    private List checkCache(QueryKey qk) {
+        if (qk == null)
+            return null;
+        FetchConfiguration fetch = getContext().getFetchConfiguration();
+        if (!fetch.getQueryCacheEnabled())
+            return null;
+        if (fetch.getReadLockLevel() > LockLevels.LOCK_NONE)
+            return null;
+
+        // get the cached data
+        QueryResult res = _cache.get(qk);
+        if (res == null)
+            return null;
+        if (res.isEmpty())
+            return Collections.EMPTY_LIST;
+
+        int projs = getContext().getProjectionAliases().length;
+        if (projs == 0) {
+            // make sure the data cache contains the oids for the query result;
+            // if it doesn't, then using the result could be slower than not
+            // using it because of the individual by-oid lookups
+            ClassMetaData meta = _repos.getMetaData(getContext().
+                getCandidateType(), _sctx.getClassLoader(), true);
+            if (meta.getDataCache() == null)
+                return null;
+
+            BitSet idxs = meta.getDataCache().containsAll(res);
+
+            // eventually we should optimize this to figure out how many objects
+            // the cache is missing and if only a few do a bulk fetch for them
+            int len = idxs.length();
+            if (len < res.size())
+                return null;
+            for (int i = 0; i < len; i++)
+                if (!idxs.get(i))
+                    return null;
+        }
+        return new CachedList(res, projs != 0, _sctx);
+    }
+
+    /**
+     * Wrap the result object provider returned by our delegate in a
+     * caching provider.
+     */
+    private ResultObjectProvider wrapResult(ResultObjectProvider rop,
+        QueryKey key) {
+        if (key == null)
+            return rop;
+        return new CachingResultObjectProvider(rop, getContext().
+            getProjectionAliases().length > 0, key);
+    }
+
+    /**
+     * Copy a projection element for caching / returning.
+     */
+    private static Object copyProjection(Object obj, StoreContext ctx) {
+        if (obj == null)
+            return null;
+        switch (JavaTypes.getTypeCode(obj.getClass())) {
+            case JavaTypes.STRING:
+            case JavaTypes.BOOLEAN_OBJ:
+            case JavaTypes.BYTE_OBJ:
+            case JavaTypes.CHAR_OBJ:
+            case JavaTypes.DOUBLE_OBJ:
+            case JavaTypes.FLOAT_OBJ:
+            case JavaTypes.INT_OBJ:
+            case JavaTypes.LONG_OBJ:
+            case JavaTypes.SHORT_OBJ:
+            case JavaTypes.BIGDECIMAL:
+            case JavaTypes.BIGINTEGER:
+            case JavaTypes.OID:
+                return obj;
+            case JavaTypes.DATE:
+                return ((Date) obj).clone();
+            case JavaTypes.LOCALE:
+                return ((Locale) obj).clone();
+            default:
+                if (obj instanceof CachedObjectId)
+                    return fromObjectId(((CachedObjectId) obj).oid, ctx);
+                Object oid = ctx.getObjectId(obj);
+                if (oid != null)
+                    return new CachedObjectId(oid);
+                return obj;
+        }
+    }
+
+    /**
+     * Return the result object based on its cached oid.
+     */
+    private static Object fromObjectId(Object oid, StoreContext sctx) {
+        if (oid == null)
+            return null;
+
+        Object obj = sctx.find(oid, null, null, null, 0);
+        if (obj == null)
+            throw new ObjectNotFoundException(oid);
+        return obj;
+    }
+
+    public Object writeReplace()
+        throws ObjectStreamException {
+        return _query;
+    }
+
+    public QueryContext getContext() {
+        return _query.getContext();
+    }
+
+    public void setContext(QueryContext qctx) {
+        _query.setContext(qctx);
+        _sctx = qctx.getStoreContext();
+        _repos = _sctx.getConfiguration().getMetaDataRepositoryInstance();
+    }
+
+    public boolean setQuery(Object query) {
+        return _query.setQuery(query);
+    }
+
+    public FilterListener getFilterListener(String tag) {
+        return _query.getFilterListener(tag);
+    }
+
+    public AggregateListener getAggregateListener(String tag) {
+        return _query.getAggregateListener(tag);
+    }
+
+    public Object newCompilationKey() {
+        return _query.newCompilationKey();
+    }
+
+    public Object newCompilation() {
+        return _query.newCompilation();
+    }
+
+    public void populateFromCompilation(Object comp) {
+        _query.populateFromCompilation(comp);
+    }
+
+    public void invalidateCompilation() {
+        _query.invalidateCompilation();
+    }
+
+    public boolean supportsDataStoreExecution() {
+        return _query.supportsDataStoreExecution();
+    }
+
+    public boolean supportsInMemoryExecution() {
+        return _query.supportsInMemoryExecution();
+    }
+
+    public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs) {
+        return _query.newInMemoryExecutor(meta, subs);
+    }
+
+    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
+        Executor ex = _query.newDataStoreExecutor(meta, subs);
+        return new QueryCacheExecutor(ex, meta, subs);
+    }
+
+    public boolean supportsAbstractExecutors() {
+        return _query.supportsAbstractExecutors();
+    }
+
+    public boolean requiresCandidateType() {
+        return _query.requiresCandidateType();
+    }
+
+    public boolean requiresParameterDeclarations() {
+        return _query.requiresParameterDeclarations();
+    }
+
+    public boolean supportsParameterDeclarations() {
+        return _query.supportsParameterDeclarations();
+    }
+ 
+    public Object evaluate(Object value, Object ob, Object[] params,
+        OpenJPAStateManager sm) {
+        return _query.evaluate(value, ob, params, sm);         
+    }
+
+    /**
+     * Caching executor.
+     */
+    private static class QueryCacheExecutor
+        implements Executor {
+
+        private final Executor _ex;
+        private final Class _candidate;
+        private final boolean _subs;
+
+        public QueryCacheExecutor(Executor ex, ClassMetaData meta,
+            boolean subs) {
+            _ex = ex;
+            _candidate = (meta == null) ? null : meta.getDescribedType();
+            _subs = subs;
+        }
+
+        public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
+            Range range) {
+            QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
+            QueryKey key = QueryKey.newInstance(cq.getContext(),
+                _ex.isPacking(q), params, _candidate, _subs, range.start, 
+                range.end);
+            List cached = cq.checkCache(key);
+            if (cached != null)
+                return new ListResultObjectProvider(cached);
+
+            ResultObjectProvider rop = _ex.executeQuery(cq.getDelegate(),
+                params, range);
+            return cq.wrapResult(rop, key);
+        }
+
+        /**
+         * Clear the cached queries associated with the access path
+         * classes in the query. This is done when bulk operations
+         * (such as deletes or updates) are performed so that the
+         * cache remains up-to-date.
+         */
+        private void clearAccessPath(StoreQuery q) {
+            if (q == null)
+                return;
+
+            ClassMetaData[] cmd = getAccessPathMetaDatas(q);
+            if (cmd == null || cmd.length == 0)
+                return;
+
+            List classes = new ArrayList(cmd.length);
+            for (int i = 0; i < cmd.length; i++)
+                classes.add(cmd[i].getDescribedType());
+
+            // evict from the query cache
+            QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
+            cq.getCache().onTypesChanged(new TypesChangedEvent
+                (q.getContext(), classes));
+
+            // evict from the data cache
+            for (int i = 0; i < cmd.length; i++) {
+                if (cmd[i].getDataCache() != null)
+                    cmd[i].getDataCache().removeAll(
+                        cmd[i].getDescribedType(), true);
+            }
+        }
+
+        public Number executeDelete(StoreQuery q, Object[] params) {
+            try {
+                return _ex.executeDelete(unwrap(q), params);
+            } finally {
+                clearAccessPath(q);
+            }
+        }
+
+        public Number executeUpdate(StoreQuery q, Object[] params) {
+            try {
+                return _ex.executeUpdate(unwrap(q), params);
+            } finally {
+                clearAccessPath(q);
+            }
+        }
+
+        public String[] getDataStoreActions(StoreQuery q, Object[] params,
+            Range range) {
+            return EMPTY_STRINGS;
+        }
+
+        public void validate(StoreQuery q) {
+            _ex.validate(unwrap(q));
+        }
+        
+        public void getRange(StoreQuery q, Object[] params, Range range) {
+            _ex.getRange(q, params, range); 
+        }
+
+        public Object getOrderingValue(StoreQuery q, Object[] params,
+            Object resultObject, int orderIndex) {
+            return _ex.getOrderingValue(unwrap(q), params, resultObject,
+                orderIndex);
+        }
+
+        public boolean[] getAscending(StoreQuery q) {
+            return _ex.getAscending(unwrap(q));
+        }
+
+        public boolean isPacking(StoreQuery q) {
+            return _ex.isPacking(unwrap(q));
+        }
+
+        public String getAlias(StoreQuery q) {
+            return _ex.getAlias(unwrap(q));
+        }
+
+        public Class getResultClass(StoreQuery q) {
+            return _ex.getResultClass(unwrap(q));
+        }
+
+        public String[] getProjectionAliases(StoreQuery q) {
+            return _ex.getProjectionAliases(unwrap(q));
+        }
+
+        public Class[] getProjectionTypes(StoreQuery q) {
+            return _ex.getProjectionTypes(unwrap(q));
+        }
+
+        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q) {
+            return _ex.getAccessPathMetaDatas(unwrap(q));
+        }
+
+        public int getOperation(StoreQuery q) {
+            return _ex.getOperation(unwrap(q));
+        }
+
+        public boolean isAggregate(StoreQuery q) {
+            return _ex.isAggregate(unwrap(q));
+        }
+
+        public boolean hasGrouping(StoreQuery q) {
+            return _ex.hasGrouping(unwrap(q));
+        }
+
+        public LinkedMap getParameterTypes(StoreQuery q) {
+            return _ex.getParameterTypes(unwrap(q));
+        }
+
+        public Map getUpdates(StoreQuery q) {
+            return _ex.getUpdates(unwrap(q));
+        }
+
+        private static StoreQuery unwrap(StoreQuery q) {
+            return ((QueryCacheStoreQuery) q).getDelegate();
+        }
+    }
+
+    /**
+     * Result list implementation for a cached query result. Package-protected
+     * for testing.
+     */
+    public static class CachedList
+        extends AbstractList
+        implements Serializable {
+
+        private final QueryResult _res;
+        private final boolean _proj;
+        private final StoreContext _sctx;
+
+        public CachedList(QueryResult res, boolean proj, StoreContext ctx) {
+            _res = res;
+            _proj = proj;
+            _sctx = ctx;
+        }
+
+        public Object get(int idx) {
+            if (!_proj)
+                return fromObjectId(_res.get(idx), _sctx);
+
+            Object[] cached = (Object[]) _res.get(idx);
+            if (cached == null)
+                return null;
+            Object[] uncached = new Object[cached.length];
+            for (int i = 0; i < cached.length; i++)
+                uncached[i] = copyProjection(cached[i], _sctx);
+            return uncached;
+        }
+
+        public int size() {
+            return _res.size();
+        }
+
+        public Object writeReplace()
+            throws ObjectStreamException {
+            return new ArrayList(this);
+        }
+    }
+
+    /**
+     * A wrapper around a {@link ResultObjectProvider} that builds up a list of
+     * all the OIDs in this list and registers that list with the
+     * query cache. Abandons monitoring and registering if one of the classes
+     * in the access path is modified while the query results are being loaded.
+     */
+    private class CachingResultObjectProvider
+        implements ResultObjectProvider, TypesChangedListener {
+
+        private final ResultObjectProvider _rop;
+        private final boolean _proj;
+        private final QueryKey _qk;
+        private final TreeMap _data = new TreeMap();
+        private boolean _maintainCache = true;
+        private int _pos = -1;
+
+        // used to determine list size without necessarily calling size(),
+        // which may require a DB trip or return Integer.MAX_VALUE
+        private int _max = -1;
+        private int _size = Integer.MAX_VALUE;
+
+        /**
+         * Constructor. Supply delegate result provider and our query key.
+         */
+        public CachingResultObjectProvider(ResultObjectProvider rop,
+            boolean proj, QueryKey key) {
+            _rop = rop;
+            _proj = proj;
+            _qk = key;
+            _cache.addTypesChangedListener(this);
+        }
+
+        /**
+         * Stop caching.
+         */
+        private void abortCaching() {
+            if (!_maintainCache)
+                return;
+
+            // this can be called via an event from another thread
+            synchronized (this) {
+                // it's important that we set this flag first so that any
+                // subsequent calls to this object are bypassed.
+                _maintainCache = false;
+                _cache.removeTypesChangedListener(this);
+                _data.clear();
+            }
+        }
+
+        /**
+         * Check whether we've buffered all results, while optionally adding
+         * the given result.
+         */
+        private void checkFinished(Object obj, boolean result) {
+            // this can be called at the same time as abortCaching via
+            // a types changed event
+            boolean finished = false;
+            synchronized (this) {
+                if (_maintainCache) {
+                    if (result) {
+                        Integer index = Numbers.valueOf(_pos);
+                        if (!_data.containsKey(index)) {
+                            Object cached;
+                            if (obj == null)
+                                cached = null;
+                            else if (!_proj)
+                                cached = _sctx.getObjectId(obj);
+                            else {
+                                Object[] arr = (Object[]) obj;
+                                Object[] cp = new Object[arr.length];
+                                for (int i = 0; i < arr.length; i++)
+                                    cp[i] = copyProjection(arr[i], _sctx);
+                                cached = cp;
+                            }
+                            if (cached != null)
+                                _data.put(index, cached);
+                        }
+                    }
+                    finished = _size == _data.size();
+                }
+            }
+
+            if (finished) {
+                // an abortCaching call can sneak in here via onExpire; the
+                // cache is locked during event firings, so the lock here will
+                // wait for it (or will force the next firing to wait)
+                _cache.writeLock();
+                try {
+                    // make sure we didn't abort
+                    if (_maintainCache) {
+                        QueryResult res = null;
+                        synchronized (this) {
+                            res = new QueryResult(_qk, _data.values());
+                        }
+                        _cache.put(_qk, res);
+                        abortCaching();
+                    }
+                }
+                finally {
+                    _cache.writeUnlock();
+                }
+            }
+        }
+
+        public boolean supportsRandomAccess() {
+            return _rop.supportsRandomAccess();
+        }
+
+        public void open()
+            throws Exception {
+            _rop.open();
+        }
+
+        public Object getResultObject()
+            throws Exception {
+            Object obj = _rop.getResultObject();
+            checkFinished(obj, true);
+            return obj;
+        }
+
+        public boolean next()
+            throws Exception {
+            _pos++;
+            boolean next = _rop.next();
+            if (!next && _pos == _max + 1) {
+                _size = _pos;
+                checkFinished(null, false);
+            } else if (next && _pos > _max)
+                _max = _pos;
+            return next;
+        }
+
+        public boolean absolute(int pos)
+            throws Exception {
+            _pos = pos;
+            boolean valid = _rop.absolute(pos);
+            if (!valid && _pos == _max + 1) {
+                _size = _pos;
+                checkFinished(null, false);
+            } else if (valid && _pos > _max)
+                _max = _pos;
+            return valid;
+        }
+
+        public int size()
+            throws Exception {
+            if (_size != Integer.MAX_VALUE)
+                return _size;
+            int size = _rop.size();
+            _size = size;
+            checkFinished(null, false);
+            return size;
+        }
+
+        public void reset()
+            throws Exception {
+            _rop.reset();
+            _pos = -1;
+        }
+
+        public void close()
+            throws Exception {
+            abortCaching();
+            _rop.close();
+        }
+
+        public void handleCheckedException(Exception e) {
+            _rop.handleCheckedException(e);
+        }
+
+        public void onTypesChanged(TypesChangedEvent ev) {
+            if (_qk.changeInvalidatesQuery(ev.getTypes()))
+                abortCaching();
+        }
+    }
+
+    /**
+     * Struct to recognize cached oids.
+     */
+    private static class CachedObjectId {
+
+        public final Object oid;
+
+        public CachedObjectId (Object oid)
+		{
+			this.oid = oid;
+		}
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AttributeTranslator.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AttributeTranslator.java
index f3be4a5..3904232 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AttributeTranslator.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AttributeTranslator.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-/**
- * Instances of this interface can convert a positional index for a
- * {@link FieldMetaData} that uses property access into the underlying
- * field name. Instances of {@link DynamicPersistenceCapable} for types
- * that use property access will implement this interface.
- *
- * @since 1.0.0
- */
-public interface AttributeTranslator {
-    public String pcAttributeIndexToFieldName(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+/**
+ * Instances of this interface can convert a positional index for a
+ * {@link FieldMetaData} that uses property access into the underlying
+ * field name. Instances of {@link DynamicPersistenceCapable} for types
+ * that use property access will implement this interface.
+ *
+ * @since 1.0.0
+ */
+public interface AttributeTranslator {
+    public String pcAttributeIndexToFieldName(int i);
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ClassRedefiner.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ClassRedefiner.java
index fa76f87..66fa605 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ClassRedefiner.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ClassRedefiner.java
@@ -1,152 +1,152 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.lang.instrument.Instrumentation;
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.ClassDefinition;
-import java.lang.instrument.UnmodifiableClassException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.ProtectionDomain;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.ArrayList;
-import java.io.IOException;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.lib.util.JavaVersions;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Redefines the method bodies of existing classes. Supports Java 5 VMs that
- * have a javaagent installed on the command line as well as newer VMs without
- * any javaagent flag.
- *
- * @since 1.0.0
- */
-public class ClassRedefiner {
-
-    private static final Localizer _loc = 
-        Localizer.forPackage(ClassRedefiner.class);
-
-    private static Boolean _canRedefine = null;
-
-    /**
-     * For each element in <code>classes</code>, this method will redefine
-     * all the element's methods such that field accesses are intercepted
-     * in-line. If {@link #canRedefineClasses()} returns <code>false</code>,
-     * this method is a no-op.
-     */
-    public static void redefineClasses(OpenJPAConfiguration conf,
-        final Map<Class,byte[]> classes) {
-        if (classes == null || classes.size() == 0 || !canRedefineClasses())
-            return;
-
-        Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
-        Instrumentation inst = null;
-        ClassFileTransformer t = null;
-        try {
-            inst = InstrumentationFactory.getInstrumentation();
-
-            Class[] array = classes.keySet().toArray(new Class[classes.size()]);
-            if (JavaVersions.VERSION >= 6) {
-                log.trace(_loc.get("retransform-types", classes.keySet()));
-
-                t = new ClassFileTransformer() {
-                    public byte[] transform(ClassLoader loader, String clsName,
-                        Class<?> classBeingRedefined, ProtectionDomain pd,
-                        byte[] classfileBuffer) {
-                        return classes.get(classBeingRedefined);
-                    }
-                };
-                
-                // these are Java 6 methods, and we don't have a Java 6 build
-                // module yet. The cost of reflection here is negligible
-                // compared to the redefinition / enhancement costs in total,
-                // so this should not be a big problem.
-                Method meth = inst.getClass().getMethod("addTransformer",
-                    new Class[] { ClassFileTransformer.class, boolean.class });
-                meth.invoke(inst, new Object[] { t, true });
-                meth = inst.getClass().getMethod("retransformClasses",
-                    new Class[] { array.getClass() });
-                meth.invoke(inst, new Object[] { array });
-            } else {
-                log.trace(_loc.get("redefine-types", classes.keySet()));
-                // in a Java 5 context, we can use class redefinition instead
-                ClassDefinition[] defs = new ClassDefinition[array.length];
-                for (int i = 0; i < defs.length; i++)
-                    defs[i] = new ClassDefinition(array[i],
-                        classes.get(array[i]));
-                inst.redefineClasses(defs);
-            }
-        } catch (NoSuchMethodException e) {
-            throw new InternalException(e);
-        } catch (IllegalAccessException e) {
-            throw new InternalException(e);
-        } catch (InvocationTargetException e) {
-            throw new UserException(e.getCause());
-        } catch (IOException e) {
-            throw new InternalException(e);
-        } catch (ClassNotFoundException e) {
-            throw new InternalException(e);
-        } catch (UnmodifiableClassException e) {
-            throw new InternalException(e);
-        } finally {
-            if (inst != null && t != null)
-                inst.removeTransformer(t);
-        }
-    }
-
-    /**
-     * @return whether or not this VM has an instrumentation installed that
-     * permits redefinition of classes. This assumes that all the arguments
-     * will be modifiable classes according to
-     * {@link java.lang.instrument.Instrumentation#isModifiableClass}, and
-     * only checks whether or not an instrumentation is available and
-     * if retransformation is possible.
-     */
-    public static boolean canRedefineClasses() {
-        if (_canRedefine == null) {
-            try {
-                Instrumentation inst = InstrumentationFactory
-                    .getInstrumentation();
-                if (inst == null) {
-                    _canRedefine = Boolean.FALSE;
-                } else if (JavaVersions.VERSION == 5) {
-                    // if inst is non-null and we're using Java 5,
-                    // isRetransformClassesSupported isn't available,
-                    // so we use the more basic class redefinition
-                    // instead.
-                    _canRedefine = Boolean.TRUE;
-                } else {
-                    _canRedefine = (Boolean) Instrumentation.class.getMethod(
-                        "isRetransformClassesSupported").invoke(inst);
-                }
-            } catch (Exception e) {
-                _canRedefine = Boolean.FALSE;
-            }
-        }
-        return _canRedefine.booleanValue();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.UnmodifiableClassException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.ProtectionDomain;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.io.IOException;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.lib.util.JavaVersions;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Redefines the method bodies of existing classes. Supports Java 5 VMs that
+ * have a javaagent installed on the command line as well as newer VMs without
+ * any javaagent flag.
+ *
+ * @since 1.0.0
+ */
+public class ClassRedefiner {
+
+    private static final Localizer _loc = 
+        Localizer.forPackage(ClassRedefiner.class);
+
+    private static Boolean _canRedefine = null;
+
+    /**
+     * For each element in <code>classes</code>, this method will redefine
+     * all the element's methods such that field accesses are intercepted
+     * in-line. If {@link #canRedefineClasses()} returns <code>false</code>,
+     * this method is a no-op.
+     */
+    public static void redefineClasses(OpenJPAConfiguration conf,
+        final Map<Class,byte[]> classes) {
+        if (classes == null || classes.size() == 0 || !canRedefineClasses())
+            return;
+
+        Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
+        Instrumentation inst = null;
+        ClassFileTransformer t = null;
+        try {
+            inst = InstrumentationFactory.getInstrumentation();
+
+            Class[] array = classes.keySet().toArray(new Class[classes.size()]);
+            if (JavaVersions.VERSION >= 6) {
+                log.trace(_loc.get("retransform-types", classes.keySet()));
+
+                t = new ClassFileTransformer() {
+                    public byte[] transform(ClassLoader loader, String clsName,
+                        Class<?> classBeingRedefined, ProtectionDomain pd,
+                        byte[] classfileBuffer) {
+                        return classes.get(classBeingRedefined);
+                    }
+                };
+                
+                // these are Java 6 methods, and we don't have a Java 6 build
+                // module yet. The cost of reflection here is negligible
+                // compared to the redefinition / enhancement costs in total,
+                // so this should not be a big problem.
+                Method meth = inst.getClass().getMethod("addTransformer",
+                    new Class[] { ClassFileTransformer.class, boolean.class });
+                meth.invoke(inst, new Object[] { t, true });
+                meth = inst.getClass().getMethod("retransformClasses",
+                    new Class[] { array.getClass() });
+                meth.invoke(inst, new Object[] { array });
+            } else {
+                log.trace(_loc.get("redefine-types", classes.keySet()));
+                // in a Java 5 context, we can use class redefinition instead
+                ClassDefinition[] defs = new ClassDefinition[array.length];
+                for (int i = 0; i < defs.length; i++)
+                    defs[i] = new ClassDefinition(array[i],
+                        classes.get(array[i]));
+                inst.redefineClasses(defs);
+            }
+        } catch (NoSuchMethodException e) {
+            throw new InternalException(e);
+        } catch (IllegalAccessException e) {
+            throw new InternalException(e);
+        } catch (InvocationTargetException e) {
+            throw new UserException(e.getCause());
+        } catch (IOException e) {
+            throw new InternalException(e);
+        } catch (ClassNotFoundException e) {
+            throw new InternalException(e);
+        } catch (UnmodifiableClassException e) {
+            throw new InternalException(e);
+        } finally {
+            if (inst != null && t != null)
+                inst.removeTransformer(t);
+        }
+    }
+
+    /**
+     * @return whether or not this VM has an instrumentation installed that
+     * permits redefinition of classes. This assumes that all the arguments
+     * will be modifiable classes according to
+     * {@link java.lang.instrument.Instrumentation#isModifiableClass}, and
+     * only checks whether or not an instrumentation is available and
+     * if retransformation is possible.
+     */
+    public static boolean canRedefineClasses() {
+        if (_canRedefine == null) {
+            try {
+                Instrumentation inst = InstrumentationFactory
+                    .getInstrumentation();
+                if (inst == null) {
+                    _canRedefine = Boolean.FALSE;
+                } else if (JavaVersions.VERSION == 5) {
+                    // if inst is non-null and we're using Java 5,
+                    // isRetransformClassesSupported isn't available,
+                    // so we use the more basic class redefinition
+                    // instead.
+                    _canRedefine = Boolean.TRUE;
+                } else {
+                    _canRedefine = (Boolean) Instrumentation.class.getMethod(
+                        "isRetransformClassesSupported").invoke(inst);
+                }
+            } catch (Exception e) {
+                _canRedefine = Boolean.FALSE;
+            }
+        }
+        return _canRedefine.booleanValue();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/DynamicPersistenceCapable.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/DynamicPersistenceCapable.java
index 04516f0..7861462 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/DynamicPersistenceCapable.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/DynamicPersistenceCapable.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-/**
- * Instances that implement this marker interface are dynamically-generated
- * subtypes of managed types that were loaded before being enhanced.
- *
- * @since 1.0.0
- */
-public interface DynamicPersistenceCapable {
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+/**
+ * Instances that implement this marker interface are dynamically-generated
+ * subtypes of managed types that were loaded before being enhanced.
+ *
+ * @since 1.0.0
+ */
+public interface DynamicPersistenceCapable {
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java
index 53cc3c1..f7f4d44 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java
@@ -1,302 +1,302 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.BytecodeWriter;
-import org.apache.openjpa.lib.util.JavaVersions;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Files;
-import org.apache.openjpa.lib.util.Localizer.Message;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.util.GeneratedClasses;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.UserException;
-import serp.bytecode.BCClass;
-
-/**
- * Redefines the method bodies of existing unenhanced classes to make them
- * notify state managers of mutations.
- *
- * @since 1.0.0
- */
-public class ManagedClassSubclasser {
-    private static final Localizer _loc = Localizer.forPackage(
-        ManagedClassSubclasser.class);
-
-    /**
-     * For each element in <code>classes</code>, creates and registers a
-     * new subclass that implements {@link PersistenceCapable}, and prepares
-     * OpenJPA to handle new instances of the unenhanced type. If this is
-     * invoked in a Java 6 environment, this method will redefine the methods
-     * for each class in the argument list such that field accesses are
-     * intercepted in-line. If invoked in a Java 5 environment, this
-     * redefinition is not possible; in these contexts, when using field
-     * access, OpenJPA will need to do state comparisons to detect any change
-     * to any instance at any time, and when using property access, OpenJPA
-     * will need to do state comparisons to detect changes to newly inserted
-     * instances after a flush has been called.
-     *
-     * @return the new subclasses, or <code>null</code> if <code>classes</code>
-     * is <code>null</code>.
-     * @throws UserException if <code>conf</code> requires build-time
-     * enhancement and <code>classes</code> includes unenhanced types.
-     *
-     * @since 1.0.0
-     */
-    public static List<Class> prepareUnenhancedClasses(
-        final OpenJPAConfiguration conf,
-        final Collection<? extends Class> classes,
-        final ClassLoader envLoader) {
-        if (classes == null)
-            return null;
-        if (classes.size() == 0)
-            return Collections.EMPTY_LIST;
-
-        Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
-        if (conf.getRuntimeUnenhancedClassesConstant()
-            != RuntimeUnenhancedClasssesModes.SUPPORTED) {
-            Collection unenhanced = new ArrayList();
-            for (Class cls : classes)
-                if (!PersistenceCapable.class.isAssignableFrom(cls))
-                    unenhanced.add(cls);
-            if (unenhanced.size() > 0) {
-                Message msg = _loc.get("runtime-optimization-disabled",
-                    unenhanced);
-                if (conf.getRuntimeUnenhancedClassesConstant()
-                    == RuntimeUnenhancedClasssesModes.WARN)
-                    log.warn(msg);
-                else
-                    throw new UserException(msg);
-            }
-            return null;
-        }
-
-        boolean redefine = ClassRedefiner.canRedefineClasses();
-        if (redefine)
-            log.info(_loc.get("enhance-and-subclass-and-redef-start",
-                classes));
-        else
-            log.info(_loc.get("enhance-and-subclass-no-redef-start",
-                classes));
-
-        final Map<Class, byte[]> map = new HashMap<Class, byte[]>();
-        final List subs = new ArrayList(classes.size());
-        final List ints = new ArrayList(classes.size());
-        Set<Class> unspecified = null;
-        for (Iterator iter = classes.iterator(); iter.hasNext(); ) {
-            final Class cls = (Class) iter.next();
-            final PCEnhancer enhancer = new PCEnhancer(conf, cls); 
-
-            enhancer.setBytecodeWriter(new BytecodeWriter() {
-                public void write(BCClass bc) throws IOException {
-                    ManagedClassSubclasser.write(bc, enhancer, map,
-                        cls, subs, ints);
-                }
-            });
-            if (redefine)
-                enhancer.setRedefine(true);
-            enhancer.setCreateSubclass(true);
-            enhancer.setAddDefaultConstructor(true);
-
-            // set this before enhancement as well as after since enhancement
-            // uses a different metadata repository, and the metadata config
-            // matters in the enhancement contract. Don't do any warning here,
-            // since we'll issue warnings when we do the final metadata
-            // reconfiguration at the end of this method.
-            configureMetaData(enhancer.getMetaData(), conf, redefine, false);
-
-            unspecified = collectRelatedUnspecifiedTypes(enhancer.getMetaData(),
-                classes, unspecified);
-
-            int runResult = enhancer.run();
-            if (runResult == PCEnhancer.ENHANCE_PC) {
-                try {
-                    enhancer.record();
-                } catch (IOException e) {
-                    // our impl of BytecodeWriter doesn't throw IOException
-                    throw new InternalException(e);
-                }
-            }
-        }
-
-        if (unspecified != null && !unspecified.isEmpty())
-            throw new UserException(_loc.get("unspecified-unenhanced-types",
-                classes, unspecified));
-
-        ClassRedefiner.redefineClasses(conf, map);
-        for (Class cls : map.keySet()) {
-            setIntercepting(conf, envLoader, cls);
-            configureMetaData(conf, envLoader, cls, redefine);
-        }
-        for (Class cls : (Collection<Class>) subs)
-            configureMetaData(conf, envLoader, cls, redefine);
-        for (Class cls : (Collection<Class>) ints)
-            setIntercepting(conf, envLoader, cls);
-
-        return subs;
-    }
-
-    private static Set<Class> collectRelatedUnspecifiedTypes(ClassMetaData meta,
-        Collection<? extends Class> classes, Set<Class> unspecified) {
-        unspecified = collectUnspecifiedType(meta.getPCSuperclass(), classes,
-            unspecified);
-
-        for (FieldMetaData fmd : meta.getFields()) {
-            if (fmd.isTransient())
-                continue;
-            if (fmd.isTypePC())
-                unspecified = collectUnspecifiedType(fmd.getType(), classes,
-                    unspecified);
-            if (fmd.getElement() != null && fmd.getElement().isTypePC())
-                unspecified = collectUnspecifiedType(fmd.getElement().getType(),
-                    classes, unspecified);
-            if (fmd.getKey() != null && fmd.getKey().isTypePC())
-                unspecified = collectUnspecifiedType(fmd.getKey().getType(),
-                    classes, unspecified);
-            if (fmd.getValue() != null && fmd.getValue().isTypePC())
-                unspecified = collectUnspecifiedType(fmd.getValue().getType(),
-                    classes, unspecified);
-        }
-        return unspecified;
-    }
-
-    private static Set<Class> collectUnspecifiedType(Class cls,
-        Collection<? extends Class> classes, Set<Class> unspecified) {
-        if (cls != null && !classes.contains(cls)
-            && !ImplHelper.isManagedType(null, cls)) {
-            if (unspecified == null)
-                unspecified = new HashSet<Class>();
-            unspecified.add(cls);
-        }
-        return unspecified;
-    }
-
-    private static void configureMetaData(OpenJPAConfiguration conf,
-        ClassLoader envLoader, Class cls, boolean redefineAvailable) {
-        ClassMetaData meta = conf.getMetaDataRepositoryInstance()
-            .getMetaData(cls, envLoader, true);
-        configureMetaData(meta, conf, redefineAvailable, true);
-    }
-
-    private static void configureMetaData(ClassMetaData meta,
-        OpenJPAConfiguration conf, boolean redefineAvailable, boolean warn) {
-
-        setDetachedState(meta);
-
-        if (warn && meta.getAccessType() == ClassMetaData.ACCESS_FIELD
-            && !redefineAvailable) {
-            // only warn about declared fields; superclass fields will be
-            // warned about when the superclass is handled
-            for (FieldMetaData fmd : meta.getDeclaredFields()) {
-                switch (fmd.getTypeCode()) {
-                    case JavaTypes.COLLECTION:
-                    case JavaTypes.MAP:
-                        // we can lazily load these, since we own the
-                        // relationship container
-                        break;
-                    default:
-                        if (!fmd.isInDefaultFetchGroup()
-                            && !(fmd.isVersion() || fmd.isPrimaryKey())) {
-                            Log log = conf.getLog(
-                                OpenJPAConfiguration.LOG_ENHANCE);
-                            log.warn(_loc.get("subclasser-fetch-group-override",
-                                meta.getDescribedType().getName(),
-                                fmd.getName()));
-                            fmd.setInDefaultFetchGroup(true);
-                        }
-                }
-            }
-        }
-    }
-
-    private static void write(BCClass bc, PCEnhancer enhancer,
-        Map<Class, byte[]> map, Class cls, List subs, List ints)
-        throws IOException {
-
-        if (bc == enhancer.getManagedTypeBytecode()) {
-            // if it was already defined, don't put it in the map,
-            // but do set the metadata accordingly.
-            if (enhancer.isAlreadyRedefined())
-                ints.add(bc.getType());
-            else if (JavaVersions.VERSION >= 5) {
-                map.put(bc.getType(), bc.toByteArray());
-                debugBytecodes(bc);
-            }
-        } else {
-            if (!enhancer.isAlreadySubclassed()) {
-                debugBytecodes(bc);
-                
-                // this is the new subclass
-                ClassLoader loader = GeneratedClasses.getMostDerivedLoader(
-                    cls, PersistenceCapable.class);
-                subs.add(GeneratedClasses.loadBCClass(bc, loader));
-            }
-        }
-    }
-
-    private static void debugBytecodes(BCClass bc) throws IOException {
-        // Write the bytecodes to disk for debugging purposes.
-        if ("true".equals(System.getProperty(
-            ManagedClassSubclasser.class.getName() + ".dumpBytecodes")))
-        {
-            File tmp = new File(System.getProperty("java.io.tmpdir"));
-            File dir = new File(tmp, "openjpa");
-            dir = new File(dir, "pcsubclasses");
-            dir.mkdirs();
-            dir = Files.getPackageFile(dir, bc.getPackageName(), true);
-            File f = new File(dir, bc.getClassName() + ".class");
-            System.err.println("Writing to " + f);
-            bc.write(f);
-        }
-    }
-
-    private static void setIntercepting(OpenJPAConfiguration conf,
-        ClassLoader envLoader, Class cls) {
-        ClassMetaData meta = conf.getMetaDataRepositoryInstance()
-            .getMetaData(cls, envLoader, true);
-        meta.setIntercepting(true);
-    }
-
-    /**
-     * If the metadata is configured to use a synthetic
-     * detached state, reset it to not use a detached
-     * state field, since we can't add fields when redefining.
-     */
-    private static void setDetachedState(ClassMetaData meta) {
-        if (ClassMetaData.SYNTHETIC.equals(meta.getDetachedState()))
-            meta.setDetachedState(null);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.BytecodeWriter;
+import org.apache.openjpa.lib.util.JavaVersions;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Files;
+import org.apache.openjpa.lib.util.Localizer.Message;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.GeneratedClasses;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.UserException;
+import serp.bytecode.BCClass;
+
+/**
+ * Redefines the method bodies of existing unenhanced classes to make them
+ * notify state managers of mutations.
+ *
+ * @since 1.0.0
+ */
+public class ManagedClassSubclasser {
+    private static final Localizer _loc = Localizer.forPackage(
+        ManagedClassSubclasser.class);
+
+    /**
+     * For each element in <code>classes</code>, creates and registers a
+     * new subclass that implements {@link PersistenceCapable}, and prepares
+     * OpenJPA to handle new instances of the unenhanced type. If this is
+     * invoked in a Java 6 environment, this method will redefine the methods
+     * for each class in the argument list such that field accesses are
+     * intercepted in-line. If invoked in a Java 5 environment, this
+     * redefinition is not possible; in these contexts, when using field
+     * access, OpenJPA will need to do state comparisons to detect any change
+     * to any instance at any time, and when using property access, OpenJPA
+     * will need to do state comparisons to detect changes to newly inserted
+     * instances after a flush has been called.
+     *
+     * @return the new subclasses, or <code>null</code> if <code>classes</code>
+     * is <code>null</code>.
+     * @throws UserException if <code>conf</code> requires build-time
+     * enhancement and <code>classes</code> includes unenhanced types.
+     *
+     * @since 1.0.0
+     */
+    public static List<Class> prepareUnenhancedClasses(
+        final OpenJPAConfiguration conf,
+        final Collection<? extends Class> classes,
+        final ClassLoader envLoader) {
+        if (classes == null)
+            return null;
+        if (classes.size() == 0)
+            return Collections.EMPTY_LIST;
+
+        Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
+        if (conf.getRuntimeUnenhancedClassesConstant()
+            != RuntimeUnenhancedClasssesModes.SUPPORTED) {
+            Collection unenhanced = new ArrayList();
+            for (Class cls : classes)
+                if (!PersistenceCapable.class.isAssignableFrom(cls))
+                    unenhanced.add(cls);
+            if (unenhanced.size() > 0) {
+                Message msg = _loc.get("runtime-optimization-disabled",
+                    unenhanced);
+                if (conf.getRuntimeUnenhancedClassesConstant()
+                    == RuntimeUnenhancedClasssesModes.WARN)
+                    log.warn(msg);
+                else
+                    throw new UserException(msg);
+            }
+            return null;
+        }
+
+        boolean redefine = ClassRedefiner.canRedefineClasses();
+        if (redefine)
+            log.info(_loc.get("enhance-and-subclass-and-redef-start",
+                classes));
+        else
+            log.info(_loc.get("enhance-and-subclass-no-redef-start",
+                classes));
+
+        final Map<Class, byte[]> map = new HashMap<Class, byte[]>();
+        final List subs = new ArrayList(classes.size());
+        final List ints = new ArrayList(classes.size());
+        Set<Class> unspecified = null;
+        for (Iterator iter = classes.iterator(); iter.hasNext(); ) {
+            final Class cls = (Class) iter.next();
+            final PCEnhancer enhancer = new PCEnhancer(conf, cls); 
+
+            enhancer.setBytecodeWriter(new BytecodeWriter() {
+                public void write(BCClass bc) throws IOException {
+                    ManagedClassSubclasser.write(bc, enhancer, map,
+                        cls, subs, ints);
+                }
+            });
+            if (redefine)
+                enhancer.setRedefine(true);
+            enhancer.setCreateSubclass(true);
+            enhancer.setAddDefaultConstructor(true);
+
+            // set this before enhancement as well as after since enhancement
+            // uses a different metadata repository, and the metadata config
+            // matters in the enhancement contract. Don't do any warning here,
+            // since we'll issue warnings when we do the final metadata
+            // reconfiguration at the end of this method.
+            configureMetaData(enhancer.getMetaData(), conf, redefine, false);
+
+            unspecified = collectRelatedUnspecifiedTypes(enhancer.getMetaData(),
+                classes, unspecified);
+
+            int runResult = enhancer.run();
+            if (runResult == PCEnhancer.ENHANCE_PC) {
+                try {
+                    enhancer.record();
+                } catch (IOException e) {
+                    // our impl of BytecodeWriter doesn't throw IOException
+                    throw new InternalException(e);
+                }
+            }
+        }
+
+        if (unspecified != null && !unspecified.isEmpty())
+            throw new UserException(_loc.get("unspecified-unenhanced-types",
+                classes, unspecified));
+
+        ClassRedefiner.redefineClasses(conf, map);
+        for (Class cls : map.keySet()) {
+            setIntercepting(conf, envLoader, cls);
+            configureMetaData(conf, envLoader, cls, redefine);
+        }
+        for (Class cls : (Collection<Class>) subs)
+            configureMetaData(conf, envLoader, cls, redefine);
+        for (Class cls : (Collection<Class>) ints)
+            setIntercepting(conf, envLoader, cls);
+
+        return subs;
+    }
+
+    private static Set<Class> collectRelatedUnspecifiedTypes(ClassMetaData meta,
+        Collection<? extends Class> classes, Set<Class> unspecified) {
+        unspecified = collectUnspecifiedType(meta.getPCSuperclass(), classes,
+            unspecified);
+
+        for (FieldMetaData fmd : meta.getFields()) {
+            if (fmd.isTransient())
+                continue;
+            if (fmd.isTypePC())
+                unspecified = collectUnspecifiedType(fmd.getType(), classes,
+                    unspecified);
+            if (fmd.getElement() != null && fmd.getElement().isTypePC())
+                unspecified = collectUnspecifiedType(fmd.getElement().getType(),
+                    classes, unspecified);
+            if (fmd.getKey() != null && fmd.getKey().isTypePC())
+                unspecified = collectUnspecifiedType(fmd.getKey().getType(),
+                    classes, unspecified);
+            if (fmd.getValue() != null && fmd.getValue().isTypePC())
+                unspecified = collectUnspecifiedType(fmd.getValue().getType(),
+                    classes, unspecified);
+        }
+        return unspecified;
+    }
+
+    private static Set<Class> collectUnspecifiedType(Class cls,
+        Collection<? extends Class> classes, Set<Class> unspecified) {
+        if (cls != null && !classes.contains(cls)
+            && !ImplHelper.isManagedType(null, cls)) {
+            if (unspecified == null)
+                unspecified = new HashSet<Class>();
+            unspecified.add(cls);
+        }
+        return unspecified;
+    }
+
+    private static void configureMetaData(OpenJPAConfiguration conf,
+        ClassLoader envLoader, Class cls, boolean redefineAvailable) {
+        ClassMetaData meta = conf.getMetaDataRepositoryInstance()
+            .getMetaData(cls, envLoader, true);
+        configureMetaData(meta, conf, redefineAvailable, true);
+    }
+
+    private static void configureMetaData(ClassMetaData meta,
+        OpenJPAConfiguration conf, boolean redefineAvailable, boolean warn) {
+
+        setDetachedState(meta);
+
+        if (warn && meta.getAccessType() == ClassMetaData.ACCESS_FIELD
+            && !redefineAvailable) {
+            // only warn about declared fields; superclass fields will be
+            // warned about when the superclass is handled
+            for (FieldMetaData fmd : meta.getDeclaredFields()) {
+                switch (fmd.getTypeCode()) {
+                    case JavaTypes.COLLECTION:
+                    case JavaTypes.MAP:
+                        // we can lazily load these, since we own the
+                        // relationship container
+                        break;
+                    default:
+                        if (!fmd.isInDefaultFetchGroup()
+                            && !(fmd.isVersion() || fmd.isPrimaryKey())) {
+                            Log log = conf.getLog(
+                                OpenJPAConfiguration.LOG_ENHANCE);
+                            log.warn(_loc.get("subclasser-fetch-group-override",
+                                meta.getDescribedType().getName(),
+                                fmd.getName()));
+                            fmd.setInDefaultFetchGroup(true);
+                        }
+                }
+            }
+        }
+    }
+
+    private static void write(BCClass bc, PCEnhancer enhancer,
+        Map<Class, byte[]> map, Class cls, List subs, List ints)
+        throws IOException {
+
+        if (bc == enhancer.getManagedTypeBytecode()) {
+            // if it was already defined, don't put it in the map,
+            // but do set the metadata accordingly.
+            if (enhancer.isAlreadyRedefined())
+                ints.add(bc.getType());
+            else if (JavaVersions.VERSION >= 5) {
+                map.put(bc.getType(), bc.toByteArray());
+                debugBytecodes(bc);
+            }
+        } else {
+            if (!enhancer.isAlreadySubclassed()) {
+                debugBytecodes(bc);
+                
+                // this is the new subclass
+                ClassLoader loader = GeneratedClasses.getMostDerivedLoader(
+                    cls, PersistenceCapable.class);
+                subs.add(GeneratedClasses.loadBCClass(bc, loader));
+            }
+        }
+    }
+
+    private static void debugBytecodes(BCClass bc) throws IOException {
+        // Write the bytecodes to disk for debugging purposes.
+        if ("true".equals(System.getProperty(
+            ManagedClassSubclasser.class.getName() + ".dumpBytecodes")))
+        {
+            File tmp = new File(System.getProperty("java.io.tmpdir"));
+            File dir = new File(tmp, "openjpa");
+            dir = new File(dir, "pcsubclasses");
+            dir.mkdirs();
+            dir = Files.getPackageFile(dir, bc.getPackageName(), true);
+            File f = new File(dir, bc.getClassName() + ".class");
+            System.err.println("Writing to " + f);
+            bc.write(f);
+        }
+    }
+
+    private static void setIntercepting(OpenJPAConfiguration conf,
+        ClassLoader envLoader, Class cls) {
+        ClassMetaData meta = conf.getMetaDataRepositoryInstance()
+            .getMetaData(cls, envLoader, true);
+        meta.setIntercepting(true);
+    }
+
+    /**
+     * If the metadata is configured to use a synthetic
+     * detached state, reset it to not use a detached
+     * state field, since we can't add fields when redefining.
+     */
+    private static void setDetachedState(ClassMetaData meta) {
+        if (ClassMetaData.SYNTHETIC.equals(meta.getDetachedState()))
+            meta.setDetachedState(null);
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedInstanceProvider.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedInstanceProvider.java
index 1934f15..ebdd746 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedInstanceProvider.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ManagedInstanceProvider.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-/**
- * Instances of this interface can provide an underlying instance.
- *
- * @since 1.0.0
- */
-public interface ManagedInstanceProvider {
-    public Object getManagedInstance();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+/**
+ * Instances of this interface can provide an underlying instance.
+ *
+ * @since 1.0.0
+ */
+public interface ManagedInstanceProvider {
+    public Object getManagedInstance();
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
index 8c189ee..dd95fa2 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
@@ -1,1077 +1,1077 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.enhance;
-
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.kernel.AbstractPCData;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCData;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.util.InternalException;
-import serp.bytecode.BCClass;
-import serp.bytecode.BCField;
-import serp.bytecode.BCMethod;
-import serp.bytecode.Code;
-import serp.bytecode.Constants;
-import serp.bytecode.ExceptionHandler;
-import serp.bytecode.Instruction;
-import serp.bytecode.JumpInstruction;
-import serp.bytecode.LookupSwitchInstruction;
-
-/**
- * Generates {@link PCData} instances which avoid primitve wrappers
- * to optimize memory use and performance at the cost of slightly higher
- * startup time.
- *
- * @author Steve Kim
- * @nojavadoc
- * @since 0.3.2
- */
-public class PCDataGenerator
-    extends DynamicStorageGenerator {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (PCDataGenerator.class);
-
-    protected static final String POSTFIX = "$openjpapcdata";
-
-    private final Map _generated = new ConcurrentHashMap();
-    private final OpenJPAConfiguration _conf;
-    private final Log _log;
-
-    public PCDataGenerator(OpenJPAConfiguration conf) {
-        _conf = conf;
-        _log = _conf.getLogFactory().getLog(OpenJPAConfiguration.LOG_ENHANCE);
-    }
-
-    /**
-     * Return the configuration.
-     */
-    public OpenJPAConfiguration getConfiguration() {
-        return _conf;
-    }
-
-    /**
-     * Return a {@link PCData} instance for the given oid and metadata.
-     */
-    public PCData generatePCData(Object oid, ClassMetaData meta) {
-        if (meta == null)
-            return null;
-        Class type = meta.getDescribedType();
-        DynamicStorage storage = (DynamicStorage) _generated.get(type);
-        if (storage == null) {
-            storage = generateStorage(meta);
-            _generated.put(type, storage);
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("pcdata-created", type.getName(), meta));
-        }
-        DynamicPCData data = (DynamicPCData) storage.newInstance();
-        data.setId(oid);
-        data.setStorageGenerator(this);
-        finish(data, meta);
-        return data;
-    }
-
-    /**
-     * Actually generate the factory instance.
-     */
-    private DynamicStorage generateStorage(ClassMetaData meta) {
-        if (_log.isTraceEnabled())
-            _log.trace(_loc.get("pcdata-generate", meta));
-
-        FieldMetaData[] fields = meta.getFields();
-        int[] types = new int[fields.length];
-        for (int i = 0; i < types.length; i++)
-            types[i] = replaceType(fields[i]);
-        return generateStorage(types, meta);
-    }
-
-    /**
-     * Perform any final actions before the pcdata is returned to client code.
-     */
-    protected void finish(DynamicPCData data, ClassMetaData meta) {
-    }
-
-    protected int getCreateFieldMethods(int typeCode) {
-        if (typeCode >= JavaTypes.OBJECT)
-            return POLICY_SILENT;
-        // don't bother creating set/get<Primitive> methods
-        return POLICY_EMPTY;
-    }
-
-    protected void declareClasses(BCClass bc) {
-        super.declareClasses(bc);
-        bc.declareInterface(DynamicPCData.class);
-        bc.setSuperclass(AbstractPCData.class);
-    }
-
-    protected final String getClassName(Object obj) {
-        return getUniqueName(((ClassMetaData) obj).getDescribedType());
-    }
-
-    /**
-     * Creates a unique name for the given type's pcdata implementation.
-     */
-    protected String getUniqueName(Class type) {
-        return type.getName() + "$" + System.identityHashCode(type) + POSTFIX;
-    }
-
-    protected final void decorate(Object obj, BCClass bc, int[] types) {
-        super.decorate(obj, bc, types);
-        ClassMetaData meta = (ClassMetaData) obj;
-
-        enhanceConstructor(bc);
-        addBaseFields(bc);
-        addImplDataMethods(bc, meta);
-        addFieldImplDataMethods(bc, meta);
-        addVersionMethods(bc);
-        addGetType(bc, meta);
-        addLoadMethod(bc, meta);
-        addLoadWithFieldsMethod(bc, meta);
-        addStoreMethods(bc, meta);
-        addNewEmbedded(bc);
-        addGetData(bc);
-        decorate(bc, meta);
-    }
-
-    /**
-     * Apply additional decoration to generated class.
-     */
-    protected void decorate(BCClass bc, ClassMetaData meta) {
-    }
-
-    /**
-     * Enhance constructor to initialize fields
-     */
-    private void enhanceConstructor(BCClass bc) {
-        BCMethod cons = bc.getDeclaredMethod("<init>", (String[]) null);
-        Code code = cons.getCode(false);
-        code.afterLast();
-        code.previous();
-
-        // private BitSet loaded = new BitSet();
-        BCField loaded = addBeanField(bc, "loaded", BitSet.class);
-        loaded.setFinal(true);
-        code.aload().setThis();
-        code.anew().setType(BitSet.class);
-        code.dup();
-        code.constant().setValue(bc.getFields().length);
-        code.invokespecial().setMethod(BitSet.class, "<init>", void.class,
-            new Class[]{ int.class });
-        code.putfield().setField(loaded);
-
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Have to load the type since it may not be available to the
-     * same classloader (i.e. rar vs. ear). The context classloader
-     * (i.e. the user app classloader) should be fine.
-     */
-    private void addGetType(BCClass bc, ClassMetaData meta) {
-        BCField type = bc.declareField("type", Class.class);
-        type.setStatic(true);
-        type.makePrivate();
-        // public Class getType() {
-        BCMethod getter = bc.declareMethod("getType", Class.class, null);
-        getter.makePublic();
-        Code code = getter.getCode(true);
-        // if (type == null) {
-        // 		try {
-        // 			type = Class.forName
-        // 				(meta.getDescribedType().getName(), true,
-        // 				Thread.currentThread().getContextClassLoader());
-        // 		} catch (ClassNotFoundException cnfe) {
-        // 			throw new InternalException();
-        // 		}
-        // }
-        code.getstatic().setField(type);
-
-        Collection jumps = new LinkedList();
-        jumps.add(code.ifnonnull());
-        ExceptionHandler handler = code.addExceptionHandler();
-
-        handler.setTryStart(code.constant().setValue
-            (meta.getDescribedType().getName()));
-        code.constant().setValue(true);
-        code.invokestatic().setMethod(Thread.class, "currentThread",
-            Thread.class, null);
-        code.invokevirtual().setMethod(Thread.class, "getContextClassLoader",
-            ClassLoader.class, null);
-        code.invokestatic().setMethod(Class.class, "forName", Class.class,
-            new Class[]{ String.class, boolean.class, ClassLoader.class });
-        code.putstatic().setField(type);
-        Instruction go2 = code.go2();
-        jumps.add(go2);
-        handler.setTryEnd(go2);
-        handler.setCatch(ClassNotFoundException.class);
-        handler.setHandlerStart(throwException
-            (code, InternalException.class));
-        setTarget(code.getstatic().setField(type), jumps);
-        code.areturn();
-
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Declare standard dynamic pcdata fields.
-     */
-    private void addBaseFields(BCClass bc) {
-        addBeanField(bc, "id", Object.class);
-        BCField field = addBeanField(bc, "storageGenerator",
-            PCDataGenerator.class);
-        field.setAccessFlags(field.getAccessFlags()
-            | Constants.ACCESS_TRANSIENT);
-    }
-
-    /**
-     * Add methods for loading and storing class-level impl data.
-     */
-    private void addImplDataMethods(BCClass bc, ClassMetaData meta) {
-        // void storeImplData(OpenJPAStateManager);
-        BCMethod meth = bc.declareMethod("storeImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-        Code code = meth.getCode(true);
-
-        BCField impl = null;
-        if (!usesImplData(meta))
-            code.vreturn();
-        else {
-            // if (sm.isImplDataCacheable())
-            // 		setImplData(sm.getImplData());
-            impl = addBeanField(bc, "implData", Object.class);
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "isImplDataCacheable", boolean.class, null);
-            JumpInstruction ifins = code.ifeq();
-            code.aload().setThis();
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getImplData", Object.class, null);
-            code.invokevirtual().setMethod("setImplData", void.class,
-                new Class[]{ Object.class });
-            ifins.setTarget(code.vreturn());
-        }
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // void loadImplData(OpenJPAStateManager);
-        meth = bc.declareMethod("loadImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-        code = meth.getCode(true);
-        if (!usesImplData(meta))
-            code.vreturn();
-        else {
-            // if (sm.getImplData() == null && implData != null)
-            // 		sm.setImplData(impl, true);
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getImplData", Object.class, null);
-            JumpInstruction ifins = code.ifnonnull();
-            code.aload().setThis();
-            code.getfield().setField(impl);
-            JumpInstruction ifins2 = code.ifnull();
-            code.aload().setParam(0);
-            code.aload().setThis();
-            code.getfield().setField(impl);
-            code.constant().setValue(true);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "setImplData", void.class,
-                new Class[]{ Object.class, boolean.class });
-            Instruction ins = code.vreturn();
-            ifins.setTarget(ins);
-            ifins2.setTarget(ins);
-        }
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Add methods for loading and storing class-level impl data.
-     */
-    private void addFieldImplDataMethods(BCClass bc, ClassMetaData meta) {
-        // public void loadImplData(OpenJPAStateManager sm, int i)
-        BCMethod meth = bc.declareMethod("loadImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class, int.class });
-        meth.makePrivate();
-        Code code = meth.getCode(true);
-
-        int count = countImplDataFields(meta);
-        BCField impl = null;
-        if (count == 0)
-            code.vreturn();
-        else {
-            // Object[] fieldImpl
-            impl = bc.declareField("fieldImpl", Object[].class);
-            impl.makePrivate();
-
-            // if (fieldImpl != null)
-            code.aload().setThis();
-            code.getfield().setField(impl);
-            JumpInstruction ifins = code.ifnonnull();
-            code.vreturn();
-
-            // Object obj = null;
-            int obj = code.getNextLocalsIndex();
-            ifins.setTarget(code.constant().setNull());
-            code.astore().setLocal(obj);
-
-            // establish switch target, then move before it
-            Instruction target = code.aload().setLocal(obj);
-            code.previous();
-
-            // switch(i)
-            code.iload().setParam(1);
-            LookupSwitchInstruction lswitch = code.lookupswitch();
-            FieldMetaData[] fields = meta.getFields();
-            int cacheable = 0;
-            for (int i = 0; i < fields.length; i++) {
-                if (!usesImplData(fields[i]))
-                    continue;
-                // case x: obj = fieldImpl[y]; break;
-                lswitch.addCase(i, code.aload().setThis());
-                code.getfield().setField(impl);
-                code.constant().setValue(cacheable++);
-                code.aaload();
-                code.astore().setLocal(obj);
-                code.go2().setTarget(target);
-            }
-            lswitch.setDefaultTarget(target);
-
-            // if (obj != null)
-            code.next();    // jump back over target
-            ifins = code.ifnonnull();
-            code.vreturn();
-
-            // sm.setImplData(index, impl);
-            ifins.setTarget(code.aload().setParam(0));
-            code.iload().setParam(1);
-            code.aload().setLocal(obj);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "setImplData", void.class,
-                new Class[]{ int.class, Object.class });
-            code.vreturn();
-        }
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
-
-        // void storeImplData(OpenJPAStateManager sm, int index, boolean loaded)
-        meth = bc.declareMethod("storeImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class, int.class, boolean.class });
-        code = meth.getCode(true);
-        if (count == 0)
-            code.vreturn();
-        else {
-            // int arrIdx = -1;
-            // switch(index)
-            int arrIdx = code.getNextLocalsIndex();
-            code.constant().setValue(-1);
-            code.istore().setLocal(arrIdx);
-            code.iload().setParam(1);
-            LookupSwitchInstruction lswitch = code.lookupswitch();
-
-            // establish switch target, then move before it
-            Instruction switchTarget = code.iload().setLocal(arrIdx);
-            code.previous();
-
-            FieldMetaData[] fields = meta.getFields();
-            int cacheable = 0;
-            for (int i = 0; i < fields.length; i++) {
-                if (!usesImplData(fields[i]))
-                    continue;
-                // case x: arrIdx = y; break;
-                lswitch.addCase(i, code.constant().setValue(cacheable++));
-                code.istore().setLocal(arrIdx);
-                code.go2().setTarget(switchTarget);
-            }
-            lswitch.setDefaultTarget(switchTarget);
-            code.next();    // step over switch target
-
-            // if (arrIdx != -1)
-            code.constant().setValue(-1);
-            JumpInstruction ifins = code.ificmpne();
-            code.vreturn();
-
-            // create null target, then move before it
-            Instruction nullTarget = code.aload().setThis();
-            code.previous();
-
-            // if (loaded)
-            ifins.setTarget(code.iload().setParam(2));
-            code.ifeq().setTarget(nullTarget);
-
-            // Object obj = sm.getImplData(index)
-            int obj = code.getNextLocalsIndex();
-            code.aload().setParam(0);
-            code.iload().setParam(1);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getImplData", Object.class, new Class[]{ int.class });
-            code.astore().setLocal(obj);
-
-            // if (obj != null)
-            code.aload().setLocal(obj);
-            code.ifnull().setTarget(nullTarget);
-
-            // if (fieldImpl == null)
-            // 		fieldImpl = new Object[fields];
-            code.aload().setThis();
-            code.getfield().setField(impl);
-            ifins = code.ifnonnull();
-            code.aload().setThis();
-            code.constant().setValue(count);
-            code.anewarray().setType(Object.class);
-            code.putfield().setField(impl);
-
-            // fieldImpl[arrIdx] = obj;
-            // return;
-            ifins.setTarget(code.aload().setThis());
-            code.getfield().setField(impl);
-            code.iload().setLocal(arrIdx);
-            code.aload().setLocal(obj);
-            code.aastore();
-            code.vreturn();
-
-            // if (fieldImpl != null)
-            // 		fieldImpl[index] = null;
-            code.next(); // step over nullTarget
-            code.getfield().setField(impl);
-            ifins = code.ifnonnull();
-            code.vreturn();
-            ifins.setTarget(code.aload().setThis());
-            code.getfield().setField(impl);
-            code.iload().setLocal(arrIdx);
-            code.constant().setNull();
-            code.aastore();
-            code.vreturn();
-        }
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Add methods for loading and storing version data.
-     */
-    protected void addVersionMethods(BCClass bc) {
-        // void storeVersion(OpenJPAStateManager sm);
-        addBeanField(bc, "version", Object.class);
-        BCMethod meth = bc.declareMethod("storeVersion", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-        Code code = meth.getCode(true);
-
-        // version = sm.getVersion();
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokeinterface()
-            .setMethod(OpenJPAStateManager.class, "getVersion",
-                Object.class, null);
-        code.putfield().setField("version", Object.class);
-        code.vreturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // void loadVersion(OpenJPAStateManager sm)
-        meth = bc.declareMethod("loadVersion", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-        code = meth.getCode(true);
-
-        // if (sm.getVersion() == null)
-        // 		sm.setVersion(version);
-        code.aload().setParam(0);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "getVersion", Object.class, null);
-        JumpInstruction ifins = code.ifnonnull();
-        code.aload().setParam(0);
-        code.aload().setThis();
-        code.getfield().setField("version", Object.class);
-        code.invokeinterface()
-            .setMethod(OpenJPAStateManager.class, "setVersion",
-                void.class, new Class[]{ Object.class });
-        ifins.setTarget(code.vreturn());
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    private void addLoadMethod(BCClass bc, ClassMetaData meta) {
-        // public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
-        // 		Object context)
-        Code code = addLoadMethod(bc, false);
-        FieldMetaData[] fmds = meta.getFields();
-        Collection jumps = new LinkedList();
-        Collection jumps2;
-		
-        int local = code.getNextLocalsIndex();
-        code.constant().setNull();
-        code.astore().setLocal(local);
-        int inter = code.getNextLocalsIndex();
-        code.constant().setNull();
-        code.astore().setLocal(inter);
-
-        int objectCount = 0;
-        boolean intermediate;
-        for (int i = 0; i < fmds.length; i++) {
-            jumps2 = new LinkedList();
-            intermediate = usesIntermediate(fmds[i]);
-            setTarget(code.aload().setThis(), jumps);
-            // if (loaded.get(i)) or (!loaded.get(i)) depending on inter resp
-            code.getfield().setField("loaded", BitSet.class);
-            code.constant().setValue(i);
-            code.invokevirtual().setMethod(BitSet.class, "get",
-                boolean.class, new Class[]{ int.class });
-            jumps.add(code.ifne());
-
-            if (intermediate)
-                addLoadIntermediate(code, i, objectCount, jumps2, inter);
-            jumps2.add(code.go2());
-
-            // if (fetch.requiresFetch(fmds[i])!=FetchConfiguration.FETCH_NONE)
-            setTarget(code.aload().setParam(1), jumps);
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getMetaData", ClassMetaData.class, null);
-            code.constant().setValue(fmds[i].getIndex());
-            code.invokevirtual().setMethod(ClassMetaData.class,
-                "getField", FieldMetaData.class, new Class[]{int.class});
-            code.invokeinterface().setMethod (FetchConfiguration.class, 
-                "requiresFetch", int.class, new Class[]{FieldMetaData.class});
-            code.constant().setValue(FetchConfiguration.FETCH_NONE);
-            jumps2.add(code.ificmpeq());
-            addLoad(bc, code, fmds[i], objectCount, local, false);
-
-            jumps = jumps2;
-            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
-                objectCount++;
-        }
-        setTarget(code.vreturn(), jumps);
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    private void addLoadWithFieldsMethod(BCClass bc, ClassMetaData meta) {
-        Code code = addLoadMethod(bc, true);
-        // public void load(OpenJPAStateManager sm, BitSet fields,
-        // 		FetchConfiguration fetch, Object conn)
-        FieldMetaData[] fmds = meta.getFields();
-        Collection jumps = new LinkedList();
-        Collection jumps2;
-        int objectCount = 0;
-        boolean intermediate;
-        int local = code.getNextLocalsIndex();
-        code.constant().setNull();
-        code.astore().setLocal(local);
-        int inter = code.getNextLocalsIndex();
-        code.constant().setNull();
-        code.astore().setLocal(inter);
-
-        for (int i = 0; i < fmds.length; i++) {
-            jumps2 = new LinkedList();
-            intermediate = usesIntermediate(fmds[i]);
-            // if (fields.get(i))
-            // {
-            // 		if (loaded.get(i))
-            setTarget(code.aload().setParam(1), jumps);
-            code.constant().setValue(i);
-            code.invokevirtual().setMethod(BitSet.class, "get",
-                boolean.class, new Class[]{ int.class });
-            jumps2.add(code.ifeq());
-            code.aload().setThis();
-            code.getfield().setField("loaded", BitSet.class);
-            code.constant().setValue(i);
-            code.invokevirtual().setMethod(BitSet.class, "get",
-                boolean.class, new Class[]{ int.class });
-            if (intermediate)
-                jumps.add(code.ifeq());
-            else
-                jumps2.add(code.ifeq());
-
-            addLoad(bc, code, fmds[i], objectCount, local, true);
-            if (usesImplData(fmds[i])) {
-                // loadImplData(sm, i);
-                code.aload().setThis();
-                code.aload().setParam(0);
-                code.constant().setValue(i);
-                code.invokevirtual().setMethod("loadImplData", void.class,
-                    new Class[]{ OpenJPAStateManager.class, int.class });
-            }
-
-            // fields.clear(i);
-            code.aload().setParam(1);
-            code.constant().setValue(i);
-            code.invokevirtual().setMethod(BitSet.class, "clear", void.class,
-                new Class[] { int.class });
-
-            jumps2.add(code.go2());
-
-            if (intermediate)
-                setTarget(addLoadIntermediate
-                    (code, i, objectCount, jumps2, inter), jumps);
-
-            jumps = jumps2;
-            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
-                objectCount++;
-        }
-        setTarget(code.vreturn(), jumps);
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Declare and start the base load method.
-     */
-    private Code addLoadMethod(BCClass bc, boolean fields) {
-        Class[] args = null;
-        if (fields)
-            args = new Class[]{ OpenJPAStateManager.class, BitSet.class,
-                FetchConfiguration.class, Object.class };
-        else
-            args = new Class[]{ OpenJPAStateManager.class,
-                FetchConfiguration.class, Object.class };
-        BCMethod load = bc.declareMethod("load", void.class, args);
-        Code code = load.getCode(true);
-
-        //loadVersion(sm);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokevirtual().setMethod("loadVersion", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-
-        //loadImplData(sm);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokevirtual().setMethod("loadImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-        return code;
-    }
-
-    /**
-     * Add the field load.
-     */
-    private Instruction addLoad(BCClass bc, Code code, FieldMetaData fmd,
-        int objectCount, int local, boolean fields) {
-        int index = fmd.getIndex();
-        int typeCode = replaceType(fmd);
-        Instruction first;
-        if (typeCode < JavaTypes.OBJECT) {
-            // sm.store<type>(i, field<i>)
-            Class type = forType(fmd.getTypeCode());
-            first = code.aload().setParam(0);
-            code.constant().setValue(index);
-            code.aload().setThis();
-            code.getfield().setField(getFieldName(index), type);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "store" + StringUtils.capitalize(type.getName()),
-                void.class, new Class[]{ int.class, type });
-        } else {
-            // fmd = sm.getMetaData().getField(i);
-            int offset = fields ? 1 : 0;
-            first = code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getMetaData", ClassMetaData.class, null);
-            code.constant().setValue(fmd.getIndex());
-            code.invokevirtual().setMethod(ClassMetaData.class, "getField",
-                FieldMetaData.class, new Class[]{ int.class });
-            code.astore().setLocal(local);
-            // sm.storeField(i, toField(sm, fmd, objects[objectCount],
-            // 		fetch, context);
-            code.aload().setParam(0);
-            code.constant().setValue(index);
-            code.aload().setThis();
-            code.aload().setParam(0);
-            code.aload().setLocal(local);
-            code.aload().setThis();
-            code.getfield().setField("objects", Object[].class);
-            code.constant().setValue(objectCount);
-            code.aaload();
-            code.aload().setParam(1 + offset);
-            code.aload().setParam(2 + offset);
-            code.invokevirtual().setMethod(bc.getName(), "toField",
-                Object.class.getName(), toStrings(new Class[]{ 
-                OpenJPAStateManager.class, FieldMetaData.class,
-                Object.class, FetchConfiguration.class, Object.class }));
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "storeField", void.class,
-                new Class[]{ int.class, Object.class });
-        }
-        return first;
-    }
-
-    /**
-     * Load intermediate data if possible.
-     */
-    private Instruction addLoadIntermediate(Code code, int index,
-        int objectCount, Collection jumps2, int inter) {
-        // {
-        // 		Object inter = objects[objectCount];
-        Instruction first = code.aload().setThis();
-        code.getfield().setField("objects", Object[].class);
-        code.constant().setValue(objectCount);
-        code.aaload();
-        code.astore().setLocal(inter);
-        // 		if (inter != null && !sm.getLoaded().get(index))
-        code.aload().setLocal(inter);
-        jumps2.add(code.ifnull());
-        code.aload().setParam(0);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "getLoaded", BitSet.class, null);
-        code.constant().setValue(index);
-        code.invokevirtual().setMethod(BitSet.class, "get",
-            boolean.class, new Class[]{ int.class });
-        jumps2.add(code.ifne());
-        //			sm.setIntermediate(index, inter);
-        //	}  // end else
-        code.aload().setParam(0);
-        code.constant().setValue(index);
-        code.aload().setLocal(inter);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "setIntermediate", void.class,
-            new Class[]{ int.class, Object.class });
-        return first;
-    }
-
-    private void addStoreMethods(BCClass bc, ClassMetaData meta) {
-        // i.e. void store(OpenJPAStateManager sm, BitSet fields);
-        addStoreMethod(bc, meta, true);
-        // i.e. void store(OpenJPAStateManager sm);
-        addStoreMethod(bc, meta, false);
-    }
-
-    private void addStoreMethod(BCClass bc, ClassMetaData meta,
-        boolean fields) {
-        BCMethod store;
-        if (fields)
-            store = bc.declareMethod("store", void.class,
-                new Class[]{ OpenJPAStateManager.class, BitSet.class });
-        else
-            store = bc.declareMethod("store", void.class,
-                new Class[]{ OpenJPAStateManager.class });
-        Code code = store.getCode(true);
-
-        // initialize();
-        code.aload().setThis();
-        code.invokevirtual().setMethod("initialize", void.class, null);
-
-        // storeVersion(sm);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokevirtual().setMethod("storeVersion", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-
-        // storeImplData(sm);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokevirtual().setMethod("storeImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-
-        FieldMetaData[] fmds = meta.getFields();
-        Collection jumps = new LinkedList();
-        int objectCount = 0;
-        for (int i = 0; i < fmds.length; i++) {
-            if (fields) {
-                //  if (fields != null && fields.get(index))
-                setTarget(code.aload().setParam(1), jumps);
-                jumps.add(code.ifnull());
-                code.aload().setParam(1);
-                code.constant().setValue(i);
-                code.invokevirtual().setMethod(BitSet.class, "get",
-                    boolean.class, new Class[]{ int.class });
-                jumps.add(code.ifeq());
-            } else {
-                // if (sm.getLoaded().get(index)))
-                setTarget(code.aload().setParam(0), jumps);
-                code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                    "getLoaded", BitSet.class, null);
-                code.constant().setValue(i);
-                code.invokevirtual().setMethod(BitSet.class, "get",
-                    boolean.class, new Class[]{ int.class });
-                jumps.add(code.ifeq());
-            }
-            addStore(bc, code, fmds[i], objectCount);
-            if (usesIntermediate(fmds[i])) {
-                JumpInstruction elseIns = code.go2();
-                // else if (!loaded.get(index))
-                setTarget(code.aload().setThis(), jumps);
-                jumps.add(elseIns);
-                code.getfield().setField("loaded", BitSet.class);
-                code.constant().setValue(i);
-                code.invokevirtual().setMethod(BitSet.class, "get",
-                    boolean.class, new Class[]{ int.class });
-                jumps.add(code.ifne());
-                // Object val = sm.getIntermediate(index);
-                // if (val != null)
-                // 		objects[objectCount] = val;
-                code.aload().setParam(0);
-                code.constant().setValue(i);
-                code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                    "getIntermediate", Object.class, new Class[]{ int.class });
-                int local = code.getNextLocalsIndex();
-                code.astore().setLocal(local);
-                code.aload().setLocal(local);
-                jumps.add(code.ifnull());
-                code.aload().setThis();
-                code.getfield().setField("objects", Object[].class);
-                code.constant().setValue(objectCount);
-                code.aload().setLocal(local);
-                code.aastore();
-            }
-            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
-                objectCount++;
-        }
-        setTarget(code.vreturn(), jumps);
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
-    }
-
-    private void addStore(BCClass bc, Code code, FieldMetaData fmd,
-        int objectCount) {
-        int typeCode = replaceType(fmd);
-        int index = fmd.getIndex();
-        if (typeCode < JavaTypes.OBJECT) {
-            Class type = forType(typeCode);
-            // field<i> = sm.fetch<Type>(index)
-            code.aload().setThis();
-            code.aload().setParam(0);
-            code.constant().setValue(index);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "fetch" + StringUtils.capitalize(type.getName()), type,
-                new Class[]{ int.class });
-            code.putfield().setField(getFieldName(index), type);
-            code.aload().setThis();
-            code.getfield().setField("loaded", BitSet.class);
-            code.constant().setValue(index);
-            code.invokevirtual().setMethod(BitSet.class, "set", void.class,
-                new Class[]{ int.class });
-        } else {
-            // Object val = toData(sm.getMetaData().getField(index),
-            // 		sm.fetchField(index, false), sm.getContext());
-            int local = code.getNextLocalsIndex();
-            code.aload().setThis();
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getMetaData", ClassMetaData.class, null);
-            code.constant().setValue(fmd.getIndex());
-            code.invokevirtual().setMethod(ClassMetaData.class,
-                "getField", FieldMetaData.class, new Class[]{ int.class });
-            code.aload().setParam(0);
-            code.constant().setValue(fmd.getIndex());
-            code.constant().setValue(false);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "fetchField", Object.class, new Class[]
-                { int.class, boolean.class });
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getContext", StoreContext.class, null);
-            code.invokevirtual().setMethod(bc.getName(), "toData",
-                Object.class.getName(), toStrings(new Class []{
-                FieldMetaData.class, Object.class, StoreContext.class }));
-            code.astore().setLocal(local);
-
-            // if (val == NULL) {
-            // 		val = null;
-            // 		loaded.clear(index);
-            // 	} else
-            // 		loaded.set(index);
-            // 	objects[objectCount] = val;
-            code.aload().setLocal(local);
-            code.getstatic().setField(AbstractPCData.class, "NULL",
-                Object.class);
-            JumpInstruction ifins = code.ifacmpne();
-            code.constant().setNull();
-            code.astore().setLocal(local);
-            code.aload().setThis();
-            code.getfield().setField("loaded", BitSet.class);
-            code.constant().setValue(index);
-            code.invokevirtual().setMethod(BitSet.class, "clear", void.class,
-                new Class[]{ int.class });
-            JumpInstruction go2 = code.go2();
-            ifins.setTarget(code.aload().setThis());
-            code.getfield().setField("loaded", BitSet.class);
-            code.constant().setValue(index);
-            code.invokevirtual().setMethod(BitSet.class, "set", void.class,
-                new Class[]{ int.class });
-            go2.setTarget(code.aload().setThis());
-            code.getfield().setField("objects", Object[].class);
-            code.constant().setValue(objectCount);
-            code.aload().setLocal(local);
-            code.aastore();
-        }
-        if (!usesImplData(fmd))
-            return;
-
-        // storeImplData(sm, i, loaded.get(i);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.constant().setValue(index);
-        code.aload().setThis();
-        code.getfield().setField("loaded", BitSet.class);
-        code.constant().setValue(index);
-        code.invokevirtual().setMethod(BitSet.class, "get", boolean.class,
-            new Class[]{ int.class });
-        code.invokevirtual().setMethod("storeImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class, int.class, boolean.class });
-    }
-
-    private void addNewEmbedded(BCClass bc) {
-        // void newEmbeddedPCData(OpenJPAStateManager embedded)
-        BCMethod meth = bc.declareMethod("newEmbeddedPCData", PCData.class,
-            new Class[]{ OpenJPAStateManager.class });
-        Code code = meth.getCode(true);
-        // return getStorageGenerator().generatePCData
-        // 		(sm.getId(), sm.getMetaData());
-        code.aload().setThis();
-        code.getfield().setField("storageGenerator", PCDataGenerator.class);
-        code.aload().setParam(0);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "getId", Object.class, null);
-        code.aload().setParam(0);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "getMetaData", ClassMetaData.class, null);
-        code.invokevirtual().setMethod(PCDataGenerator.class,
-            "generatePCData", PCData.class, new Class[]
-            { Object.class, ClassMetaData.class });
-        code.areturn();
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
-    }
-
-    private void addGetData(BCClass bc) {
-        // return getObjectField(i);
-        BCMethod method = bc.declareMethod("getData", Object.class,
-            new Class[]{ int.class });
-        Code code = method.getCode(true);
-        code.aload().setThis();
-        code.iload().setParam(0);
-        code.invokevirtual().setMethod("getObject", Object.class,
-            new Class[]{ int.class });
-        code.areturn();
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
-    }
-
-    /////////////
-    // Utilities
-    /////////////
-
-    /**
-     * Return a valid {@link JavaTypes} constant for the given field
-     */
-    protected int replaceType(FieldMetaData fmd) {
-        if (usesIntermediate(fmd))
-            return JavaTypes.OBJECT;
-        return fmd.getTypeCode();
-    }
-
-    /**
-     * Whether the given field uses a cacheable intermediate value.
-     */
-    protected boolean usesIntermediate(FieldMetaData fmd) {
-        return fmd.usesIntermediate();
-    }
-
-    /**
-     * Whether the given type might have cacheable class-level impl data.
-     */
-    protected boolean usesImplData(ClassMetaData meta) {
-        return true;
-    }
-
-    /**
-     * Whether the given field might have cacheable impl data.
-     */
-    protected boolean usesImplData(FieldMetaData fmd) {
-        return fmd.usesImplData() == null;
-    }
-
-    /**
-     * The number of fields with cacheable impl data.
-     */
-    private int countImplDataFields(ClassMetaData meta) {
-        FieldMetaData[] fmds = meta.getFields();
-        int count = 0;
-        for (int i = 0; i < fmds.length; i++)
-            if (usesImplData(fmds[i]))
-                count++;
-        return count;
-    }
-
-    /**
-     * Add method which defers to AbstractPCData.
-     */
-    protected void callAbstractPCData(BCClass bc, String name, Class retType,
-        Class[] args) {
-        BCMethod meth = bc.declareMethod(name, retType, args);
-        Code code = meth.getCode(true);
-        code.aload().setThis();
-        for (int i = 0; i < args.length; i++)
-            code.xload().setParam(i).setType(args[i]);
-        code.invokevirtual().setMethod(AbstractPCData.class, name, retType,
-            args);
-        if (!void.class.equals(retType))
-            code.xreturn().setType(retType);
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
-    }
-
-    /**
-     * Set the collection of {@link JumpInstruction}s to the given instruction,
-     * clearing the collection in the process.
-     */
-    protected void setTarget(Instruction ins, Collection jumps) {
-        for (Iterator it = jumps.iterator(); it.hasNext();)
-            ((JumpInstruction) it.next()).setTarget(ins);
-        jumps.clear();
-    }
-
-    /**
-     * Transform the given array of classes to strings.
-     */
-    private static String[] toStrings(Class[] cls) {
-        String[] strings = new String[cls.length];
-        for (int i = 0; i < strings.length; i++)
-            strings[i] = cls[i].getName();
-        return strings;
-    }
-
-    /**
-     * Dynamic {@link PCData}s generated will implement this interface
-     * to simplify initialization.
-     */
-    public static interface DynamicPCData extends PCData {
-
-        public void setId(Object oid);
-
-        public PCDataGenerator getStorageGenerator();
-
-        public void setStorageGenerator (PCDataGenerator generator);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.enhance;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.AbstractPCData;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCData;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.InternalException;
+import serp.bytecode.BCClass;
+import serp.bytecode.BCField;
+import serp.bytecode.BCMethod;
+import serp.bytecode.Code;
+import serp.bytecode.Constants;
+import serp.bytecode.ExceptionHandler;
+import serp.bytecode.Instruction;
+import serp.bytecode.JumpInstruction;
+import serp.bytecode.LookupSwitchInstruction;
+
+/**
+ * Generates {@link PCData} instances which avoid primitve wrappers
+ * to optimize memory use and performance at the cost of slightly higher
+ * startup time.
+ *
+ * @author Steve Kim
+ * @nojavadoc
+ * @since 0.3.2
+ */
+public class PCDataGenerator
+    extends DynamicStorageGenerator {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (PCDataGenerator.class);
+
+    protected static final String POSTFIX = "$openjpapcdata";
+
+    private final Map _generated = new ConcurrentHashMap();
+    private final OpenJPAConfiguration _conf;
+    private final Log _log;
+
+    public PCDataGenerator(OpenJPAConfiguration conf) {
+        _conf = conf;
+        _log = _conf.getLogFactory().getLog(OpenJPAConfiguration.LOG_ENHANCE);
+    }
+
+    /**
+     * Return the configuration.
+     */
+    public OpenJPAConfiguration getConfiguration() {
+        return _conf;
+    }
+
+    /**
+     * Return a {@link PCData} instance for the given oid and metadata.
+     */
+    public PCData generatePCData(Object oid, ClassMetaData meta) {
+        if (meta == null)
+            return null;
+        Class type = meta.getDescribedType();
+        DynamicStorage storage = (DynamicStorage) _generated.get(type);
+        if (storage == null) {
+            storage = generateStorage(meta);
+            _generated.put(type, storage);
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("pcdata-created", type.getName(), meta));
+        }
+        DynamicPCData data = (DynamicPCData) storage.newInstance();
+        data.setId(oid);
+        data.setStorageGenerator(this);
+        finish(data, meta);
+        return data;
+    }
+
+    /**
+     * Actually generate the factory instance.
+     */
+    private DynamicStorage generateStorage(ClassMetaData meta) {
+        if (_log.isTraceEnabled())
+            _log.trace(_loc.get("pcdata-generate", meta));
+
+        FieldMetaData[] fields = meta.getFields();
+        int[] types = new int[fields.length];
+        for (int i = 0; i < types.length; i++)
+            types[i] = replaceType(fields[i]);
+        return generateStorage(types, meta);
+    }
+
+    /**
+     * Perform any final actions before the pcdata is returned to client code.
+     */
+    protected void finish(DynamicPCData data, ClassMetaData meta) {
+    }
+
+    protected int getCreateFieldMethods(int typeCode) {
+        if (typeCode >= JavaTypes.OBJECT)
+            return POLICY_SILENT;
+        // don't bother creating set/get<Primitive> methods
+        return POLICY_EMPTY;
+    }
+
+    protected void declareClasses(BCClass bc) {
+        super.declareClasses(bc);
+        bc.declareInterface(DynamicPCData.class);
+        bc.setSuperclass(AbstractPCData.class);
+    }
+
+    protected final String getClassName(Object obj) {
+        return getUniqueName(((ClassMetaData) obj).getDescribedType());
+    }
+
+    /**
+     * Creates a unique name for the given type's pcdata implementation.
+     */
+    protected String getUniqueName(Class type) {
+        return type.getName() + "$" + System.identityHashCode(type) + POSTFIX;
+    }
+
+    protected final void decorate(Object obj, BCClass bc, int[] types) {
+        super.decorate(obj, bc, types);
+        ClassMetaData meta = (ClassMetaData) obj;
+
+        enhanceConstructor(bc);
+        addBaseFields(bc);
+        addImplDataMethods(bc, meta);
+        addFieldImplDataMethods(bc, meta);
+        addVersionMethods(bc);
+        addGetType(bc, meta);
+        addLoadMethod(bc, meta);
+        addLoadWithFieldsMethod(bc, meta);
+        addStoreMethods(bc, meta);
+        addNewEmbedded(bc);
+        addGetData(bc);
+        decorate(bc, meta);
+    }
+
+    /**
+     * Apply additional decoration to generated class.
+     */
+    protected void decorate(BCClass bc, ClassMetaData meta) {
+    }
+
+    /**
+     * Enhance constructor to initialize fields
+     */
+    private void enhanceConstructor(BCClass bc) {
+        BCMethod cons = bc.getDeclaredMethod("<init>", (String[]) null);
+        Code code = cons.getCode(false);
+        code.afterLast();
+        code.previous();
+
+        // private BitSet loaded = new BitSet();
+        BCField loaded = addBeanField(bc, "loaded", BitSet.class);
+        loaded.setFinal(true);
+        code.aload().setThis();
+        code.anew().setType(BitSet.class);
+        code.dup();
+        code.constant().setValue(bc.getFields().length);
+        code.invokespecial().setMethod(BitSet.class, "<init>", void.class,
+            new Class[]{ int.class });
+        code.putfield().setField(loaded);
+
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Have to load the type since it may not be available to the
+     * same classloader (i.e. rar vs. ear). The context classloader
+     * (i.e. the user app classloader) should be fine.
+     */
+    private void addGetType(BCClass bc, ClassMetaData meta) {
+        BCField type = bc.declareField("type", Class.class);
+        type.setStatic(true);
+        type.makePrivate();
+        // public Class getType() {
+        BCMethod getter = bc.declareMethod("getType", Class.class, null);
+        getter.makePublic();
+        Code code = getter.getCode(true);
+        // if (type == null) {
+        // 		try {
+        // 			type = Class.forName
+        // 				(meta.getDescribedType().getName(), true,
+        // 				Thread.currentThread().getContextClassLoader());
+        // 		} catch (ClassNotFoundException cnfe) {
+        // 			throw new InternalException();
+        // 		}
+        // }
+        code.getstatic().setField(type);
+
+        Collection jumps = new LinkedList();
+        jumps.add(code.ifnonnull());
+        ExceptionHandler handler = code.addExceptionHandler();
+
+        handler.setTryStart(code.constant().setValue
+            (meta.getDescribedType().getName()));
+        code.constant().setValue(true);
+        code.invokestatic().setMethod(Thread.class, "currentThread",
+            Thread.class, null);
+        code.invokevirtual().setMethod(Thread.class, "getContextClassLoader",
+            ClassLoader.class, null);
+        code.invokestatic().setMethod(Class.class, "forName", Class.class,
+            new Class[]{ String.class, boolean.class, ClassLoader.class });
+        code.putstatic().setField(type);
+        Instruction go2 = code.go2();
+        jumps.add(go2);
+        handler.setTryEnd(go2);
+        handler.setCatch(ClassNotFoundException.class);
+        handler.setHandlerStart(throwException
+            (code, InternalException.class));
+        setTarget(code.getstatic().setField(type), jumps);
+        code.areturn();
+
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Declare standard dynamic pcdata fields.
+     */
+    private void addBaseFields(BCClass bc) {
+        addBeanField(bc, "id", Object.class);
+        BCField field = addBeanField(bc, "storageGenerator",
+            PCDataGenerator.class);
+        field.setAccessFlags(field.getAccessFlags()
+            | Constants.ACCESS_TRANSIENT);
+    }
+
+    /**
+     * Add methods for loading and storing class-level impl data.
+     */
+    private void addImplDataMethods(BCClass bc, ClassMetaData meta) {
+        // void storeImplData(OpenJPAStateManager);
+        BCMethod meth = bc.declareMethod("storeImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+        Code code = meth.getCode(true);
+
+        BCField impl = null;
+        if (!usesImplData(meta))
+            code.vreturn();
+        else {
+            // if (sm.isImplDataCacheable())
+            // 		setImplData(sm.getImplData());
+            impl = addBeanField(bc, "implData", Object.class);
+            code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "isImplDataCacheable", boolean.class, null);
+            JumpInstruction ifins = code.ifeq();
+            code.aload().setThis();
+            code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getImplData", Object.class, null);
+            code.invokevirtual().setMethod("setImplData", void.class,
+                new Class[]{ Object.class });
+            ifins.setTarget(code.vreturn());
+        }
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // void loadImplData(OpenJPAStateManager);
+        meth = bc.declareMethod("loadImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+        code = meth.getCode(true);
+        if (!usesImplData(meta))
+            code.vreturn();
+        else {
+            // if (sm.getImplData() == null && implData != null)
+            // 		sm.setImplData(impl, true);
+            code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getImplData", Object.class, null);
+            JumpInstruction ifins = code.ifnonnull();
+            code.aload().setThis();
+            code.getfield().setField(impl);
+            JumpInstruction ifins2 = code.ifnull();
+            code.aload().setParam(0);
+            code.aload().setThis();
+            code.getfield().setField(impl);
+            code.constant().setValue(true);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "setImplData", void.class,
+                new Class[]{ Object.class, boolean.class });
+            Instruction ins = code.vreturn();
+            ifins.setTarget(ins);
+            ifins2.setTarget(ins);
+        }
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Add methods for loading and storing class-level impl data.
+     */
+    private void addFieldImplDataMethods(BCClass bc, ClassMetaData meta) {
+        // public void loadImplData(OpenJPAStateManager sm, int i)
+        BCMethod meth = bc.declareMethod("loadImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class, int.class });
+        meth.makePrivate();
+        Code code = meth.getCode(true);
+
+        int count = countImplDataFields(meta);
+        BCField impl = null;
+        if (count == 0)
+            code.vreturn();
+        else {
+            // Object[] fieldImpl
+            impl = bc.declareField("fieldImpl", Object[].class);
+            impl.makePrivate();
+
+            // if (fieldImpl != null)
+            code.aload().setThis();
+            code.getfield().setField(impl);
+            JumpInstruction ifins = code.ifnonnull();
+            code.vreturn();
+
+            // Object obj = null;
+            int obj = code.getNextLocalsIndex();
+            ifins.setTarget(code.constant().setNull());
+            code.astore().setLocal(obj);
+
+            // establish switch target, then move before it
+            Instruction target = code.aload().setLocal(obj);
+            code.previous();
+
+            // switch(i)
+            code.iload().setParam(1);
+            LookupSwitchInstruction lswitch = code.lookupswitch();
+            FieldMetaData[] fields = meta.getFields();
+            int cacheable = 0;
+            for (int i = 0; i < fields.length; i++) {
+                if (!usesImplData(fields[i]))
+                    continue;
+                // case x: obj = fieldImpl[y]; break;
+                lswitch.addCase(i, code.aload().setThis());
+                code.getfield().setField(impl);
+                code.constant().setValue(cacheable++);
+                code.aaload();
+                code.astore().setLocal(obj);
+                code.go2().setTarget(target);
+            }
+            lswitch.setDefaultTarget(target);
+
+            // if (obj != null)
+            code.next();    // jump back over target
+            ifins = code.ifnonnull();
+            code.vreturn();
+
+            // sm.setImplData(index, impl);
+            ifins.setTarget(code.aload().setParam(0));
+            code.iload().setParam(1);
+            code.aload().setLocal(obj);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "setImplData", void.class,
+                new Class[]{ int.class, Object.class });
+            code.vreturn();
+        }
+        code.calculateMaxLocals();
+        code.calculateMaxStack();
+
+        // void storeImplData(OpenJPAStateManager sm, int index, boolean loaded)
+        meth = bc.declareMethod("storeImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class, int.class, boolean.class });
+        code = meth.getCode(true);
+        if (count == 0)
+            code.vreturn();
+        else {
+            // int arrIdx = -1;
+            // switch(index)
+            int arrIdx = code.getNextLocalsIndex();
+            code.constant().setValue(-1);
+            code.istore().setLocal(arrIdx);
+            code.iload().setParam(1);
+            LookupSwitchInstruction lswitch = code.lookupswitch();
+
+            // establish switch target, then move before it
+            Instruction switchTarget = code.iload().setLocal(arrIdx);
+            code.previous();
+
+            FieldMetaData[] fields = meta.getFields();
+            int cacheable = 0;
+            for (int i = 0; i < fields.length; i++) {
+                if (!usesImplData(fields[i]))
+                    continue;
+                // case x: arrIdx = y; break;
+                lswitch.addCase(i, code.constant().setValue(cacheable++));
+                code.istore().setLocal(arrIdx);
+                code.go2().setTarget(switchTarget);
+            }
+            lswitch.setDefaultTarget(switchTarget);
+            code.next();    // step over switch target
+
+            // if (arrIdx != -1)
+            code.constant().setValue(-1);
+            JumpInstruction ifins = code.ificmpne();
+            code.vreturn();
+
+            // create null target, then move before it
+            Instruction nullTarget = code.aload().setThis();
+            code.previous();
+
+            // if (loaded)
+            ifins.setTarget(code.iload().setParam(2));
+            code.ifeq().setTarget(nullTarget);
+
+            // Object obj = sm.getImplData(index)
+            int obj = code.getNextLocalsIndex();
+            code.aload().setParam(0);
+            code.iload().setParam(1);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getImplData", Object.class, new Class[]{ int.class });
+            code.astore().setLocal(obj);
+
+            // if (obj != null)
+            code.aload().setLocal(obj);
+            code.ifnull().setTarget(nullTarget);
+
+            // if (fieldImpl == null)
+            // 		fieldImpl = new Object[fields];
+            code.aload().setThis();
+            code.getfield().setField(impl);
+            ifins = code.ifnonnull();
+            code.aload().setThis();
+            code.constant().setValue(count);
+            code.anewarray().setType(Object.class);
+            code.putfield().setField(impl);
+
+            // fieldImpl[arrIdx] = obj;
+            // return;
+            ifins.setTarget(code.aload().setThis());
+            code.getfield().setField(impl);
+            code.iload().setLocal(arrIdx);
+            code.aload().setLocal(obj);
+            code.aastore();
+            code.vreturn();
+
+            // if (fieldImpl != null)
+            // 		fieldImpl[index] = null;
+            code.next(); // step over nullTarget
+            code.getfield().setField(impl);
+            ifins = code.ifnonnull();
+            code.vreturn();
+            ifins.setTarget(code.aload().setThis());
+            code.getfield().setField(impl);
+            code.iload().setLocal(arrIdx);
+            code.constant().setNull();
+            code.aastore();
+            code.vreturn();
+        }
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Add methods for loading and storing version data.
+     */
+    protected void addVersionMethods(BCClass bc) {
+        // void storeVersion(OpenJPAStateManager sm);
+        addBeanField(bc, "version", Object.class);
+        BCMethod meth = bc.declareMethod("storeVersion", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+        Code code = meth.getCode(true);
+
+        // version = sm.getVersion();
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokeinterface()
+            .setMethod(OpenJPAStateManager.class, "getVersion",
+                Object.class, null);
+        code.putfield().setField("version", Object.class);
+        code.vreturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // void loadVersion(OpenJPAStateManager sm)
+        meth = bc.declareMethod("loadVersion", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+        code = meth.getCode(true);
+
+        // if (sm.getVersion() == null)
+        // 		sm.setVersion(version);
+        code.aload().setParam(0);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+            "getVersion", Object.class, null);
+        JumpInstruction ifins = code.ifnonnull();
+        code.aload().setParam(0);
+        code.aload().setThis();
+        code.getfield().setField("version", Object.class);
+        code.invokeinterface()
+            .setMethod(OpenJPAStateManager.class, "setVersion",
+                void.class, new Class[]{ Object.class });
+        ifins.setTarget(code.vreturn());
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    private void addLoadMethod(BCClass bc, ClassMetaData meta) {
+        // public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
+        // 		Object context)
+        Code code = addLoadMethod(bc, false);
+        FieldMetaData[] fmds = meta.getFields();
+        Collection jumps = new LinkedList();
+        Collection jumps2;
+		
+        int local = code.getNextLocalsIndex();
+        code.constant().setNull();
+        code.astore().setLocal(local);
+        int inter = code.getNextLocalsIndex();
+        code.constant().setNull();
+        code.astore().setLocal(inter);
+
+        int objectCount = 0;
+        boolean intermediate;
+        for (int i = 0; i < fmds.length; i++) {
+            jumps2 = new LinkedList();
+            intermediate = usesIntermediate(fmds[i]);
+            setTarget(code.aload().setThis(), jumps);
+            // if (loaded.get(i)) or (!loaded.get(i)) depending on inter resp
+            code.getfield().setField("loaded", BitSet.class);
+            code.constant().setValue(i);
+            code.invokevirtual().setMethod(BitSet.class, "get",
+                boolean.class, new Class[]{ int.class });
+            jumps.add(code.ifne());
+
+            if (intermediate)
+                addLoadIntermediate(code, i, objectCount, jumps2, inter);
+            jumps2.add(code.go2());
+
+            // if (fetch.requiresFetch(fmds[i])!=FetchConfiguration.FETCH_NONE)
+            setTarget(code.aload().setParam(1), jumps);
+            code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getMetaData", ClassMetaData.class, null);
+            code.constant().setValue(fmds[i].getIndex());
+            code.invokevirtual().setMethod(ClassMetaData.class,
+                "getField", FieldMetaData.class, new Class[]{int.class});
+            code.invokeinterface().setMethod (FetchConfiguration.class, 
+                "requiresFetch", int.class, new Class[]{FieldMetaData.class});
+            code.constant().setValue(FetchConfiguration.FETCH_NONE);
+            jumps2.add(code.ificmpeq());
+            addLoad(bc, code, fmds[i], objectCount, local, false);
+
+            jumps = jumps2;
+            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
+                objectCount++;
+        }
+        setTarget(code.vreturn(), jumps);
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    private void addLoadWithFieldsMethod(BCClass bc, ClassMetaData meta) {
+        Code code = addLoadMethod(bc, true);
+        // public void load(OpenJPAStateManager sm, BitSet fields,
+        // 		FetchConfiguration fetch, Object conn)
+        FieldMetaData[] fmds = meta.getFields();
+        Collection jumps = new LinkedList();
+        Collection jumps2;
+        int objectCount = 0;
+        boolean intermediate;
+        int local = code.getNextLocalsIndex();
+        code.constant().setNull();
+        code.astore().setLocal(local);
+        int inter = code.getNextLocalsIndex();
+        code.constant().setNull();
+        code.astore().setLocal(inter);
+
+        for (int i = 0; i < fmds.length; i++) {
+            jumps2 = new LinkedList();
+            intermediate = usesIntermediate(fmds[i]);
+            // if (fields.get(i))
+            // {
+            // 		if (loaded.get(i))
+            setTarget(code.aload().setParam(1), jumps);
+            code.constant().setValue(i);
+            code.invokevirtual().setMethod(BitSet.class, "get",
+                boolean.class, new Class[]{ int.class });
+            jumps2.add(code.ifeq());
+            code.aload().setThis();
+            code.getfield().setField("loaded", BitSet.class);
+            code.constant().setValue(i);
+            code.invokevirtual().setMethod(BitSet.class, "get",
+                boolean.class, new Class[]{ int.class });
+            if (intermediate)
+                jumps.add(code.ifeq());
+            else
+                jumps2.add(code.ifeq());
+
+            addLoad(bc, code, fmds[i], objectCount, local, true);
+            if (usesImplData(fmds[i])) {
+                // loadImplData(sm, i);
+                code.aload().setThis();
+                code.aload().setParam(0);
+                code.constant().setValue(i);
+                code.invokevirtual().setMethod("loadImplData", void.class,
+                    new Class[]{ OpenJPAStateManager.class, int.class });
+            }
+
+            // fields.clear(i);
+            code.aload().setParam(1);
+            code.constant().setValue(i);
+            code.invokevirtual().setMethod(BitSet.class, "clear", void.class,
+                new Class[] { int.class });
+
+            jumps2.add(code.go2());
+
+            if (intermediate)
+                setTarget(addLoadIntermediate
+                    (code, i, objectCount, jumps2, inter), jumps);
+
+            jumps = jumps2;
+            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
+                objectCount++;
+        }
+        setTarget(code.vreturn(), jumps);
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Declare and start the base load method.
+     */
+    private Code addLoadMethod(BCClass bc, boolean fields) {
+        Class[] args = null;
+        if (fields)
+            args = new Class[]{ OpenJPAStateManager.class, BitSet.class,
+                FetchConfiguration.class, Object.class };
+        else
+            args = new Class[]{ OpenJPAStateManager.class,
+                FetchConfiguration.class, Object.class };
+        BCMethod load = bc.declareMethod("load", void.class, args);
+        Code code = load.getCode(true);
+
+        //loadVersion(sm);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokevirtual().setMethod("loadVersion", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+
+        //loadImplData(sm);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokevirtual().setMethod("loadImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+        return code;
+    }
+
+    /**
+     * Add the field load.
+     */
+    private Instruction addLoad(BCClass bc, Code code, FieldMetaData fmd,
+        int objectCount, int local, boolean fields) {
+        int index = fmd.getIndex();
+        int typeCode = replaceType(fmd);
+        Instruction first;
+        if (typeCode < JavaTypes.OBJECT) {
+            // sm.store<type>(i, field<i>)
+            Class type = forType(fmd.getTypeCode());
+            first = code.aload().setParam(0);
+            code.constant().setValue(index);
+            code.aload().setThis();
+            code.getfield().setField(getFieldName(index), type);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "store" + StringUtils.capitalize(type.getName()),
+                void.class, new Class[]{ int.class, type });
+        } else {
+            // fmd = sm.getMetaData().getField(i);
+            int offset = fields ? 1 : 0;
+            first = code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getMetaData", ClassMetaData.class, null);
+            code.constant().setValue(fmd.getIndex());
+            code.invokevirtual().setMethod(ClassMetaData.class, "getField",
+                FieldMetaData.class, new Class[]{ int.class });
+            code.astore().setLocal(local);
+            // sm.storeField(i, toField(sm, fmd, objects[objectCount],
+            // 		fetch, context);
+            code.aload().setParam(0);
+            code.constant().setValue(index);
+            code.aload().setThis();
+            code.aload().setParam(0);
+            code.aload().setLocal(local);
+            code.aload().setThis();
+            code.getfield().setField("objects", Object[].class);
+            code.constant().setValue(objectCount);
+            code.aaload();
+            code.aload().setParam(1 + offset);
+            code.aload().setParam(2 + offset);
+            code.invokevirtual().setMethod(bc.getName(), "toField",
+                Object.class.getName(), toStrings(new Class[]{ 
+                OpenJPAStateManager.class, FieldMetaData.class,
+                Object.class, FetchConfiguration.class, Object.class }));
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "storeField", void.class,
+                new Class[]{ int.class, Object.class });
+        }
+        return first;
+    }
+
+    /**
+     * Load intermediate data if possible.
+     */
+    private Instruction addLoadIntermediate(Code code, int index,
+        int objectCount, Collection jumps2, int inter) {
+        // {
+        // 		Object inter = objects[objectCount];
+        Instruction first = code.aload().setThis();
+        code.getfield().setField("objects", Object[].class);
+        code.constant().setValue(objectCount);
+        code.aaload();
+        code.astore().setLocal(inter);
+        // 		if (inter != null && !sm.getLoaded().get(index))
+        code.aload().setLocal(inter);
+        jumps2.add(code.ifnull());
+        code.aload().setParam(0);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+            "getLoaded", BitSet.class, null);
+        code.constant().setValue(index);
+        code.invokevirtual().setMethod(BitSet.class, "get",
+            boolean.class, new Class[]{ int.class });
+        jumps2.add(code.ifne());
+        //			sm.setIntermediate(index, inter);
+        //	}  // end else
+        code.aload().setParam(0);
+        code.constant().setValue(index);
+        code.aload().setLocal(inter);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+            "setIntermediate", void.class,
+            new Class[]{ int.class, Object.class });
+        return first;
+    }
+
+    private void addStoreMethods(BCClass bc, ClassMetaData meta) {
+        // i.e. void store(OpenJPAStateManager sm, BitSet fields);
+        addStoreMethod(bc, meta, true);
+        // i.e. void store(OpenJPAStateManager sm);
+        addStoreMethod(bc, meta, false);
+    }
+
+    private void addStoreMethod(BCClass bc, ClassMetaData meta,
+        boolean fields) {
+        BCMethod store;
+        if (fields)
+            store = bc.declareMethod("store", void.class,
+                new Class[]{ OpenJPAStateManager.class, BitSet.class });
+        else
+            store = bc.declareMethod("store", void.class,
+                new Class[]{ OpenJPAStateManager.class });
+        Code code = store.getCode(true);
+
+        // initialize();
+        code.aload().setThis();
+        code.invokevirtual().setMethod("initialize", void.class, null);
+
+        // storeVersion(sm);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokevirtual().setMethod("storeVersion", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+
+        // storeImplData(sm);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokevirtual().setMethod("storeImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class });
+
+        FieldMetaData[] fmds = meta.getFields();
+        Collection jumps = new LinkedList();
+        int objectCount = 0;
+        for (int i = 0; i < fmds.length; i++) {
+            if (fields) {
+                //  if (fields != null && fields.get(index))
+                setTarget(code.aload().setParam(1), jumps);
+                jumps.add(code.ifnull());
+                code.aload().setParam(1);
+                code.constant().setValue(i);
+                code.invokevirtual().setMethod(BitSet.class, "get",
+                    boolean.class, new Class[]{ int.class });
+                jumps.add(code.ifeq());
+            } else {
+                // if (sm.getLoaded().get(index)))
+                setTarget(code.aload().setParam(0), jumps);
+                code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                    "getLoaded", BitSet.class, null);
+                code.constant().setValue(i);
+                code.invokevirtual().setMethod(BitSet.class, "get",
+                    boolean.class, new Class[]{ int.class });
+                jumps.add(code.ifeq());
+            }
+            addStore(bc, code, fmds[i], objectCount);
+            if (usesIntermediate(fmds[i])) {
+                JumpInstruction elseIns = code.go2();
+                // else if (!loaded.get(index))
+                setTarget(code.aload().setThis(), jumps);
+                jumps.add(elseIns);
+                code.getfield().setField("loaded", BitSet.class);
+                code.constant().setValue(i);
+                code.invokevirtual().setMethod(BitSet.class, "get",
+                    boolean.class, new Class[]{ int.class });
+                jumps.add(code.ifne());
+                // Object val = sm.getIntermediate(index);
+                // if (val != null)
+                // 		objects[objectCount] = val;
+                code.aload().setParam(0);
+                code.constant().setValue(i);
+                code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                    "getIntermediate", Object.class, new Class[]{ int.class });
+                int local = code.getNextLocalsIndex();
+                code.astore().setLocal(local);
+                code.aload().setLocal(local);
+                jumps.add(code.ifnull());
+                code.aload().setThis();
+                code.getfield().setField("objects", Object[].class);
+                code.constant().setValue(objectCount);
+                code.aload().setLocal(local);
+                code.aastore();
+            }
+            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
+                objectCount++;
+        }
+        setTarget(code.vreturn(), jumps);
+        code.calculateMaxLocals();
+        code.calculateMaxStack();
+    }
+
+    private void addStore(BCClass bc, Code code, FieldMetaData fmd,
+        int objectCount) {
+        int typeCode = replaceType(fmd);
+        int index = fmd.getIndex();
+        if (typeCode < JavaTypes.OBJECT) {
+            Class type = forType(typeCode);
+            // field<i> = sm.fetch<Type>(index)
+            code.aload().setThis();
+            code.aload().setParam(0);
+            code.constant().setValue(index);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "fetch" + StringUtils.capitalize(type.getName()), type,
+                new Class[]{ int.class });
+            code.putfield().setField(getFieldName(index), type);
+            code.aload().setThis();
+            code.getfield().setField("loaded", BitSet.class);
+            code.constant().setValue(index);
+            code.invokevirtual().setMethod(BitSet.class, "set", void.class,
+                new Class[]{ int.class });
+        } else {
+            // Object val = toData(sm.getMetaData().getField(index),
+            // 		sm.fetchField(index, false), sm.getContext());
+            int local = code.getNextLocalsIndex();
+            code.aload().setThis();
+            code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getMetaData", ClassMetaData.class, null);
+            code.constant().setValue(fmd.getIndex());
+            code.invokevirtual().setMethod(ClassMetaData.class,
+                "getField", FieldMetaData.class, new Class[]{ int.class });
+            code.aload().setParam(0);
+            code.constant().setValue(fmd.getIndex());
+            code.constant().setValue(false);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "fetchField", Object.class, new Class[]
+                { int.class, boolean.class });
+            code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                "getContext", StoreContext.class, null);
+            code.invokevirtual().setMethod(bc.getName(), "toData",
+                Object.class.getName(), toStrings(new Class []{
+                FieldMetaData.class, Object.class, StoreContext.class }));
+            code.astore().setLocal(local);
+
+            // if (val == NULL) {
+            // 		val = null;
+            // 		loaded.clear(index);
+            // 	} else
+            // 		loaded.set(index);
+            // 	objects[objectCount] = val;
+            code.aload().setLocal(local);
+            code.getstatic().setField(AbstractPCData.class, "NULL",
+                Object.class);
+            JumpInstruction ifins = code.ifacmpne();
+            code.constant().setNull();
+            code.astore().setLocal(local);
+            code.aload().setThis();
+            code.getfield().setField("loaded", BitSet.class);
+            code.constant().setValue(index);
+            code.invokevirtual().setMethod(BitSet.class, "clear", void.class,
+                new Class[]{ int.class });
+            JumpInstruction go2 = code.go2();
+            ifins.setTarget(code.aload().setThis());
+            code.getfield().setField("loaded", BitSet.class);
+            code.constant().setValue(index);
+            code.invokevirtual().setMethod(BitSet.class, "set", void.class,
+                new Class[]{ int.class });
+            go2.setTarget(code.aload().setThis());
+            code.getfield().setField("objects", Object[].class);
+            code.constant().setValue(objectCount);
+            code.aload().setLocal(local);
+            code.aastore();
+        }
+        if (!usesImplData(fmd))
+            return;
+
+        // storeImplData(sm, i, loaded.get(i);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.constant().setValue(index);
+        code.aload().setThis();
+        code.getfield().setField("loaded", BitSet.class);
+        code.constant().setValue(index);
+        code.invokevirtual().setMethod(BitSet.class, "get", boolean.class,
+            new Class[]{ int.class });
+        code.invokevirtual().setMethod("storeImplData", void.class,
+            new Class[]{ OpenJPAStateManager.class, int.class, boolean.class });
+    }
+
+    private void addNewEmbedded(BCClass bc) {
+        // void newEmbeddedPCData(OpenJPAStateManager embedded)
+        BCMethod meth = bc.declareMethod("newEmbeddedPCData", PCData.class,
+            new Class[]{ OpenJPAStateManager.class });
+        Code code = meth.getCode(true);
+        // return getStorageGenerator().generatePCData
+        // 		(sm.getId(), sm.getMetaData());
+        code.aload().setThis();
+        code.getfield().setField("storageGenerator", PCDataGenerator.class);
+        code.aload().setParam(0);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+            "getId", Object.class, null);
+        code.aload().setParam(0);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+            "getMetaData", ClassMetaData.class, null);
+        code.invokevirtual().setMethod(PCDataGenerator.class,
+            "generatePCData", PCData.class, new Class[]
+            { Object.class, ClassMetaData.class });
+        code.areturn();
+        code.calculateMaxLocals();
+        code.calculateMaxStack();
+    }
+
+    private void addGetData(BCClass bc) {
+        // return getObjectField(i);
+        BCMethod method = bc.declareMethod("getData", Object.class,
+            new Class[]{ int.class });
+        Code code = method.getCode(true);
+        code.aload().setThis();
+        code.iload().setParam(0);
+        code.invokevirtual().setMethod("getObject", Object.class,
+            new Class[]{ int.class });
+        code.areturn();
+        code.calculateMaxLocals();
+        code.calculateMaxStack();
+    }
+
+    /////////////
+    // Utilities
+    /////////////
+
+    /**
+     * Return a valid {@link JavaTypes} constant for the given field
+     */
+    protected int replaceType(FieldMetaData fmd) {
+        if (usesIntermediate(fmd))
+            return JavaTypes.OBJECT;
+        return fmd.getTypeCode();
+    }
+
+    /**
+     * Whether the given field uses a cacheable intermediate value.
+     */
+    protected boolean usesIntermediate(FieldMetaData fmd) {
+        return fmd.usesIntermediate();
+    }
+
+    /**
+     * Whether the given type might have cacheable class-level impl data.
+     */
+    protected boolean usesImplData(ClassMetaData meta) {
+        return true;
+    }
+
+    /**
+     * Whether the given field might have cacheable impl data.
+     */
+    protected boolean usesImplData(FieldMetaData fmd) {
+        return fmd.usesImplData() == null;
+    }
+
+    /**
+     * The number of fields with cacheable impl data.
+     */
+    private int countImplDataFields(ClassMetaData meta) {
+        FieldMetaData[] fmds = meta.getFields();
+        int count = 0;
+        for (int i = 0; i < fmds.length; i++)
+            if (usesImplData(fmds[i]))
+                count++;
+        return count;
+    }
+
+    /**
+     * Add method which defers to AbstractPCData.
+     */
+    protected void callAbstractPCData(BCClass bc, String name, Class retType,
+        Class[] args) {
+        BCMethod meth = bc.declareMethod(name, retType, args);
+        Code code = meth.getCode(true);
+        code.aload().setThis();
+        for (int i = 0; i < args.length; i++)
+            code.xload().setParam(i).setType(args[i]);
+        code.invokevirtual().setMethod(AbstractPCData.class, name, retType,
+            args);
+        if (!void.class.equals(retType))
+            code.xreturn().setType(retType);
+        code.calculateMaxLocals();
+        code.calculateMaxStack();
+    }
+
+    /**
+     * Set the collection of {@link JumpInstruction}s to the given instruction,
+     * clearing the collection in the process.
+     */
+    protected void setTarget(Instruction ins, Collection jumps) {
+        for (Iterator it = jumps.iterator(); it.hasNext();)
+            ((JumpInstruction) it.next()).setTarget(ins);
+        jumps.clear();
+    }
+
+    /**
+     * Transform the given array of classes to strings.
+     */
+    private static String[] toStrings(Class[] cls) {
+        String[] strings = new String[cls.length];
+        for (int i = 0; i < strings.length; i++)
+            strings[i] = cls[i].getName();
+        return strings;
+    }
+
+    /**
+     * Dynamic {@link PCData}s generated will implement this interface
+     * to simplify initialization.
+     */
+    public static interface DynamicPCData extends PCData {
+
+        public void setId(Object oid);
+
+        public PCDataGenerator getStorageGenerator();
+
+        public void setStorageGenerator (PCDataGenerator generator);
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
index 793c03e..a73a226 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
@@ -113,6 +113,8 @@
     // Each enhanced class will return the value of this field via
     // public int getEnhancementContractVersion()
     public static final int ENHANCER_VERSION = 2;
+    
+    boolean _addVersionInitFlag = true;
 
     public static final int ENHANCE_NONE = 0;
     public static final int ENHANCE_AWARE = 2 << 0;
@@ -134,6 +136,8 @@
     private static final String SUPER = PRE + "PCSuperclass";
     private static final Class OIDFSTYPE = FieldSupplier.class;
     private static final Class OIDFCTYPE = FieldConsumer.class;
+    
+    private static final String VERSION_INIT_STR =  PRE + "VersionInit";
 
     private static final Localizer _loc = Localizer.forPackage
         (PCEnhancer.class);
@@ -151,12 +155,12 @@
             try {
                 auxEnhancers.add(AccessController.doPrivileged(
                     J2DoPrivHelper.newInstanceAction(classes[i])));
-		    } catch (Throwable t) {
+            } catch (Throwable t) {
                 // aux enhancer may rely on non-existant spec classes, etc
-		    }
-		}
-    	_auxEnhancers = (AuxiliaryEnhancer[]) auxEnhancers.toArray
-            (new AuxiliaryEnhancer[auxEnhancers.size()]);
+            }
+        }
+        _auxEnhancers = (AuxiliaryEnhancer[]) auxEnhancers.toArray
+        (new AuxiliaryEnhancer[auxEnhancers.size()]);
     }
 
     private BCClass _pc;
@@ -428,6 +432,7 @@
      */
     public void setCreateSubclass(boolean subclass) {
         _subclass = subclass;
+        _addVersionInitFlag = false;
     }
 
     /**
@@ -1093,8 +1098,13 @@
             addCopyKeyFieldsToObjectIdMethod(false);
             addCopyKeyFieldsFromObjectIdMethod(true);
             addCopyKeyFieldsFromObjectIdMethod(false);
+            if (_meta.hasAbstractPKField() == true) {
+                addGetIDOwningClass();
+            }
             addNewObjectIdInstanceMethod(true);
             addNewObjectIdInstanceMethod(false);
+        } else if (_meta.hasPKFieldsFromAbstractClass()) {
+            addGetIDOwningClass();
         }
     }
 
@@ -1342,6 +1352,16 @@
                     code.checkcast().setType(fmds[i].getDeclaredType());
 
                 addSetManagedValueCode(code, fmds[i]);
+                
+                if(_addVersionInitFlag){
+                    if(fmds[i].isVersion()){
+                        // If this case is setting the version field
+                        // pcVersionInit = true;
+                        loadManagedInstance(code, false);
+                        code.constant().setValue(1);
+                        putfield(code, null, VERSION_INIT_STR, boolean.class);
+                    }
+                }
                 code.vreturn();
             }
 
@@ -2486,14 +2506,28 @@
             // new ObjectId (cls, oid)
             code.anew().setType(ObjectId.class);
             code.dup();
-            code.classconstant().setClass(getType(_meta));
+            if (_meta.hasAbstractPKField() == false) {
+                code.classconstant().setClass(getType(_meta));
+            } else {
+                code.aload().setThis();
+                code.invokevirtual().setMethod(
+                        PRE + "GetIDOwningClass", Class.class, null);
+            }
         }
 
         // new <oid class> ();
         code.anew().setType(oidType);
         code.dup();
         if (_meta.isOpenJPAIdentity() || (obj && usesClsString == Boolean.TRUE))
-            code.classconstant().setClass(getType(_meta));
+        {
+            if (_meta.hasAbstractPKField() == false) {
+                code.classconstant().setClass(getType(_meta));
+            } else {
+                code.aload().setThis();
+                code.invokevirtual().setMethod(
+                    PRE + "GetIDOwningClass", Class.class, null);
+            }
+        }
         if (obj) {
             code.aload().setParam(0);
             code.checkcast().setType(String.class);
@@ -2526,6 +2560,18 @@
         code.calculateMaxLocals();
     }
 
+    private void addGetIDOwningClass() throws NoSuchMethodException {
+        BCMethod method = _pc.declareMethod(PRE + "GetIDOwningClass",
+            Class.class, null);
+        Code code = method.getCode(true);
+
+        code.classconstant().setClass(getType(_meta));
+        code.areturn();
+
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
     /**
      * When communicating with the StateManager, many methods are used
      * depending on the class of state being passed. This method,
@@ -2674,7 +2720,12 @@
         _pc.declareField(PRE + "FieldTypes", Class[].class).setStatic(true);
         _pc.declareField(PRE + "FieldFlags", byte[].class).setStatic(true);
         _pc.declareField(SUPER, Class.class).setStatic(true);
-
+        if (_addVersionInitFlag && _meta.getVersionField() != null) {
+            // protected transient boolean pcVersionInit;
+            BCField field = _pc.declareField(VERSION_INIT_STR, boolean.class);
+            field.makeProtected();
+            field.setTransient(true);
+        }
         if (_meta.getPCSuperclass() == null || getCreateSubclass()) {
             BCField field = _pc.declareField(SM, SMTYPE);
             field.makeProtected();
@@ -3123,8 +3174,25 @@
             ifins = ifDefaultValue(code, version);
             code.getstatic().setField(Boolean.class, "TRUE", Boolean.class);
             code.areturn();
-            ifins.setTarget(code.getstatic().setField(Boolean.class, "FALSE",
-                Boolean.class));
+            if (!_addVersionInitFlag){
+                // else return false;
+                ifins.setTarget(code.getstatic().setField(Boolean.class, "FALSE", Boolean.class));
+            }else{
+                FieldMetaData versionInit = _meta.getDeclaredField(VERSION_INIT_STR);
+                // noop
+                ifins.setTarget(code.nop());
+                // if (pcVersionInit)
+                // return true
+                // else return false;
+                loadManagedInstance(code, false);
+                getfield(code, null, versionInit.getName());
+                ifins = ifDefaultValue(code, versionInit);
+                code.getstatic().setField(Boolean.class, "TRUE", Boolean.class);
+                code.areturn();
+                ifins.setTarget(code.nop());
+                code.getstatic().setField(Boolean.class, "FALSE", Boolean.class);
+                
+            }
             code.areturn();
             return false;
         }
@@ -3587,6 +3655,14 @@
         loadManagedInstance(code, true);
         code.xload().setParam(firstParamOffset);
         addSetManagedValueCode(code, fmd);
+        if(fmd.isVersion()==true && _addVersionInitFlag){
+            // if we are setting the version, flip the versionInit flag to true
+            FieldMetaData v = _meta.addDeclaredField(VERSION_INIT_STR, boolean.class);
+            v.setTransient(true);
+            loadManagedInstance(code, true);
+            code.constant().setValue(1);
+            addSetManagedValueCode(code, v);   
+        }
         code.vreturn();
 
         // inst.pcStateManager.setting<fieldType>Field (inst,
@@ -4193,6 +4269,7 @@
         } else {
             // regular enhancement + property access
             Method meth = (Method) fmd.getBackingMember();
+
             code.invokevirtual().setMethod(PRE + meth.getName(),
                 meth.getReturnType(), meth.getParameterTypes());
         }
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java
index 9d5b213..454e16e 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java
@@ -1,288 +1,288 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.enhance;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.ReferenceMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-import org.apache.openjpa.util.UserException;
-import org.apache.openjpa.util.InvalidStateException;
-
-/**
- * Tracks registered persistence-capable classes.
- *
- * @since 0.4.0
- * @author Abe White
- */
-public class PCRegistry {
-    // DO NOT ADD ADDITIONAL DEPENDENCIES TO THIS CLASS
-
-    private static final Localizer _loc = Localizer.forPackage
-        (PCRegistry.class);
-
-    // map of pc classes to meta structs; weak so the VM can GC classes
-    private static final Map _metas = new ConcurrentReferenceHashMap
-        (ReferenceMap.WEAK, ReferenceMap.HARD);
-
-    // register class listeners
-    private static final Collection _listeners = new LinkedList();
-
-    /**
-     * Register a {@link RegisterClassListener}.
-     */
-    public static void addRegisterClassListener(RegisterClassListener rcl) {
-        if (rcl == null)
-            return;
-
-        // we have to be positive that every listener gets notified for
-        // every class, so lots of locking
-        synchronized (_listeners) {
-            _listeners.add(rcl);
-        }
-        synchronized (_metas) {
-            for (Iterator itr = _metas.keySet().iterator(); itr.hasNext();)
-                rcl.register((Class) itr.next());
-        }
-    }
-
-    /**
-     * Removes a {@link RegisterClassListener}.
-     */
-    public static void removeRegisterClassListener(RegisterClassListener rcl) {
-        synchronized (_listeners) {
-            _listeners.remove(rcl);
-        }
-    }
-
-    /**
-     * Get the field names for a <code>PersistenceCapable</code> class.
-     */
-    public static String[] getFieldNames(Class pcClass) {
-        Meta meta = getMeta(pcClass);
-        return meta.fieldNames;
-    }
-
-    /**
-     * Get the field types for a <code>PersistenceCapable</code> class.
-     */
-    public static Class[] getFieldTypes(Class pcClass) {
-        Meta meta = getMeta(pcClass);
-        return meta.fieldTypes;
-    }
-
-    /**
-     * Return the persistent superclass for a <code>PersistenceCapable</code>
-     * class, or null if none. The superclass may or may not implement
-     * {@link PersistenceCapable}, depending on the access type of the class.
-     */
-    public static Class getPersistentSuperclass(Class pcClass) {
-        Meta meta = getMeta(pcClass);
-        return meta.pcSuper;
-    }
-
-    /**
-     * Create a new instance of the class and assign its state manager.
-     * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
-     */
-    public static PersistenceCapable newInstance(Class pcClass,
-        StateManager sm, boolean clear) {
-        Meta meta = getMeta(pcClass);
-        return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, clear);
-    }
-
-    /**
-     * Create a new instance of the class and assign its state manager and oid.
-     * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
-     */
-    public static PersistenceCapable newInstance(Class pcClass,
-        StateManager sm, Object oid, boolean clear) {
-        Meta meta = getMeta(pcClass);
-        return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, oid, clear);
-    }
-
-    /**
-     * Return the persistence-capable type for <code>type</code>. This might
-     * be a generated subclass of <code>type</code>.
-     *
-     * @since 1.1.0
-     */
-    public static Class getPCType(Class type) {
-        Meta meta = getMeta(type);
-        return (meta.pc == null) ? null : meta.pc.getClass();
-    }
-
-    /**
-     * Create a new identity object for the given
-     * <code>PersistenceCapable</code> class.
-     */
-    public static Object newObjectId(Class pcClass) {
-        Meta meta = getMeta(pcClass);
-        return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance();
-    }
-
-    /**
-     * Create a new identity object for the given
-     * <code>PersistenceCapable</code> class, using the <code>String</code>
-     * form of the constructor.
-     */
-    public static Object newObjectId(Class pcClass, String str) {
-        Meta meta = getMeta(pcClass);
-        return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance(str);
-    }
-
-    /**
-     * Return the alias for the given type.
-     */
-    public static String getTypeAlias(Class pcClass) {
-        return getMeta(pcClass).alias;
-    }
-
-    /**
-     * Copy fields from an outside source to the key fields in the identity
-     * object.
-     */
-    public static void copyKeyFieldsToObjectId(Class pcClass, FieldSupplier fm,
-        Object oid) {
-        Meta meta = getMeta(pcClass);
-        if (meta.pc == null)
-            throw new UserException(_loc.get("copy-no-id", pcClass));
-
-        meta.pc.pcCopyKeyFieldsToObjectId(fm, oid);
-    }
-
-    /**
-     * Copy fields to an outside source from the key fields in the identity
-     * object.
-     */
-    public static void copyKeyFieldsFromObjectId(Class pcClass,
-        FieldConsumer fm, Object oid) {
-        Meta meta = getMeta(pcClass);
-        if (meta.pc == null)
-            throw new UserException(_loc.get("copy-no-id", pcClass));
-
-        meta.pc.pcCopyKeyFieldsFromObjectId(fm, oid);
-    }
-
-    /**
-     * Register metadata by class.
-     *
-     * @param fieldTypes managed field types
-     * @param fieldFlags managed field flags
-     * @param sup the most immediate persistent superclass
-     * @param pcClass the <code>PersistenceCapable</code> class
-     * @param fieldNames managed field names
-     * @param alias the class alias
-     * @param pc an instance of the class, if not abstract
-     */
-    public static void register(Class pcClass, String[] fieldNames,
-        Class[] fieldTypes, byte[] fieldFlags, Class sup, String alias,
-        PersistenceCapable pc) {
-        if (pcClass == null)
-            throw new NullPointerException();
-
-        // we have to be positive that every listener gets notified for
-        // every class, so lots of locking
-        Meta meta = new Meta(pc, fieldNames, fieldTypes, sup, alias);
-        synchronized (_metas) {
-            _metas.put(pcClass, meta);
-        }
-        synchronized (_listeners) {
-            for (Iterator i = _listeners.iterator(); i.hasNext();)
-                ((RegisterClassListener) i.next()).register(pcClass);
-        }
-    }
-
-    /**
-     * De-Register all metadata associated with the given ClassLoader. 
-     * Allows ClassLoaders to be garbage collected.
-     *
-     * @param cl the ClassLoader
-     */
-    public static void deRegister(ClassLoader cl) {
-        synchronized (_metas) {
-            for (Iterator i = _metas.keySet().iterator(); i.hasNext();) {
-                Class pcClass = (Class) i.next();
-                if (pcClass.getClassLoader() == cl) {
-                    _metas.remove(pcClass);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Returns a collection of class objects of the registered
-     * persistence-capable classes.
-     */
-    public static Collection getRegisteredTypes() {
-        return Collections.unmodifiableCollection(_metas.keySet());
-    }
-
-    /**
-     * Returns <code>true</code> if <code>cls</code> is already registered.
-     */
-    public static boolean isRegistered(Class cls) {
-        return _metas.containsKey(cls);
-    }
-
-    /**
-     * Look up the metadata for a <code>PersistenceCapable</code> class.
-     */
-    private static Meta getMeta(Class pcClass) {
-        Meta ret = (Meta) _metas.get(pcClass);
-        if (ret == null)
-            throw new IllegalStateException(_loc.get("no-meta", pcClass).
-                getMessage());
-        return ret;
-    }
-
-    /**
-     * Listener for persistent class registration events.
-     */
-    public static interface RegisterClassListener {
-
-        public void register(Class cls);
-    }
-
-    /**
-     * This is a helper class to manage metadata per persistence-capable class.
-     */
-    private static class Meta {
-
-        public final PersistenceCapable pc;
-        public final String[] fieldNames;
-        public final Class[] fieldTypes;
-        public final Class pcSuper;
-        public final String alias;
-
-        public Meta(PersistenceCapable pc, String[] fieldNames,
-            Class[] fieldTypes, Class pcSuper, String alias) {
-            this.pc = pc;
-            this.fieldNames = fieldNames;
-            this.fieldTypes = fieldTypes;
-            this.pcSuper = pcSuper;
-			this.alias = alias;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.enhance;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.ReferenceMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+import org.apache.openjpa.util.UserException;
+import org.apache.openjpa.util.InvalidStateException;
+
+/**
+ * Tracks registered persistence-capable classes.
+ *
+ * @since 0.4.0
+ * @author Abe White
+ */
+public class PCRegistry {
+    // DO NOT ADD ADDITIONAL DEPENDENCIES TO THIS CLASS
+
+    private static final Localizer _loc = Localizer.forPackage
+        (PCRegistry.class);
+
+    // map of pc classes to meta structs; weak so the VM can GC classes
+    private static final Map _metas = new ConcurrentReferenceHashMap
+        (ReferenceMap.WEAK, ReferenceMap.HARD);
+
+    // register class listeners
+    private static final Collection _listeners = new LinkedList();
+
+    /**
+     * Register a {@link RegisterClassListener}.
+     */
+    public static void addRegisterClassListener(RegisterClassListener rcl) {
+        if (rcl == null)
+            return;
+
+        // we have to be positive that every listener gets notified for
+        // every class, so lots of locking
+        synchronized (_listeners) {
+            _listeners.add(rcl);
+        }
+        synchronized (_metas) {
+            for (Iterator itr = _metas.keySet().iterator(); itr.hasNext();)
+                rcl.register((Class) itr.next());
+        }
+    }
+
+    /**
+     * Removes a {@link RegisterClassListener}.
+     */
+    public static void removeRegisterClassListener(RegisterClassListener rcl) {
+        synchronized (_listeners) {
+            _listeners.remove(rcl);
+        }
+    }
+
+    /**
+     * Get the field names for a <code>PersistenceCapable</code> class.
+     */
+    public static String[] getFieldNames(Class pcClass) {
+        Meta meta = getMeta(pcClass);
+        return meta.fieldNames;
+    }
+
+    /**
+     * Get the field types for a <code>PersistenceCapable</code> class.
+     */
+    public static Class[] getFieldTypes(Class pcClass) {
+        Meta meta = getMeta(pcClass);
+        return meta.fieldTypes;
+    }
+
+    /**
+     * Return the persistent superclass for a <code>PersistenceCapable</code>
+     * class, or null if none. The superclass may or may not implement
+     * {@link PersistenceCapable}, depending on the access type of the class.
+     */
+    public static Class getPersistentSuperclass(Class pcClass) {
+        Meta meta = getMeta(pcClass);
+        return meta.pcSuper;
+    }
+
+    /**
+     * Create a new instance of the class and assign its state manager.
+     * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
+     */
+    public static PersistenceCapable newInstance(Class pcClass,
+        StateManager sm, boolean clear) {
+        Meta meta = getMeta(pcClass);
+        return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, clear);
+    }
+
+    /**
+     * Create a new instance of the class and assign its state manager and oid.
+     * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
+     */
+    public static PersistenceCapable newInstance(Class pcClass,
+        StateManager sm, Object oid, boolean clear) {
+        Meta meta = getMeta(pcClass);
+        return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, oid, clear);
+    }
+
+    /**
+     * Return the persistence-capable type for <code>type</code>. This might
+     * be a generated subclass of <code>type</code>.
+     *
+     * @since 1.1.0
+     */
+    public static Class getPCType(Class type) {
+        Meta meta = getMeta(type);
+        return (meta.pc == null) ? null : meta.pc.getClass();
+    }
+
+    /**
+     * Create a new identity object for the given
+     * <code>PersistenceCapable</code> class.
+     */
+    public static Object newObjectId(Class pcClass) {
+        Meta meta = getMeta(pcClass);
+        return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance();
+    }
+
+    /**
+     * Create a new identity object for the given
+     * <code>PersistenceCapable</code> class, using the <code>String</code>
+     * form of the constructor.
+     */
+    public static Object newObjectId(Class pcClass, String str) {
+        Meta meta = getMeta(pcClass);
+        return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance(str);
+    }
+
+    /**
+     * Return the alias for the given type.
+     */
+    public static String getTypeAlias(Class pcClass) {
+        return getMeta(pcClass).alias;
+    }
+
+    /**
+     * Copy fields from an outside source to the key fields in the identity
+     * object.
+     */
+    public static void copyKeyFieldsToObjectId(Class pcClass, FieldSupplier fm,
+        Object oid) {
+        Meta meta = getMeta(pcClass);
+        if (meta.pc == null)
+            throw new UserException(_loc.get("copy-no-id", pcClass));
+
+        meta.pc.pcCopyKeyFieldsToObjectId(fm, oid);
+    }
+
+    /**
+     * Copy fields to an outside source from the key fields in the identity
+     * object.
+     */
+    public static void copyKeyFieldsFromObjectId(Class pcClass,
+        FieldConsumer fm, Object oid) {
+        Meta meta = getMeta(pcClass);
+        if (meta.pc == null)
+            throw new UserException(_loc.get("copy-no-id", pcClass));
+
+        meta.pc.pcCopyKeyFieldsFromObjectId(fm, oid);
+    }
+
+    /**
+     * Register metadata by class.
+     *
+     * @param fieldTypes managed field types
+     * @param fieldFlags managed field flags
+     * @param sup the most immediate persistent superclass
+     * @param pcClass the <code>PersistenceCapable</code> class
+     * @param fieldNames managed field names
+     * @param alias the class alias
+     * @param pc an instance of the class, if not abstract
+     */
+    public static void register(Class pcClass, String[] fieldNames,
+        Class[] fieldTypes, byte[] fieldFlags, Class sup, String alias,
+        PersistenceCapable pc) {
+        if (pcClass == null)
+            throw new NullPointerException();
+
+        // we have to be positive that every listener gets notified for
+        // every class, so lots of locking
+        Meta meta = new Meta(pc, fieldNames, fieldTypes, sup, alias);
+        synchronized (_metas) {
+            _metas.put(pcClass, meta);
+        }
+        synchronized (_listeners) {
+            for (Iterator i = _listeners.iterator(); i.hasNext();)
+                ((RegisterClassListener) i.next()).register(pcClass);
+        }
+    }
+
+    /**
+     * De-Register all metadata associated with the given ClassLoader. 
+     * Allows ClassLoaders to be garbage collected.
+     *
+     * @param cl the ClassLoader
+     */
+    public static void deRegister(ClassLoader cl) {
+        synchronized (_metas) {
+            for (Iterator i = _metas.keySet().iterator(); i.hasNext();) {
+                Class pcClass = (Class) i.next();
+                if (pcClass.getClassLoader() == cl) {
+                    _metas.remove(pcClass);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Returns a collection of class objects of the registered
+     * persistence-capable classes.
+     */
+    public static Collection getRegisteredTypes() {
+        return Collections.unmodifiableCollection(_metas.keySet());
+    }
+
+    /**
+     * Returns <code>true</code> if <code>cls</code> is already registered.
+     */
+    public static boolean isRegistered(Class cls) {
+        return _metas.containsKey(cls);
+    }
+
+    /**
+     * Look up the metadata for a <code>PersistenceCapable</code> class.
+     */
+    private static Meta getMeta(Class pcClass) {
+        Meta ret = (Meta) _metas.get(pcClass);
+        if (ret == null)
+            throw new IllegalStateException(_loc.get("no-meta", pcClass).
+                getMessage());
+        return ret;
+    }
+
+    /**
+     * Listener for persistent class registration events.
+     */
+    public static interface RegisterClassListener {
+
+        public void register(Class cls);
+    }
+
+    /**
+     * This is a helper class to manage metadata per persistence-capable class.
+     */
+    private static class Meta {
+
+        public final PersistenceCapable pc;
+        public final String[] fieldNames;
+        public final Class[] fieldTypes;
+        public final Class pcSuper;
+        public final String alias;
+
+        public Meta(PersistenceCapable pc, String[] fieldNames,
+            Class[] fieldTypes, Class pcSuper, String alias) {
+            this.pc = pc;
+            this.fieldNames = fieldNames;
+            this.fieldTypes = fieldTypes;
+            this.pcSuper = pcSuper;
+			this.alias = alias;
+		}
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
index fa82574..aef221a 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
@@ -1,272 +1,272 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.util.UserException;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Localizer.Message;
-import org.apache.openjpa.lib.log.Log;
-import serp.bytecode.BCField;
-import serp.bytecode.BCClass;
-import serp.bytecode.BCMethod;
-
-/**
- *	<p>Validates that a given type meets the JPA contract, plus a few
- *  OpenJPA-specific additions for subclassing / redefinition:
- *
- *	<ul>
- * 		<li>must have an accessible no-args constructor</li>
- * 		<li>must be a public or protected class</li>
- * 		<li>must not be final</li>
- * 		<li>must not extend an enhanced class</li>
- *		<li>all persistent data represented by accessible setter/getter
- * 			methods (persistent properties)</li>
- * 		<li>if versioning is to be used, exactly one persistent property for
- * 			the numeric version data</li> <!-- ##### is this true? -->
- *
- * 		<li>When using property access, the backing field for a persistent
- *          property must be:
- * 			<ul>
- * 				<!-- ##### JPA validation of these needs to be tested -->
- * 				<li>private</li>
- * 				<li>set only in the designated setter,
- * 					in the constructor, or in {@link Object#clone()},
- * 					<code>readObject(ObjectInputStream)</code>, or
- * 					{@link Externalizable#readExternal(ObjectInput)}.</li>
- * 				<li>read only in the designated getter and the
- * 					constructor.</li>
- *			</ul>
- * 		</li>
- * 	</ul>
- *
- * 	<p>If you use this technique and use the <code>new</code> keyword instead of
- * 	a OpenJPA-supplied construction routine, OpenJPA will need to do extra work
- *  with persistent-new-flushed instances, since OpenJPA cannot in this case
- *  track what happens to such an instance.</p>
- *
- * 	@since 1.0.0
- */
-public class PCSubclassValidator {
-
-    private static final Localizer loc =
-        Localizer.forPackage(PCSubclassValidator.class);
-
-    private final ClassMetaData meta;
-    private final BCClass pc;
-    private final Log log;
-    private final boolean failOnContractViolations;
-
-    private Collection errors;
-    private Collection contractViolations;
-
-    public PCSubclassValidator(ClassMetaData meta, BCClass bc, Log log,
-        boolean enforceContractViolations) {
-        this.meta = meta;
-        this.pc = bc;
-        this.log = log;
-        this.failOnContractViolations = enforceContractViolations;
-    }
-
-    public void assertCanSubclass() {
-        Class superclass = meta.getDescribedType();
-        String name = superclass.getName();
-        if (superclass.isInterface())
-            addError(loc.get("subclasser-no-ifaces", name), meta);
-        if (Modifier.isFinal(superclass.getModifiers()))
-            addError(loc.get("subclasser-no-final-classes", name), meta);
-        if (Modifier.isPrivate(superclass.getModifiers()))
-            addError(loc.get("subclasser-no-private-classes", name), meta);
-        if (PersistenceCapable.class.isAssignableFrom(superclass))
-            addError(loc.get("subclasser-super-already-pc", name), meta);
-
-        try {
-            Constructor c = superclass.getDeclaredConstructor(new Class[0]);
-            if (!(Modifier.isProtected(c.getModifiers())
-                || Modifier.isPublic(c.getModifiers())))
-                addError(loc.get("subclasser-private-ctor", name), meta);
-        }
-        catch (NoSuchMethodException e) {
-            addError(loc.get("subclasser-no-void-ctor", name),
-                meta);
-        }
-
-        // if the BCClass we loaded is already pc and the superclass is not,
-        // then we should never get here, so let's make sure that the
-        // calling context is caching correctly by throwing an exception.
-        if (pc.isInstanceOf(PersistenceCapable.class) &&
-            !PersistenceCapable.class.isAssignableFrom(superclass))
-            throw new InternalException(
-                loc.get("subclasser-class-already-pc", name));
-
-        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY)
-            checkPropertiesAreInterceptable();
-
-        if (errors != null && !errors.isEmpty())
-            throw new UserException(errors.toString());
-        else if (contractViolations != null &&
-            !contractViolations.isEmpty() && log.isWarnEnabled())
-            log.warn(contractViolations.toString());
-    }
-
-    private void checkPropertiesAreInterceptable() {
-        // just considers accessor methods for now.
-        FieldMetaData[] fmds = meta.getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            Method getter = (Method) fmds[i].getBackingMember();
-            if (getter == null) {
-                addError(loc.get("subclasser-no-getter",
-                    fmds[i].getName()), fmds[i]);
-                continue;
-            }
-            BCField returnedField = checkGetterIsSubclassable(getter, fmds[i]);
-
-            Method setter = setterForField(fmds[i]);
-            if (setter == null) {
-                addError(loc.get("subclasser-no-setter", fmds[i].getName()),
-                    fmds[i]);
-                continue;
-            }
-            BCField assignedField = checkSetterIsSubclassable(setter, fmds[i]);
-            if (assignedField == null)
-                continue;
-
-            if (assignedField != returnedField)
-                addContractViolation(loc.get
-                    ("subclasser-setter-getter-field-mismatch",
-                        fmds[i].getName(), returnedField,assignedField),
-                    fmds[i]);
-
-            // ### scan through all the rest of the class to make sure it
-            // ### doesn't use the field.
-        }
-    }
-
-    private Method setterForField(FieldMetaData fmd) {
-        try {
-            return fmd.getDeclaringType().getDeclaredMethod(
-                "set" + StringUtils.capitalize(fmd.getName()),
-                new Class[]{ fmd.getDeclaredType() });
-        }
-        catch (NoSuchMethodException e) {
-            return null;
-        }
-    }
-
-    /**
-     * @return the name of the field that is returned by <code>meth</code>, or
-     *         <code>null</code> if something other than a single field is
-     *         returned, or if it cannot be determined what is returned.
-     */
-    private BCField checkGetterIsSubclassable(Method meth, FieldMetaData fmd) {
-        checkMethodIsSubclassable(meth, fmd);
-        BCField field = PCEnhancer.getReturnedField(getBCMethod(meth));
-        if (field == null) {
-            addContractViolation(loc.get("subclasser-invalid-getter",
-                fmd.getName()), fmd);
-            return null;
-        } else {
-            return field;
-        }
-    }
-
-    /**
-     * @return the field that is set in <code>meth</code>, or
-     *         <code>null</code> if something other than a single field is
-     *         set, or if it cannot be determined what is set.
-     */
-    private BCField checkSetterIsSubclassable(Method meth, FieldMetaData fmd) {
-        checkMethodIsSubclassable(meth, fmd);
-        BCField field = PCEnhancer.getAssignedField(getBCMethod(meth));
-        if (field == null) {
-            addContractViolation(loc.get("subclasser-invalid-setter",
-                fmd.getName()), fmd);
-            return null;
-        } else {
-            return field;
-        }
-    }
-
-    private BCMethod getBCMethod(Method meth) {
-        BCClass bc = pc.getProject().loadClass(meth.getDeclaringClass());
-        return bc.getDeclaredMethod(meth.getName(), meth.getParameterTypes());
-    }
-
-    private void checkMethodIsSubclassable(Method meth, FieldMetaData fmd) {
-        String className = fmd.getDefiningMetaData().
-            getDescribedType().getName();
-        if (!(Modifier.isProtected(meth.getModifiers())
-            || Modifier.isPublic(meth.getModifiers())))
-            addError(loc.get("subclasser-private-accessors-unsupported",
-                className, meth.getName()), fmd);
-        if (Modifier.isFinal(meth.getModifiers()))
-            addError(loc.get("subclasser-final-methods-not-allowed",
-                className, meth.getName()), fmd);
-        if (Modifier.isNative(meth.getModifiers()))
-            addContractViolation(loc.get
-                ("subclasser-native-methods-not-allowed", className,
-                    meth.getName()),
-                fmd);
-        if (Modifier.isStatic(meth.getModifiers()))
-            addError(loc.get("subclasser-static-methods-not-supported",
-                className, meth.getName()), fmd);
-    }
-
-    private void addError(Message s, ClassMetaData cls) {
-        if (errors == null)
-            errors = new ArrayList();
-
-        errors.add(loc.get("subclasser-error-meta", s,
-            cls.getDescribedType().getName(),
-            cls.getSourceFile()));
-    }
-
-    private void addError(Message s, FieldMetaData fmd) {
-        if (errors == null)
-            errors = new ArrayList();
-
-        errors.add(loc.get("subclasser-error-field", s,
-            fmd.getFullName(),
-            fmd.getDeclaringMetaData().getSourceFile()));
-    }
-
-    private void addContractViolation(Message m, FieldMetaData fmd) {
-        // add the violation as an error in case we're processing violations
-        // as errors; this keeps them in the order that they were found rather
-        // than just adding the violations to the end of the list.
-        if (failOnContractViolations)
-            addError(m, fmd);
-
-        if (contractViolations == null)
-            contractViolations = new ArrayList();
-
-        contractViolations.add(loc.get
-            ("subclasser-contract-violation-field", m.getMessage(),
-                fmd.getFullName(), fmd.getDeclaringMetaData().getSourceFile()));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.util.UserException;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Localizer.Message;
+import org.apache.openjpa.lib.log.Log;
+import serp.bytecode.BCField;
+import serp.bytecode.BCClass;
+import serp.bytecode.BCMethod;
+
+/**
+ *	<p>Validates that a given type meets the JPA contract, plus a few
+ *  OpenJPA-specific additions for subclassing / redefinition:
+ *
+ *	<ul>
+ * 		<li>must have an accessible no-args constructor</li>
+ * 		<li>must be a public or protected class</li>
+ * 		<li>must not be final</li>
+ * 		<li>must not extend an enhanced class</li>
+ *		<li>all persistent data represented by accessible setter/getter
+ * 			methods (persistent properties)</li>
+ * 		<li>if versioning is to be used, exactly one persistent property for
+ * 			the numeric version data</li> <!-- ##### is this true? -->
+ *
+ * 		<li>When using property access, the backing field for a persistent
+ *          property must be:
+ * 			<ul>
+ * 				<!-- ##### JPA validation of these needs to be tested -->
+ * 				<li>private</li>
+ * 				<li>set only in the designated setter,
+ * 					in the constructor, or in {@link Object#clone()},
+ * 					<code>readObject(ObjectInputStream)</code>, or
+ * 					{@link Externalizable#readExternal(ObjectInput)}.</li>
+ * 				<li>read only in the designated getter and the
+ * 					constructor.</li>
+ *			</ul>
+ * 		</li>
+ * 	</ul>
+ *
+ * 	<p>If you use this technique and use the <code>new</code> keyword instead of
+ * 	a OpenJPA-supplied construction routine, OpenJPA will need to do extra work
+ *  with persistent-new-flushed instances, since OpenJPA cannot in this case
+ *  track what happens to such an instance.</p>
+ *
+ * 	@since 1.0.0
+ */
+public class PCSubclassValidator {
+
+    private static final Localizer loc =
+        Localizer.forPackage(PCSubclassValidator.class);
+
+    private final ClassMetaData meta;
+    private final BCClass pc;
+    private final Log log;
+    private final boolean failOnContractViolations;
+
+    private Collection errors;
+    private Collection contractViolations;
+
+    public PCSubclassValidator(ClassMetaData meta, BCClass bc, Log log,
+        boolean enforceContractViolations) {
+        this.meta = meta;
+        this.pc = bc;
+        this.log = log;
+        this.failOnContractViolations = enforceContractViolations;
+    }
+
+    public void assertCanSubclass() {
+        Class superclass = meta.getDescribedType();
+        String name = superclass.getName();
+        if (superclass.isInterface())
+            addError(loc.get("subclasser-no-ifaces", name), meta);
+        if (Modifier.isFinal(superclass.getModifiers()))
+            addError(loc.get("subclasser-no-final-classes", name), meta);
+        if (Modifier.isPrivate(superclass.getModifiers()))
+            addError(loc.get("subclasser-no-private-classes", name), meta);
+        if (PersistenceCapable.class.isAssignableFrom(superclass))
+            addError(loc.get("subclasser-super-already-pc", name), meta);
+
+        try {
+            Constructor c = superclass.getDeclaredConstructor(new Class[0]);
+            if (!(Modifier.isProtected(c.getModifiers())
+                || Modifier.isPublic(c.getModifiers())))
+                addError(loc.get("subclasser-private-ctor", name), meta);
+        }
+        catch (NoSuchMethodException e) {
+            addError(loc.get("subclasser-no-void-ctor", name),
+                meta);
+        }
+
+        // if the BCClass we loaded is already pc and the superclass is not,
+        // then we should never get here, so let's make sure that the
+        // calling context is caching correctly by throwing an exception.
+        if (pc.isInstanceOf(PersistenceCapable.class) &&
+            !PersistenceCapable.class.isAssignableFrom(superclass))
+            throw new InternalException(
+                loc.get("subclasser-class-already-pc", name));
+
+        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY)
+            checkPropertiesAreInterceptable();
+
+        if (errors != null && !errors.isEmpty())
+            throw new UserException(errors.toString());
+        else if (contractViolations != null &&
+            !contractViolations.isEmpty() && log.isWarnEnabled())
+            log.warn(contractViolations.toString());
+    }
+
+    private void checkPropertiesAreInterceptable() {
+        // just considers accessor methods for now.
+        FieldMetaData[] fmds = meta.getFields();
+        for (int i = 0; i < fmds.length; i++) {
+            Method getter = (Method) fmds[i].getBackingMember();
+            if (getter == null) {
+                addError(loc.get("subclasser-no-getter",
+                    fmds[i].getName()), fmds[i]);
+                continue;
+            }
+            BCField returnedField = checkGetterIsSubclassable(getter, fmds[i]);
+
+            Method setter = setterForField(fmds[i]);
+            if (setter == null) {
+                addError(loc.get("subclasser-no-setter", fmds[i].getName()),
+                    fmds[i]);
+                continue;
+            }
+            BCField assignedField = checkSetterIsSubclassable(setter, fmds[i]);
+            if (assignedField == null)
+                continue;
+
+            if (assignedField != returnedField)
+                addContractViolation(loc.get
+                    ("subclasser-setter-getter-field-mismatch",
+                        fmds[i].getName(), returnedField,assignedField),
+                    fmds[i]);
+
+            // ### scan through all the rest of the class to make sure it
+            // ### doesn't use the field.
+        }
+    }
+
+    private Method setterForField(FieldMetaData fmd) {
+        try {
+            return fmd.getDeclaringType().getDeclaredMethod(
+                "set" + StringUtils.capitalize(fmd.getName()),
+                new Class[]{ fmd.getDeclaredType() });
+        }
+        catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    /**
+     * @return the name of the field that is returned by <code>meth</code>, or
+     *         <code>null</code> if something other than a single field is
+     *         returned, or if it cannot be determined what is returned.
+     */
+    private BCField checkGetterIsSubclassable(Method meth, FieldMetaData fmd) {
+        checkMethodIsSubclassable(meth, fmd);
+        BCField field = PCEnhancer.getReturnedField(getBCMethod(meth));
+        if (field == null) {
+            addContractViolation(loc.get("subclasser-invalid-getter",
+                fmd.getName()), fmd);
+            return null;
+        } else {
+            return field;
+        }
+    }
+
+    /**
+     * @return the field that is set in <code>meth</code>, or
+     *         <code>null</code> if something other than a single field is
+     *         set, or if it cannot be determined what is set.
+     */
+    private BCField checkSetterIsSubclassable(Method meth, FieldMetaData fmd) {
+        checkMethodIsSubclassable(meth, fmd);
+        BCField field = PCEnhancer.getAssignedField(getBCMethod(meth));
+        if (field == null) {
+            addContractViolation(loc.get("subclasser-invalid-setter",
+                fmd.getName()), fmd);
+            return null;
+        } else {
+            return field;
+        }
+    }
+
+    private BCMethod getBCMethod(Method meth) {
+        BCClass bc = pc.getProject().loadClass(meth.getDeclaringClass());
+        return bc.getDeclaredMethod(meth.getName(), meth.getParameterTypes());
+    }
+
+    private void checkMethodIsSubclassable(Method meth, FieldMetaData fmd) {
+        String className = fmd.getDefiningMetaData().
+            getDescribedType().getName();
+        if (!(Modifier.isProtected(meth.getModifiers())
+            || Modifier.isPublic(meth.getModifiers())))
+            addError(loc.get("subclasser-private-accessors-unsupported",
+                className, meth.getName()), fmd);
+        if (Modifier.isFinal(meth.getModifiers()))
+            addError(loc.get("subclasser-final-methods-not-allowed",
+                className, meth.getName()), fmd);
+        if (Modifier.isNative(meth.getModifiers()))
+            addContractViolation(loc.get
+                ("subclasser-native-methods-not-allowed", className,
+                    meth.getName()),
+                fmd);
+        if (Modifier.isStatic(meth.getModifiers()))
+            addError(loc.get("subclasser-static-methods-not-supported",
+                className, meth.getName()), fmd);
+    }
+
+    private void addError(Message s, ClassMetaData cls) {
+        if (errors == null)
+            errors = new ArrayList();
+
+        errors.add(loc.get("subclasser-error-meta", s,
+            cls.getDescribedType().getName(),
+            cls.getSourceFile()));
+    }
+
+    private void addError(Message s, FieldMetaData fmd) {
+        if (errors == null)
+            errors = new ArrayList();
+
+        errors.add(loc.get("subclasser-error-field", s,
+            fmd.getFullName(),
+            fmd.getDeclaringMetaData().getSourceFile()));
+    }
+
+    private void addContractViolation(Message m, FieldMetaData fmd) {
+        // add the violation as an error in case we're processing violations
+        // as errors; this keeps them in the order that they were found rather
+        // than just adding the violations to the end of the list.
+        if (failOnContractViolations)
+            addError(m, fmd);
+
+        if (contractViolations == null)
+            contractViolations = new ArrayList();
+
+        contractViolations.add(loc.get
+            ("subclasser-contract-violation-field", m.getMessage(),
+                fmd.getFullName(), fmd.getDeclaringMetaData().getSourceFile()));
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RedefinitionHelper.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RedefinitionHelper.java
index 85ecedb..b49ad7e 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RedefinitionHelper.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RedefinitionHelper.java
@@ -1,237 +1,237 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.Method;
-import java.lang.reflect.Field;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.StateManagerImpl;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.util.ImplHelper;
-
-/**
- * Helper methods for managed types that use method redefinition for field
- * tracking.
- *
- * @since 1.0.0
- */
-public class RedefinitionHelper {
-
-    /**
-     * Call {@link StateManagerImpl#dirtyCheck} if the argument is a
-     * {@link StateManagerImpl}.
-     */
-    public static void dirtyCheck(StateManager sm) {
-        if (sm instanceof StateManagerImpl)
-            ((StateManagerImpl) sm).dirtyCheck();
-    }
-
-    /**
-     * Notify the state manager for <code>o</code> (if any) that a field
-     * is about to be accessed.
-     */
-    public static void accessingField(Object o, int absoluteIndex) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.accessingField(absoluteIndex);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, boolean cur,
-        boolean next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingBooleanField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, char cur, char next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingCharField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, byte cur, byte next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingByteField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, short cur, short next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingShortField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, int cur, int next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingIntField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, long cur, long next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingLongField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, float cur, float next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingFloatField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, double cur,
-        double next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingDoubleField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, String cur,
-        String next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingStringField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Setting state callback.
-     */
-    public static void settingField(Object o, int idx, Object cur,
-        Object next) {
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
-        if (pc == null)
-            return;
-        StateManager sm = pc.pcGetStateManager();
-        if (sm != null)
-            sm.settingObjectField(pc, idx, cur, next,
-                OpenJPAStateManager.SET_USER);
-    }
-
-    /**
-     * Create a container instance that will delegate back to the state
-     * manager to emulate lazy loading. This is used by PC subclasses for
-     * unenhanced types that could not be redefined, and thus do not have
-     * field-interception capabilities. Do this for all collection and
-     * map field types, even if they are in the dfg, in case the fetch
-     * groups are reset at runtime.
-     *
-     * @since 1.1.0
-     */
-    public static void assignLazyLoadProxies(StateManagerImpl sm) {
-        FieldMetaData[] fmds = sm.getMetaData().getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            switch (fmds[i].getTypeCode()) {
-                case JavaTypes.COLLECTION:
-                case JavaTypes.MAP:
-                    PersistenceCapable pc = sm.getPersistenceCapable();
-                    Field field = (Field) fmds[i].getBackingMember();
-                    Reflection.set(pc, field,
-                        newLazyLoadingProxy(fmds[i].getDeclaredType(), i, sm));
-                    break;
-            }
-        }
-    }
-
-    private static Object newLazyLoadingProxy(Class type, final int idx,
-        final StateManagerImpl sm) {
-        InvocationHandler handler = new InvocationHandler() {
-
-            public Object invoke(Object proxy, Method method, Object[] args)
-                throws Throwable {
-                // this will replace the field in the instance, so the dynamic
-                // proxy should only be called the first time a
-                // lazy-load-proxied field is used in normal usage.
-                Object delegate = sm.fetch(idx);
-                return method.invoke(delegate, args);
-            }
-        };
-        return Proxy.newProxyInstance(type.getClassLoader(),
-            new Class[] { type }, handler);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StateManagerImpl;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.ImplHelper;
+
+/**
+ * Helper methods for managed types that use method redefinition for field
+ * tracking.
+ *
+ * @since 1.0.0
+ */
+public class RedefinitionHelper {
+
+    /**
+     * Call {@link StateManagerImpl#dirtyCheck} if the argument is a
+     * {@link StateManagerImpl}.
+     */
+    public static void dirtyCheck(StateManager sm) {
+        if (sm instanceof StateManagerImpl)
+            ((StateManagerImpl) sm).dirtyCheck();
+    }
+
+    /**
+     * Notify the state manager for <code>o</code> (if any) that a field
+     * is about to be accessed.
+     */
+    public static void accessingField(Object o, int absoluteIndex) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.accessingField(absoluteIndex);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, boolean cur,
+        boolean next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingBooleanField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, char cur, char next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingCharField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, byte cur, byte next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingByteField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, short cur, short next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingShortField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, int cur, int next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingIntField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, long cur, long next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingLongField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, float cur, float next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingFloatField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, double cur,
+        double next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingDoubleField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, String cur,
+        String next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingStringField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Setting state callback.
+     */
+    public static void settingField(Object o, int idx, Object cur,
+        Object next) {
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(o, null);
+        if (pc == null)
+            return;
+        StateManager sm = pc.pcGetStateManager();
+        if (sm != null)
+            sm.settingObjectField(pc, idx, cur, next,
+                OpenJPAStateManager.SET_USER);
+    }
+
+    /**
+     * Create a container instance that will delegate back to the state
+     * manager to emulate lazy loading. This is used by PC subclasses for
+     * unenhanced types that could not be redefined, and thus do not have
+     * field-interception capabilities. Do this for all collection and
+     * map field types, even if they are in the dfg, in case the fetch
+     * groups are reset at runtime.
+     *
+     * @since 1.1.0
+     */
+    public static void assignLazyLoadProxies(StateManagerImpl sm) {
+        FieldMetaData[] fmds = sm.getMetaData().getFields();
+        for (int i = 0; i < fmds.length; i++) {
+            switch (fmds[i].getTypeCode()) {
+                case JavaTypes.COLLECTION:
+                case JavaTypes.MAP:
+                    PersistenceCapable pc = sm.getPersistenceCapable();
+                    Field field = (Field) fmds[i].getBackingMember();
+                    Reflection.set(pc, field,
+                        newLazyLoadingProxy(fmds[i].getDeclaredType(), i, sm));
+                    break;
+            }
+        }
+    }
+
+    private static Object newLazyLoadingProxy(Class type, final int idx,
+        final StateManagerImpl sm) {
+        InvocationHandler handler = new InvocationHandler() {
+
+            public Object invoke(Object proxy, Method method, Object[] args)
+                throws Throwable {
+                // this will replace the field in the instance, so the dynamic
+                // proxy should only be called the first time a
+                // lazy-load-proxied field is used in normal usage.
+                Object delegate = sm.fetch(idx);
+                return method.invoke(delegate, args);
+            }
+        };
+        return Proxy.newProxyInstance(type.getClassLoader(),
+            new Class[] { type }, handler);
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ReflectingPersistenceCapable.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ReflectingPersistenceCapable.java
index 869c5e8..d3bce10 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ReflectingPersistenceCapable.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ReflectingPersistenceCapable.java
@@ -1,387 +1,387 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.StateManagerImpl;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.util.ApplicationIds;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.ObjectId;
-
-/**
- * Implementation of the {@link PersistenceCapable} interface that can handle
- * the persistence-capable contract for instances that were not enhanced
- * before class load time.
- *
- * @since 1.0.0
- */
-public class ReflectingPersistenceCapable
-    implements PersistenceCapable, ManagedInstanceProvider, Serializable {
-
-    private Object o;
-    private StateManager sm;
-
-    // this will be reconstituted in readObject()
-    private transient PersistenceCapable pcSubclassInstance;
-
-    // this will reconstituted by a call to pcReplaceStateManager() by the
-    // instance that has a reference to the deserialized data
-    private transient ClassMetaData meta;
-
-    private boolean serializationUserVisible = true;
-
-    public ReflectingPersistenceCapable(Object o, OpenJPAConfiguration conf) {
-        this.o = o;
-        Class type = o.getClass();
-        pcSubclassInstance = PCRegistry.newInstance(type, null, false);
-        meta = conf.getMetaDataRepositoryInstance()
-            .getMetaData(type, null, true);
-    }
-
-    public int pcGetEnhancementContractVersion() {
-        return PCEnhancer.ENHANCER_VERSION;
-    }
-
-    public Object pcGetGenericContext() {
-        if (sm == null)
-            return null;
-        else
-            return sm.getGenericContext();
-    }
-
-    public StateManager pcGetStateManager() {
-        return sm;
-    }
-
-    public void pcReplaceStateManager(StateManager sm) {
-        this.sm = sm;
-        if (meta == null && sm instanceof OpenJPAStateManager)
-            meta = ((OpenJPAStateManager) sm).getMetaData();
-    }
-
-    public void pcProvideField(int i) {
-        Object value = getValue(i, o);
-        switch (meta.getField(i).getTypeCode()) {
-            case JavaTypes.BOOLEAN:
-                sm.providedBooleanField(this, i, value == null ? false :
-                    ((Boolean) value).booleanValue());
-                break;
-            case JavaTypes.BYTE:
-                sm.providedByteField(this, i, value == null ? 0 :
-                    ((Byte) value).byteValue());
-                break;
-            case JavaTypes.CHAR:
-                sm.providedCharField(this, i, value == null ? 0 :
-                    ((Character) value).charValue());
-                break;
-            case JavaTypes.DOUBLE:
-                sm.providedDoubleField(this, i, value == null ? 0 :
-                    ((Double) value).doubleValue());
-                break;
-            case JavaTypes.FLOAT:
-                sm.providedFloatField(this, i, value == null ? 0 :
-                    ((Float) value).floatValue());
-                break;
-            case JavaTypes.INT:
-                sm.providedIntField(this, i, value == null ? 0 :
-                    ((Integer) value).intValue());
-                break;
-            case JavaTypes.LONG:
-                sm.providedLongField(this, i, value == null ? 0 :
-                    ((Long) value).longValue());
-                break;
-            case JavaTypes.SHORT:
-                sm.providedShortField(this, i, value == null ? 0 :
-                    ((Short) value).shortValue());
-                break;
-            case JavaTypes.STRING:
-                sm.providedStringField(this, i, (String) value);
-                break;
-            default:
-                sm.providedObjectField(this, i, value);
-                break;
-        }
-    }
-
-    public void pcProvideFields(int[] fieldIndices) {
-        for(int i = 0; i < fieldIndices.length; i++)
-            pcProvideField(fieldIndices[i]);
-    }
-
-    public void pcReplaceField(int i) {
-        switch(meta.getField(i).getTypeCode()) {
-            case JavaTypes.BOOLEAN:
-                setValue(i, o, Boolean.valueOf(
-                    sm.replaceBooleanField(this, i)));
-                break;
-            case JavaTypes.BYTE:
-                setValue(i, o, new Byte(sm.replaceByteField(this, i)));
-                break;
-            case JavaTypes.CHAR:
-                setValue(i, o, new Character(sm.replaceCharField(this, i)));
-                break;
-            case JavaTypes.DOUBLE:
-                setValue(i, o, new Double(sm.replaceDoubleField(this, i)));
-                break;
-            case JavaTypes.FLOAT:
-                setValue(i, o, new Float(sm.replaceFloatField(this, i)));
-                break;
-            case JavaTypes.INT:
-                setValue(i, o, new Integer(sm.replaceIntField(this, i)));
-                break;
-            case JavaTypes.LONG:
-                setValue(i, o, new Long(sm.replaceLongField(this, i)));
-                break;
-            case JavaTypes.SHORT:
-                setValue(i, o, new Short(sm.replaceShortField(this, i)));
-                break;
-            case JavaTypes.STRING:
-                setValue(i, o, sm.replaceStringField(this, i));
-                break;
-            default:
-                setValue(i, o, sm.replaceObjectField(this, i));
-                break;
-        }
-    }
-
-    public void pcReplaceFields(int[] fieldIndices) {
-        for(int i = 0; i < fieldIndices.length; i++)
-            pcReplaceField(fieldIndices[i]);
-    }
-
-    public void pcCopyField(Object fromObject, int i) {
-        // this doesn't need switch treatment because we're just
-        // reflecting on both sides, bypassing field managers.
-        setValue(i, o, getValue(i, fromObject));
-    }
-
-    public void pcCopyFields(Object fromObject, int[] fieldIndices) {
-        if (fromObject instanceof ReflectingPersistenceCapable)
-            fromObject = ((ReflectingPersistenceCapable) fromObject)
-                .getManagedInstance();
-        
-        for(int i = 0; i < fieldIndices.length; i++)
-            pcCopyField(fromObject, fieldIndices[i]);
-    }
-
-    public void pcDirty(String fieldName) {
-        if (sm != null)
-            sm.dirty(fieldName);
-    }
-
-    public Object pcFetchObjectId() {
-        if (sm != null)
-            return sm.fetchObjectId();
-        else
-            return null;
-    }
-
-    public Object pcGetVersion() {
-        if (sm == null)
-            return null;
-        else
-            return sm.getVersion();
-    }
-
-    public boolean pcIsDirty() {
-        if (sm == null)
-            return false;
-        else {
-            if (sm instanceof StateManagerImpl)
-                ((StateManagerImpl) sm).dirtyCheck();
-            return sm.isDirty();
-        }
-    }
-
-    public boolean pcIsTransactional() {
-        if (sm == null)
-            return false;
-        else
-            return sm.isTransactional();
-    }
-
-    public boolean pcIsPersistent() {
-        if (sm == null)
-            return false;
-        else
-            return sm.isPersistent();
-    }
-
-    public boolean pcIsNew() {
-        if (sm == null)
-            return false;
-        else
-            return sm.isNew();
-    }
-
-    public boolean pcIsDeleted() {
-        if (sm == null)
-            return false;
-        else
-            return sm.isDeleted();
-    }
-
-    // null == unknown
-    public Boolean pcIsDetached() {
-        if (sm != null)
-            return Boolean.valueOf(sm.isDetached());
-
-        // ##### we could do a lot more here if a detached state field
-        // ##### was specified.
-        return null;
-    }
-
-    public PersistenceCapable pcNewInstance(StateManager sm, boolean clear) {
-        return pcSubclassInstance.pcNewInstance(sm, clear);
-    }
-
-    public PersistenceCapable pcNewInstance(StateManager sm, Object oid,
-        boolean clear) {
-        return pcSubclassInstance.pcNewInstance(sm, oid, clear);
-    }
-
-    public Object pcNewObjectIdInstance() {
-        FieldMetaData[] pkFields = meta.getPrimaryKeyFields();
-        Object[] pks = new Object[pkFields.length];
-        for (int i = 0; i < pkFields.length; i++)
-            pks[i] = getValue(pkFields[i].getIndex(), o);
-        return ApplicationIds.fromPKValues(pks, meta);
-    }
-    
-    public Object pcNewObjectIdInstance(Object oid) {
-        return pcSubclassInstance.pcNewObjectIdInstance(oid);
-    }
-
-    public void pcCopyKeyFieldsToObjectId(Object oid) {
-        Object target;
-        if (oid instanceof ObjectId)
-            target = ((ObjectId) oid).getId();
-        else
-            target = oid;
-
-        FieldMetaData[] pks = meta.getPrimaryKeyFields();
-        for (int i = 0; i < pks.length; i++) {
-            Object val = getValue(pks[i].getIndex(), o);
-            Field f = Reflection.findField(target.getClass(), pks[i].getName(),
-                true);
-            Reflection.set(target, f, val);
-        }
-    }
-
-    public void pcCopyKeyFieldsToObjectId(FieldSupplier supplier, Object obj) {
-        // This is only ever invoked against PCs in the PCRegistry. Such PCs
-        // will always be enhanced types or subtypes of user types, and will
-        // never be a ReflectingPersistenceCapable.
-        throw new InternalException();
-    }
-
-    public void pcCopyKeyFieldsFromObjectId(FieldConsumer consumer,
-        Object obj) {
-        // This is only ever invoked against PCs in the PCRegistry. Such PCs
-        // will always be enhanced types or subtypes of user types, and will
-        // never be a ReflectingPersistenceCapable.
-        throw new InternalException();
-    }
-
-    public Object pcGetDetachedState() {
-        // ##### we can implement this if a state field has been set
-        return null;
-    }
-
-    public void pcSetDetachedState(Object state) {
-        // StateManagerImpl will invoke this with null during instance
-        // initialization
-        if (state != null)
-            throw new UnsupportedOperationException();
-        // ##### we can implement this if a state field has been set
-    }
-
-    public void pcSetSerializationUserVisible(boolean userVisible) {
-        serializationUserVisible = userVisible;
-    }
-
-    public boolean pcIsSerializationUserVisible() {
-        return serializationUserVisible;
-    }
-
-    public Object getManagedInstance() {
-        return o;
-    }
-
-    private Object getValue(int i, Object o) {
-        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY) {
-            Field field = Reflection.findField(meta.getDescribedType(),
-                toFieldName(i), true);
-            return Reflection.get(o, field);
-        } else {
-            Field field = (Field) meta.getField(i).getBackingMember();
-            return Reflection.get(o, field);
-        }
-    }
-
-    private String toFieldName(int i) {
-        if (pcSubclassInstance instanceof AttributeTranslator)
-            return ((AttributeTranslator) pcSubclassInstance)
-                .pcAttributeIndexToFieldName(i);
-        else
-            return meta.getField(i).getName();
-    }
-
-    private void setValue(int i, Object o, Object val) {
-        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY) {
-            if (!meta.isIntercepting()) {
-                Method meth = Reflection.findSetter(meta.getDescribedType(),
-                    meta.getField(i).getName(), true);
-                Reflection.set(o, meth, val);
-            } else {
-                Field field = Reflection.findField(meta.getDescribedType(),
-                    toFieldName(i), true);
-                Reflection.set(o, field, val);
-            }
-        } else {
-            Field field = (Field) meta.getField(i).getBackingMember();
-            Reflection.set(o, field, val);
-        }
-    }
-
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        out.defaultWriteObject();
-        out.writeObject(meta.getDescribedType());
-    }
-
-    private void readObject(ObjectInputStream in)
-        throws ClassNotFoundException, IOException {
-        in.defaultReadObject();
-        Class type = (Class) in.readObject();
-        pcSubclassInstance = PCRegistry.newInstance(type, null, false);
-        ImplHelper.registerPersistenceCapable(this);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StateManagerImpl;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.ApplicationIds;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.ObjectId;
+
+/**
+ * Implementation of the {@link PersistenceCapable} interface that can handle
+ * the persistence-capable contract for instances that were not enhanced
+ * before class load time.
+ *
+ * @since 1.0.0
+ */
+public class ReflectingPersistenceCapable
+    implements PersistenceCapable, ManagedInstanceProvider, Serializable {
+
+    private Object o;
+    private StateManager sm;
+
+    // this will be reconstituted in readObject()
+    private transient PersistenceCapable pcSubclassInstance;
+
+    // this will reconstituted by a call to pcReplaceStateManager() by the
+    // instance that has a reference to the deserialized data
+    private transient ClassMetaData meta;
+
+    private boolean serializationUserVisible = true;
+
+    public ReflectingPersistenceCapable(Object o, OpenJPAConfiguration conf) {
+        this.o = o;
+        Class type = o.getClass();
+        pcSubclassInstance = PCRegistry.newInstance(type, null, false);
+        meta = conf.getMetaDataRepositoryInstance()
+            .getMetaData(type, null, true);
+    }
+
+    public int pcGetEnhancementContractVersion() {
+        return PCEnhancer.ENHANCER_VERSION;
+    }
+
+    public Object pcGetGenericContext() {
+        if (sm == null)
+            return null;
+        else
+            return sm.getGenericContext();
+    }
+
+    public StateManager pcGetStateManager() {
+        return sm;
+    }
+
+    public void pcReplaceStateManager(StateManager sm) {
+        this.sm = sm;
+        if (meta == null && sm instanceof OpenJPAStateManager)
+            meta = ((OpenJPAStateManager) sm).getMetaData();
+    }
+
+    public void pcProvideField(int i) {
+        Object value = getValue(i, o);
+        switch (meta.getField(i).getTypeCode()) {
+            case JavaTypes.BOOLEAN:
+                sm.providedBooleanField(this, i, value == null ? false :
+                    ((Boolean) value).booleanValue());
+                break;
+            case JavaTypes.BYTE:
+                sm.providedByteField(this, i, value == null ? 0 :
+                    ((Byte) value).byteValue());
+                break;
+            case JavaTypes.CHAR:
+                sm.providedCharField(this, i, value == null ? 0 :
+                    ((Character) value).charValue());
+                break;
+            case JavaTypes.DOUBLE:
+                sm.providedDoubleField(this, i, value == null ? 0 :
+                    ((Double) value).doubleValue());
+                break;
+            case JavaTypes.FLOAT:
+                sm.providedFloatField(this, i, value == null ? 0 :
+                    ((Float) value).floatValue());
+                break;
+            case JavaTypes.INT:
+                sm.providedIntField(this, i, value == null ? 0 :
+                    ((Integer) value).intValue());
+                break;
+            case JavaTypes.LONG:
+                sm.providedLongField(this, i, value == null ? 0 :
+                    ((Long) value).longValue());
+                break;
+            case JavaTypes.SHORT:
+                sm.providedShortField(this, i, value == null ? 0 :
+                    ((Short) value).shortValue());
+                break;
+            case JavaTypes.STRING:
+                sm.providedStringField(this, i, (String) value);
+                break;
+            default:
+                sm.providedObjectField(this, i, value);
+                break;
+        }
+    }
+
+    public void pcProvideFields(int[] fieldIndices) {
+        for(int i = 0; i < fieldIndices.length; i++)
+            pcProvideField(fieldIndices[i]);
+    }
+
+    public void pcReplaceField(int i) {
+        switch(meta.getField(i).getTypeCode()) {
+            case JavaTypes.BOOLEAN:
+                setValue(i, o, Boolean.valueOf(
+                    sm.replaceBooleanField(this, i)));
+                break;
+            case JavaTypes.BYTE:
+                setValue(i, o, new Byte(sm.replaceByteField(this, i)));
+                break;
+            case JavaTypes.CHAR:
+                setValue(i, o, new Character(sm.replaceCharField(this, i)));
+                break;
+            case JavaTypes.DOUBLE:
+                setValue(i, o, new Double(sm.replaceDoubleField(this, i)));
+                break;
+            case JavaTypes.FLOAT:
+                setValue(i, o, new Float(sm.replaceFloatField(this, i)));
+                break;
+            case JavaTypes.INT:
+                setValue(i, o, new Integer(sm.replaceIntField(this, i)));
+                break;
+            case JavaTypes.LONG:
+                setValue(i, o, new Long(sm.replaceLongField(this, i)));
+                break;
+            case JavaTypes.SHORT:
+                setValue(i, o, new Short(sm.replaceShortField(this, i)));
+                break;
+            case JavaTypes.STRING:
+                setValue(i, o, sm.replaceStringField(this, i));
+                break;
+            default:
+                setValue(i, o, sm.replaceObjectField(this, i));
+                break;
+        }
+    }
+
+    public void pcReplaceFields(int[] fieldIndices) {
+        for(int i = 0; i < fieldIndices.length; i++)
+            pcReplaceField(fieldIndices[i]);
+    }
+
+    public void pcCopyField(Object fromObject, int i) {
+        // this doesn't need switch treatment because we're just
+        // reflecting on both sides, bypassing field managers.
+        setValue(i, o, getValue(i, fromObject));
+    }
+
+    public void pcCopyFields(Object fromObject, int[] fieldIndices) {
+        if (fromObject instanceof ReflectingPersistenceCapable)
+            fromObject = ((ReflectingPersistenceCapable) fromObject)
+                .getManagedInstance();
+        
+        for(int i = 0; i < fieldIndices.length; i++)
+            pcCopyField(fromObject, fieldIndices[i]);
+    }
+
+    public void pcDirty(String fieldName) {
+        if (sm != null)
+            sm.dirty(fieldName);
+    }
+
+    public Object pcFetchObjectId() {
+        if (sm != null)
+            return sm.fetchObjectId();
+        else
+            return null;
+    }
+
+    public Object pcGetVersion() {
+        if (sm == null)
+            return null;
+        else
+            return sm.getVersion();
+    }
+
+    public boolean pcIsDirty() {
+        if (sm == null)
+            return false;
+        else {
+            if (sm instanceof StateManagerImpl)
+                ((StateManagerImpl) sm).dirtyCheck();
+            return sm.isDirty();
+        }
+    }
+
+    public boolean pcIsTransactional() {
+        if (sm == null)
+            return false;
+        else
+            return sm.isTransactional();
+    }
+
+    public boolean pcIsPersistent() {
+        if (sm == null)
+            return false;
+        else
+            return sm.isPersistent();
+    }
+
+    public boolean pcIsNew() {
+        if (sm == null)
+            return false;
+        else
+            return sm.isNew();
+    }
+
+    public boolean pcIsDeleted() {
+        if (sm == null)
+            return false;
+        else
+            return sm.isDeleted();
+    }
+
+    // null == unknown
+    public Boolean pcIsDetached() {
+        if (sm != null)
+            return Boolean.valueOf(sm.isDetached());
+
+        // ##### we could do a lot more here if a detached state field
+        // ##### was specified.
+        return null;
+    }
+
+    public PersistenceCapable pcNewInstance(StateManager sm, boolean clear) {
+        return pcSubclassInstance.pcNewInstance(sm, clear);
+    }
+
+    public PersistenceCapable pcNewInstance(StateManager sm, Object oid,
+        boolean clear) {
+        return pcSubclassInstance.pcNewInstance(sm, oid, clear);
+    }
+
+    public Object pcNewObjectIdInstance() {
+        FieldMetaData[] pkFields = meta.getPrimaryKeyFields();
+        Object[] pks = new Object[pkFields.length];
+        for (int i = 0; i < pkFields.length; i++)
+            pks[i] = getValue(pkFields[i].getIndex(), o);
+        return ApplicationIds.fromPKValues(pks, meta);
+    }
+    
+    public Object pcNewObjectIdInstance(Object oid) {
+        return pcSubclassInstance.pcNewObjectIdInstance(oid);
+    }
+
+    public void pcCopyKeyFieldsToObjectId(Object oid) {
+        Object target;
+        if (oid instanceof ObjectId)
+            target = ((ObjectId) oid).getId();
+        else
+            target = oid;
+
+        FieldMetaData[] pks = meta.getPrimaryKeyFields();
+        for (int i = 0; i < pks.length; i++) {
+            Object val = getValue(pks[i].getIndex(), o);
+            Field f = Reflection.findField(target.getClass(), pks[i].getName(),
+                true);
+            Reflection.set(target, f, val);
+        }
+    }
+
+    public void pcCopyKeyFieldsToObjectId(FieldSupplier supplier, Object obj) {
+        // This is only ever invoked against PCs in the PCRegistry. Such PCs
+        // will always be enhanced types or subtypes of user types, and will
+        // never be a ReflectingPersistenceCapable.
+        throw new InternalException();
+    }
+
+    public void pcCopyKeyFieldsFromObjectId(FieldConsumer consumer,
+        Object obj) {
+        // This is only ever invoked against PCs in the PCRegistry. Such PCs
+        // will always be enhanced types or subtypes of user types, and will
+        // never be a ReflectingPersistenceCapable.
+        throw new InternalException();
+    }
+
+    public Object pcGetDetachedState() {
+        // ##### we can implement this if a state field has been set
+        return null;
+    }
+
+    public void pcSetDetachedState(Object state) {
+        // StateManagerImpl will invoke this with null during instance
+        // initialization
+        if (state != null)
+            throw new UnsupportedOperationException();
+        // ##### we can implement this if a state field has been set
+    }
+
+    public void pcSetSerializationUserVisible(boolean userVisible) {
+        serializationUserVisible = userVisible;
+    }
+
+    public boolean pcIsSerializationUserVisible() {
+        return serializationUserVisible;
+    }
+
+    public Object getManagedInstance() {
+        return o;
+    }
+
+    private Object getValue(int i, Object o) {
+        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY) {
+            Field field = Reflection.findField(meta.getDescribedType(),
+                toFieldName(i), true);
+            return Reflection.get(o, field);
+        } else {
+            Field field = (Field) meta.getField(i).getBackingMember();
+            return Reflection.get(o, field);
+        }
+    }
+
+    private String toFieldName(int i) {
+        if (pcSubclassInstance instanceof AttributeTranslator)
+            return ((AttributeTranslator) pcSubclassInstance)
+                .pcAttributeIndexToFieldName(i);
+        else
+            return meta.getField(i).getName();
+    }
+
+    private void setValue(int i, Object o, Object val) {
+        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY) {
+            if (!meta.isIntercepting()) {
+                Method meth = Reflection.findSetter(meta.getDescribedType(),
+                    meta.getField(i).getName(), true);
+                Reflection.set(o, meth, val);
+            } else {
+                Field field = Reflection.findField(meta.getDescribedType(),
+                    toFieldName(i), true);
+                Reflection.set(o, field, val);
+            }
+        } else {
+            Field field = (Field) meta.getField(i).getBackingMember();
+            Reflection.set(o, field, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+        out.writeObject(meta.getDescribedType());
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws ClassNotFoundException, IOException {
+        in.defaultReadObject();
+        Class type = (Class) in.readObject();
+        pcSubclassInstance = PCRegistry.newInstance(type, null, false);
+        ImplHelper.registerPersistenceCapable(this);
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClassesModes.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClassesModes.java
index 73a16b2..a37b537 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClassesModes.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClassesModes.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-/**
- * Possible values for the <code>openjpa.RuntimeUnenhancedClasses</code>
- * configuration setting.
- *
- * @since 1.0.0
- */
-public interface RuntimeUnenhancedClassesModes {
-    public final static int SUPPORTED = 0;
-    public final static int UNSUPPORTED = 1;
-    public final static int WARN = 2;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+/**
+ * Possible values for the <code>openjpa.RuntimeUnenhancedClasses</code>
+ * configuration setting.
+ *
+ * @since 1.0.0
+ */
+public interface RuntimeUnenhancedClassesModes {
+    public final static int SUPPORTED = 0;
+    public final static int UNSUPPORTED = 1;
+    public final static int WARN = 2;
 }
\ No newline at end of file
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClasssesModes.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClasssesModes.java
index 8066b37..41848ae 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClasssesModes.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/RuntimeUnenhancedClasssesModes.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-/**
- * Possible values for the <code>openjpa.RuntimeUnenhancedClasses</code>
- * configuration setting.
- *
- * @since 1.0.0
- */
-public interface RuntimeUnenhancedClasssesModes {
-    public final static int SUPPORTED = 0;
-    public final static int UNSUPPORTED = 1;
-    public final static int WARN = 2;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+/**
+ * Possible values for the <code>openjpa.RuntimeUnenhancedClasses</code>
+ * configuration setting.
+ *
+ * @since 1.0.0
+ */
+public interface RuntimeUnenhancedClasssesModes {
+    public final static int SUPPORTED = 0;
+    public final static int UNSUPPORTED = 1;
+    public final static int WARN = 2;
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEvent.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEvent.java
index 3786a55..4c2ba87 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEvent.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEvent.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-import java.util.EventObject;
-
-import org.apache.openjpa.kernel.BrokerFactory;
-
-/**
- * Event fired when a {@link BrokerFactory} is created.
- *
- * @since 1.0.0
- */
-public class BrokerFactoryEvent
-    extends EventObject {
-
-    /**
-     * Fired after a {@link BrokerFactory} has been fully created.
-     * This happens after the factory has been made read-only.
-     */
-    public static final int BROKER_FACTORY_CREATED = 0;
-
-    private int eventType;
-
-    public BrokerFactoryEvent(BrokerFactory brokerFactory, int eventType) {
-        super(brokerFactory);
-        this.eventType = eventType;
-    }
-
-    public BrokerFactory getBrokerFactory() {
-        return (BrokerFactory) getSource();
-    }
-
-    /**
-     * @return one of the event type codes defined in this event class.
-     */
-    public int getEventType() {
-        return eventType;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+import java.util.EventObject;
+
+import org.apache.openjpa.kernel.BrokerFactory;
+
+/**
+ * Event fired when a {@link BrokerFactory} is created.
+ *
+ * @since 1.0.0
+ */
+public class BrokerFactoryEvent
+    extends EventObject {
+
+    /**
+     * Fired after a {@link BrokerFactory} has been fully created.
+     * This happens after the factory has been made read-only.
+     */
+    public static final int BROKER_FACTORY_CREATED = 0;
+
+    private int eventType;
+
+    public BrokerFactoryEvent(BrokerFactory brokerFactory, int eventType) {
+        super(brokerFactory);
+        this.eventType = eventType;
+    }
+
+    public BrokerFactory getBrokerFactory() {
+        return (BrokerFactory) getSource();
+    }
+
+    /**
+     * @return one of the event type codes defined in this event class.
+     */
+    public int getEventType() {
+        return eventType;
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEventManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEventManager.java
index 925d079..183e7eb 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEventManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryEventManager.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-
-/**
- * {@link EventManager} responsible for notifying listeners of
- * {@link BrokerFactoryEvent}s.
- *
- * @since 1.0.0
- */
-public class BrokerFactoryEventManager
-    extends AbstractConcurrentEventManager {
-
-    private static final Localizer _loc = Localizer.forPackage(
-        BrokerFactoryEventManager.class);
-
-    private final Configuration _conf;
-
-    public BrokerFactoryEventManager(Configuration conf) {
-        _conf = conf;
-    }
-
-    protected void fireEvent(Object event, Object listener) {
-        try {
-            BrokerFactoryEvent e = (BrokerFactoryEvent) event;
-            ((BrokerFactoryListener) listener).eventFired(e);
-        } catch (Exception e) {
-            _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME).warn(
-                _loc.get("broker-factory-listener-exception"), e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * {@link EventManager} responsible for notifying listeners of
+ * {@link BrokerFactoryEvent}s.
+ *
+ * @since 1.0.0
+ */
+public class BrokerFactoryEventManager
+    extends AbstractConcurrentEventManager {
+
+    private static final Localizer _loc = Localizer.forPackage(
+        BrokerFactoryEventManager.class);
+
+    private final Configuration _conf;
+
+    public BrokerFactoryEventManager(Configuration conf) {
+        _conf = conf;
+    }
+
+    protected void fireEvent(Object event, Object listener) {
+        try {
+            BrokerFactoryEvent e = (BrokerFactoryEvent) event;
+            ((BrokerFactoryListener) listener).eventFired(e);
+        } catch (Exception e) {
+            _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME).warn(
+                _loc.get("broker-factory-listener-exception"), e);
+        }
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryListener.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryListener.java
index 12ba15d..35f129c 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryListener.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/BrokerFactoryListener.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-/**
- * Interface for listening to {@link BrokerFactoryEvent} objects. Should be
- * registered with a {@link OpenJPAConfiguration}'s
- * {@link BrokerFactoryEventManager}.
- *
- * @since 1.0.0
- */
-public interface BrokerFactoryListener {
-
-    /**
-     * Invoked after a {@link BrokerFactory} has been fully created.
-     * This happens after the factory has been made read-only.
-     */
-    public void eventFired(BrokerFactoryEvent event);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+/**
+ * Interface for listening to {@link BrokerFactoryEvent} objects. Should be
+ * registered with a {@link OpenJPAConfiguration}'s
+ * {@link BrokerFactoryEventManager}.
+ *
+ * @since 1.0.0
+ */
+public interface BrokerFactoryListener {
+
+    /**
+     * Invoked after a {@link BrokerFactory} has been fully created.
+     * This happens after the factory has been made read-only.
+     */
+    public void eventFired(BrokerFactoryEvent event);
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostDeleteListener.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostDeleteListener.java
index 7273d0c..a0525a0 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostDeleteListener.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostDeleteListener.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-/**
- * @since 1.1.0
- */
-public interface PostDeleteListener {
-    
-    /**
-     * Receives notifications before an update is performed. Differs from
-     * {@link DeleteListener#afterDelete(LifecycleEvent)} in that the latter
-     * is called after the delete operation, whereas this is called after the
-     * delete statements have been sent to the data store.
-     */
-    public void afterDeletePerformed(LifecycleEvent event);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+/**
+ * @since 1.1.0
+ */
+public interface PostDeleteListener {
+    
+    /**
+     * Receives notifications before an update is performed. Differs from
+     * {@link DeleteListener#afterDelete(LifecycleEvent)} in that the latter
+     * is called after the delete operation, whereas this is called after the
+     * delete statements have been sent to the data store.
+     */
+    public void afterDeletePerformed(LifecycleEvent event);
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostPersistListener.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostPersistListener.java
index 76a54c7..7af19bb 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostPersistListener.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/PostPersistListener.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-/**
- * @since 1.1.0
- */
-public interface PostPersistListener {
-
-    /**
-     * Receives notifications after a persist operation has been written to the
-     * data store. Differs from {@link PersistListener#afterPersist} in that
-     * the latter is called at the end of the persist() operation itself, not
-     * after the flush.
-     */
-    public void afterPersistPerformed(LifecycleEvent event);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+/**
+ * @since 1.1.0
+ */
+public interface PostPersistListener {
+
+    /**
+     * Receives notifications after a persist operation has been written to the
+     * data store. Differs from {@link PersistListener#afterPersist} in that
+     * the latter is called at the end of the persist() operation itself, not
+     * after the flush.
+     */
+    public void afterPersistPerformed(LifecycleEvent event);
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java
index 4f87e14..3168a6b 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java
@@ -1,253 +1,253 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.event;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Collections;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Manager that can be used to track and notify
- * {@link RemoteCommitListener}s on remote commit events. If remote events
- * are enabled, this manager should be installed as a transaction listener on
- * all brokers so that it knows when commits are made.
- *
- * @author Patrick Linskey
- * @author Abe White
- * @since 0.3.0
- */
-public class RemoteCommitEventManager
-    extends AbstractConcurrentEventManager
-    implements EndTransactionListener, Closeable {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (RemoteCommitEventManager.class);
-
-    private final RemoteCommitProvider _provider;
-    private boolean _transmitPersIds = false;
-
-    /**
-     * Constructor. Supply configuration.
-     */
-    public RemoteCommitEventManager(OpenJPAConfiguration conf) {
-        _provider = conf.newRemoteCommitProviderInstance();
-        if (_provider != null) {
-            _provider.setRemoteCommitEventManager(this);
-        }
-    }
-
-    /**
-     * Return true if remote events are enabled.
-     */
-    public boolean areRemoteEventsEnabled() {
-        return _provider != null;
-    }
-
-    /**
-     * Return the {@link RemoteCommitProvider} that this manager uses.
-     *
-     * @since 0.3.1
-     */
-    public RemoteCommitProvider getRemoteCommitProvider() {
-        return _provider;
-    }
-
-    /**
-     * Whether the oids of added instances will be transmitted.
-     */
-    public boolean getTransmitPersistedObjectIds() {
-        return _transmitPersIds;
-    }
-
-    /**
-     * Whether the oids of added instances will be transmitted.
-     */
-    public void setTransmitPersistedObjectIds(boolean transmit) {
-        _transmitPersIds = transmit;
-    }
-
-    /**
-     * Adds an OpenJPA-internal listener to this RemoteCommitEventManager.
-     * Listeners so registered will be fired before any that are registered
-     * via {@link #addListener}. This means that the external listeners can
-     * rely on internal caches and data structures being up-to-date by the
-     * time that they are invoked.
-     *
-     * @since 1.0.0
-     */
-    public void addInternalListener(RemoteCommitListener listen) {
-        if (_provider == null)
-            throw new UserException(_loc.get("no-provider"));
-        ((List) _listeners).add(0, listen);
-    }
-
-    public void addListener(RemoteCommitListener listen) {
-        if (_provider == null)
-            throw new UserException(_loc.get("no-provider"));
-        super.addListener(listen);
-    }
-
-    /**
-     * Close this manager and all registered listeners.
-     */
-    public void close() {
-        if (_provider != null) {
-            _provider.close();
-            Collection listeners = getListeners();
-            for (Iterator itr = listeners.iterator(); itr.hasNext();)
-                ((RemoteCommitListener) itr.next()).close();
-        }
-    }
-
-    protected void fireEvent(Object event, Object listener) {
-        RemoteCommitListener listen = (RemoteCommitListener) listener;
-        RemoteCommitEvent ev = (RemoteCommitEvent) event;
-        listen.afterCommit(ev);
-    }
-
-    /**
-     * Fire an event to local listeners only notifying them of a detected
-     * stale record.
-     *
-     * @since 1.0.0
-     */
-    public void fireLocalStaleNotification(Object oid) {
-        RemoteCommitEvent ev = new RemoteCommitEvent(
-            RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION,
-            null, null, Collections.singleton(oid), null);
-        fireEvent(ev);
-    }
-
-    //////////////////////////////////////
-    // TransactionListener implementation
-    //////////////////////////////////////
-
-    public void afterCommit(TransactionEvent event) {
-        if (_provider != null) {
-            RemoteCommitEvent rce = createRemoteCommitEvent(event);
-            if (rce != null)
-                _provider.broadcast(rce);
-        }
-    }
-
-    /**
-     * Create a remote commit event from the given transaction event.
-     */
-    private RemoteCommitEvent createRemoteCommitEvent(TransactionEvent event) {
-        Broker broker = (Broker) event.getSource();
-        int payload;
-        Collection persIds = null;
-        Collection addClassNames = null;
-        Collection updates = null;
-        Collection deletes = null;
-
-        if (broker.isTrackChangesByType()) {
-            payload = RemoteCommitEvent.PAYLOAD_EXTENTS;
-            addClassNames = toClassNames(event.getPersistedTypes());
-            updates = toClassNames(event.getUpdatedTypes());
-            deletes = toClassNames(event.getDeletedTypes());
-            if (addClassNames == null && updates == null && deletes == null)
-                return null;
-        } else {
-            Collection trans = event.getTransactionalObjects();
-            if (trans.isEmpty())
-                return null;
-
-            payload = (_transmitPersIds)
-                ? RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS
-                : RemoteCommitEvent.PAYLOAD_OIDS;
-            Object oid;
-            Object obj;
-            OpenJPAStateManager sm;
-            for (Iterator itr = trans.iterator(); itr.hasNext();) {
-                obj = itr.next();
-                sm = broker.getStateManager(obj);
-
-                if (sm == null || !sm.isPersistent() || !sm.isDirty())
-                    continue;
-                if (sm.isNew() && sm.isDeleted())
-                    continue;
-
-                oid = sm.fetchObjectId();
-                if (sm.isNew()) {
-                    if (_transmitPersIds) {
-                        if (persIds == null)
-                            persIds = new ArrayList();
-                        persIds.add(oid);
-                    }
-                    if (addClassNames == null)
-                        addClassNames = new HashSet();
-                    addClassNames.add(obj.getClass().getName());
-                } else if (sm.isDeleted()) {
-                    if (deletes == null)
-                        deletes = new ArrayList();
-                    deletes.add(oid);
-                } else {
-                    if (updates == null)
-                        updates = new ArrayList();
-                    updates.add(oid);
-                }
-            }
-            if (addClassNames == null && updates == null && deletes == null)
-                return null;
-        }
-        return new RemoteCommitEvent(payload, persIds, addClassNames, updates,
-            deletes);
-    }
-
-    /**
-     * Transform a collection of classes to class names.
-     */
-    private static Collection toClassNames(Collection clss) {
-        if (clss.isEmpty())
-            return null;
-
-        List names = new ArrayList(clss);
-        for (int i = 0; i < names.size(); i++)
-            names.set(i, ((Class) names.get(i)).getName());
-        return names;
-    }
-
-    public void beforeCommit(TransactionEvent event) {
-    }
-
-    public void afterRollback(TransactionEvent event) {
-    }
-
-    public void afterCommitComplete(TransactionEvent event) {
-    }
-
-    public void afterRollbackComplete(TransactionEvent event) {
-    }
-
-    public void afterStateTransitions(TransactionEvent event)
-	{
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.event;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Collections;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Manager that can be used to track and notify
+ * {@link RemoteCommitListener}s on remote commit events. If remote events
+ * are enabled, this manager should be installed as a transaction listener on
+ * all brokers so that it knows when commits are made.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ * @since 0.3.0
+ */
+public class RemoteCommitEventManager
+    extends AbstractConcurrentEventManager
+    implements EndTransactionListener, Closeable {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (RemoteCommitEventManager.class);
+
+    private final RemoteCommitProvider _provider;
+    private boolean _transmitPersIds = false;
+
+    /**
+     * Constructor. Supply configuration.
+     */
+    public RemoteCommitEventManager(OpenJPAConfiguration conf) {
+        _provider = conf.newRemoteCommitProviderInstance();
+        if (_provider != null) {
+            _provider.setRemoteCommitEventManager(this);
+        }
+    }
+
+    /**
+     * Return true if remote events are enabled.
+     */
+    public boolean areRemoteEventsEnabled() {
+        return _provider != null;
+    }
+
+    /**
+     * Return the {@link RemoteCommitProvider} that this manager uses.
+     *
+     * @since 0.3.1
+     */
+    public RemoteCommitProvider getRemoteCommitProvider() {
+        return _provider;
+    }
+
+    /**
+     * Whether the oids of added instances will be transmitted.
+     */
+    public boolean getTransmitPersistedObjectIds() {
+        return _transmitPersIds;
+    }
+
+    /**
+     * Whether the oids of added instances will be transmitted.
+     */
+    public void setTransmitPersistedObjectIds(boolean transmit) {
+        _transmitPersIds = transmit;
+    }
+
+    /**
+     * Adds an OpenJPA-internal listener to this RemoteCommitEventManager.
+     * Listeners so registered will be fired before any that are registered
+     * via {@link #addListener}. This means that the external listeners can
+     * rely on internal caches and data structures being up-to-date by the
+     * time that they are invoked.
+     *
+     * @since 1.0.0
+     */
+    public void addInternalListener(RemoteCommitListener listen) {
+        if (_provider == null)
+            throw new UserException(_loc.get("no-provider"));
+        ((List) _listeners).add(0, listen);
+    }
+
+    public void addListener(RemoteCommitListener listen) {
+        if (_provider == null)
+            throw new UserException(_loc.get("no-provider"));
+        super.addListener(listen);
+    }
+
+    /**
+     * Close this manager and all registered listeners.
+     */
+    public void close() {
+        if (_provider != null) {
+            _provider.close();
+            Collection listeners = getListeners();
+            for (Iterator itr = listeners.iterator(); itr.hasNext();)
+                ((RemoteCommitListener) itr.next()).close();
+        }
+    }
+
+    protected void fireEvent(Object event, Object listener) {
+        RemoteCommitListener listen = (RemoteCommitListener) listener;
+        RemoteCommitEvent ev = (RemoteCommitEvent) event;
+        listen.afterCommit(ev);
+    }
+
+    /**
+     * Fire an event to local listeners only notifying them of a detected
+     * stale record.
+     *
+     * @since 1.0.0
+     */
+    public void fireLocalStaleNotification(Object oid) {
+        RemoteCommitEvent ev = new RemoteCommitEvent(
+            RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION,
+            null, null, Collections.singleton(oid), null);
+        fireEvent(ev);
+    }
+
+    //////////////////////////////////////
+    // TransactionListener implementation
+    //////////////////////////////////////
+
+    public void afterCommit(TransactionEvent event) {
+        if (_provider != null) {
+            RemoteCommitEvent rce = createRemoteCommitEvent(event);
+            if (rce != null)
+                _provider.broadcast(rce);
+        }
+    }
+
+    /**
+     * Create a remote commit event from the given transaction event.
+     */
+    private RemoteCommitEvent createRemoteCommitEvent(TransactionEvent event) {
+        Broker broker = (Broker) event.getSource();
+        int payload;
+        Collection persIds = null;
+        Collection addClassNames = null;
+        Collection updates = null;
+        Collection deletes = null;
+
+        if (broker.isTrackChangesByType()) {
+            payload = RemoteCommitEvent.PAYLOAD_EXTENTS;
+            addClassNames = toClassNames(event.getPersistedTypes());
+            updates = toClassNames(event.getUpdatedTypes());
+            deletes = toClassNames(event.getDeletedTypes());
+            if (addClassNames == null && updates == null && deletes == null)
+                return null;
+        } else {
+            Collection trans = event.getTransactionalObjects();
+            if (trans.isEmpty())
+                return null;
+
+            payload = (_transmitPersIds)
+                ? RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS
+                : RemoteCommitEvent.PAYLOAD_OIDS;
+            Object oid;
+            Object obj;
+            OpenJPAStateManager sm;
+            for (Iterator itr = trans.iterator(); itr.hasNext();) {
+                obj = itr.next();
+                sm = broker.getStateManager(obj);
+
+                if (sm == null || !sm.isPersistent() || !sm.isDirty())
+                    continue;
+                if (sm.isNew() && sm.isDeleted())
+                    continue;
+
+                oid = sm.fetchObjectId();
+                if (sm.isNew()) {
+                    if (_transmitPersIds) {
+                        if (persIds == null)
+                            persIds = new ArrayList();
+                        persIds.add(oid);
+                    }
+                    if (addClassNames == null)
+                        addClassNames = new HashSet();
+                    addClassNames.add(obj.getClass().getName());
+                } else if (sm.isDeleted()) {
+                    if (deletes == null)
+                        deletes = new ArrayList();
+                    deletes.add(oid);
+                } else {
+                    if (updates == null)
+                        updates = new ArrayList();
+                    updates.add(oid);
+                }
+            }
+            if (addClassNames == null && updates == null && deletes == null)
+                return null;
+        }
+        return new RemoteCommitEvent(payload, persIds, addClassNames, updates,
+            deletes);
+    }
+
+    /**
+     * Transform a collection of classes to class names.
+     */
+    private static Collection toClassNames(Collection clss) {
+        if (clss.isEmpty())
+            return null;
+
+        List names = new ArrayList(clss);
+        for (int i = 0; i < names.size(); i++)
+            names.set(i, ((Class) names.get(i)).getName());
+        return names;
+    }
+
+    public void beforeCommit(TransactionEvent event) {
+    }
+
+    public void afterRollback(TransactionEvent event) {
+    }
+
+    public void afterCommitComplete(TransactionEvent event) {
+    }
+
+    public void afterRollbackComplete(TransactionEvent event) {
+    }
+
+    public void afterStateTransitions(TransactionEvent event)
+	{
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java
index c8a449a..b796f26 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.event;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
-
-/**
- * Single-JVM-only implementation of {@link RemoteCommitProvider}
- * that listens for object modifications and propagates those changes
- * to other SingleJVMRemoteCommitProviders in the same JVM. This is
- * only useful for linking together multiple factories in the same
- * JVM that are all loaded in the same classloader, which is a rare
- * circumstance.
- *
- * @author Patrick Linskey
- * @since 0.2.5.0
- */
-public class SingleJVMRemoteCommitProvider
-    extends AbstractRemoteCommitProvider {
-
-    private static Set s_providers = new ConcurrentReferenceHashSet(
-        ConcurrentReferenceHashSet.HARD);
-
-    public SingleJVMRemoteCommitProvider() {
-        s_providers.add(this);
-    }
-
-    public void broadcast(RemoteCommitEvent event) {
-        SingleJVMRemoteCommitProvider provider;
-        for (Iterator iter = s_providers.iterator(); iter.hasNext();) {
-            provider = (SingleJVMRemoteCommitProvider) iter.next();
-
-            // don't notify this object -- this provider's factory
-            // should not be notified of commits that originated
-            // with one of its brokers
-            if (provider == this)
-                continue;
-
-            provider.fireEvent(event);
-        }
-    }
-
-    public void close() {
-        s_providers.remove(this);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.event;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
+
+/**
+ * Single-JVM-only implementation of {@link RemoteCommitProvider}
+ * that listens for object modifications and propagates those changes
+ * to other SingleJVMRemoteCommitProviders in the same JVM. This is
+ * only useful for linking together multiple factories in the same
+ * JVM that are all loaded in the same classloader, which is a rare
+ * circumstance.
+ *
+ * @author Patrick Linskey
+ * @since 0.2.5.0
+ */
+public class SingleJVMRemoteCommitProvider
+    extends AbstractRemoteCommitProvider {
+
+    private static Set s_providers = new ConcurrentReferenceHashSet(
+        ConcurrentReferenceHashSet.HARD);
+
+    public SingleJVMRemoteCommitProvider() {
+        s_providers.add(this);
+    }
+
+    public void broadcast(RemoteCommitEvent event) {
+        SingleJVMRemoteCommitProvider provider;
+        for (Iterator iter = s_providers.iterator(); iter.hasNext();) {
+            provider = (SingleJVMRemoteCommitProvider) iter.next();
+
+            // don't notify this object -- this provider's factory
+            // should not be notified of commits that originated
+            // with one of its brokers
+            if (provider == this)
+                continue;
+
+            provider.fireEvent(event);
+        }
+    }
+
+    public void close() {
+        s_providers.remove(this);
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/TCPRemoteCommitProvider.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/TCPRemoteCommitProvider.java
index 987cafa..079d802 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/TCPRemoteCommitProvider.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/TCPRemoteCommitProvider.java
@@ -1,948 +1,948 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.event;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-import java.util.Collections;
-
-import org.apache.commons.pool.PoolableObjectFactory;
-import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.GeneralException;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.Serialization;
-import java.util.concurrent.locks.ReentrantLock;
-
-import serp.util.Strings;
-
-/**
- * TCP-based implementation of {@link RemoteCommitProvider} that
- * listens for object modifications and propagates those changes to
- * other RemoteCommitProviders over TCP sockets.
- *
- * @author Brian Leair
- * @author Patrick Linskey
- * @since 0.2.5.0
- */
-public class TCPRemoteCommitProvider
-    extends AbstractRemoteCommitProvider
-    implements Configurable {
-
-    private static final int DEFAULT_PORT = 5636;
-
-    private static final Localizer s_loc = Localizer.forPackage
-        (TCPRemoteCommitProvider.class);
-    private static long s_idSequence = System.currentTimeMillis();
-
-    //	A map of listen ports to listeners in this JVM. We might
-    //	want to look into allowing same port, different interface --
-    //	that is not currently possible in a single JVM.
-    private static final Map s_portListenerMap = new HashMap();
-
-    private long _id;
-    private byte[] _localhost;
-    private int _port = DEFAULT_PORT;
-    private int _maxActive = 2;
-    private int _maxIdle = 2;
-    private int _recoveryTimeMillis = 15000;
-    private TCPPortListener _listener;
-    private BroadcastQueue _broadcastQueue = new BroadcastQueue();
-    private final List _broadcastThreads = Collections.synchronizedList(
-        new LinkedList());
-
-    private ArrayList _addresses = new ArrayList();
-    private ReentrantLock _addressesLock;
-
-    public TCPRemoteCommitProvider()
-        throws UnknownHostException {
-        // obtain a unique ID.
-        synchronized (TCPRemoteCommitProvider.class) {
-            _id = s_idSequence++;
-        }
-
-        // cache the local IP address.
-        _localhost = InetAddress.getLocalHost().getAddress();
-        _addressesLock = new ReentrantLock();
-        setNumBroadcastThreads(2);
-    }
-
-    /**
-     * The port that this provider should listen on.
-     */
-    public int getPort() {
-        return _port;
-    }
-
-    /**
-     * The port that this provider should listen on. Set once only.
-     */
-    public void setPort(int port) {
-        _port = port;
-    }
-
-    /**
-     * The number of milliseconds to wait before retrying
-     * to reconnect to a peer after it becomes unreachable.
-     */
-    public void setRecoveryTimeMillis(int recoverytime) {
-        _recoveryTimeMillis = recoverytime;
-    }
-
-    /**
-     * The number of milliseconds to wait before retrying
-     * to reconnect to a peer after it becomes unreachable.
-     */
-    public int getRecoveryTimeMillis() {
-        return _recoveryTimeMillis;
-    }
-
-    /**
-     * The maximum number of sockets that this provider can
-     * simetaneously open to each peer in the cluster.
-     */
-    public void setMaxActive(int maxActive) {
-        _maxActive = maxActive;
-    }
-
-    /**
-     * The maximum number of sockets that this provider can
-     * simetaneously open to each peer in the cluster.
-     */
-    public int getMaxActive() {
-        return _maxActive;
-    }
-
-    /**
-     * The number of idle sockets that this provider can keep open
-     * to each peer in the cluster.
-     */
-    public void setMaxIdle(int maxIdle) {
-        _maxIdle = maxIdle;
-    }
-
-    /**
-     * The number of idle sockets that this provider can keep open
-     * to each peer in the cluster.
-     */
-    public int getMaxIdle() {
-        return _maxIdle;
-    }
-
-    /**
-     * The number of worker threads that are used for
-     * transmitting packets to peers in the cluster.
-     */
-    public void setNumBroadcastThreads(int numBroadcastThreads) {
-        synchronized (_broadcastThreads) {
-            int cur = _broadcastThreads.size();
-            if (cur > numBroadcastThreads) {
-                // Notify the extra worker threads so they stop themselves
-                // Threads will not end until they send another pk.
-                for (int i = numBroadcastThreads; i < cur; i++) {
-                    BroadcastWorkerThread worker = (BroadcastWorkerThread)
-                        _broadcastThreads.remove(0);
-                    worker.setRunning(false);
-                }
-            } else if (cur < numBroadcastThreads) {
-                // Create additional worker threads
-                for (int i = cur; i < numBroadcastThreads; i++) {
-                    BroadcastWorkerThread wt = new BroadcastWorkerThread();
-                    wt.setDaemon(true);
-                    wt.start();
-                    _broadcastThreads.add(wt);
-                }
-            }
-        }
-    }
-
-    /**
-     * The number of worker threads that are used for
-     * transmitting packets to peers in the cluster.
-     */
-    public int getNumBroadcastThreads() {
-        return _broadcastThreads.size();
-    }
-
-    /**
-     * Sets the list of addresses of peers to which this provider will
-     * send events to. The peers are semicolon-separated <code>names</code>
-     * list in the form of "myhost1:portA;myhost2:portB".
-     */
-    public void setAddresses(String names)
-        throws UnknownHostException {
-        // NYI. Could look for equivalence of addresses and avoid
-        // changing those that didn't change.
-
-        _addressesLock.lock();
-        try {
-            for (Iterator iter = _addresses.iterator(); iter.hasNext();) {
-                ((HostAddress) iter.next()).close();
-            }
-            String[] toks = Strings.split(names, ";", 0);
-            _addresses = new ArrayList(toks.length);
-
-            InetAddress localhost = InetAddress.getLocalHost();
-            String localhostName = localhost.getHostName();
-
-            for (int i = 0; i < toks.length; i++) {
-                String host = toks[i];
-                String hostname;
-                int tmpPort;
-                int colon = host.indexOf(':');
-                if (colon != -1) {
-                    hostname = host.substring(0, colon);
-                    tmpPort = Integer.parseInt(host.substring(colon + 1));
-                } else {
-                    hostname = host;
-                    tmpPort = DEFAULT_PORT;
-                }
-                InetAddress tmpAddress = (InetAddress) AccessController
-                    .doPrivileged(J2DoPrivHelper.getByNameAction(hostname)); 
-
-                // bleair: For each address we would rather make use of
-                // the jdk1.4 isLinkLocalAddress () || isLoopbackAddress ().
-                // (Though in practice on win32 they don't work anyways!)
-                // Instead we will check hostname. Not perfect, but
-                // it will match often enough (people will typically
-                // use the DNS machine names and be cutting/pasting.)
-                if (localhostName.equals(hostname)) {
-                    // This string matches the hostname for for ourselves, we
-                    // don't actually need to send ourselves messages.
-                    if (log.isTraceEnabled()) {
-                        log.trace(s_loc.get("tcp-address-asself",
-                            tmpAddress.getHostName() + ":" + tmpPort));
-                    }
-                } else {
-                    HostAddress newAddress = new HostAddress(host);
-                    _addresses.add(newAddress);
-                    if (log.isTraceEnabled()) {
-                        log.trace(s_loc.get("tcp-address-set",
-                            newAddress._address.getHostName() + ":"
-                                + newAddress._port));
-                    }
-                }
-            }
-        } catch (PrivilegedActionException pae) {
-            throw (UnknownHostException) pae.getException();
-        } finally {
-            _addressesLock.unlock();
-        }
-    }
-
-    // ---------- Configurable implementation ----------
-
-    /**
-     * Subclasses that need to perform actions in
-     * {@link Configurable#endConfiguration} must invoke this method.
-     */
-    public void endConfiguration() {
-        super.endConfiguration();
-        synchronized (s_portListenerMap) {
-            // see if a listener exists for this port.
-            _listener = (TCPPortListener) s_portListenerMap.get
-                (String.valueOf(_port));
-
-            if (_listener == null ||
-                (!_listener.isRunning() && _listener._port == _port)) {
-                try {
-                    _listener = new TCPPortListener(_port, log);
-                    _listener.listen();
-                    s_portListenerMap.put(String.valueOf(_port), _listener);
-                } catch (Exception e) {
-                    throw new GeneralException(s_loc.get("tcp-init-exception",
-                        String.valueOf(_port)), e).setFatal(true);
-                }
-            } else if (_listener.isRunning()) {
-                if (_listener._port != _port) {
-                    // this really shouldn't be able to happen.
-                    throw new GeneralException(s_loc.get
-                        ("tcp-not-equal", String.valueOf(_port))).
-                        setFatal(true);
-                }
-            } else
-                throw new InternalException(s_loc.get("tcp-listener-broken"));
-            _listener.addProvider(this);
-        }
-
-        _addressesLock.lock();
-        try {
-            HostAddress curAddress;
-            for (Iterator iter = _addresses.iterator();
-                iter.hasNext();) {
-                curAddress = (HostAddress) iter.next();
-                curAddress.setMaxActive(_maxActive);
-                curAddress.setMaxIdle(_maxIdle);
-            }
-        }
-        finally {
-            _addressesLock.unlock();
-        }
-    }
-
-    // ---------- RemoteCommitProvider implementation ----------
-
-    // pre 3.3.4	= <no version number transmitted>
-    // 3.3 Preview 	= 0x1428acfd;
-    // 3.4 			= 0x1428acff;
-    private static final long PROTOCOL_VERSION = 0x1428acff;
-
-    public void broadcast(RemoteCommitEvent event) {
-        try {
-            // build a packet notifying other JVMs of object changes.
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-
-            oos.writeLong(PROTOCOL_VERSION);
-            oos.writeLong(_id);
-            oos.writeInt(_port);
-            oos.writeObject(_localhost);
-            oos.writeObject(event);
-            oos.flush();
-
-            byte[] bytes = baos.toByteArray();
-            baos.close();
-            if (_broadcastThreads.isEmpty())
-                sendUpdatePacket(bytes);
-            else
-                _broadcastQueue.addPacket(bytes);
-        } catch (IOException ioe) {
-            if (log.isWarnEnabled())
-                log.warn(s_loc.get("tcp-payload-create-error"), ioe);
-        }
-    }
-
-    /**
-     * Sends a change notification packet to other machines in this
-     * provider cluster.
-     */
-    private void sendUpdatePacket(byte[] bytes) {
-        _addressesLock.lock();
-        try {
-            for (Iterator iter = _addresses.iterator(); iter.hasNext();)
-                ((HostAddress) iter.next()).sendUpdatePacket(bytes);
-        } finally {
-            _addressesLock.unlock();
-        }
-    }
-
-    public void close() {
-        if (_listener != null)
-            _listener.removeProvider(this);
-
-        // Remove Broadcast Threads then close sockets.
-        _broadcastQueue.close();
-
-        // Wait for _broadcastThreads to get cleaned up.
-        while(!_broadcastThreads.isEmpty()) {
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException ie) {
-                // Ignore.
-            }
-        }
-        
-        _addressesLock.lock();
-        try {
-            for (Iterator iter = _addresses.iterator(); iter.hasNext();)
-                ((HostAddress) iter.next()).close();
-        } finally {
-            _addressesLock.unlock();
-        }
-    }
-
-    /**
-     * Utility class to hold messages to be sent. This
-     * allows calls to broadcast () to return without
-     * waiting for the send to complete.
-     */
-    private static class BroadcastQueue {
-
-        private LinkedList _packetQueue = new LinkedList();
-        private boolean _closed = false;
-
-        public synchronized void close() {
-            _closed = true;
-            notifyAll();
-        }
-
-        public synchronized boolean isClosed() {
-            return _closed;
-        }
-
-        public synchronized void addPacket(byte[] bytes) {
-            _packetQueue.addLast(bytes);
-            notify();
-        }
-
-        /**
-         * @return the bytes defining the packet to process, or
-         * <code>null</code> if the queue is empty.
-         */
-        public synchronized byte[] removePacket()
-            throws InterruptedException {
-            // only wait if the queue is still open. This allows processing
-            // of events in the queue to continue, while avoiding sleeping
-            // during shutdown.
-            while (!_closed && _packetQueue.isEmpty())
-                wait();
-            if (_packetQueue.isEmpty())
-                return null;
-            else
-                return (byte[]) _packetQueue.removeFirst();
-        }
-    }
-
-    /**
-     * Threads to broadcast packets placed in the {@link BroadcastQueue}.
-     */
-    private class BroadcastWorkerThread
-        extends Thread {
-
-        private boolean _keepRunning = true;
-
-        public void run() {
-            while (_keepRunning) {
-                try {
-                    // This will block until there is a packet to send, or
-                    // until the queue is closed.
-                    byte[] bytes = _broadcastQueue.removePacket();
-                    if (bytes != null)
-                        sendUpdatePacket(bytes);
-                    else if (_broadcastQueue.isClosed())
-                        _keepRunning = false;
-                } catch (InterruptedException e) {
-                    // End the thread.
-                    break;
-                }
-            }
-            remove();
-        }
-
-        public void setRunning(boolean keepRunning) {
-            _keepRunning = keepRunning;
-        }
-        
-        private void remove() {
-            _broadcastThreads.remove(this);
-        }
-    }
-
-    /**
-     * Responsible for listening for incoming packets and processing them.
-     */
-    private static class TCPPortListener
-        implements Runnable {
-
-        private final Log _log;
-        private ServerSocket _receiveSocket;
-        private Thread _acceptThread;
-        private Set _receiverThreads = new HashSet();
-        private final Set _providers = new HashSet();
-
-        /**
-         * Cache the local IP address
-         */
-        private byte[] _localhost;
-
-        /**
-         * The port that this listener should listen on. Configured
-         * by TCPRemoteCommitProvider.
-         */
-        private int _port;
-
-        /**
-         * Should be set to <code>true</code> once the listener is listening.
-         */
-        private boolean _isRunning = false;
-
-        /**
-         * Construct a new TCPPortListener configured to use the specified port.
-         */
-        private TCPPortListener(int port, Log log)
-            throws IOException {
-            _port = port;
-            _log = log;
-            try {
-                _receiveSocket = (ServerSocket) AccessController
-                    .doPrivileged(J2DoPrivHelper.newServerSocketAction(_port));
-            } catch (PrivilegedActionException pae) {
-                throw (IOException) pae.getException();
-            }
-            _localhost = InetAddress.getLocalHost().getAddress();
-
-            if (_log.isTraceEnabled())
-                _log.info(s_loc.get("tcp-start-listener",
-                    String.valueOf(_port)));
-        }
-
-        private void listen() {
-            _acceptThread = new Thread(this);
-            _acceptThread.setDaemon(true);
-            _acceptThread.start();
-        }
-
-        /**
-         * All providers added here will be notified of any incoming
-         * provider messages. There will be one of these per
-         * BrokerFactory in a given JVM.
-         * {@link TCPRemoteCommitProvider#endConfiguration} invokes
-         * <code>addProvider</code> with <code>this</code> upon
-         * completion of configuration.
-         */
-        private void addProvider(TCPRemoteCommitProvider provider) {
-            synchronized (_providers) {
-                _providers.add(provider);
-            }
-        }
-
-        /**
-         * Remove a provider from the list of providers to notify of
-         * commit events.
-         */
-        private synchronized void removeProvider
-            (TCPRemoteCommitProvider provider) {
-            synchronized (_providers) {
-                _providers.remove(provider);
-
-                // if the provider list is empty, shut down the thread.
-                if (_providers.size() == 0) {
-                    _isRunning = false;
-                    try {
-                        _receiveSocket.close();
-                    } catch (IOException ioe) {
-                        if (_log.isWarnEnabled())
-                            _log.warn(s_loc.get("tcp-close-error"), ioe);
-                    }
-                    _acceptThread.interrupt();
-                }
-            }
-        }
-
-        private boolean isRunning() {
-            synchronized (_providers) {
-                return _isRunning;
-            }
-        }
-
-        public void run() {
-            synchronized (_providers) {
-                _isRunning = true;
-            }
-
-            Socket s = null;
-            while (_isRunning) {
-                try {
-                    s = null;
-                    // Block, waiting to accept new connection from a peer
-                    s = (Socket) AccessController.doPrivileged(J2DoPrivHelper
-                        .acceptAction(_receiveSocket));
-                    if (_log.isTraceEnabled()) {
-                        _log.trace(s_loc.get("tcp-received-connection",
-                            s.getInetAddress().getHostAddress()
-                                + ":" + s.getPort()));
-                    }
-                    ReceiveSocketHandler sh = new ReceiveSocketHandler(s);
-                    Thread receiverThread = new Thread(sh);
-                    receiverThread.setDaemon(true);
-                    receiverThread.start();
-                    _receiverThreads.add(receiverThread);
-                } catch (Exception e) {
-                    if (e instanceof PrivilegedActionException)
-                        e = ((PrivilegedActionException) e).getException();
-                    if (!(e instanceof SocketException) || _isRunning)
-                        if (_log.isWarnEnabled())
-                            _log.warn(s_loc.get("tcp-accept-error"), e);
-
-                    // Nominal case (InterruptedException) because close ()
-                    // calls _acceptThread.interrupt ();
-                    try {
-                        if (s != null)
-                            s.close();
-                    } catch (Exception ee) {
-                        if (_log.isWarnEnabled())
-                            _log.warn(s_loc.get("tcp-close-error"), e);
-                    }
-                }
-            }
-
-            // We are done listening. Interrupt any worker threads.
-            Thread worker;
-            for (Iterator iter = _receiverThreads.iterator();
-                iter.hasNext();) {
-                worker = (Thread) iter.next();
-                // FYI, the worker threads are blocked
-                // reading from the socket's InputStream. InputStreams
-                // aren't interruptable, so this interrupt isn't
-                // really going to be delivered until something breaks
-                // the InputStream.
-                worker.interrupt();
-            }
-            synchronized (_providers) {
-                try {
-                    if (_isRunning)
-                        _receiveSocket.close();
-                } catch (Exception e) {
-                    if (_log.isWarnEnabled())
-                        _log.warn(s_loc.get("tcp-close-error"), e);
-                }
-                _isRunning = false;
-                if (_log.isTraceEnabled())
-                    _log.trace(s_loc.get("tcp-close-listener",
-                        _port + ""));
-            }
-        }
-
-        /**
-         * Utility class that acts as a worker thread to receive Events
-         * from broadcasters.
-         */
-        private class ReceiveSocketHandler
-            implements Runnable {
-
-            private InputStream _in;
-            private Socket _s;
-
-            private ReceiveSocketHandler(Socket s) {
-                // We are the receiving end and we don't send any messages
-                // back to the broadcaster. Turn off Nagle's so that
-                // we will send ack packets without waiting.
-                _s = s;
-                try {
-                    _s.setTcpNoDelay(true);
-                    _in = new BufferedInputStream(s.getInputStream());
-                } catch (IOException ioe) {
-                    if (_log.isInfoEnabled())
-                        _log.info(s_loc.get("tcp-socket-option-error"), ioe);
-                    _s = null;
-                } catch (Exception e) {
-                    if (_log.isWarnEnabled())
-                        _log.warn(s_loc.get("tcp-receive-error"), e);
-                    _s = null;
-                }
-            }
-
-            public void run() {
-                if (_s == null)
-                    return;
-                while (_isRunning && _s != null) {
-                    try {
-                        // This will block our thread, waiting to read
-                        // the next Event-object-message.
-                        handle(_in);
-                    } catch (EOFException eof) {
-                        // EOFException raised when peer is properly
-                        // closing its end.
-                        if (_log.isTraceEnabled()) {
-                            _log.trace(s_loc.get("tcp-close-socket",
-                                _s.getInetAddress().getHostAddress()
-                                    + ":" + _s.getPort()));
-                        }
-                        break;
-                    } catch (Throwable e) {
-                        if (_log.isWarnEnabled())
-                            _log.warn(s_loc.get("tcp-receive-error"), e);
-                        break;
-                    }
-                }
-                // We are done receiving on this socket and this worker
-                // thread is terminating.
-                try {
-                    _in.close();
-                    if (_s != null)
-                        _s.close();
-                } catch (IOException e) {
-                    _log.warn(s_loc.get("tcp-close-socket-error",
-                        _s.getInetAddress().getHostAddress() + ":"
-                            + _s.getPort()), e);
-                }
-            }
-
-            /**
-             * Process an {@link InputStream} containing objects written
-             * by {@link TCPRemoteCommitProvider#broadcast(RemoteCommitEvent)}.
-             */
-            private void handle(InputStream in)
-                throws IOException, ClassNotFoundException {
-                // This will block waiting for the next
-                ObjectInputStream ois = 
-                    new Serialization.ClassResolvingObjectInputStream(in);
-
-                long protocolVersion = ois.readLong();
-                if (protocolVersion != PROTOCOL_VERSION) {
-                    if (_log.isWarnEnabled()) {
-                        _log.warn(s_loc.get("tcp-wrong-version-error",
-                            _s.getInetAddress().getHostAddress() + ":"
-                                + _s.getPort()));
-                        return;
-                    }
-                }
-
-                long senderId = ois.readLong();
-                int senderPort = ois.readInt();
-                byte[] senderAddress = (byte[]) ois.readObject();
-                RemoteCommitEvent rce = (RemoteCommitEvent) ois.readObject();
-                if (_log.isTraceEnabled()) {
-                    _log.trace(s_loc.get("tcp-received-event",
-                        _s.getInetAddress().getHostAddress() + ":"
-                            + _s.getPort()));
-                }
-
-                boolean fromSelf = senderPort == _port &&
-                    Arrays.equals(senderAddress, _localhost);
-                TCPRemoteCommitProvider provider;
-                synchronized (_providers) {
-                    // bleair: We're iterating, but currenlty there can really
-                    // only be a single provider.
-                    for (Iterator iter = _providers.iterator();
-                        iter.hasNext();) {
-                        provider = (TCPRemoteCommitProvider) iter.next();
-                        if (senderId != provider._id || !fromSelf)
-                            provider.eventManager.fireEvent(rce);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Utility class to store an InetAddress and an int. Not using
-     * InetSocketAddress because it's a JDK1.4 API. This also
-     * provides a wrapper around the socket(s) associated with this address.
-     */
-    private class HostAddress {
-
-        private InetAddress _address;
-        private int _port;
-        private long _timeLastError; // millis
-        private boolean _isAvailable; // is peer thought to be up
-        private int _infosIssued = 0; // limit log entries
-
-        private GenericObjectPool _socketPool; // reusable open sockets
-
-        /**
-         * Construct a new host address from a string of the form
-         * "host:port" or of the form "host".
-         */
-        private HostAddress(String host)
-            throws UnknownHostException {
-            int colon = host.indexOf(':');
-            try {
-                if (colon != -1) {
-                    _address = (InetAddress) AccessController
-                        .doPrivileged(J2DoPrivHelper.getByNameAction(host
-                            .substring(0, colon)));
-                    _port = Integer.parseInt(host.substring(colon + 1));
-                } else {
-                    _address = (InetAddress) AccessController
-                        .doPrivileged(J2DoPrivHelper.getByNameAction(host));
-                    _port = DEFAULT_PORT;
-                }
-            } catch (PrivilegedActionException pae) {
-                throw (UnknownHostException) pae.getException();
-            }
-            // -1 max wait == as long as it takes
-            _socketPool = new GenericObjectPool
-                (new SocketPoolableObjectFactory(), _maxActive,
-                    GenericObjectPool.WHEN_EXHAUSTED_BLOCK, -1);
-            _isAvailable = true;
-        }
-
-        private void setMaxActive(int maxActive) {
-            _socketPool.setMaxActive(maxActive);
-        }
-
-        private void setMaxIdle(int maxIdle) {
-            _socketPool.setMaxIdle(maxIdle);
-        }
-
-        public void close() {
-            // Close the pool of sockets to this peer. This
-            // will close all sockets in the pool.
-            try {
-                _socketPool.close();
-            } catch (Exception e) {
-                if (log.isWarnEnabled()) {
-                    log.warn(s_loc.get("tcp-close-pool-error"), e);
-                }
-            }
-        }
-
-        private void sendUpdatePacket(byte[] bytes) {
-            if (!_isAvailable) {
-                long now = System.currentTimeMillis();
-                if (now - _timeLastError < _recoveryTimeMillis)
-                    // Not enough time has passed since the last error
-                    return;
-            }
-            Socket s = null;
-            try {
-                s = getSocket();
-                OutputStream os = s.getOutputStream();
-                os.write(bytes);
-                os.flush();
-
-                if (log.isTraceEnabled()) {
-                    log.trace(s_loc.get("tcp-sent-update",
-                        _address.getHostAddress() + ":" + _port,
-                        String.valueOf(s.getLocalPort())));
-                }
-                _isAvailable = true;
-                _infosIssued = 0;
-                // Return the socket to the pool; the socket is
-                // still good.
-                returnSocket(s);
-            } catch (Exception e) {
-                // There has been a problem sending to the peer.
-                // The OS socket that was being used is can no longer
-                // be used.
-                if (s != null)
-                    this.closeSocket(s);
-                this.clearAllSockets();
-
-                if (_isAvailable) {
-                    // Log a warning, the peer was up and has now gone down
-                    if (log.isWarnEnabled()) {
-                        log.warn(s_loc.get("tcp-send-error",
-                            _address.getHostAddress() + ":" + _port), e);
-                    }
-                    _isAvailable = false;
-                    // Once enough time has passed we will log another warning
-                    _timeLastError = System.currentTimeMillis();
-                } else {
-                    long now = System.currentTimeMillis();
-                    if (now - _timeLastError > _recoveryTimeMillis) {
-                        if (_infosIssued < 5) {
-                            // Enough time has passed, and peer is still down
-                            _timeLastError = System.currentTimeMillis();
-                            // We were trying to reestablish the connection,
-                            // but we failed again. Log a message, but
-                            // lower severity. This log will occur periodically
-                            // for 5 times until the peer comes back.
-                            if (log.isInfoEnabled()) {
-                                log.info(s_loc.get("tcp-send-still-error",
-                                    _address.getHostAddress() + ":"
-                                        + _port), e);
-                            }
-                            _infosIssued++;
-                        }
-                    }
-                }
-            }
-        }
-
-        private Socket getSocket()
-            throws Exception {
-            return (Socket) _socketPool.borrowObject();
-        }
-
-        private void returnSocket(Socket s)
-            throws Exception {
-            _socketPool.returnObject(s);
-        }
-
-        private void clearAllSockets() {
-            _socketPool.clear();
-        }
-
-        private void closeSocket(Socket s) {
-            // All sockets come from the pool.
-            // This socket is no longer usable, so delete it from the
-            // pool.
-            try {
-                _socketPool.invalidateObject(s);
-            } catch (Exception e) {
-            }
-        }
-
-        /**
-         * Factory for pooled sockets.
-         */
-        private class SocketPoolableObjectFactory
-            implements PoolableObjectFactory {
-
-            public Object makeObject()
-                throws IOException {
-                try {
-                    Socket s = (Socket) AccessController
-                        .doPrivileged(J2DoPrivHelper.newSocketAction(_address,
-                            _port));
-                    if (log.isTraceEnabled()) {
-                        log.trace(s_loc.get("tcp-open-connection", _address
-                            + ":" + _port, "" + s.getLocalPort()));
-                    }
-                    return s;
-                } catch (PrivilegedActionException pae) {
-                    throw (IOException) pae.getException();
-                }
-            }
-
-            public void destroyObject(Object obj) {
-                // silentClose ().
-                try {
-                    Socket s = (Socket) obj;
-                    if (log.isTraceEnabled())
-                        log.trace(s_loc.get("tcp-close-sending-socket",
-                            _address + ":" + _port, "" + s.getLocalPort()));
-                    s.close();
-                } catch (Exception e) {
-                    log.warn(s_loc.get("tcp-close-socket-error",
-                        _address.getHostAddress() + ":" + _port), e);
-                }
-            }
-
-            public boolean validateObject(Object obj) {
-                return true;
-            }
-
-            public void activateObject (Object value)
-			{
-			}
-
-			public void passivateObject (Object value)
-			{
-			}
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.event;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.Collections;
+
+import org.apache.commons.pool.PoolableObjectFactory;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.GeneralException;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.Serialization;
+import java.util.concurrent.locks.ReentrantLock;
+
+import serp.util.Strings;
+
+/**
+ * TCP-based implementation of {@link RemoteCommitProvider} that
+ * listens for object modifications and propagates those changes to
+ * other RemoteCommitProviders over TCP sockets.
+ *
+ * @author Brian Leair
+ * @author Patrick Linskey
+ * @since 0.2.5.0
+ */
+public class TCPRemoteCommitProvider
+    extends AbstractRemoteCommitProvider
+    implements Configurable {
+
+    private static final int DEFAULT_PORT = 5636;
+
+    private static final Localizer s_loc = Localizer.forPackage
+        (TCPRemoteCommitProvider.class);
+    private static long s_idSequence = System.currentTimeMillis();
+
+    //	A map of listen ports to listeners in this JVM. We might
+    //	want to look into allowing same port, different interface --
+    //	that is not currently possible in a single JVM.
+    private static final Map s_portListenerMap = new HashMap();
+
+    private long _id;
+    private byte[] _localhost;
+    private int _port = DEFAULT_PORT;
+    private int _maxActive = 2;
+    private int _maxIdle = 2;
+    private int _recoveryTimeMillis = 15000;
+    private TCPPortListener _listener;
+    private BroadcastQueue _broadcastQueue = new BroadcastQueue();
+    private final List _broadcastThreads = Collections.synchronizedList(
+        new LinkedList());
+
+    private ArrayList _addresses = new ArrayList();
+    private ReentrantLock _addressesLock;
+
+    public TCPRemoteCommitProvider()
+        throws UnknownHostException {
+        // obtain a unique ID.
+        synchronized (TCPRemoteCommitProvider.class) {
+            _id = s_idSequence++;
+        }
+
+        // cache the local IP address.
+        _localhost = InetAddress.getLocalHost().getAddress();
+        _addressesLock = new ReentrantLock();
+        setNumBroadcastThreads(2);
+    }
+
+    /**
+     * The port that this provider should listen on.
+     */
+    public int getPort() {
+        return _port;
+    }
+
+    /**
+     * The port that this provider should listen on. Set once only.
+     */
+    public void setPort(int port) {
+        _port = port;
+    }
+
+    /**
+     * The number of milliseconds to wait before retrying
+     * to reconnect to a peer after it becomes unreachable.
+     */
+    public void setRecoveryTimeMillis(int recoverytime) {
+        _recoveryTimeMillis = recoverytime;
+    }
+
+    /**
+     * The number of milliseconds to wait before retrying
+     * to reconnect to a peer after it becomes unreachable.
+     */
+    public int getRecoveryTimeMillis() {
+        return _recoveryTimeMillis;
+    }
+
+    /**
+     * The maximum number of sockets that this provider can
+     * simetaneously open to each peer in the cluster.
+     */
+    public void setMaxActive(int maxActive) {
+        _maxActive = maxActive;
+    }
+
+    /**
+     * The maximum number of sockets that this provider can
+     * simetaneously open to each peer in the cluster.
+     */
+    public int getMaxActive() {
+        return _maxActive;
+    }
+
+    /**
+     * The number of idle sockets that this provider can keep open
+     * to each peer in the cluster.
+     */
+    public void setMaxIdle(int maxIdle) {
+        _maxIdle = maxIdle;
+    }
+
+    /**
+     * The number of idle sockets that this provider can keep open
+     * to each peer in the cluster.
+     */
+    public int getMaxIdle() {
+        return _maxIdle;
+    }
+
+    /**
+     * The number of worker threads that are used for
+     * transmitting packets to peers in the cluster.
+     */
+    public void setNumBroadcastThreads(int numBroadcastThreads) {
+        synchronized (_broadcastThreads) {
+            int cur = _broadcastThreads.size();
+            if (cur > numBroadcastThreads) {
+                // Notify the extra worker threads so they stop themselves
+                // Threads will not end until they send another pk.
+                for (int i = numBroadcastThreads; i < cur; i++) {
+                    BroadcastWorkerThread worker = (BroadcastWorkerThread)
+                        _broadcastThreads.remove(0);
+                    worker.setRunning(false);
+                }
+            } else if (cur < numBroadcastThreads) {
+                // Create additional worker threads
+                for (int i = cur; i < numBroadcastThreads; i++) {
+                    BroadcastWorkerThread wt = new BroadcastWorkerThread();
+                    wt.setDaemon(true);
+                    wt.start();
+                    _broadcastThreads.add(wt);
+                }
+            }
+        }
+    }
+
+    /**
+     * The number of worker threads that are used for
+     * transmitting packets to peers in the cluster.
+     */
+    public int getNumBroadcastThreads() {
+        return _broadcastThreads.size();
+    }
+
+    /**
+     * Sets the list of addresses of peers to which this provider will
+     * send events to. The peers are semicolon-separated <code>names</code>
+     * list in the form of "myhost1:portA;myhost2:portB".
+     */
+    public void setAddresses(String names)
+        throws UnknownHostException {
+        // NYI. Could look for equivalence of addresses and avoid
+        // changing those that didn't change.
+
+        _addressesLock.lock();
+        try {
+            for (Iterator iter = _addresses.iterator(); iter.hasNext();) {
+                ((HostAddress) iter.next()).close();
+            }
+            String[] toks = Strings.split(names, ";", 0);
+            _addresses = new ArrayList(toks.length);
+
+            InetAddress localhost = InetAddress.getLocalHost();
+            String localhostName = localhost.getHostName();
+
+            for (int i = 0; i < toks.length; i++) {
+                String host = toks[i];
+                String hostname;
+                int tmpPort;
+                int colon = host.indexOf(':');
+                if (colon != -1) {
+                    hostname = host.substring(0, colon);
+                    tmpPort = Integer.parseInt(host.substring(colon + 1));
+                } else {
+                    hostname = host;
+                    tmpPort = DEFAULT_PORT;
+                }
+                InetAddress tmpAddress = (InetAddress) AccessController
+                    .doPrivileged(J2DoPrivHelper.getByNameAction(hostname)); 
+
+                // bleair: For each address we would rather make use of
+                // the jdk1.4 isLinkLocalAddress () || isLoopbackAddress ().
+                // (Though in practice on win32 they don't work anyways!)
+                // Instead we will check hostname. Not perfect, but
+                // it will match often enough (people will typically
+                // use the DNS machine names and be cutting/pasting.)
+                if (localhostName.equals(hostname)) {
+                    // This string matches the hostname for for ourselves, we
+                    // don't actually need to send ourselves messages.
+                    if (log.isTraceEnabled()) {
+                        log.trace(s_loc.get("tcp-address-asself",
+                            tmpAddress.getHostName() + ":" + tmpPort));
+                    }
+                } else {
+                    HostAddress newAddress = new HostAddress(host);
+                    _addresses.add(newAddress);
+                    if (log.isTraceEnabled()) {
+                        log.trace(s_loc.get("tcp-address-set",
+                            newAddress._address.getHostName() + ":"
+                                + newAddress._port));
+                    }
+                }
+            }
+        } catch (PrivilegedActionException pae) {
+            throw (UnknownHostException) pae.getException();
+        } finally {
+            _addressesLock.unlock();
+        }
+    }
+
+    // ---------- Configurable implementation ----------
+
+    /**
+     * Subclasses that need to perform actions in
+     * {@link Configurable#endConfiguration} must invoke this method.
+     */
+    public void endConfiguration() {
+        super.endConfiguration();
+        synchronized (s_portListenerMap) {
+            // see if a listener exists for this port.
+            _listener = (TCPPortListener) s_portListenerMap.get
+                (String.valueOf(_port));
+
+            if (_listener == null ||
+                (!_listener.isRunning() && _listener._port == _port)) {
+                try {
+                    _listener = new TCPPortListener(_port, log);
+                    _listener.listen();
+                    s_portListenerMap.put(String.valueOf(_port), _listener);
+                } catch (Exception e) {
+                    throw new GeneralException(s_loc.get("tcp-init-exception",
+                        String.valueOf(_port)), e).setFatal(true);
+                }
+            } else if (_listener.isRunning()) {
+                if (_listener._port != _port) {
+                    // this really shouldn't be able to happen.
+                    throw new GeneralException(s_loc.get
+                        ("tcp-not-equal", String.valueOf(_port))).
+                        setFatal(true);
+                }
+            } else
+                throw new InternalException(s_loc.get("tcp-listener-broken"));
+            _listener.addProvider(this);
+        }
+
+        _addressesLock.lock();
+        try {
+            HostAddress curAddress;
+            for (Iterator iter = _addresses.iterator();
+                iter.hasNext();) {
+                curAddress = (HostAddress) iter.next();
+                curAddress.setMaxActive(_maxActive);
+                curAddress.setMaxIdle(_maxIdle);
+            }
+        }
+        finally {
+            _addressesLock.unlock();
+        }
+    }
+
+    // ---------- RemoteCommitProvider implementation ----------
+
+    // pre 3.3.4	= <no version number transmitted>
+    // 3.3 Preview 	= 0x1428acfd;
+    // 3.4 			= 0x1428acff;
+    private static final long PROTOCOL_VERSION = 0x1428acff;
+
+    public void broadcast(RemoteCommitEvent event) {
+        try {
+            // build a packet notifying other JVMs of object changes.
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+            oos.writeLong(PROTOCOL_VERSION);
+            oos.writeLong(_id);
+            oos.writeInt(_port);
+            oos.writeObject(_localhost);
+            oos.writeObject(event);
+            oos.flush();
+
+            byte[] bytes = baos.toByteArray();
+            baos.close();
+            if (_broadcastThreads.isEmpty())
+                sendUpdatePacket(bytes);
+            else
+                _broadcastQueue.addPacket(bytes);
+        } catch (IOException ioe) {
+            if (log.isWarnEnabled())
+                log.warn(s_loc.get("tcp-payload-create-error"), ioe);
+        }
+    }
+
+    /**
+     * Sends a change notification packet to other machines in this
+     * provider cluster.
+     */
+    private void sendUpdatePacket(byte[] bytes) {
+        _addressesLock.lock();
+        try {
+            for (Iterator iter = _addresses.iterator(); iter.hasNext();)
+                ((HostAddress) iter.next()).sendUpdatePacket(bytes);
+        } finally {
+            _addressesLock.unlock();
+        }
+    }
+
+    public void close() {
+        if (_listener != null)
+            _listener.removeProvider(this);
+
+        // Remove Broadcast Threads then close sockets.
+        _broadcastQueue.close();
+
+        // Wait for _broadcastThreads to get cleaned up.
+        while(!_broadcastThreads.isEmpty()) {
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException ie) {
+                // Ignore.
+            }
+        }
+        
+        _addressesLock.lock();
+        try {
+            for (Iterator iter = _addresses.iterator(); iter.hasNext();)
+                ((HostAddress) iter.next()).close();
+        } finally {
+            _addressesLock.unlock();
+        }
+    }
+
+    /**
+     * Utility class to hold messages to be sent. This
+     * allows calls to broadcast () to return without
+     * waiting for the send to complete.
+     */
+    private static class BroadcastQueue {
+
+        private LinkedList _packetQueue = new LinkedList();
+        private boolean _closed = false;
+
+        public synchronized void close() {
+            _closed = true;
+            notifyAll();
+        }
+
+        public synchronized boolean isClosed() {
+            return _closed;
+        }
+
+        public synchronized void addPacket(byte[] bytes) {
+            _packetQueue.addLast(bytes);
+            notify();
+        }
+
+        /**
+         * @return the bytes defining the packet to process, or
+         * <code>null</code> if the queue is empty.
+         */
+        public synchronized byte[] removePacket()
+            throws InterruptedException {
+            // only wait if the queue is still open. This allows processing
+            // of events in the queue to continue, while avoiding sleeping
+            // during shutdown.
+            while (!_closed && _packetQueue.isEmpty())
+                wait();
+            if (_packetQueue.isEmpty())
+                return null;
+            else
+                return (byte[]) _packetQueue.removeFirst();
+        }
+    }
+
+    /**
+     * Threads to broadcast packets placed in the {@link BroadcastQueue}.
+     */
+    private class BroadcastWorkerThread
+        extends Thread {
+
+        private boolean _keepRunning = true;
+
+        public void run() {
+            while (_keepRunning) {
+                try {
+                    // This will block until there is a packet to send, or
+                    // until the queue is closed.
+                    byte[] bytes = _broadcastQueue.removePacket();
+                    if (bytes != null)
+                        sendUpdatePacket(bytes);
+                    else if (_broadcastQueue.isClosed())
+                        _keepRunning = false;
+                } catch (InterruptedException e) {
+                    // End the thread.
+                    break;
+                }
+            }
+            remove();
+        }
+
+        public void setRunning(boolean keepRunning) {
+            _keepRunning = keepRunning;
+        }
+        
+        private void remove() {
+            _broadcastThreads.remove(this);
+        }
+    }
+
+    /**
+     * Responsible for listening for incoming packets and processing them.
+     */
+    private static class TCPPortListener
+        implements Runnable {
+
+        private final Log _log;
+        private ServerSocket _receiveSocket;
+        private Thread _acceptThread;
+        private Set _receiverThreads = new HashSet();
+        private final Set _providers = new HashSet();
+
+        /**
+         * Cache the local IP address
+         */
+        private byte[] _localhost;
+
+        /**
+         * The port that this listener should listen on. Configured
+         * by TCPRemoteCommitProvider.
+         */
+        private int _port;
+
+        /**
+         * Should be set to <code>true</code> once the listener is listening.
+         */
+        private boolean _isRunning = false;
+
+        /**
+         * Construct a new TCPPortListener configured to use the specified port.
+         */
+        private TCPPortListener(int port, Log log)
+            throws IOException {
+            _port = port;
+            _log = log;
+            try {
+                _receiveSocket = (ServerSocket) AccessController
+                    .doPrivileged(J2DoPrivHelper.newServerSocketAction(_port));
+            } catch (PrivilegedActionException pae) {
+                throw (IOException) pae.getException();
+            }
+            _localhost = InetAddress.getLocalHost().getAddress();
+
+            if (_log.isTraceEnabled())
+                _log.info(s_loc.get("tcp-start-listener",
+                    String.valueOf(_port)));
+        }
+
+        private void listen() {
+            _acceptThread = new Thread(this);
+            _acceptThread.setDaemon(true);
+            _acceptThread.start();
+        }
+
+        /**
+         * All providers added here will be notified of any incoming
+         * provider messages. There will be one of these per
+         * BrokerFactory in a given JVM.
+         * {@link TCPRemoteCommitProvider#endConfiguration} invokes
+         * <code>addProvider</code> with <code>this</code> upon
+         * completion of configuration.
+         */
+        private void addProvider(TCPRemoteCommitProvider provider) {
+            synchronized (_providers) {
+                _providers.add(provider);
+            }
+        }
+
+        /**
+         * Remove a provider from the list of providers to notify of
+         * commit events.
+         */
+        private synchronized void removeProvider
+            (TCPRemoteCommitProvider provider) {
+            synchronized (_providers) {
+                _providers.remove(provider);
+
+                // if the provider list is empty, shut down the thread.
+                if (_providers.size() == 0) {
+                    _isRunning = false;
+                    try {
+                        _receiveSocket.close();
+                    } catch (IOException ioe) {
+                        if (_log.isWarnEnabled())
+                            _log.warn(s_loc.get("tcp-close-error"), ioe);
+                    }
+                    _acceptThread.interrupt();
+                }
+            }
+        }
+
+        private boolean isRunning() {
+            synchronized (_providers) {
+                return _isRunning;
+            }
+        }
+
+        public void run() {
+            synchronized (_providers) {
+                _isRunning = true;
+            }
+
+            Socket s = null;
+            while (_isRunning) {
+                try {
+                    s = null;
+                    // Block, waiting to accept new connection from a peer
+                    s = (Socket) AccessController.doPrivileged(J2DoPrivHelper
+                        .acceptAction(_receiveSocket));
+                    if (_log.isTraceEnabled()) {
+                        _log.trace(s_loc.get("tcp-received-connection",
+                            s.getInetAddress().getHostAddress()
+                                + ":" + s.getPort()));
+                    }
+                    ReceiveSocketHandler sh = new ReceiveSocketHandler(s);
+                    Thread receiverThread = new Thread(sh);
+                    receiverThread.setDaemon(true);
+                    receiverThread.start();
+                    _receiverThreads.add(receiverThread);
+                } catch (Exception e) {
+                    if (e instanceof PrivilegedActionException)
+                        e = ((PrivilegedActionException) e).getException();
+                    if (!(e instanceof SocketException) || _isRunning)
+                        if (_log.isWarnEnabled())
+                            _log.warn(s_loc.get("tcp-accept-error"), e);
+
+                    // Nominal case (InterruptedException) because close ()
+                    // calls _acceptThread.interrupt ();
+                    try {
+                        if (s != null)
+                            s.close();
+                    } catch (Exception ee) {
+                        if (_log.isWarnEnabled())
+                            _log.warn(s_loc.get("tcp-close-error"), e);
+                    }
+                }
+            }
+
+            // We are done listening. Interrupt any worker threads.
+            Thread worker;
+            for (Iterator iter = _receiverThreads.iterator();
+                iter.hasNext();) {
+                worker = (Thread) iter.next();
+                // FYI, the worker threads are blocked
+                // reading from the socket's InputStream. InputStreams
+                // aren't interruptable, so this interrupt isn't
+                // really going to be delivered until something breaks
+                // the InputStream.
+                worker.interrupt();
+            }
+            synchronized (_providers) {
+                try {
+                    if (_isRunning)
+                        _receiveSocket.close();
+                } catch (Exception e) {
+                    if (_log.isWarnEnabled())
+                        _log.warn(s_loc.get("tcp-close-error"), e);
+                }
+                _isRunning = false;
+                if (_log.isTraceEnabled())
+                    _log.trace(s_loc.get("tcp-close-listener",
+                        _port + ""));
+            }
+        }
+
+        /**
+         * Utility class that acts as a worker thread to receive Events
+         * from broadcasters.
+         */
+        private class ReceiveSocketHandler
+            implements Runnable {
+
+            private InputStream _in;
+            private Socket _s;
+
+            private ReceiveSocketHandler(Socket s) {
+                // We are the receiving end and we don't send any messages
+                // back to the broadcaster. Turn off Nagle's so that
+                // we will send ack packets without waiting.
+                _s = s;
+                try {
+                    _s.setTcpNoDelay(true);
+                    _in = new BufferedInputStream(s.getInputStream());
+                } catch (IOException ioe) {
+                    if (_log.isInfoEnabled())
+                        _log.info(s_loc.get("tcp-socket-option-error"), ioe);
+                    _s = null;
+                } catch (Exception e) {
+                    if (_log.isWarnEnabled())
+                        _log.warn(s_loc.get("tcp-receive-error"), e);
+                    _s = null;
+                }
+            }
+
+            public void run() {
+                if (_s == null)
+                    return;
+                while (_isRunning && _s != null) {
+                    try {
+                        // This will block our thread, waiting to read
+                        // the next Event-object-message.
+                        handle(_in);
+                    } catch (EOFException eof) {
+                        // EOFException raised when peer is properly
+                        // closing its end.
+                        if (_log.isTraceEnabled()) {
+                            _log.trace(s_loc.get("tcp-close-socket",
+                                _s.getInetAddress().getHostAddress()
+                                    + ":" + _s.getPort()));
+                        }
+                        break;
+                    } catch (Throwable e) {
+                        if (_log.isWarnEnabled())
+                            _log.warn(s_loc.get("tcp-receive-error"), e);
+                        break;
+                    }
+                }
+                // We are done receiving on this socket and this worker
+                // thread is terminating.
+                try {
+                    _in.close();
+                    if (_s != null)
+                        _s.close();
+                } catch (IOException e) {
+                    _log.warn(s_loc.get("tcp-close-socket-error",
+                        _s.getInetAddress().getHostAddress() + ":"
+                            + _s.getPort()), e);
+                }
+            }
+
+            /**
+             * Process an {@link InputStream} containing objects written
+             * by {@link TCPRemoteCommitProvider#broadcast(RemoteCommitEvent)}.
+             */
+            private void handle(InputStream in)
+                throws IOException, ClassNotFoundException {
+                // This will block waiting for the next
+                ObjectInputStream ois = 
+                    new Serialization.ClassResolvingObjectInputStream(in);
+
+                long protocolVersion = ois.readLong();
+                if (protocolVersion != PROTOCOL_VERSION) {
+                    if (_log.isWarnEnabled()) {
+                        _log.warn(s_loc.get("tcp-wrong-version-error",
+                            _s.getInetAddress().getHostAddress() + ":"
+                                + _s.getPort()));
+                        return;
+                    }
+                }
+
+                long senderId = ois.readLong();
+                int senderPort = ois.readInt();
+                byte[] senderAddress = (byte[]) ois.readObject();
+                RemoteCommitEvent rce = (RemoteCommitEvent) ois.readObject();
+                if (_log.isTraceEnabled()) {
+                    _log.trace(s_loc.get("tcp-received-event",
+                        _s.getInetAddress().getHostAddress() + ":"
+                            + _s.getPort()));
+                }
+
+                boolean fromSelf = senderPort == _port &&
+                    Arrays.equals(senderAddress, _localhost);
+                TCPRemoteCommitProvider provider;
+                synchronized (_providers) {
+                    // bleair: We're iterating, but currenlty there can really
+                    // only be a single provider.
+                    for (Iterator iter = _providers.iterator();
+                        iter.hasNext();) {
+                        provider = (TCPRemoteCommitProvider) iter.next();
+                        if (senderId != provider._id || !fromSelf)
+                            provider.eventManager.fireEvent(rce);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Utility class to store an InetAddress and an int. Not using
+     * InetSocketAddress because it's a JDK1.4 API. This also
+     * provides a wrapper around the socket(s) associated with this address.
+     */
+    private class HostAddress {
+
+        private InetAddress _address;
+        private int _port;
+        private long _timeLastError; // millis
+        private boolean _isAvailable; // is peer thought to be up
+        private int _infosIssued = 0; // limit log entries
+
+        private GenericObjectPool _socketPool; // reusable open sockets
+
+        /**
+         * Construct a new host address from a string of the form
+         * "host:port" or of the form "host".
+         */
+        private HostAddress(String host)
+            throws UnknownHostException {
+            int colon = host.indexOf(':');
+            try {
+                if (colon != -1) {
+                    _address = (InetAddress) AccessController
+                        .doPrivileged(J2DoPrivHelper.getByNameAction(host
+                            .substring(0, colon)));
+                    _port = Integer.parseInt(host.substring(colon + 1));
+                } else {
+                    _address = (InetAddress) AccessController
+                        .doPrivileged(J2DoPrivHelper.getByNameAction(host));
+                    _port = DEFAULT_PORT;
+                }
+            } catch (PrivilegedActionException pae) {
+                throw (UnknownHostException) pae.getException();
+            }
+            // -1 max wait == as long as it takes
+            _socketPool = new GenericObjectPool
+                (new SocketPoolableObjectFactory(), _maxActive,
+                    GenericObjectPool.WHEN_EXHAUSTED_BLOCK, -1);
+            _isAvailable = true;
+        }
+
+        private void setMaxActive(int maxActive) {
+            _socketPool.setMaxActive(maxActive);
+        }
+
+        private void setMaxIdle(int maxIdle) {
+            _socketPool.setMaxIdle(maxIdle);
+        }
+
+        public void close() {
+            // Close the pool of sockets to this peer. This
+            // will close all sockets in the pool.
+            try {
+                _socketPool.close();
+            } catch (Exception e) {
+                if (log.isWarnEnabled()) {
+                    log.warn(s_loc.get("tcp-close-pool-error"), e);
+                }
+            }
+        }
+
+        private void sendUpdatePacket(byte[] bytes) {
+            if (!_isAvailable) {
+                long now = System.currentTimeMillis();
+                if (now - _timeLastError < _recoveryTimeMillis)
+                    // Not enough time has passed since the last error
+                    return;
+            }
+            Socket s = null;
+            try {
+                s = getSocket();
+                OutputStream os = s.getOutputStream();
+                os.write(bytes);
+                os.flush();
+
+                if (log.isTraceEnabled()) {
+                    log.trace(s_loc.get("tcp-sent-update",
+                        _address.getHostAddress() + ":" + _port,
+                        String.valueOf(s.getLocalPort())));
+                }
+                _isAvailable = true;
+                _infosIssued = 0;
+                // Return the socket to the pool; the socket is
+                // still good.
+                returnSocket(s);
+            } catch (Exception e) {
+                // There has been a problem sending to the peer.
+                // The OS socket that was being used is can no longer
+                // be used.
+                if (s != null)
+                    this.closeSocket(s);
+                this.clearAllSockets();
+
+                if (_isAvailable) {
+                    // Log a warning, the peer was up and has now gone down
+                    if (log.isWarnEnabled()) {
+                        log.warn(s_loc.get("tcp-send-error",
+                            _address.getHostAddress() + ":" + _port), e);
+                    }
+                    _isAvailable = false;
+                    // Once enough time has passed we will log another warning
+                    _timeLastError = System.currentTimeMillis();
+                } else {
+                    long now = System.currentTimeMillis();
+                    if (now - _timeLastError > _recoveryTimeMillis) {
+                        if (_infosIssued < 5) {
+                            // Enough time has passed, and peer is still down
+                            _timeLastError = System.currentTimeMillis();
+                            // We were trying to reestablish the connection,
+                            // but we failed again. Log a message, but
+                            // lower severity. This log will occur periodically
+                            // for 5 times until the peer comes back.
+                            if (log.isInfoEnabled()) {
+                                log.info(s_loc.get("tcp-send-still-error",
+                                    _address.getHostAddress() + ":"
+                                        + _port), e);
+                            }
+                            _infosIssued++;
+                        }
+                    }
+                }
+            }
+        }
+
+        private Socket getSocket()
+            throws Exception {
+            return (Socket) _socketPool.borrowObject();
+        }
+
+        private void returnSocket(Socket s)
+            throws Exception {
+            _socketPool.returnObject(s);
+        }
+
+        private void clearAllSockets() {
+            _socketPool.clear();
+        }
+
+        private void closeSocket(Socket s) {
+            // All sockets come from the pool.
+            // This socket is no longer usable, so delete it from the
+            // pool.
+            try {
+                _socketPool.invalidateObject(s);
+            } catch (Exception e) {
+            }
+        }
+
+        /**
+         * Factory for pooled sockets.
+         */
+        private class SocketPoolableObjectFactory
+            implements PoolableObjectFactory {
+
+            public Object makeObject()
+                throws IOException {
+                try {
+                    Socket s = (Socket) AccessController
+                        .doPrivileged(J2DoPrivHelper.newSocketAction(_address,
+                            _port));
+                    if (log.isTraceEnabled()) {
+                        log.trace(s_loc.get("tcp-open-connection", _address
+                            + ":" + _port, "" + s.getLocalPort()));
+                    }
+                    return s;
+                } catch (PrivilegedActionException pae) {
+                    throw (IOException) pae.getException();
+                }
+            }
+
+            public void destroyObject(Object obj) {
+                // silentClose ().
+                try {
+                    Socket s = (Socket) obj;
+                    if (log.isTraceEnabled())
+                        log.trace(s_loc.get("tcp-close-sending-socket",
+                            _address + ":" + _port, "" + s.getLocalPort()));
+                    s.close();
+                } catch (Exception e) {
+                    log.warn(s_loc.get("tcp-close-socket-error",
+                        _address.getHostAddress() + ":" + _port), e);
+                }
+            }
+
+            public boolean validateObject(Object obj) {
+                return true;
+            }
+
+            public void activateObject (Object value)
+			{
+			}
+
+			public void passivateObject (Object value)
+			{
+			}
+		}
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/TransactionEventManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/TransactionEventManager.java
index adcd0dd..b806234 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/TransactionEventManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/TransactionEventManager.java
@@ -1,129 +1,129 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.event;
-
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-
-/**
- * Manager that can be used to track and notify transaction listeners
- * of transaction-related events.
- *
- * @author Patrick Linskey
- * @author Abe White
- * @since 0.3.0
- * @nojavadoc
- */
-public class TransactionEventManager
-    extends AbstractConcurrentEventManager {
-
-    private int _begin = 0;
-    private int _flush = 0;
-    private int _end = 0;
-
-    public void addListener(Object listener) {
-        super.addListener(listener);
-        if (listener instanceof BeginTransactionListener)
-            _begin++;
-        if (listener instanceof FlushTransactionListener)
-            _flush++;
-        if (listener instanceof EndTransactionListener)
-            _end++;
-    }
-
-    public boolean removeListener(Object listener) {
-        if (!super.removeListener(listener))
-            return false;
-
-        if (listener instanceof BeginTransactionListener)
-            _begin--;
-        if (listener instanceof FlushTransactionListener)
-            _flush--;
-        if (listener instanceof EndTransactionListener)
-            _end--;
-        return true;
-    }
-
-    /**
-     * Whether there are any begin transaction listeners.
-     */
-    public boolean hasBeginListeners() {
-        return _begin > 0;
-    }
-
-    /**
-     * Whether there are any flush transaction listeners.
-     */
-    public boolean hasFlushListeners() {
-        return _flush > 0;
-    }
-
-    /**
-     * Whether there are any end transaction listeners.
-     */
-    public boolean hasEndListeners() {
-        return _end > 0;
-    }
-
-    /**
-     * Fire the given event to all registered listeners.
-     */
-    protected void fireEvent(Object event, Object listener) {
-        TransactionEvent ev = (TransactionEvent) event;
-        switch (ev.getType()) {
-            case TransactionEvent.AFTER_BEGIN:
-                if (listener instanceof BeginTransactionListener)
-                    ((BeginTransactionListener) listener).afterBegin(ev);
-                break;
-            case TransactionEvent.BEFORE_FLUSH:
-                if (listener instanceof FlushTransactionListener)
-                    ((FlushTransactionListener) listener).beforeFlush(ev);
-                break;
-            case TransactionEvent.AFTER_FLUSH:
-                if (listener instanceof FlushTransactionListener)
-                    ((FlushTransactionListener) listener).afterFlush(ev);
-                break;
-            case TransactionEvent.BEFORE_COMMIT:
-                if (listener instanceof EndTransactionListener)
-                    ((EndTransactionListener) listener).beforeCommit(ev);
-                break;
-            case TransactionEvent.AFTER_COMMIT:
-                if (listener instanceof EndTransactionListener)
-                    ((EndTransactionListener) listener).afterCommit(ev);
-                break;
-            case TransactionEvent.AFTER_ROLLBACK:
-                if (listener instanceof EndTransactionListener)
-                    ((EndTransactionListener) listener).afterRollback(ev);
-                break;
-            case TransactionEvent.AFTER_STATE_TRANSITIONS:
-                if (listener instanceof EndTransactionListener)
-                    ((EndTransactionListener) listener)
-                        .afterStateTransitions(ev);
-                break;
-            case TransactionEvent.AFTER_COMMIT_COMPLETE:
-                if (listener instanceof EndTransactionListener)
-                    ((EndTransactionListener) listener).afterCommitComplete(ev);
-                break;
-            case TransactionEvent.AFTER_ROLLBACK_COMPLETE:
-                if (listener instanceof EndTransactionListener)
-                    ((EndTransactionListener) listener)
-                        .afterRollbackComplete(ev);
-                break;
-        }
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.event;
+
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+
+/**
+ * Manager that can be used to track and notify transaction listeners
+ * of transaction-related events.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ * @since 0.3.0
+ * @nojavadoc
+ */
+public class TransactionEventManager
+    extends AbstractConcurrentEventManager {
+
+    private int _begin = 0;
+    private int _flush = 0;
+    private int _end = 0;
+
+    public void addListener(Object listener) {
+        super.addListener(listener);
+        if (listener instanceof BeginTransactionListener)
+            _begin++;
+        if (listener instanceof FlushTransactionListener)
+            _flush++;
+        if (listener instanceof EndTransactionListener)
+            _end++;
+    }
+
+    public boolean removeListener(Object listener) {
+        if (!super.removeListener(listener))
+            return false;
+
+        if (listener instanceof BeginTransactionListener)
+            _begin--;
+        if (listener instanceof FlushTransactionListener)
+            _flush--;
+        if (listener instanceof EndTransactionListener)
+            _end--;
+        return true;
+    }
+
+    /**
+     * Whether there are any begin transaction listeners.
+     */
+    public boolean hasBeginListeners() {
+        return _begin > 0;
+    }
+
+    /**
+     * Whether there are any flush transaction listeners.
+     */
+    public boolean hasFlushListeners() {
+        return _flush > 0;
+    }
+
+    /**
+     * Whether there are any end transaction listeners.
+     */
+    public boolean hasEndListeners() {
+        return _end > 0;
+    }
+
+    /**
+     * Fire the given event to all registered listeners.
+     */
+    protected void fireEvent(Object event, Object listener) {
+        TransactionEvent ev = (TransactionEvent) event;
+        switch (ev.getType()) {
+            case TransactionEvent.AFTER_BEGIN:
+                if (listener instanceof BeginTransactionListener)
+                    ((BeginTransactionListener) listener).afterBegin(ev);
+                break;
+            case TransactionEvent.BEFORE_FLUSH:
+                if (listener instanceof FlushTransactionListener)
+                    ((FlushTransactionListener) listener).beforeFlush(ev);
+                break;
+            case TransactionEvent.AFTER_FLUSH:
+                if (listener instanceof FlushTransactionListener)
+                    ((FlushTransactionListener) listener).afterFlush(ev);
+                break;
+            case TransactionEvent.BEFORE_COMMIT:
+                if (listener instanceof EndTransactionListener)
+                    ((EndTransactionListener) listener).beforeCommit(ev);
+                break;
+            case TransactionEvent.AFTER_COMMIT:
+                if (listener instanceof EndTransactionListener)
+                    ((EndTransactionListener) listener).afterCommit(ev);
+                break;
+            case TransactionEvent.AFTER_ROLLBACK:
+                if (listener instanceof EndTransactionListener)
+                    ((EndTransactionListener) listener).afterRollback(ev);
+                break;
+            case TransactionEvent.AFTER_STATE_TRANSITIONS:
+                if (listener instanceof EndTransactionListener)
+                    ((EndTransactionListener) listener)
+                        .afterStateTransitions(ev);
+                break;
+            case TransactionEvent.AFTER_COMMIT_COMPLETE:
+                if (listener instanceof EndTransactionListener)
+                    ((EndTransactionListener) listener).afterCommitComplete(ev);
+                break;
+            case TransactionEvent.AFTER_ROLLBACK_COMPLETE:
+                if (listener instanceof EndTransactionListener)
+                    ((EndTransactionListener) listener)
+                        .afterRollbackComplete(ev);
+                break;
+        }
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/UpdateListener.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/UpdateListener.java
index b274521..a9f24b0 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/UpdateListener.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/UpdateListener.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-/**
- * @since 1.1.0
- */
-public interface UpdateListener {
-
-    /**
-     * Receives notifications before an update is performed. Differs from
-     * {@link StoreListener#beforeStore} in that the latter is called for
-     * updated and new records, whereas this is only invoked for updated
-     * records.
-     */
-    public void beforeUpdate(LifecycleEvent event);
-
-    /**
-     * Receives notifications before an update is performed. Differs from
-     * {@link StoreListener#afterStore} in that the latter is called for
-     * updated and new records, whereas this is only invoked for updated
-     * records, and that this is called after the record is actually flushed
-     * to the store.
-     */
-    public void afterUpdatePerformed(LifecycleEvent event);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+/**
+ * @since 1.1.0
+ */
+public interface UpdateListener {
+
+    /**
+     * Receives notifications before an update is performed. Differs from
+     * {@link StoreListener#beforeStore} in that the latter is called for
+     * updated and new records, whereas this is only invoked for updated
+     * records.
+     */
+    public void beforeUpdate(LifecycleEvent event);
+
+    /**
+     * Receives notifications before an update is performed. Differs from
+     * {@link StoreListener#afterStore} in that the latter is called for
+     * updated and new records, whereas this is only invoked for updated
+     * records, and that this is called after the record is actually flushed
+     * to the store.
+     */
+    public void afterUpdatePerformed(LifecycleEvent event);
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
index 7659a9b..7398858 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
@@ -1,827 +1,827 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.ObjectStreamException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.collections.set.MapBackedSet;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.conf.OpenJPAVersion;
-import org.apache.openjpa.conf.BrokerValue;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.datacache.DataCacheStoreManager;
-import org.apache.openjpa.ee.ManagedRuntime;
-import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.ManagedClassSubclasser;
-import org.apache.openjpa.event.BrokerFactoryEvent;
-import org.apache.openjpa.event.RemoteCommitEventManager;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.GeneralException;
-import org.apache.openjpa.util.InvalidStateException;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Abstract implementation of the {@link BrokerFactory}
- * that must be subclassed for a specific runtime.
- *
- * @author Abe White
- */
-public abstract class AbstractBrokerFactory
-    implements BrokerFactory {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (AbstractBrokerFactory.class);
-
-    // static mapping of configurations to pooled broker factories
-    private static final Map _pool = Collections.synchronizedMap(new HashMap());
-
-    // configuration
-    private final OpenJPAConfiguration _conf;
-    private transient boolean _readOnly = false;
-    private transient boolean _closed = false;
-    private transient RuntimeException _closedException = null;
-    private Map _userObjects = null;
-
-    // internal lock: spec forbids synchronization on this object
-    private final ReentrantLock _lock = new ReentrantLock();
-
-    // maps global transactions to associated brokers
-    private transient ConcurrentHashMap _transactional
-        = new ConcurrentHashMap();
-
-    // weak-ref tracking of open brokers
-    private transient Set _brokers;
-
-    // cache the class names loaded from the persistent classes property so
-    // that we can re-load them for each new broker
-    private transient Collection _pcClassNames = null;
-    private transient Collection _pcClassLoaders = null;
-    private transient boolean _persistentTypesLoaded = false;
-
-    // lifecycle listeners to pass to each broker
-    private transient Map _lifecycleListeners = null;
-
-    // transaction listeners to pass to each broker
-    private transient List _transactionListeners = null;
-
-    // key under which this instance can be stored in the broker pool
-    // and later identified
-    private Object _poolKey;
-
-    /**
-     * Return an internal factory pool key for the given configuration.
-     *
-     * @since 1.1.0
-     */
-    protected static Object toPoolKey(Map map) {
-        Object key = Configurations.getProperty("Id", map);
-        return ( key != null) ? key : map;
-    }
-
-    /**
-     * Register <code>factory</code> in the pool under <code>key</code>.
-     *
-     * @since 1.1.0
-     */
-    protected static void pool(Object key, AbstractBrokerFactory factory) {
-        synchronized(_pool) {
-            _pool.put(key, factory);
-            factory.setPoolKey(key);
-            factory.makeReadOnly();
-        }
-    }
-
-    /**
-     * Return the pooled factory matching the given key, or null
-     * if none. The key must be of the form created by {@link #getPoolKey}.
-     */
-    public static AbstractBrokerFactory getPooledFactoryForKey(Object key) {
-        return (AbstractBrokerFactory) _pool.get(key);
-    }
-
-    /**
-     * Constructor. Configuration must be provided on construction.
-     */
-    protected AbstractBrokerFactory(OpenJPAConfiguration config) {
-        _conf = config;
-        _brokers = newBrokerSet();
-        getPcClassLoaders();
-    }
-
-    /**
-     * Return the configuration for this factory.
-     */
-    public OpenJPAConfiguration getConfiguration() {
-        return _conf;
-    }
-
-    public Broker newBroker() {
-        return newBroker(_conf.getConnectionUserName(),
-            _conf.getConnectionPassword());
-    }
-
-    public Broker newBroker(String user, String pass) {
-        return newBroker(user, pass, _conf.isTransactionModeManaged(),
-            _conf.getConnectionRetainModeConstant());
-    }
-
-    public Broker newBroker(boolean managed, int connRetainMode) {
-        return newBroker(_conf.getConnectionUserName(),
-            _conf.getConnectionPassword(), managed, connRetainMode);
-    }
-
-    public Broker newBroker(String user, String pass, boolean managed,
-        int connRetainMode) {
-        return newBroker(user, pass, managed, connRetainMode, true);
-    }
-
-    public Broker newBroker(String user, String pass, boolean managed,
-        int connRetainMode, boolean findExisting) {
-        try {
-            assertOpen();
-            makeReadOnly();
-
-            BrokerImpl broker = null;
-            if (findExisting)
-                broker = findBroker(user, pass, managed);
-            if (broker == null) {
-                broker = newBrokerImpl(user, pass);
-                initializeBroker(managed, connRetainMode, broker, false);
-            }
-            return broker;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        }
-    }
-
-    void initializeBroker(boolean managed, int connRetainMode,
-        BrokerImpl broker, boolean fromDeserialization) {
-        assertOpen();
-        makeReadOnly();
-
-        // decorate the store manager for data caching and custom
-        // result object providers; always make sure it's a delegating
-        // store manager, because it's easier for users to deal with
-        // that way
-        StoreManager sm = newStoreManager();
-        DelegatingStoreManager dsm = null;
-        if (_conf.getDataCacheManagerInstance().getSystemDataCache()
-            != null)
-            dsm = new DataCacheStoreManager(sm);
-        dsm = new ROPStoreManager((dsm == null) ? sm : dsm);
-
-        broker.initialize(this, dsm, managed, connRetainMode,
-            fromDeserialization);
-        if (!fromDeserialization)
-            addListeners(broker);
-
-        // if we're using remote events, register the event manager so
-        // that it can broadcast commit notifications from the broker
-        RemoteCommitEventManager remote = _conf.
-            getRemoteCommitEventManager();
-        if (remote.areRemoteEventsEnabled())
-            broker.addTransactionListener(remote);
-
-        loadPersistentTypes(broker.getClassLoader());
-        _brokers.add(broker);
-        _conf.setReadOnly(Configuration.INIT_STATE_FROZEN);
-    }
-
-    /**
-     * Add factory-registered lifecycle listeners to the broker.
-     */
-    protected void addListeners(BrokerImpl broker) {
-        if (_lifecycleListeners != null && !_lifecycleListeners.isEmpty()) {
-            Map.Entry entry;
-            for (Iterator itr = _lifecycleListeners.entrySet().iterator();
-                itr.hasNext();) {
-                entry = (Map.Entry) itr.next();
-                broker.addLifecycleListener(entry.getKey(), (Class[])
-                    entry.getValue());
-            }
-        }
-
-        if (_transactionListeners != null && !_transactionListeners.isEmpty()) {
-            for (Iterator itr = _transactionListeners.iterator();
-                itr.hasNext(); ) {
-                broker.addTransactionListener(itr.next());
-            }
-        }
-    }
-
-    /**
-     * Load the configured persistent classes list. Performed automatically
-     * whenever a broker is created.
-     */
-    private void loadPersistentTypes(ClassLoader envLoader) {
-        // if we've loaded the persistent types and the class name list
-        // is empty, then we can simply return. Note that there is a
-        // potential threading scenario in which _persistentTypesLoaded is
-        // false when read, but the work to populate _pcClassNames has
-        // already been done. This is ok; _pcClassNames can tolerate
-        // concurrent access, so the worst case is that the list is
-        // persistent type data is processed multiple times, which this
-        // algorithm takes into account.
-        if (_persistentTypesLoaded && _pcClassNames.isEmpty())
-            return;
-
-        // cache persistent type names if not already
-        ClassLoader loader = _conf.getClassResolverInstance().
-            getClassLoader(getClass(), envLoader);
-        Collection toRedefine = new ArrayList();
-        if (!_persistentTypesLoaded) {
-            Collection clss = _conf.getMetaDataRepositoryInstance().
-                loadPersistentTypes(false, loader);
-            if (clss.isEmpty())
-                _pcClassNames = Collections.EMPTY_SET;
-            else {
-                Collection c = new ArrayList(clss.size());
-                for (Iterator itr = clss.iterator(); itr.hasNext();) {
-                    Class cls = (Class) itr.next();
-                    c.add(cls.getName());
-                    if (needsSub(cls))
-                        toRedefine.add(cls);
-                }
-                getPcClassLoaders().add(loader);
-                _pcClassNames = c;
-            }
-            _persistentTypesLoaded = true;
-        } else {
-            // reload with this loader
-            if (getPcClassLoaders().add(loader)) {
-                for (Iterator itr = _pcClassNames.iterator(); itr.hasNext();) {
-                    try {
-                        Class cls =
-                            Class.forName((String) itr.next(), true, loader);
-                        if (needsSub(cls))
-                            toRedefine.add(cls);
-                    } catch (Throwable t) {
-                        _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME)
-                            .warn(null, t);
-                    }
-                }
-            }
-        }
-
-        // get the ManagedClassSubclasser into the loop
-        ManagedClassSubclasser.prepareUnenhancedClasses(
-            _conf, toRedefine, envLoader);
-    }
-
-    private boolean needsSub(Class cls) {
-        return !cls.isInterface()
-            && !PersistenceCapable.class.isAssignableFrom(cls);
-    }
-
-    public void addLifecycleListener(Object listener, Class[] classes) {
-        lock();
-        try {
-            assertOpen();
-            if (_lifecycleListeners == null)
-                _lifecycleListeners = new HashMap(7);
-            _lifecycleListeners.put(listener, classes);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void removeLifecycleListener(Object listener) {
-        lock();
-        try {
-            assertOpen();
-            if (_lifecycleListeners != null)
-                _lifecycleListeners.remove(listener);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void addTransactionListener(Object listener) {
-        lock();
-        try {
-            assertOpen();
-            if (_transactionListeners == null)
-                _transactionListeners = new LinkedList();
-            _transactionListeners.add(listener);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void removeTransactionListener(Object listener) {
-        lock();
-        try {
-            assertOpen();
-            if (_transactionListeners != null)
-                _transactionListeners.remove(listener);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Returns true if this broker factory is closed.
-     */
-    public boolean isClosed() {
-        return _closed;
-    }
-
-    public void close() {
-        lock();
-        try {
-            assertOpen();
-            assertNoActiveTransaction();
-
-            // remove from factory pool
-            synchronized (_pool) {
-                if (_pool.get(_poolKey) == this)
-                    _pool.remove(_poolKey);
-            }
-
-            // close all brokers
-            Broker broker;
-            for (Iterator itr = _brokers.iterator(); itr.hasNext();) {
-                broker = (Broker) itr.next();
-                // Check for null because _brokers may contain weak references
-                if ((broker != null) && (!broker.isClosed()))
-                    broker.close();
-            }
-
-            if(_conf.metaDataRepositoryAvailable()) {
-                // remove metadata repository from listener list
-                PCRegistry.removeRegisterClassListener
-                    (_conf.getMetaDataRepositoryInstance());
-            }
-
-            _conf.close();
-            _closed = true;
-            Log log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
-            if (log.isTraceEnabled())
-                _closedException = new IllegalStateException();
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Subclasses should override this method to add a <code>Platform</code>
-     * property listing the runtime platform, such as:
-     * <code>OpenJPA JDBC Edition: Oracle Database</code>
-     */
-    public Properties getProperties() {
-        // required props are VendorName and VersionNumber
-        Properties props = new Properties();
-        props.setProperty("VendorName", OpenJPAVersion.VENDOR_NAME);
-        props.setProperty("VersionNumber", OpenJPAVersion.VERSION_NUMBER);
-        props.setProperty("VersionId", OpenJPAVersion.VERSION_ID);
-        return props;
-    }
-
-    public Object getUserObject(Object key) {
-        lock();
-        try {
-            assertOpen();
-            return (_userObjects == null) ? null : _userObjects.get(key);
-        } finally {
-            unlock();
-        }
-    }
-
-    public Object putUserObject(Object key, Object val) {
-        lock();
-        try {
-            assertOpen();
-            if (val == null)
-                return (_userObjects == null) ? null : _userObjects.remove(key);
-
-            if (_userObjects == null)
-                _userObjects = new HashMap();
-            return _userObjects.put(key, val);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void lock() {
-        _lock.lock();
-    }
-
-    public void unlock() {
-        _lock.unlock();
-    }
-
-    /**
-     * Replaces the factory with this JVMs pooled version if it exists. Also
-     * freezes the factory.
-     */
-    protected Object readResolve()
-        throws ObjectStreamException {
-        AbstractBrokerFactory factory = getPooledFactoryForKey(_poolKey);
-        if (factory != null)
-            return factory;
-
-        // reset these transient fields to empty values
-        _transactional = new ConcurrentHashMap();
-        _brokers = newBrokerSet();
-
-        makeReadOnly();
-        return this;
-    }
-
-    private Set newBrokerSet() {
-        BrokerValue bv;
-        if (_conf instanceof OpenJPAConfigurationImpl)
-            bv = ((OpenJPAConfigurationImpl) _conf).brokerPlugin;
-        else
-            bv = (BrokerValue) _conf.getValue(BrokerValue.KEY);
-
-        if (FinalizingBrokerImpl.class.isAssignableFrom(
-            bv.getTemplateBrokerType(_conf))) {
-            return MapBackedSet.decorate(new ConcurrentHashMap(),
-                new Object() { });
-        } else {
-            return new ConcurrentReferenceHashSet(
-                ConcurrentReferenceHashSet.WEAK);
-        }
-    }
-
-    ////////////////////////
-    // Methods for Override
-    ////////////////////////
-
-    /**
-     * Return a new StoreManager for this runtime. Note that the instance
-     * returned here may be wrapped before being passed to the
-     * {@link #newBroker} method.
-     */
-    protected abstract StoreManager newStoreManager();
-
-    /**
-     * Find a pooled broker, or return null if none. If using
-     * managed transactions, looks for a transactional broker;
-     * otherwise returns null by default. This method will be called before
-     * {@link #newStoreManager} so that factory subclasses implementing
-     * pooling can return a matching manager before a new {@link StoreManager}
-     * is created.
-     */
-    protected BrokerImpl findBroker(String user, String pass, boolean managed) {
-        if (managed)
-            return findTransactionalBroker(user, pass);
-        return null;
-    }
-
-    /**
-     * Return a broker configured with the proper settings.
-     * By default, this method constructs a new
-     * BrokerImpl of the class set for this factory.
-     */
-    protected BrokerImpl newBrokerImpl(String user, String pass) {
-        BrokerImpl broker = _conf.newBrokerInstance(user, pass);
-        if (broker == null)
-            throw new UserException(_loc.get("no-broker-class",
-                _conf.getBrokerImpl()));
-
-        return broker;
-    }
-
-    /**
-     * Setup transient state used by this factory based on the
-     * current configuration, which will subsequently be locked down. This
-     * method will be called before the first broker is requested,
-     * and will be re-called each time the factory is deserialized into a JVM
-     * that has no configuration for this data store.
-     */
-    protected void setup() {
-    }
-
-    /////////////
-    // Utilities
-    /////////////
-
-    /**
-     * Find a managed runtime broker associated with the
-     * current transaction, or returns null if none.
-     */
-    protected BrokerImpl findTransactionalBroker(String user, String pass) {
-        Transaction trans;
-        ManagedRuntime mr = _conf.getManagedRuntimeInstance();
-        Object txKey;
-        try {
-            trans = mr.getTransactionManager().
-                getTransaction();
-            txKey = mr.getTransactionKey();
-
-            if (trans == null
-                || trans.getStatus() == Status.STATUS_NO_TRANSACTION
-                || trans.getStatus() == Status.STATUS_UNKNOWN)
-                return null;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        }
-
-        Collection brokers = (Collection) _transactional.get(txKey);
-        if (brokers != null) {
-            // we don't need to synchronize on brokers since one JTA transaction
-            // can never be active on multiple concurrent threads.
-            BrokerImpl broker;
-            for (Iterator itr = brokers.iterator(); itr.hasNext();) {
-                broker = (BrokerImpl) itr.next();
-                if (StringUtils.equals(broker.getConnectionUserName(),
-                    user) && StringUtils.equals
-                    (broker.getConnectionPassword(), pass))
-                    return broker;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Configures the given broker with the current factory option settings.
-     */
-    protected void configureBroker(BrokerImpl broker) {
-        broker.setOptimistic(_conf.getOptimistic());
-        broker.setNontransactionalRead(_conf.getNontransactionalRead());
-        broker.setNontransactionalWrite(_conf.getNontransactionalWrite());
-        broker.setRetainState(_conf.getRetainState());
-        broker.setRestoreState(_conf.getRestoreStateConstant());
-        broker.setAutoClear(_conf.getAutoClearConstant());
-        broker.setIgnoreChanges(_conf.getIgnoreChanges());
-        broker.setMultithreaded(_conf.getMultithreaded());
-        broker.setAutoDetach(_conf.getAutoDetachConstant());
-        broker.setDetachState(_conf.getDetachStateInstance().
-            getDetachState());
-    }
-
-    /**
-     * Freezes the configuration of this factory.
-     */
-    public void makeReadOnly() {
-        if (_readOnly)
-            return;
-
-        lock();
-        try {
-            // check again
-            if (_readOnly)
-                return;
-            _readOnly = true;
-
-            Log log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
-            if (log.isInfoEnabled())
-                log.info(getFactoryInitializationBanner());
-            if (log.isTraceEnabled()) {
-                Map props = _conf.toProperties(true);
-                String lineSep = J2DoPrivHelper.getLineSeparator();
-                StringBuffer buf = new StringBuffer();
-                Map.Entry entry;
-                for (Iterator itr = props.entrySet().iterator();
-                    itr.hasNext();) {
-                    entry = (Map.Entry) itr.next();
-                    buf.append(entry.getKey()).append(": ").
-                        append(entry.getValue());
-                    if (itr.hasNext())
-                        buf.append(lineSep);
-                }
-                log.trace(_loc.get("factory-properties", buf.toString()));
-            }
-
-            // setup transient state
-            setup();
-
-            // register the metdata repository to auto-load persistent types
-            // and make sure types are enhanced
-            MetaDataRepository repos = _conf.getMetaDataRepositoryInstance();
-            repos.setValidate(repos.VALIDATE_RUNTIME, true);
-            repos.setResolve(repos.MODE_MAPPING_INIT, true);
-            PCRegistry.addRegisterClassListener(repos);
-
-            // freeze underlying configuration and eagerly initialize to
-            // avoid synchronization
-            _conf.setReadOnly(Configuration.INIT_STATE_FREEZING);
-            _conf.instantiateAll();
-
-            // fire an event for all the broker factory listeners
-            // registered on the configuration.
-            _conf.getBrokerFactoryEventManager().fireEvent(
-                new BrokerFactoryEvent(this,
-                    BrokerFactoryEvent.BROKER_FACTORY_CREATED));
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Return an object to be written to the log when this broker factory
-     * initializes. This happens after the configuration is fully loaded.
-     */
-    protected Object getFactoryInitializationBanner() {
-        return _loc.get("factory-init", OpenJPAVersion.VERSION_NUMBER);
-    }
-
-    /**
-     * Throw an exception if the factory is closed.  The exact message and
-     * content of the exception varies whether TRACE is enabled or not.
-     */
-    private void assertOpen() {
-        if (_closed) {
-            if (_closedException == null)  // TRACE not enabled
-                throw new InvalidStateException(_loc
-                        .get("closed-factory-notrace"));
-            else
-                throw new InvalidStateException(_loc.get("closed-factory"))
-                        .setCause(_closedException);
-        }
-    }
-
-    ////////////////////
-    // Broker utilities
-    ////////////////////
-
-    /**
-     * Throws a {@link UserException} if a transaction is active. The thrown
-     * exception will contain all the Brokers with active transactions as
-     * failed objects in the nested exceptions.
-     */
-    private void assertNoActiveTransaction() {
-        Collection excs;
-        if (_transactional.isEmpty())
-            return;
-
-        excs = new ArrayList(_transactional.size());
-        for (Iterator trans = _transactional.values().iterator();
-            trans.hasNext();) {
-            Collection brokers = (Collection) trans.next();
-            for (Iterator itr = brokers.iterator(); itr.hasNext();) {
-                excs.add(new InvalidStateException(_loc.get("active")).
-                    setFailedObject(itr.next()));
-            }
-        }
-
-        if (!excs.isEmpty())
-            throw new InvalidStateException(_loc.get("nested-exceps")).
-                setNestedThrowables((Throwable[]) excs.toArray
-                    (new Throwable[excs.size()]));
-    }
-
-    /**
-     * Synchronize the given broker with a managed transaction,
-     * optionally starting one if none is in progress.
-     *
-     * @return true if synched with transaction, false otherwise
-     */
-    boolean syncWithManagedTransaction(BrokerImpl broker, boolean begin) {
-        Transaction trans;
-        try {
-            ManagedRuntime mr = broker.getManagedRuntime();
-            TransactionManager tm = mr.getTransactionManager();
-            trans = tm.getTransaction();
-            if (trans != null
-                && (trans.getStatus() == Status.STATUS_NO_TRANSACTION
-                || trans.getStatus() == Status.STATUS_UNKNOWN))
-                trans = null;
-
-            if (trans == null && begin) {
-                tm.begin();
-                trans = tm.getTransaction();
-            } else if (trans == null)
-                return false;
-
-            // synch broker and trans
-            trans.registerSynchronization(broker);
-
-            // we don't need to synchronize on brokers or guard against multiple
-            // threads using the same trans since one JTA transaction can never
-            // be active on multiple concurrent threads.
-            Object txKey = mr.getTransactionKey();
-            Collection brokers = (Collection) _transactional.get(txKey);
-            
-            if (brokers == null) {
-                brokers = new ArrayList(2);
-                _transactional.put(txKey, brokers);
-                trans.registerSynchronization(new RemoveTransactionSync(txKey));
-            }
-            brokers.add(broker);
-            
-            return true;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        }
-    }
-
-    /**
-     * Returns a set of all the open brokers associated with this factory. The
-     * returned set is unmodifiable, and may contain null references.
-     */
-    public Collection getOpenBrokers() {
-        return Collections.unmodifiableCollection(_brokers);
-    }
-
-    /**
-     * Release <code>broker</code> from any internal data structures. This
-     * is invoked by <code>broker</code> after the broker is fully closed.
-     *
-     * @since 1.1.0
-     */
-    protected void releaseBroker(BrokerImpl broker) {
-        _brokers.remove(broker);
-    }
-
-    /**
-     * @return a key that can be used to obtain this broker factory from the
-     * pool at a later time.
-     *
-     * @since 1.1.0
-     */
-    public Object getPoolKey() {
-        return _poolKey;
-    }
-
-    /**
-     * Set a key that can be used to obtain this broker factory from the
-     * pool at a later time.
-     *
-     * @since 1.1.0
-     */
-    void setPoolKey(Object key) {
-        _poolKey = key;
-    }
-
-    /**
-     * Simple synchronization listener to remove completed transactions
-     * from our cache.
-     */
-    private class RemoveTransactionSync
-        implements Synchronization {
-
-        private final Object _trans;
-
-        public RemoveTransactionSync(Object trans) {
-            _trans = trans;
-        }
-
-        public void beforeCompletion() {
-        }
-
-        public void afterCompletion(int status) {
-            _transactional.remove (_trans);
-		}
-	}
-    
-    /**
-     * Method insures that deserialized EMF has this reference re-instantiated
-     */
-    private Collection getPcClassLoaders() {
-       if (_pcClassLoaders == null)
-         _pcClassLoaders = new ConcurrentReferenceHashSet(
-             ConcurrentReferenceHashSet.WEAK);
-          
-       return _pcClassLoaders;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.ObjectStreamException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.collections.set.MapBackedSet;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAVersion;
+import org.apache.openjpa.conf.BrokerValue;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.datacache.DataCacheStoreManager;
+import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.enhance.PCRegistry;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.ManagedClassSubclasser;
+import org.apache.openjpa.event.BrokerFactoryEvent;
+import org.apache.openjpa.event.RemoteCommitEventManager;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.GeneralException;
+import org.apache.openjpa.util.InvalidStateException;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Abstract implementation of the {@link BrokerFactory}
+ * that must be subclassed for a specific runtime.
+ *
+ * @author Abe White
+ */
+public abstract class AbstractBrokerFactory
+    implements BrokerFactory {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (AbstractBrokerFactory.class);
+
+    // static mapping of configurations to pooled broker factories
+    private static final Map _pool = Collections.synchronizedMap(new HashMap());
+
+    // configuration
+    private final OpenJPAConfiguration _conf;
+    private transient boolean _readOnly = false;
+    private transient boolean _closed = false;
+    private transient RuntimeException _closedException = null;
+    private Map _userObjects = null;
+
+    // internal lock: spec forbids synchronization on this object
+    private final ReentrantLock _lock = new ReentrantLock();
+
+    // maps global transactions to associated brokers
+    private transient ConcurrentHashMap _transactional
+        = new ConcurrentHashMap();
+
+    // weak-ref tracking of open brokers
+    private transient Set _brokers;
+
+    // cache the class names loaded from the persistent classes property so
+    // that we can re-load them for each new broker
+    private transient Collection _pcClassNames = null;
+    private transient Collection _pcClassLoaders = null;
+    private transient boolean _persistentTypesLoaded = false;
+
+    // lifecycle listeners to pass to each broker
+    private transient Map _lifecycleListeners = null;
+
+    // transaction listeners to pass to each broker
+    private transient List _transactionListeners = null;
+
+    // key under which this instance can be stored in the broker pool
+    // and later identified
+    private Object _poolKey;
+
+    /**
+     * Return an internal factory pool key for the given configuration.
+     *
+     * @since 1.1.0
+     */
+    protected static Object toPoolKey(Map map) {
+        Object key = Configurations.getProperty("Id", map);
+        return ( key != null) ? key : map;
+    }
+
+    /**
+     * Register <code>factory</code> in the pool under <code>key</code>.
+     *
+     * @since 1.1.0
+     */
+    protected static void pool(Object key, AbstractBrokerFactory factory) {
+        synchronized(_pool) {
+            _pool.put(key, factory);
+            factory.setPoolKey(key);
+            factory.makeReadOnly();
+        }
+    }
+
+    /**
+     * Return the pooled factory matching the given key, or null
+     * if none. The key must be of the form created by {@link #getPoolKey}.
+     */
+    public static AbstractBrokerFactory getPooledFactoryForKey(Object key) {
+        return (AbstractBrokerFactory) _pool.get(key);
+    }
+
+    /**
+     * Constructor. Configuration must be provided on construction.
+     */
+    protected AbstractBrokerFactory(OpenJPAConfiguration config) {
+        _conf = config;
+        _brokers = newBrokerSet();
+        getPcClassLoaders();
+    }
+
+    /**
+     * Return the configuration for this factory.
+     */
+    public OpenJPAConfiguration getConfiguration() {
+        return _conf;
+    }
+
+    public Broker newBroker() {
+        return newBroker(_conf.getConnectionUserName(),
+            _conf.getConnectionPassword());
+    }
+
+    public Broker newBroker(String user, String pass) {
+        return newBroker(user, pass, _conf.isTransactionModeManaged(),
+            _conf.getConnectionRetainModeConstant());
+    }
+
+    public Broker newBroker(boolean managed, int connRetainMode) {
+        return newBroker(_conf.getConnectionUserName(),
+            _conf.getConnectionPassword(), managed, connRetainMode);
+    }
+
+    public Broker newBroker(String user, String pass, boolean managed,
+        int connRetainMode) {
+        return newBroker(user, pass, managed, connRetainMode, true);
+    }
+
+    public Broker newBroker(String user, String pass, boolean managed,
+        int connRetainMode, boolean findExisting) {
+        try {
+            assertOpen();
+            makeReadOnly();
+
+            BrokerImpl broker = null;
+            if (findExisting)
+                broker = findBroker(user, pass, managed);
+            if (broker == null) {
+                broker = newBrokerImpl(user, pass);
+                initializeBroker(managed, connRetainMode, broker, false);
+            }
+            return broker;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+    }
+
+    void initializeBroker(boolean managed, int connRetainMode,
+        BrokerImpl broker, boolean fromDeserialization) {
+        assertOpen();
+        makeReadOnly();
+
+        // decorate the store manager for data caching and custom
+        // result object providers; always make sure it's a delegating
+        // store manager, because it's easier for users to deal with
+        // that way
+        StoreManager sm = newStoreManager();
+        DelegatingStoreManager dsm = null;
+        if (_conf.getDataCacheManagerInstance().getSystemDataCache()
+            != null)
+            dsm = new DataCacheStoreManager(sm);
+        dsm = new ROPStoreManager((dsm == null) ? sm : dsm);
+
+        broker.initialize(this, dsm, managed, connRetainMode,
+            fromDeserialization);
+        if (!fromDeserialization)
+            addListeners(broker);
+
+        // if we're using remote events, register the event manager so
+        // that it can broadcast commit notifications from the broker
+        RemoteCommitEventManager remote = _conf.
+            getRemoteCommitEventManager();
+        if (remote.areRemoteEventsEnabled())
+            broker.addTransactionListener(remote);
+
+        loadPersistentTypes(broker.getClassLoader());
+        _brokers.add(broker);
+        _conf.setReadOnly(Configuration.INIT_STATE_FROZEN);
+    }
+
+    /**
+     * Add factory-registered lifecycle listeners to the broker.
+     */
+    protected void addListeners(BrokerImpl broker) {
+        if (_lifecycleListeners != null && !_lifecycleListeners.isEmpty()) {
+            Map.Entry entry;
+            for (Iterator itr = _lifecycleListeners.entrySet().iterator();
+                itr.hasNext();) {
+                entry = (Map.Entry) itr.next();
+                broker.addLifecycleListener(entry.getKey(), (Class[])
+                    entry.getValue());
+            }
+        }
+
+        if (_transactionListeners != null && !_transactionListeners.isEmpty()) {
+            for (Iterator itr = _transactionListeners.iterator();
+                itr.hasNext(); ) {
+                broker.addTransactionListener(itr.next());
+            }
+        }
+    }
+
+    /**
+     * Load the configured persistent classes list. Performed automatically
+     * whenever a broker is created.
+     */
+    public void loadPersistentTypes(ClassLoader envLoader) {
+        // if we've loaded the persistent types and the class name list
+        // is empty, then we can simply return. Note that there is a
+        // potential threading scenario in which _persistentTypesLoaded is
+        // false when read, but the work to populate _pcClassNames has
+        // already been done. This is ok; _pcClassNames can tolerate
+        // concurrent access, so the worst case is that the list is
+        // persistent type data is processed multiple times, which this
+        // algorithm takes into account.
+        if (_persistentTypesLoaded && _pcClassNames.isEmpty())
+            return;
+
+        // cache persistent type names if not already
+        ClassLoader loader = _conf.getClassResolverInstance().
+            getClassLoader(getClass(), envLoader);
+        Collection toRedefine = new ArrayList();
+        if (!_persistentTypesLoaded) {
+            Collection clss = _conf.getMetaDataRepositoryInstance().
+                loadPersistentTypes(false, loader);
+            if (clss.isEmpty())
+                _pcClassNames = Collections.EMPTY_SET;
+            else {
+                Collection c = new ArrayList(clss.size());
+                for (Iterator itr = clss.iterator(); itr.hasNext();) {
+                    Class cls = (Class) itr.next();
+                    c.add(cls.getName());
+                    if (needsSub(cls))
+                        toRedefine.add(cls);
+                }
+                getPcClassLoaders().add(loader);
+                _pcClassNames = c;
+            }
+            _persistentTypesLoaded = true;
+        } else {
+            // reload with this loader
+            if (getPcClassLoaders().add(loader)) {
+                for (Iterator itr = _pcClassNames.iterator(); itr.hasNext();) {
+                    try {
+                        Class cls =
+                            Class.forName((String) itr.next(), true, loader);
+                        if (needsSub(cls))
+                            toRedefine.add(cls);
+                    } catch (Throwable t) {
+                        _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME)
+                            .warn(null, t);
+                    }
+                }
+            }
+        }
+
+        // get the ManagedClassSubclasser into the loop
+        ManagedClassSubclasser.prepareUnenhancedClasses(
+            _conf, toRedefine, envLoader);
+    }
+
+    private boolean needsSub(Class cls) {
+        return !cls.isInterface()
+            && !PersistenceCapable.class.isAssignableFrom(cls);
+    }
+
+    public void addLifecycleListener(Object listener, Class[] classes) {
+        lock();
+        try {
+            assertOpen();
+            if (_lifecycleListeners == null)
+                _lifecycleListeners = new HashMap(7);
+            _lifecycleListeners.put(listener, classes);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void removeLifecycleListener(Object listener) {
+        lock();
+        try {
+            assertOpen();
+            if (_lifecycleListeners != null)
+                _lifecycleListeners.remove(listener);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void addTransactionListener(Object listener) {
+        lock();
+        try {
+            assertOpen();
+            if (_transactionListeners == null)
+                _transactionListeners = new LinkedList();
+            _transactionListeners.add(listener);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void removeTransactionListener(Object listener) {
+        lock();
+        try {
+            assertOpen();
+            if (_transactionListeners != null)
+                _transactionListeners.remove(listener);
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Returns true if this broker factory is closed.
+     */
+    public boolean isClosed() {
+        return _closed;
+    }
+
+    public void close() {
+        lock();
+        try {
+            assertOpen();
+            assertNoActiveTransaction();
+
+            // remove from factory pool
+            synchronized (_pool) {
+                if (_pool.get(_poolKey) == this)
+                    _pool.remove(_poolKey);
+            }
+
+            // close all brokers
+            Broker broker;
+            for (Iterator itr = _brokers.iterator(); itr.hasNext();) {
+                broker = (Broker) itr.next();
+                // Check for null because _brokers may contain weak references
+                if ((broker != null) && (!broker.isClosed()))
+                    broker.close();
+            }
+
+            if(_conf.metaDataRepositoryAvailable()) {
+                // remove metadata repository from listener list
+                PCRegistry.removeRegisterClassListener
+                    (_conf.getMetaDataRepositoryInstance());
+            }
+
+            _conf.close();
+            _closed = true;
+            Log log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
+            if (log.isTraceEnabled())
+                _closedException = new IllegalStateException();
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Subclasses should override this method to add a <code>Platform</code>
+     * property listing the runtime platform, such as:
+     * <code>OpenJPA JDBC Edition: Oracle Database</code>
+     */
+    public Properties getProperties() {
+        // required props are VendorName and VersionNumber
+        Properties props = new Properties();
+        props.setProperty("VendorName", OpenJPAVersion.VENDOR_NAME);
+        props.setProperty("VersionNumber", OpenJPAVersion.VERSION_NUMBER);
+        props.setProperty("VersionId", OpenJPAVersion.VERSION_ID);
+        return props;
+    }
+
+    public Object getUserObject(Object key) {
+        lock();
+        try {
+            assertOpen();
+            return (_userObjects == null) ? null : _userObjects.get(key);
+        } finally {
+            unlock();
+        }
+    }
+
+    public Object putUserObject(Object key, Object val) {
+        lock();
+        try {
+            assertOpen();
+            if (val == null)
+                return (_userObjects == null) ? null : _userObjects.remove(key);
+
+            if (_userObjects == null)
+                _userObjects = new HashMap();
+            return _userObjects.put(key, val);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void lock() {
+        _lock.lock();
+    }
+
+    public void unlock() {
+        _lock.unlock();
+    }
+
+    /**
+     * Replaces the factory with this JVMs pooled version if it exists. Also
+     * freezes the factory.
+     */
+    protected Object readResolve()
+        throws ObjectStreamException {
+        AbstractBrokerFactory factory = getPooledFactoryForKey(_poolKey);
+        if (factory != null)
+            return factory;
+
+        // reset these transient fields to empty values
+        _transactional = new ConcurrentHashMap();
+        _brokers = newBrokerSet();
+
+        makeReadOnly();
+        return this;
+    }
+
+    private Set newBrokerSet() {
+        BrokerValue bv;
+        if (_conf instanceof OpenJPAConfigurationImpl)
+            bv = ((OpenJPAConfigurationImpl) _conf).brokerPlugin;
+        else
+            bv = (BrokerValue) _conf.getValue(BrokerValue.KEY);
+
+        if (FinalizingBrokerImpl.class.isAssignableFrom(
+            bv.getTemplateBrokerType(_conf))) {
+            return MapBackedSet.decorate(new ConcurrentHashMap(),
+                new Object() { });
+        } else {
+            return new ConcurrentReferenceHashSet(
+                ConcurrentReferenceHashSet.WEAK);
+        }
+    }
+
+    ////////////////////////
+    // Methods for Override
+    ////////////////////////
+
+    /**
+     * Return a new StoreManager for this runtime. Note that the instance
+     * returned here may be wrapped before being passed to the
+     * {@link #newBroker} method.
+     */
+    protected abstract StoreManager newStoreManager();
+
+    /**
+     * Find a pooled broker, or return null if none. If using
+     * managed transactions, looks for a transactional broker;
+     * otherwise returns null by default. This method will be called before
+     * {@link #newStoreManager} so that factory subclasses implementing
+     * pooling can return a matching manager before a new {@link StoreManager}
+     * is created.
+     */
+    protected BrokerImpl findBroker(String user, String pass, boolean managed) {
+        if (managed)
+            return findTransactionalBroker(user, pass);
+        return null;
+    }
+
+    /**
+     * Return a broker configured with the proper settings.
+     * By default, this method constructs a new
+     * BrokerImpl of the class set for this factory.
+     */
+    protected BrokerImpl newBrokerImpl(String user, String pass) {
+        BrokerImpl broker = _conf.newBrokerInstance(user, pass);
+        if (broker == null)
+            throw new UserException(_loc.get("no-broker-class",
+                _conf.getBrokerImpl()));
+
+        return broker;
+    }
+
+    /**
+     * Setup transient state used by this factory based on the
+     * current configuration, which will subsequently be locked down. This
+     * method will be called before the first broker is requested,
+     * and will be re-called each time the factory is deserialized into a JVM
+     * that has no configuration for this data store.
+     */
+    protected void setup() {
+    }
+
+    /////////////
+    // Utilities
+    /////////////
+
+    /**
+     * Find a managed runtime broker associated with the
+     * current transaction, or returns null if none.
+     */
+    protected BrokerImpl findTransactionalBroker(String user, String pass) {
+        Transaction trans;
+        ManagedRuntime mr = _conf.getManagedRuntimeInstance();
+        Object txKey;
+        try {
+            trans = mr.getTransactionManager().
+                getTransaction();
+            txKey = mr.getTransactionKey();
+
+            if (trans == null
+                || trans.getStatus() == Status.STATUS_NO_TRANSACTION
+                || trans.getStatus() == Status.STATUS_UNKNOWN)
+                return null;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        }
+
+        Collection brokers = (Collection) _transactional.get(txKey);
+        if (brokers != null) {
+            // we don't need to synchronize on brokers since one JTA transaction
+            // can never be active on multiple concurrent threads.
+            BrokerImpl broker;
+            for (Iterator itr = brokers.iterator(); itr.hasNext();) {
+                broker = (BrokerImpl) itr.next();
+                if (StringUtils.equals(broker.getConnectionUserName(),
+                    user) && StringUtils.equals
+                    (broker.getConnectionPassword(), pass))
+                    return broker;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Configures the given broker with the current factory option settings.
+     */
+    protected void configureBroker(BrokerImpl broker) {
+        broker.setOptimistic(_conf.getOptimistic());
+        broker.setNontransactionalRead(_conf.getNontransactionalRead());
+        broker.setNontransactionalWrite(_conf.getNontransactionalWrite());
+        broker.setRetainState(_conf.getRetainState());
+        broker.setRestoreState(_conf.getRestoreStateConstant());
+        broker.setAutoClear(_conf.getAutoClearConstant());
+        broker.setIgnoreChanges(_conf.getIgnoreChanges());
+        broker.setMultithreaded(_conf.getMultithreaded());
+        broker.setAutoDetach(_conf.getAutoDetachConstant());
+        broker.setDetachState(_conf.getDetachStateInstance().
+            getDetachState());
+    }
+
+    /**
+     * Freezes the configuration of this factory.
+     */
+    public void makeReadOnly() {
+        if (_readOnly)
+            return;
+
+        lock();
+        try {
+            // check again
+            if (_readOnly)
+                return;
+            _readOnly = true;
+
+            Log log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
+            if (log.isInfoEnabled())
+                log.info(getFactoryInitializationBanner());
+            if (log.isTraceEnabled()) {
+                Map props = _conf.toProperties(true);
+                String lineSep = J2DoPrivHelper.getLineSeparator();
+                StringBuffer buf = new StringBuffer();
+                Map.Entry entry;
+                for (Iterator itr = props.entrySet().iterator();
+                    itr.hasNext();) {
+                    entry = (Map.Entry) itr.next();
+                    buf.append(entry.getKey()).append(": ").
+                        append(entry.getValue());
+                    if (itr.hasNext())
+                        buf.append(lineSep);
+                }
+                log.trace(_loc.get("factory-properties", buf.toString()));
+            }
+
+            // setup transient state
+            setup();
+
+            // register the metdata repository to auto-load persistent types
+            // and make sure types are enhanced
+            MetaDataRepository repos = _conf.getMetaDataRepositoryInstance();
+            repos.setValidate(repos.VALIDATE_RUNTIME, true);
+            repos.setResolve(repos.MODE_MAPPING_INIT, true);
+            PCRegistry.addRegisterClassListener(repos);
+
+            // freeze underlying configuration and eagerly initialize to
+            // avoid synchronization
+            _conf.setReadOnly(Configuration.INIT_STATE_FREEZING);
+            _conf.instantiateAll();
+
+            // fire an event for all the broker factory listeners
+            // registered on the configuration.
+            _conf.getBrokerFactoryEventManager().fireEvent(
+                new BrokerFactoryEvent(this,
+                    BrokerFactoryEvent.BROKER_FACTORY_CREATED));
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Return an object to be written to the log when this broker factory
+     * initializes. This happens after the configuration is fully loaded.
+     */
+    protected Object getFactoryInitializationBanner() {
+        return _loc.get("factory-init", OpenJPAVersion.VERSION_NUMBER);
+    }
+
+    /**
+     * Throw an exception if the factory is closed.  The exact message and
+     * content of the exception varies whether TRACE is enabled or not.
+     */
+    private void assertOpen() {
+        if (_closed) {
+            if (_closedException == null)  // TRACE not enabled
+                throw new InvalidStateException(_loc
+                        .get("closed-factory-notrace"));
+            else
+                throw new InvalidStateException(_loc.get("closed-factory"))
+                        .setCause(_closedException);
+        }
+    }
+
+    ////////////////////
+    // Broker utilities
+    ////////////////////
+
+    /**
+     * Throws a {@link UserException} if a transaction is active. The thrown
+     * exception will contain all the Brokers with active transactions as
+     * failed objects in the nested exceptions.
+     */
+    private void assertNoActiveTransaction() {
+        Collection excs;
+        if (_transactional.isEmpty())
+            return;
+
+        excs = new ArrayList(_transactional.size());
+        for (Iterator trans = _transactional.values().iterator();
+            trans.hasNext();) {
+            Collection brokers = (Collection) trans.next();
+            for (Iterator itr = brokers.iterator(); itr.hasNext();) {
+                excs.add(new InvalidStateException(_loc.get("active")).
+                    setFailedObject(itr.next()));
+            }
+        }
+
+        if (!excs.isEmpty())
+            throw new InvalidStateException(_loc.get("nested-exceps")).
+                setNestedThrowables((Throwable[]) excs.toArray
+                    (new Throwable[excs.size()]));
+    }
+
+    /**
+     * Synchronize the given broker with a managed transaction,
+     * optionally starting one if none is in progress.
+     *
+     * @return true if synched with transaction, false otherwise
+     */
+    boolean syncWithManagedTransaction(BrokerImpl broker, boolean begin) {
+        Transaction trans;
+        try {
+            ManagedRuntime mr = broker.getManagedRuntime();
+            TransactionManager tm = mr.getTransactionManager();
+            trans = tm.getTransaction();
+            if (trans != null
+                && (trans.getStatus() == Status.STATUS_NO_TRANSACTION
+                || trans.getStatus() == Status.STATUS_UNKNOWN))
+                trans = null;
+
+            if (trans == null && begin) {
+                tm.begin();
+                trans = tm.getTransaction();
+            } else if (trans == null)
+                return false;
+
+            // synch broker and trans
+            trans.registerSynchronization(broker);
+
+            // we don't need to synchronize on brokers or guard against multiple
+            // threads using the same trans since one JTA transaction can never
+            // be active on multiple concurrent threads.
+            Object txKey = mr.getTransactionKey();
+            Collection brokers = (Collection) _transactional.get(txKey);
+            
+            if (brokers == null) {
+                brokers = new ArrayList(2);
+                _transactional.put(txKey, brokers);
+                trans.registerSynchronization(new RemoveTransactionSync(txKey));
+            }
+            brokers.add(broker);
+            
+            return true;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        }
+    }
+
+    /**
+     * Returns a set of all the open brokers associated with this factory. The
+     * returned set is unmodifiable, and may contain null references.
+     */
+    public Collection getOpenBrokers() {
+        return Collections.unmodifiableCollection(_brokers);
+    }
+
+    /**
+     * Release <code>broker</code> from any internal data structures. This
+     * is invoked by <code>broker</code> after the broker is fully closed.
+     *
+     * @since 1.1.0
+     */
+    protected void releaseBroker(BrokerImpl broker) {
+        _brokers.remove(broker);
+    }
+
+    /**
+     * @return a key that can be used to obtain this broker factory from the
+     * pool at a later time.
+     *
+     * @since 1.1.0
+     */
+    public Object getPoolKey() {
+        return _poolKey;
+    }
+
+    /**
+     * Set a key that can be used to obtain this broker factory from the
+     * pool at a later time.
+     *
+     * @since 1.1.0
+     */
+    void setPoolKey(Object key) {
+        _poolKey = key;
+    }
+
+    /**
+     * Simple synchronization listener to remove completed transactions
+     * from our cache.
+     */
+    private class RemoveTransactionSync
+        implements Synchronization {
+
+        private final Object _trans;
+
+        public RemoveTransactionSync(Object trans) {
+            _trans = trans;
+        }
+
+        public void beforeCompletion() {
+        }
+
+        public void afterCompletion(int status) {
+            _transactional.remove (_trans);
+		}
+	}
+    
+    /**
+     * Method insures that deserialized EMF has this reference re-instantiated
+     */
+    private Collection getPcClassLoaders() {
+       if (_pcClassLoaders == null)
+         _pcClassLoaders = new ConcurrentReferenceHashSet(
+             ConcurrentReferenceHashSet.WEAK);
+          
+       return _pcClassLoaders;
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java
index f8f12dc..273fdbb 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java
@@ -1,190 +1,190 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.util.Map;
-
-import org.apache.commons.collections.map.LinkedMap;
-import org.apache.openjpa.kernel.exps.AggregateListener;
-import org.apache.openjpa.kernel.exps.FilterListener;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.UnsupportedException;
-
-/**
- * Abstract {@link StoreQuery} that implements most methods as no-ops.
- *
- * @author Abe White
- * @since 0.4.0
- */
-public abstract class AbstractStoreQuery
-    implements StoreQuery {
-
-    protected QueryContext ctx = null;
-   
-    public QueryContext getContext() {
-        return ctx;
-    }
-
-    public void setContext(QueryContext ctx) {
-        this.ctx = ctx;
-    }
-
-    public boolean setQuery(Object query) {
-        return false;
-    }
-
-    public FilterListener getFilterListener(String tag) {
-        return null;
-    }
-
-    public AggregateListener getAggregateListener(String tag) {
-        return null;
-    }
-
-    public Object newCompilationKey() {
-        return null;
-    }
-
-    public Object newCompilation() {
-        return null;
-    }
-
-    public void populateFromCompilation(Object comp) {
-    }
-
-    public void invalidateCompilation() {
-    }
-
-    public boolean supportsDataStoreExecution() {
-        return false;
-    }
-
-    public boolean supportsInMemoryExecution() {
-        return false;
-    }
-
-    public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs) {
-        throw new InternalException();
-    }
-
-    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
-        throw new InternalException();
-    }
-
-    public boolean supportsAbstractExecutors() {
-        return false;
-    }
-
-    public boolean requiresCandidateType() {
-        return true;
-    }
-
-    public boolean requiresParameterDeclarations() {
-        return true;
-    }
-
-    public boolean supportsParameterDeclarations() {
-        return true;
-    }
-
-    public Object evaluate(Object value, Object ob, Object[] params,
-        OpenJPAStateManager sm) {
-        throw new UnsupportedException();
-    }
-
-    /**
-     * Abstract {@link Executor} that implements most methods as no-ops.
-     */
-    public static abstract class AbstractExecutor
-        implements Executor {
-
-        public Number executeDelete(StoreQuery q, Object[] params) {
-            return q.getContext().deleteInMemory(q, this, params);
-        }
-
-        public Number executeUpdate(StoreQuery q, Object[] params) {
-            return q.getContext().updateInMemory(q, this, params);
-        }
-
-        public String[] getDataStoreActions(StoreQuery q, Object[] params,
-            Range range) {
-            return EMPTY_STRINGS;
-        }
-
-        public void validate(StoreQuery q) {
-        }
-
-        public void getRange(StoreQuery q, Object[] params, Range range) {
-        }
-
-        public Object getOrderingValue(StoreQuery q, Object[] params,
-            Object resultObject, int orderIndex) {
-            return null;
-        }
-
-        public boolean[] getAscending(StoreQuery q) {
-            return EMPTY_BOOLEANS;
-        }
-
-        public boolean isPacking(StoreQuery q) {
-            return false;
-        }
-
-        public String getAlias(StoreQuery q) {
-            return null;
-        }
-
-        public String[] getProjectionAliases(StoreQuery q) {
-            return EMPTY_STRINGS;
-        }
-
-        public Class[] getProjectionTypes(StoreQuery q) {
-            return EMPTY_CLASSES;
-        }
-
-        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q) {
-            return EMPTY_METAS;
-        }
-
-        public int getOperation(StoreQuery q) {
-            return OP_SELECT;
-        }
-
-        public boolean isAggregate(StoreQuery q) {
-            return false;
-        }
-
-        public boolean hasGrouping(StoreQuery q) {
-            return false;
-        }
-
-        public LinkedMap getParameterTypes(StoreQuery q) {
-            return EMPTY_PARAMS;
-        }
-
-        public Class getResultClass(StoreQuery q) {
-            return null;
-        }
-
-        public Map getUpdates(StoreQuery q) {
-            return null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.util.Map;
+
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.openjpa.kernel.exps.AggregateListener;
+import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.UnsupportedException;
+
+/**
+ * Abstract {@link StoreQuery} that implements most methods as no-ops.
+ *
+ * @author Abe White
+ * @since 0.4.0
+ */
+public abstract class AbstractStoreQuery
+    implements StoreQuery {
+
+    protected QueryContext ctx = null;
+   
+    public QueryContext getContext() {
+        return ctx;
+    }
+
+    public void setContext(QueryContext ctx) {
+        this.ctx = ctx;
+    }
+
+    public boolean setQuery(Object query) {
+        return false;
+    }
+
+    public FilterListener getFilterListener(String tag) {
+        return null;
+    }
+
+    public AggregateListener getAggregateListener(String tag) {
+        return null;
+    }
+
+    public Object newCompilationKey() {
+        return null;
+    }
+
+    public Object newCompilation() {
+        return null;
+    }
+
+    public void populateFromCompilation(Object comp) {
+    }
+
+    public void invalidateCompilation() {
+    }
+
+    public boolean supportsDataStoreExecution() {
+        return false;
+    }
+
+    public boolean supportsInMemoryExecution() {
+        return false;
+    }
+
+    public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs) {
+        throw new InternalException();
+    }
+
+    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
+        throw new InternalException();
+    }
+
+    public boolean supportsAbstractExecutors() {
+        return false;
+    }
+
+    public boolean requiresCandidateType() {
+        return true;
+    }
+
+    public boolean requiresParameterDeclarations() {
+        return true;
+    }
+
+    public boolean supportsParameterDeclarations() {
+        return true;
+    }
+
+    public Object evaluate(Object value, Object ob, Object[] params,
+        OpenJPAStateManager sm) {
+        throw new UnsupportedException();
+    }
+
+    /**
+     * Abstract {@link Executor} that implements most methods as no-ops.
+     */
+    public static abstract class AbstractExecutor
+        implements Executor {
+
+        public Number executeDelete(StoreQuery q, Object[] params) {
+            return q.getContext().deleteInMemory(q, this, params);
+        }
+
+        public Number executeUpdate(StoreQuery q, Object[] params) {
+            return q.getContext().updateInMemory(q, this, params);
+        }
+
+        public String[] getDataStoreActions(StoreQuery q, Object[] params,
+            Range range) {
+            return EMPTY_STRINGS;
+        }
+
+        public void validate(StoreQuery q) {
+        }
+
+        public void getRange(StoreQuery q, Object[] params, Range range) {
+        }
+
+        public Object getOrderingValue(StoreQuery q, Object[] params,
+            Object resultObject, int orderIndex) {
+            return null;
+        }
+
+        public boolean[] getAscending(StoreQuery q) {
+            return EMPTY_BOOLEANS;
+        }
+
+        public boolean isPacking(StoreQuery q) {
+            return false;
+        }
+
+        public String getAlias(StoreQuery q) {
+            return null;
+        }
+
+        public String[] getProjectionAliases(StoreQuery q) {
+            return EMPTY_STRINGS;
+        }
+
+        public Class[] getProjectionTypes(StoreQuery q) {
+            return EMPTY_CLASSES;
+        }
+
+        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q) {
+            return EMPTY_METAS;
+        }
+
+        public int getOperation(StoreQuery q) {
+            return OP_SELECT;
+        }
+
+        public boolean isAggregate(StoreQuery q) {
+            return false;
+        }
+
+        public boolean hasGrouping(StoreQuery q) {
+            return false;
+        }
+
+        public LinkedMap getParameterTypes(StoreQuery q) {
+            return EMPTY_PARAMS;
+        }
+
+        public Class getResultClass(StoreQuery q) {
+            return null;
+        }
+
+        public Map getUpdates(StoreQuery q) {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachStrategy.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachStrategy.java
index fa9e0f2..2906698 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachStrategy.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachStrategy.java
@@ -265,21 +265,27 @@
      * Return a managed, possibly hollow reference for the given detached
      * object.
      */
-    protected Object getReference(AttachManager manager, Object toAttach,
-        OpenJPAStateManager sm, ValueMetaData vmd) {
+    protected Object getReference(AttachManager manager, Object toAttach, OpenJPAStateManager sm, ValueMetaData vmd) {
         if (toAttach == null)
             return null;
 
-        if (manager.getBroker().isNew(toAttach)
-            || manager.getBroker().isPersistent(toAttach)) {
+        if (manager.getBroker().isNew(toAttach)) {
+            // Check if toAttach is already mapped to a managed instance
+            PersistenceCapable pc = manager.getAttachedCopy(toAttach);
+            if (pc != null) {
+                return pc;
+            } else {
+                return toAttach;
+            }
+        } else if (manager.getBroker().isPersistent(toAttach)) {
             return toAttach;
         } else if (manager.getBroker().isDetached(toAttach)) {
             Object oid = manager.getDetachedObjectId(toAttach);
-            if (oid != null)
+            if (oid != null) {
                 return manager.getBroker().find(oid, false, null);
+            }
         }
-        throw new UserException(_loc.get("cant-cascade-attach", vmd))
-            .setFailedObject(toAttach);
+        throw new UserException(_loc.get("cant-cascade-attach", vmd)).setFailedObject(toAttach);
     }
 
     /**
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
index 60ac73f..f441052 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
@@ -1,4755 +1,4779 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Modifier;
-import java.security.AccessController;
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-
-import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.commons.collections.map.IdentityMap;
-import org.apache.commons.collections.map.LinkedMap;
-import org.apache.commons.collections.set.MapBackedSet;
-import org.apache.openjpa.conf.Compatibility;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.datacache.DataCache;
-import org.apache.openjpa.ee.ManagedRuntime;
-import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.event.LifecycleEventManager;
-import org.apache.openjpa.event.RemoteCommitEventManager;
-import org.apache.openjpa.event.TransactionEvent;
-import org.apache.openjpa.event.TransactionEventManager;
-import org.apache.openjpa.kernel.exps.ExpressionParser;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.ReferenceHashMap;
-import org.apache.openjpa.lib.util.ReferenceHashSet;
-import org.apache.openjpa.lib.util.ReferenceMap;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.meta.SequenceMetaData;
-import org.apache.openjpa.meta.ValueMetaData;
-import org.apache.openjpa.meta.ValueStrategies;
-import org.apache.openjpa.util.ApplicationIds;
-import org.apache.openjpa.util.CallbackException;
-import org.apache.openjpa.util.Exceptions;
-import org.apache.openjpa.util.GeneralException;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.InvalidStateException;
-import org.apache.openjpa.util.NoTransactionException;
-import org.apache.openjpa.util.ObjectExistsException;
-import org.apache.openjpa.util.ObjectId;
-import org.apache.openjpa.util.ObjectNotFoundException;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.OptimisticException;
-import org.apache.openjpa.util.RuntimeExceptionTranslator;
-import org.apache.openjpa.util.StoreException;
-import org.apache.openjpa.util.UnsupportedException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Concrete {@link Broker}. The broker handles object-level behavior,
- * but leaves all interaction with the data store to a {@link StoreManager}
- * that must be supplied at initialization.
- *
- * @author Abe White
- */
-public class BrokerImpl
-    implements Broker, FindCallbacks, Cloneable, Serializable {
-
-    /**
-     * Incremental flush.
-     */
-    protected static final int FLUSH_INC = 0;
-
-    /**
-     * Flush in preparation of commit.
-     */
-    protected static final int FLUSH_COMMIT = 1;
-
-    /**
-     * Flush to check consistency of cache, then immediately rollback changes.
-     */
-    protected static final int FLUSH_ROLLBACK = 2;
-
-    /**
-     * Run persistence-by-reachability and other flush-time operations without
-     * accessing the database.
-     */
-    protected static final int FLUSH_LOGICAL = 3;
-
-    static final int STATUS_INIT = 0;
-    static final int STATUS_TRANSIENT = 1;
-    static final int STATUS_OID_ASSIGN = 2;
-    static final int STATUS_COMMIT_NEW = 3;
-
-    private static final int FLAG_ACTIVE = 2 << 0;
-    private static final int FLAG_STORE_ACTIVE = 2 << 1;
-    private static final int FLAG_CLOSE_INVOKED = 2 << 2;
-    private static final int FLAG_PRESTORING = 2 << 3;
-    private static final int FLAG_DEREFDELETING = 2 << 4;
-    private static final int FLAG_FLUSHING = 2 << 5;
-    private static final int FLAG_STORE_FLUSHING = 2 << 6;
-    private static final int FLAG_FLUSHED = 2 << 7;
-    private static final int FLAG_FLUSH_REQUIRED = 2 << 8;
-    private static final int FLAG_REMOTE_LISTENER = 2 << 9;
-    private static final int FLAG_RETAINED_CONN = 2 << 10;
-    private static final int FLAG_TRANS_ENDING = 2 << 11;
-
-    private static final Object[] EMPTY_OBJECTS = new Object[0];
-
-    private static final Localizer _loc =
-        Localizer.forPackage(BrokerImpl.class);
-
-    //	the store manager in use; this may be a decorator such as a
-    //	data cache store manager around the native store manager
-    private transient DelegatingStoreManager _store = null;
-
-    private FetchConfiguration _fc = null;
-    private String _user = null;
-    private String _pass = null;
-
-    // these must be rebuilt by the facade layer during its deserialization
-    private transient Log _log = null;
-    private transient Compatibility _compat = null;
-    private transient ManagedRuntime _runtime = null;
-    private transient LockManager _lm = null;
-    private transient InverseManager _im = null;
-    private transient ReentrantLock _lock = null;
-    private transient OpCallbacks _call = null;
-    private transient RuntimeExceptionTranslator _extrans = null;
-
-    // ref to producing factory and configuration
-    private transient AbstractBrokerFactory _factory = null;
-    private transient OpenJPAConfiguration _conf = null;
-
-    // cache class loader associated with the broker
-    private transient ClassLoader _loader = null;
-
-    // user state
-    private Synchronization _sync = null;
-    private Map _userObjects = null;
-
-    // managed object caches
-    private ManagedCache _cache = null;
-    private TransactionalCache _transCache = null;
-    private Set _transAdditions = null;
-    private Set _derefCache = null;
-    private Set _derefAdditions = null;
-
-    // these are used for method-internal state only
-    private transient Map _loading = null;
-    private transient Set _operating = null;
-
-    private Set _persistedClss = null;
-    private Set _updatedClss = null;
-    private Set _deletedClss = null;
-    private Set _pending = null;
-    private int findAllDepth = 0;
-
-    // track instances that become transactional after the first savepoint
-    // (the first uses the transactional cache)
-    private Set _savepointCache = null;
-    private LinkedMap _savepoints = null;
-    private transient SavepointManager _spm = null;
-
-    // track open queries and extents so we can free their resources on close
-    private transient ReferenceHashSet _queries = null;
-    private transient ReferenceHashSet _extents = null;
-
-    // track operation stack depth. Transient because operations cannot
-    // span serialization.
-    private transient int _operationCount = 0;
-
-    // options
-    private boolean _nontransRead = false;
-    private boolean _nontransWrite = false;
-    private boolean _retainState = false;
-    private int _autoClear = CLEAR_DATASTORE;
-    private int _restoreState = RESTORE_IMMUTABLE;
-    private boolean _optimistic = false;
-    private boolean _ignoreChanges = false;
-    private boolean _multithreaded = false;
-    private boolean _managed = false;
-    private boolean _syncManaged = false;
-    private int _connRetainMode = CONN_RETAIN_DEMAND;
-    private boolean _evictDataCache = false;
-    private boolean _populateDataCache = true;
-    private boolean _largeTransaction = false;
-    private int _autoDetach = 0;
-    private int _detachState = DETACH_LOADED;
-    private boolean _detachedNew = true;
-    private boolean _orderDirty = false;
-
-    // status
-    private int _flags = 0;
-
-    // this is not in status because it should not be serialized
-    private transient boolean _isSerializing = false;
-
-    // transient because closed brokers can't be serialized
-    private transient boolean _closed = false;
-    private transient RuntimeException _closedException = null;
-
-    // event managers
-    private TransactionEventManager _transEventManager = null;
-    private int _transCallbackMode = 0;
-    private LifecycleEventManager _lifeEventManager = null;
-    private int _lifeCallbackMode = 0;
-
-    private transient boolean _initializeWasInvoked = false;
-    private LinkedList _fcs;
-
-    /**
-     * Set the persistence manager's authentication. This is the first
-     * method called after construction.
-     *
-     * @param user the username this broker represents; used when pooling
-     * brokers to make sure that a request to the factory for
-     * a connection with an explicit user is delegated to a suitable broker
-     * @param pass the password for the above user
-     */
-    public void setAuthentication(String user, String pass) {
-        _user = user;
-        _pass = pass;
-    }
-
-    /**
-     * Initialize the persistence manager. This method is called
-     * automatically by the factory before use.
-     *
-     * @param factory the factory used to create this broker
-     * @param sm a concrete StoreManager implementation to
-     * handle interaction with the data store
-     * @param managed the transaction mode
-     * @param connMode the connection retain mode
-     * @param fromDeserialization whether this call happened because of a
-     * deserialization or creation of a new BrokerImpl.
-     */
-    public void initialize(AbstractBrokerFactory factory,
-        DelegatingStoreManager sm, boolean managed, int connMode,
-        boolean fromDeserialization) {
-        _initializeWasInvoked = true;
-        _loader = (ClassLoader) AccessController.doPrivileged(
-            J2DoPrivHelper.getContextClassLoaderAction());
-        if (!fromDeserialization)
-            _conf = factory.getConfiguration();
-        _compat = _conf.getCompatibilityInstance();
-        _factory = factory;
-        _log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
-        if (!fromDeserialization)
-            _cache = new ManagedCache(this);
-        initializeOperatingSet();
-        _connRetainMode = connMode;
-        _managed = managed;
-        if (managed)
-            _runtime = _conf.getManagedRuntimeInstance();
-        else
-            _runtime = new LocalManagedRuntime(this);
-
-        if (!fromDeserialization) {
-            _lifeEventManager = new LifecycleEventManager();
-            _transEventManager = new TransactionEventManager();
-            int cmode = _conf.getMetaDataRepositoryInstance().
-                getMetaDataFactory().getDefaults().getCallbackMode();
-            setLifecycleListenerCallbackMode(cmode);
-            setTransactionListenerCallbackMode(cmode);
-
-            // setup default options
-            _factory.configureBroker(this);
-        }
-
-        // make sure to do this after configuring broker so that store manager
-        // can look to broker configuration; we set both store and lock managers
-        // before initializing them because they may each try to access the
-        // other in thier initialization
-        _store = sm;
-        _lm = _conf.newLockManagerInstance();
-        _im = _conf.newInverseManagerInstance();
-        _spm = _conf.getSavepointManagerInstance();
-        _store.setContext(this);
-        _lm.setContext(this);
-
-        if (_connRetainMode == CONN_RETAIN_ALWAYS)
-            retainConnection();
-        if (!fromDeserialization) {
-            _fc = _store.newFetchConfiguration();
-            _fc.setContext(this);
-        }
-
-        // synch with the global transaction in progress, if any
-        if (_factory.syncWithManagedTransaction(this, false))
-            beginInternal();
-    }
-
-    private void initializeOperatingSet() {
-        _operating = MapBackedSet.decorate(new IdentityMap());
-    }
-    
-    /**
-     * Gets the unmodifiable set of instances being operated.
-     */
-    protected Set getOperatingSet() {
-    	return Collections.unmodifiableSet(_operating);
-    }
-
-    public Object clone()
-        throws CloneNotSupportedException {
-        if (_initializeWasInvoked)
-            throw new CloneNotSupportedException();
-        else {
-            return super.clone();
-        }
-    }
-
-    /**
-     * Create a {@link Map} to be used for the primary managed object cache.
-     * Maps oids to state managers. By default, this creates a
-     * {@link ReferenceMap} with soft values.
-     */
-    protected Map newManagedObjectCache() {
-        return new ReferenceHashMap(ReferenceMap.HARD, ReferenceMap.SOFT);
-    }
-
-    //////////////////////////////////
-    // Implementation of StoreContext
-    //////////////////////////////////
-
-    public Broker getBroker() {
-        return this;
-    }
-
-    //////////////
-    // Properties
-    //////////////
-
-    public void setImplicitBehavior(OpCallbacks call,
-        RuntimeExceptionTranslator ex) {
-        if (_call == null)
-            _call = call;
-        if (_extrans == null)
-            _extrans = ex;
-    }
-
-    RuntimeExceptionTranslator getInstanceExceptionTranslator() {
-        return (_operationCount == 0) ? _extrans : null;
-    }
-
-    public BrokerFactory getBrokerFactory() {
-        return _factory;
-    }
-
-    public OpenJPAConfiguration getConfiguration() {
-        return _conf;
-    }
-
-    public FetchConfiguration getFetchConfiguration() {
-        return _fc;
-    }
-
-    public FetchConfiguration pushFetchConfiguration() {
-        if (_fcs == null)
-            _fcs = new LinkedList();
-        _fcs.add(_fc);
-        _fc = (FetchConfiguration) _fc.clone();
-        return _fc;
-    }
-
-    public void popFetchConfiguration() {
-        if (_fcs == null || _fcs.isEmpty())
-            throw new UserException(_loc.get("fetch-configuration-stack-empty"));
-        _fc = (FetchConfiguration) _fcs.removeLast();
-    }
-
-    public int getConnectionRetainMode() {
-        return _connRetainMode;
-    }
-
-    public boolean isManaged() {
-        return _managed;
-    }
-
-    public ManagedRuntime getManagedRuntime() {
-        return _runtime;
-    }
-
-    public ClassLoader getClassLoader() {
-        return _loader;
-    }
-
-    public DelegatingStoreManager getStoreManager() {
-        return _store;
-    }
-
-    public LockManager getLockManager() {
-        return _lm;
-    }
-
-    public InverseManager getInverseManager() {
-        return _im;
-    }
-
-    public String getConnectionUserName() {
-        return _user;
-    }
-
-    public String getConnectionPassword() {
-        return _pass;
-    }
-
-    public boolean getMultithreaded() {
-        return _multithreaded;
-    }
-
-    public void setMultithreaded(boolean multithreaded) {
-        assertOpen();
-        _multithreaded = multithreaded;
-        if (multithreaded && _lock == null)
-            _lock = new ReentrantLock();
-        else if (!multithreaded)
-            _lock = null;
-    }
-
-    public boolean getIgnoreChanges() {
-        return _ignoreChanges;
-    }
-
-    public void setIgnoreChanges(boolean val) {
-        assertOpen();
-        _ignoreChanges = val;
-    }
-
-    public boolean getNontransactionalRead() {
-        return _nontransRead;
-    }
-
-    public void setNontransactionalRead(boolean val) {
-        assertOpen();
-        if ((_flags & FLAG_PRESTORING) != 0)
-            throw new UserException(_loc.get("illegal-op-in-prestore"));
-
-        // make sure the runtime supports it
-        if (val && !_conf.supportedOptions().contains
-            (_conf.OPTION_NONTRANS_READ))
-            throw new UnsupportedException(_loc.get
-                ("nontrans-read-not-supported"));
-
-        _nontransRead = val;
-    }
-
-    public boolean getNontransactionalWrite() {
-        return _nontransWrite;
-    }
-
-    public void setNontransactionalWrite(boolean val) {
-        assertOpen();
-        if ((_flags & FLAG_PRESTORING) != 0)
-            throw new UserException(_loc.get("illegal-op-in-prestore"));
-
-        _nontransWrite = val;
-    }
-
-    public boolean getOptimistic() {
-        return _optimistic;
-    }
-
-    public void setOptimistic(boolean val) {
-        assertOpen();
-        if ((_flags & FLAG_ACTIVE) != 0)
-            throw new InvalidStateException(_loc.get("trans-active",
-                "Optimistic"));
-
-        // make sure the runtime supports it
-        if (val && !_conf.supportedOptions().contains(_conf.OPTION_OPTIMISTIC))
-            throw new UnsupportedException(_loc.get
-                ("optimistic-not-supported"));
-
-        _optimistic = val;
-    }
-
-    public int getRestoreState() {
-        return _restoreState;
-    }
-
-    public void setRestoreState(int val) {
-        assertOpen();
-        if ((_flags & FLAG_ACTIVE) != 0)
-            throw new InvalidStateException(_loc.get("trans-active",
-                "Restore"));
-
-        _restoreState = val;
-    }
-
-    public boolean getRetainState() {
-        return _retainState;
-    }
-
-    public void setRetainState(boolean val) {
-        assertOpen();
-        if ((_flags & FLAG_PRESTORING) != 0)
-            throw new UserException(_loc.get("illegal-op-in-prestore"));
-        _retainState = val;
-    }
-
-    public int getAutoClear() {
-        return _autoClear;
-    }
-
-    public void setAutoClear(int val) {
-        assertOpen();
-        _autoClear = val;
-    }
-
-    public int getAutoDetach() {
-        return _autoDetach;
-    }
-
-    public void setAutoDetach(int detachFlags) {
-        assertOpen();
-        _autoDetach = detachFlags;
-    }
-
-    public void setAutoDetach(int detachFlag, boolean on) {
-        assertOpen();
-        if (on)
-            _autoDetach |= detachFlag;
-        else
-            _autoDetach &= ~detachFlag;
-    }
-
-    public int getDetachState() {
-        return _detachState;
-    }
-
-    public void setDetachState(int mode) {
-        assertOpen();
-        _detachState = mode;
-    }
-
-    public boolean isDetachedNew() {
-        return _detachedNew;
-    }
-
-    public void setDetachedNew(boolean isNew) {
-        assertOpen();
-        _detachedNew = isNew;
-    }
-
-    public boolean getSyncWithManagedTransactions() {
-        return _syncManaged;
-    }
-
-    public void setSyncWithManagedTransactions(boolean sync) {
-        assertOpen();
-        _syncManaged = sync;
-    }
-
-    public boolean getEvictFromDataCache() {
-        return _evictDataCache;
-    }
-
-    public void setEvictFromDataCache(boolean evict) {
-        assertOpen();
-        _evictDataCache = evict;
-    }
-
-    public boolean getPopulateDataCache() {
-        return _populateDataCache;
-    }
-
-    public void setPopulateDataCache(boolean cache) {
-        assertOpen();
-        _populateDataCache = cache;
-    }
-
-    public boolean isTrackChangesByType() {
-        return _largeTransaction;
-    }
-
-    public void setTrackChangesByType(boolean largeTransaction) {
-        assertOpen();
-        _largeTransaction = largeTransaction;
-    }
-
-    public Object getUserObject(Object key) {
-        beginOperation(false);
-        try {
-            return (_userObjects == null) ? null : _userObjects.get(key);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Object putUserObject(Object key, Object val) {
-        beginOperation(false);
-        try {
-            if (val == null)
-                return (_userObjects == null) ? null : _userObjects.remove(key);
-
-            if (_userObjects == null)
-                _userObjects = new HashMap();
-            return _userObjects.put(key, val);
-        } finally {
-            endOperation();
-        }
-    }
-
-    //////////
-    // Events
-    //////////
-
-    public void addLifecycleListener(Object listener, Class[] classes) {
-        beginOperation(false);
-        try {
-            _lifeEventManager.addListener(listener, classes);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void removeLifecycleListener(Object listener) {
-        beginOperation(false);
-        try {
-            _lifeEventManager.removeListener(listener);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public int getLifecycleListenerCallbackMode() {
-        return _lifeCallbackMode;
-    }
-
-    public void setLifecycleListenerCallbackMode(int mode) {
-        beginOperation(false);
-        try {
-            _lifeCallbackMode = mode;
-            _lifeEventManager.setFailFast((mode & CALLBACK_FAIL_FAST) != 0);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Give state managers access to the lifecycle event manager.
-     */
-    public LifecycleEventManager getLifecycleEventManager() {
-        return _lifeEventManager;
-    }
-
-    /**
-     * Fire given lifecycle event, handling any exceptions appropriately.
-     *
-     * @return whether events are being processed at this time
-     */
-    boolean fireLifecycleEvent(Object src, Object related, ClassMetaData meta,
-        int eventType) {
-        if (_lifeEventManager == null)
-            return false;
-        handleCallbackExceptions(_lifeEventManager.fireEvent(src, related, 
-            meta, eventType), _lifeCallbackMode);
-        return true;
-    }
-
-    /**
-     * Take actions on callback exceptions depending on callback mode.
-     */
-    private void handleCallbackExceptions(Exception[] exceps, int mode) {
-        if (exceps.length == 0 || (mode & CALLBACK_IGNORE) != 0)
-            return;
-
-        OpenJPAException ce;
-        if (exceps.length == 1)
-            ce = new CallbackException(exceps[0]);
-        else 
-            ce = new CallbackException(_loc.get("callback-err")).
-                setNestedThrowables(exceps);
-        if ((mode & CALLBACK_ROLLBACK) != 0 && (_flags & FLAG_ACTIVE) != 0) {
-            ce.setFatal(true);
-            setRollbackOnlyInternal(ce);
-        }
-        if ((mode & CALLBACK_LOG) != 0 && _log.isWarnEnabled())
-            _log.warn(ce);
-        if ((mode & CALLBACK_RETHROW) != 0)
-            throw ce;
-    }
-
-    public void addTransactionListener(Object tl) {
-        beginOperation(false);
-        try {
-            _transEventManager.addListener(tl);
-            if (tl instanceof RemoteCommitEventManager)
-                _flags |= FLAG_REMOTE_LISTENER;
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void removeTransactionListener(Object tl) {
-        beginOperation(false);
-        try {
-            if (_transEventManager.removeListener(tl)
-                && (tl instanceof RemoteCommitEventManager))
-                _flags &= ~FLAG_REMOTE_LISTENER;
-        } finally {
-            endOperation();
-        }
-    }
-
-    public int getTransactionListenerCallbackMode() {
-        return _transCallbackMode;
-    }
-
-    public void setTransactionListenerCallbackMode(int mode) {
-        beginOperation(false);
-        try {
-            _transCallbackMode = mode;
-            _transEventManager.setFailFast((mode & CALLBACK_FAIL_FAST) != 0);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Fire given transaction event, handling any exceptions appropriately.
-     */
-    private void fireTransactionEvent(TransactionEvent trans) {
-        if (_transEventManager != null)
-            handleCallbackExceptions(_transEventManager.fireEvent(trans),
-                _transCallbackMode);
-    }
-
-    ///////////
-    // Lookups
-    ///////////
-
-    public Object find(Object oid, boolean validate, FindCallbacks call) {
-        int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
-        if (!validate)
-            flags |= OID_NOVALIDATE;
-        return find(oid, _fc, null, null, flags, call);
-    }
-
-    public Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
-        Object edata, int flags) {
-        return find(oid, fetch, exclude, edata, flags, null);
-    }
-
-    /**
-     * Internal finder.
-     */
-    protected Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
-        Object edata, int flags, FindCallbacks call) {
-        if (call == null)
-            call = this;
-        oid = call.processArgument(oid);
-        if (oid == null) {
-            if ((flags & OID_NOVALIDATE) == 0)
-                throw new ObjectNotFoundException(_loc.get("null-oid"));
-            return call.processReturn(oid, null);
-        }
-        if (fetch == null)
-            fetch = _fc;
-
-        beginOperation(true);
-        try {
-            assertNontransactionalRead();
-
-            // cached instance?
-            StateManagerImpl sm = getStateManagerImplById(oid,
-                (flags & OID_ALLOW_NEW) != 0 || hasFlushed());
-            if (sm != null) {
-                if (!requiresLoad(sm, true, fetch, edata, flags))
-                    return call.processReturn(oid, sm);
-
-                if (!sm.isLoading()) {
-                    // make sure all the configured fields are loaded; do this
-                    // after making instance transactional for locking
-                    if (!sm.isTransactional() && useTransactionalState(fetch))
-                        sm.transactional();
-                    boolean loaded;
-                    try {
-                        loaded = sm.load(fetch, StateManagerImpl.LOAD_FGS, 
-                            exclude, edata, false);
-                    } catch (ObjectNotFoundException onfe) {
-                        if ((flags & OID_NODELETED) != 0
-                            || (flags & OID_NOVALIDATE) != 0)
-                            throw onfe;
-                        return call.processReturn(oid, null);
-                    }
-
-                    // if no data needed to be loaded and the user wants to
-                    // validate, just make sure the object exists
-                    if (!loaded && (flags & OID_NOVALIDATE) == 0
-                        && _compat.getValidateTrueChecksStore()
-                        && !sm.isTransactional()
-                        && !_store.exists(sm, edata)) {
-                        if ((flags & OID_NODELETED) == 0)
-                            return call.processReturn(oid, null);
-                        throw new ObjectNotFoundException(_loc.get
-                            ("del-instance", sm.getManagedInstance(), oid)).
-                            setFailedObject(sm.getManagedInstance());
-                    }
-                }
-
-                // since the object was cached, we may need to upgrade lock
-                // if current level is higher than level of initial load
-                if ((_flags & FLAG_ACTIVE) != 0) {
-                    int level = fetch.getReadLockLevel();
-                    _lm.lock(sm, level, fetch.getLockTimeout(), edata);
-                    sm.readLocked(level, fetch.getWriteLockLevel());
-                }
-                return call.processReturn(oid, sm);
-            }
-
-            // if there's no cached sm for a new/transient id type, we
-            // it definitely doesn't exist
-            if (oid instanceof StateManagerId)
-                return call.processReturn(oid, null);
-
-            // initialize a new state manager for the datastore instance
-            sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
-            boolean load = requiresLoad(sm, false, fetch, edata, flags);
-            sm = initialize(sm, load, fetch, edata);
-            if (sm == null) {
-                if ((flags & OID_NOVALIDATE) != 0)
-                    throw new ObjectNotFoundException(oid);
-                return call.processReturn(oid, null);
-            }
-
-            // make sure all configured fields were loaded
-            if (load) {
-                try {
-                    sm.load(fetch, StateManagerImpl.LOAD_FGS, exclude,
-                        edata, false);
-                } catch (ObjectNotFoundException onfe) {
-                    if ((flags & OID_NODELETED) != 0
-                        || (flags & OID_NOVALIDATE) != 0)
-                        throw onfe;
-                    return call.processReturn(oid, null);
-                }
-            }
-            return call.processReturn(oid, sm);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Initialize a newly-constructed state manager.
-     */
-    protected StateManagerImpl initialize(StateManagerImpl sm, boolean load,
-        FetchConfiguration fetch, Object edata) {
-        if (!load) {
-            sm.initialize(sm.getMetaData().getDescribedType(),
-                PCState.HOLLOW);
-        } else {
-            PCState state = (useTransactionalState(fetch))
-                ? PCState.PCLEAN : PCState.PNONTRANS;
-            sm.setLoading(true);
-            try {
-                if (!_store.initialize(sm, state, fetch, edata))
-                    return null;
-            } finally {
-                sm.setLoading(false);
-            }
-        }
-        return sm;
-    }
-
-    public Object[] findAll(Collection oids, boolean validate,
-        FindCallbacks call) {
-        int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
-        if (!validate)
-            flags |= OID_NOVALIDATE;
-        return findAll(oids, _fc, null, null, flags, call);
-    }
-
-    public Object[] findAll(Collection oids, FetchConfiguration fetch,
-        BitSet exclude, Object edata, int flags) {
-        return findAll(oids, fetch, exclude, edata, flags, null);
-    }
-
-    /**
-     * Internal finder.
-     */
-    protected Object[] findAll(Collection oids, FetchConfiguration fetch,
-        BitSet exclude, Object edata, int flags, FindCallbacks call) {
-        findAllDepth ++;
-
-        // throw any exceptions for null oids up immediately
-        if (oids == null)
-            throw new NullPointerException("oids == null");
-        if ((flags & OID_NOVALIDATE) != 0 && oids.contains(null))
-            throw new UserException(_loc.get("null-oids"));
-
-        // we have to use a map of oid->sm rather than a simple
-        // array, so that we make sure not to create multiple sms for equivalent
-        // oids if the user has duplicates in the given array
-        if (_loading == null)
-            _loading = new HashMap((int) (oids.size() * 1.33 + 1));
-
-        if (call == null)
-            call = this;
-        if (fetch == null)
-            fetch = _fc;
-
-        beginOperation(true);
-        try {
-            assertNontransactionalRead();
-
-            // collection of state managers to pass to store manager
-            List load = null;
-            StateManagerImpl sm;
-            boolean initialized;
-            boolean transState = useTransactionalState(fetch);
-            Object obj, oid;
-            int idx = 0;
-            for (Iterator itr = oids.iterator(); itr.hasNext(); idx++) {
-                // if we've already seen this oid, skip repeats
-                obj = itr.next();
-                oid = call.processArgument(obj);
-                if (oid == null || _loading.containsKey(obj))
-                    continue;
-
-                // if we don't have a cached instance or it is not transactional
-                // and is hollow or we need to validate, load it
-                sm = getStateManagerImplById(oid, (flags & OID_ALLOW_NEW) != 0
-                    || hasFlushed());
-                initialized = sm != null;
-                if (!initialized)
-                    sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
-
-                _loading.put(obj, sm);
-                if (requiresLoad(sm, initialized, fetch, edata, flags)) {
-                    transState = transState || useTransactionalState(fetch);
-                    if (initialized && !sm.isTransactional() && transState)
-                        sm.transactional();
-                    if (load == null)
-                        load = new ArrayList(oids.size() - idx);
-                    load.add(sm);
-                } else if (!initialized)
-                    sm.initialize(sm.getMetaData().getDescribedType(),
-                        PCState.HOLLOW);
-            }
-
-            // pass all state managers in need of loading or validation to the
-            // store manager
-            if (load != null) {
-                PCState state = (transState) ? PCState.PCLEAN
-                    : PCState.PNONTRANS;
-                Collection failed = _store.loadAll(load, state,
-                    StoreManager.FORCE_LOAD_NONE, fetch, edata);
-
-                // set failed instances to null
-                if (failed != null && !failed.isEmpty()) {
-                    if ((flags & OID_NOVALIDATE) != 0)
-                        throw newObjectNotFoundException(failed);
-                    for (Iterator itr = failed.iterator(); itr.hasNext();)
-                        _loading.put(itr.next(), null);
-                }
-            }
-
-            // create results array; make sure all configured fields are
-            // loaded in each instance
-            Object[] results = new Object[oids.size()];
-            boolean active = (_flags & FLAG_ACTIVE) != 0;
-            int level = fetch.getReadLockLevel();
-            idx = 0;
-            for (Iterator itr = oids.iterator(); itr.hasNext(); idx++) {
-                oid = itr.next();
-                sm = (StateManagerImpl) _loading.get(oid);
-                if (sm != null && requiresLoad(sm, true, fetch, edata, flags)) {
-                    try {
-                        sm.load(fetch, StateManagerImpl.LOAD_FGS,
-                        	exclude, edata, false);
-                        if (active) {
-                            _lm.lock(sm, level, fetch.getLockTimeout(), edata);
-                            sm.readLocked(level, fetch.getWriteLockLevel());
-                        }
-                    }
-                    catch (ObjectNotFoundException onfe) {
-                        if ((flags & OID_NODELETED) != 0
-                            || (flags & OID_NOVALIDATE) != 0)
-                            throw onfe;
-                        sm = null;
-                    }
-                }
-                results[idx] = call.processReturn(oid, sm);
-            }
-            return results;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            findAllDepth--;
-            if (findAllDepth == 0)
-                _loading = null;
-            endOperation();
-        }
-    }
-
-    private boolean hasFlushed() {
-        return (_flags & FLAG_FLUSHED) != 0;
-    }
-
-    /**
-     * Return whether the given instance needs loading before being returned
-     * to the user.
-     */
-    private boolean requiresLoad(OpenJPAStateManager sm, boolean initialized,
-        FetchConfiguration fetch, Object edata, int flags) {
-        if (!fetch.requiresLoad())
-            return false;
-        if ((flags & OID_NOVALIDATE) == 0)
-            return true;
-        if (edata != null) // take advantage of existing result
-            return true;
-        if (initialized && sm.getPCState() != PCState.HOLLOW)
-            return false;
-        if (!initialized && sm.getMetaData().getPCSubclasses().length > 0)
-            return true;
-        return !_compat.getValidateFalseReturnsHollow();
-    }
-
-    /**
-     * Return whether to use a transactional state.
-     */
-    private boolean useTransactionalState(FetchConfiguration fetch) {
-        return (_flags & FLAG_ACTIVE) != 0 && (!_optimistic
-            || _autoClear == CLEAR_ALL
-            || fetch.getReadLockLevel() != LOCK_NONE);
-    }
-
-    public Object findCached(Object oid, FindCallbacks call) {
-        if (call == null)
-            call = this;
-        oid = call.processArgument(oid);
-        if (oid == null)
-            return call.processReturn(oid, null);
-
-        beginOperation(true);
-        try {
-            StateManagerImpl sm = getStateManagerImplById(oid, true);
-            return call.processReturn(oid, sm);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Class getObjectIdType(Class cls) {
-        if (cls == null)
-            return null;
-
-        beginOperation(false);
-        try {
-            ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
-                getMetaData(cls, _loader, false);
-            if (meta == null
-                || meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
-                return null;
-            if (meta.getIdentityType() == ClassMetaData.ID_APPLICATION)
-                return meta.getObjectIdType();
-
-            return _store.getDataStoreIdType(meta);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Object newObjectId(Class cls, Object val) {
-        if (val == null)
-            return null;
-
-        beginOperation(false);
-        try {
-            ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
-                getMetaData(cls, _loader, true);
-            switch (meta.getIdentityType()) {
-            case ClassMetaData.ID_DATASTORE:
-                // delegate to store manager for datastore ids
-                if (val instanceof String
-                    && ((String) val).startsWith(StateManagerId.STRING_PREFIX))
-                    return new StateManagerId((String) val);
-                return _store.newDataStoreId(val, meta);
-            case ClassMetaData.ID_APPLICATION:
-                if (ImplHelper.isAssignable(meta.getObjectIdType(), 
-                    val.getClass())) {
-                    if (!meta.isOpenJPAIdentity() 
-                        && meta.isObjectIdTypeShared())
-                        return new ObjectId(cls, val);
-                    return val;
-                }
-
-                // stringified app id?
-                if (val instanceof String 
-                    && !_conf.getCompatibilityInstance().
-                        getStrictIdentityValues()
-                    && !Modifier.isAbstract(cls.getModifiers()))
-                    return PCRegistry.newObjectId(cls, (String) val);
-
-                Object[] arr = (val instanceof Object[]) ? (Object[]) val
-                    : new Object[]{ val };
-                return ApplicationIds.fromPKValues(arr, meta);
-            default:
-                throw new UserException(_loc.get("meta-unknownid", cls));
-            }
-        } catch (IllegalArgumentException iae) {
-        	throw new UserException(_loc.get("bad-id-value", val,
-                val.getClass().getName(), cls)).setCause(iae);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (ClassCastException cce) {
-            throw new UserException(_loc.get("bad-id-value", val,
-                val.getClass().getName(), cls)).setCause(cce);
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Create a new state manager for the given oid.
-     */
-    private StateManagerImpl newStateManagerImpl(Object oid, boolean copy) {
-        // see if we're in the process of loading this oid in a loadAll call
-        StateManagerImpl sm;
-        if (_loading != null) {
-            sm = (StateManagerImpl) _loading.get(oid);
-            if (sm != null && sm.getPersistenceCapable() == null)
-                return sm;
-        }
-
-        // find metadata for the oid
-        Class pcType = _store.getManagedType(oid);
-        MetaDataRepository repos = _conf.getMetaDataRepositoryInstance();
-        ClassMetaData meta;
-        if (pcType != null)
-            meta = repos.getMetaData(pcType, _loader, true);
-        else
-            meta = repos.getMetaData(oid, _loader, true);
-
-        // copy the oid if needed
-        if (copy && _compat.getCopyObjectIds()) {
-            if (meta.getIdentityType() == ClassMetaData.ID_APPLICATION)
-                oid = ApplicationIds.copy(oid, meta);
-            else if (meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
-                throw new UserException(_loc.get("meta-unknownid", meta));
-            else
-                oid = _store.copyDataStoreId(oid, meta);
-        }
-
-        sm = newStateManagerImpl(oid, meta);
-        sm.setObjectId(oid);
-        return sm;
-    }
-
-    /**
-     * Create a state manager for the given oid and metadata.
-     */
-    protected StateManagerImpl newStateManagerImpl(Object oid,
-        ClassMetaData meta) {
-        return new StateManagerImpl(oid, meta, this);
-    }
-
-    ///////////////
-    // Transaction
-    ///////////////
-
-    public void begin() {
-        beginOperation(true);
-        try {
-            if ((_flags & FLAG_ACTIVE) != 0)
-                throw new InvalidStateException(_loc.get("active"));
-            _factory.syncWithManagedTransaction(this, true);
-            beginInternal();
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Notify the store manager of a transaction.
-     */
-    private void beginInternal() {
-        try {
-            beginStoreManagerTransaction(_optimistic);
-            _flags |= FLAG_ACTIVE;
-
-            // start locking
-            if (!_optimistic) {
-                _fc.setReadLockLevel(_conf.getReadLockLevelConstant());
-                _fc.setWriteLockLevel(_conf.getWriteLockLevelConstant());
-                _fc.setLockTimeout(_conf.getLockTimeout());
-            }
-            _lm.beginTransaction();
-
-            if (_transEventManager.hasBeginListeners())
-                fireTransactionEvent(new TransactionEvent(this,
-                    TransactionEvent.AFTER_BEGIN, null, null, null, null));
-        } catch (OpenJPAException ke) {
-            // if we already started the transaction, don't let it commit
-            if ((_flags & FLAG_ACTIVE) != 0)
-                setRollbackOnlyInternal(ke);
-            throw ke.setFatal(true);
-        } catch (RuntimeException re) {
-            // if we already started the transaction, don't let it commit
-            if ((_flags & FLAG_ACTIVE) != 0)
-                setRollbackOnlyInternal(re);
-            throw new StoreException(re).setFatal(true);
-        }
-
-        if (_pending != null) {
-            StateManagerImpl sm;
-            for (Iterator it = _pending.iterator(); it.hasNext();) {
-                sm = (StateManagerImpl) it.next();
-                sm.transactional();
-                if (sm.isDirty())
-                    setDirty(sm, true);
-            }
-            _pending = null;
-        }
-    }
-
-    public void beginStore() {
-        beginOperation(true);
-        try {
-            assertTransactionOperation();
-            if ((_flags & FLAG_STORE_ACTIVE) == 0)
-                beginStoreManagerTransaction(false);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new StoreException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Begin a store manager transaction.
-     */
-    private void beginStoreManagerTransaction(boolean optimistic) {
-        if (!optimistic) {
-            retainConnection();
-            _store.begin();
-            _flags |= FLAG_STORE_ACTIVE;
-        } else {
-            if (_connRetainMode == CONN_RETAIN_TRANS)
-                retainConnection();
-            _store.beginOptimistic();
-        }
-    }
-
-    /**
-     * End the current store manager transaction. Throws an
-     * exception to signal a forced rollback after failed commit, otherwise
-     * returns any exception encountered during the end process.
-     */
-    private RuntimeException endStoreManagerTransaction(boolean rollback) {
-        boolean forcedRollback = false;
-        boolean releaseConn = false;
-        RuntimeException err = null;
-        try {
-            if ((_flags & FLAG_STORE_ACTIVE) != 0) {
-                releaseConn = _connRetainMode != CONN_RETAIN_ALWAYS;
-                if (rollback)
-                    _store.rollback();
-                else
-                    _store.commit();
-            } else {
-                releaseConn = _connRetainMode == CONN_RETAIN_TRANS;
-                _store.rollbackOptimistic();
-            }
-        }
-        catch (RuntimeException re) {
-            if (!rollback) {
-                forcedRollback = true;
-                try { _store.rollback(); } catch (RuntimeException re2) {}
-            }
-            err = re;
-        } finally {
-            _flags &= ~FLAG_STORE_ACTIVE;
-        }
-
-        if (releaseConn) {
-            try {
-                releaseConnection();
-            } catch (RuntimeException re) {
-                if (err == null)
-                    err = re;
-            }
-        }
-
-        if (forcedRollback)
-            throw err;
-        return err;
-    }
-
-    public void commit() {
-        beginOperation(false);
-        try {
-            assertTransactionOperation();
-
-            javax.transaction.Transaction trans =
-                _runtime.getTransactionManager().getTransaction();
-            if (trans == null)
-                throw new InvalidStateException(_loc.get("null-trans"));
-
-            // this commit on the transaction will cause our
-            // beforeCompletion method to be invoked
-            trans.commit();
-        } catch (OpenJPAException ke) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), ke);
-            throw ke;
-        } catch (Exception e) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), e);
-            throw new StoreException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void rollback() {
-        beginOperation(false);
-        try {
-            assertTransactionOperation();
-
-            javax.transaction.Transaction trans =
-                _runtime.getTransactionManager().getTransaction();
-            if (trans != null)
-                trans.rollback();
-        } catch (OpenJPAException ke) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), ke);
-            throw ke;
-        } catch (Exception e) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), e);
-            throw new StoreException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public boolean syncWithManagedTransaction() {
-        assertOpen();
-        lock();
-        try {
-            if ((_flags & FLAG_ACTIVE) != 0)
-                return true;
-            if (!_managed)
-                throw new InvalidStateException(_loc.get("trans-not-managed"));
-            if (_factory.syncWithManagedTransaction(this, false)) {
-                beginInternal();
-                return true;
-            }
-            return false;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void commitAndResume() {
-        endAndResume(true);
-    }
-
-    public void rollbackAndResume() {
-        endAndResume(false);
-    }
-
-    private void endAndResume(boolean commit) {
-        beginOperation(false);
-        try {
-            if (commit)
-                commit();
-            else
-                rollback();
-            begin();
-        } finally {
-            endOperation();
-        }
-    }
-
-    public boolean getRollbackOnly() {
-        beginOperation(true);
-        try {
-            if ((_flags & FLAG_ACTIVE) == 0)
-                return false;
-
-            javax.transaction.Transaction trans =
-                _runtime.getTransactionManager().getTransaction();
-            if (trans == null)
-                return false;
-            return trans.getStatus() == Status.STATUS_MARKED_ROLLBACK;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Throwable getRollbackCause() {
-        beginOperation(true);
-        try {
-            if ((_flags & FLAG_ACTIVE) == 0)
-                return null;
-
-            javax.transaction.Transaction trans =
-                _runtime.getTransactionManager().getTransaction();
-            if (trans == null)
-                return null;
-            if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
-                return _runtime.getRollbackCause();
-
-            return null;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void setRollbackOnly() {
-        setRollbackOnly(new UserException());
-    }
-
-    public void setRollbackOnly(Throwable cause) {
-        beginOperation(true);
-        try {
-            assertTransactionOperation();
-            setRollbackOnlyInternal(cause);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Mark the current transaction as rollback-only.
-     */
-    private void setRollbackOnlyInternal(Throwable cause) {
-        try {
-            javax.transaction.Transaction trans =
-                _runtime.getTransactionManager().getTransaction();
-            if (trans == null)
-                throw new InvalidStateException(_loc.get("null-trans"));
-            // ensure tran is in a valid state to accept the setRollbackOnly
-            int tranStatus = trans.getStatus();
-            if ((tranStatus != Status.STATUS_NO_TRANSACTION)
-                    && (tranStatus != Status.STATUS_ROLLEDBACK)
-                    && (tranStatus != Status.STATUS_COMMITTED))
-                _runtime.setRollbackOnly(cause);
-            else if (_log.isTraceEnabled())
-                _log.trace(_loc.get("invalid-tran-status", new Integer(
-                        tranStatus), "setRollbackOnly"));
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        }
-    }
-
-    public void setSavepoint(String name) {
-        beginOperation(true);
-        try {
-            assertActiveTransaction();
-            if (_savepoints != null && _savepoints.containsKey(name))
-                throw new UserException(_loc.get("savepoint-exists", name));
-
-            if (hasFlushed() && !_spm.supportsIncrementalFlush())
-                throw new UnsupportedException(_loc.get
-                    ("savepoint-flush-not-supported"));
-
-            OpenJPASavepoint save = _spm.newSavepoint(name, this);
-            if (_savepoints == null || _savepoints.isEmpty()) {
-                save.save(getTransactionalStates());
-                _savepoints = new LinkedMap();
-            } else {
-                if (_savepointCache == null)
-                    save.save(Collections.EMPTY_LIST);
-                else {
-                    save.save(_savepointCache);
-                    _savepointCache.clear();
-                }
-            }
-            _savepoints.put(name, save);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void releaseSavepoint() {
-        beginOperation(false);
-        try {
-            if (_savepoints == null || _savepoints.isEmpty())
-                throw new UserException(_loc.get("no-lastsavepoint"));
-            releaseSavepoint((String) _savepoints.get
-                (_savepoints.size() - 1));
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void releaseSavepoint(String savepoint) {
-        beginOperation(false);
-        try {
-            assertActiveTransaction();
-
-            int index = (_savepoints == null) ? -1
-                : _savepoints.indexOf(savepoint);
-            if (index < 0)
-                throw new UserException(_loc.get("no-savepoint", savepoint));
-
-            // clear old in reverse
-            OpenJPASavepoint save;
-            while (_savepoints.size() > index + 1) {
-                save = (OpenJPASavepoint) _savepoints.remove
-                    (_savepoints.size() - 1);
-                save.release(false);
-            }
-
-            save = (OpenJPASavepoint) _savepoints.remove(index);
-            save.release(true);
-            if (_savepointCache != null)
-                _savepointCache.clear();
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void rollbackToSavepoint() {
-        beginOperation(false);
-        try {
-            if (_savepoints == null || _savepoints.isEmpty())
-                throw new UserException(_loc.get("no-lastsavepoint"));
-            rollbackToSavepoint((String) _savepoints.get
-                (_savepoints.size() - 1));
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void rollbackToSavepoint(String savepoint) {
-        beginOperation(false);
-        try {
-            assertActiveTransaction();
-
-            int index = (_savepoints == null) ? -1
-                : _savepoints.indexOf(savepoint);
-            if (index < 0)
-                throw new UserException(_loc.get("no-savepoint", savepoint));
-
-            // clear old in reverse
-            OpenJPASavepoint save;
-            while (_savepoints.size() > index + 1) {
-                save = (OpenJPASavepoint) _savepoints.remove
-                    (_savepoints.size() - 1);
-                save.release(false);
-            }
-
-            save = (OpenJPASavepoint) _savepoints.remove(index);
-            Collection saved = save.rollback(_savepoints.values());
-            if (_savepointCache != null)
-                _savepointCache.clear();
-            if (hasTransactionalObjects()) {
-                // build up a new collection of states
-                TransactionalCache oldTransCache = _transCache;
-                TransactionalCache newTransCache = new TransactionalCache
-                    (_orderDirty);
-                _transCache = null;
-
-                // currently there is the assumption that incremental
-                // flush is either a) not allowed, or b) required
-                // pre-savepoint.  this solves a number of issues including
-                // storing flushed states as well as OID handling.
-                // if future plugins do not follow this, we need to cache
-                // more info per state
-                SavepointFieldManager fm;
-                StateManagerImpl sm;
-                for (Iterator itr = saved.iterator(); itr.hasNext();) {
-                    fm = (SavepointFieldManager) itr.next();
-                    sm = fm.getStateManager();
-                    sm.rollbackToSavepoint(fm);
-                    oldTransCache.remove(sm);
-                    if (sm.isDirty())
-                        newTransCache.addDirty(sm);
-                    else
-                        newTransCache.addClean(sm);
-                }
-                for (Iterator itr = oldTransCache.iterator(); itr.hasNext();) {
-                    sm = (StateManagerImpl) itr.next();
-                    sm.rollback();
-                    removeFromTransaction(sm);
-                }
-                _transCache = newTransCache;
-            }
-        }
-        catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void flush() {
-        beginOperation(true);
-        try {
-            // return silently if no trans is active, or if this is a reentrant
-            // call, which can happen if the store manager tries to get an
-            // auto-inc oid during flush
-            if ((_flags & FLAG_ACTIVE) == 0
-                || (_flags & FLAG_STORE_FLUSHING) != 0)
-                return;
-
-            // make sure the runtime supports it
-            if (!_conf.supportedOptions().contains(_conf.OPTION_INC_FLUSH))
-                throw new UnsupportedException(_loc.get
-                    ("incremental-flush-not-supported"));
-            if (_savepoints != null && !_savepoints.isEmpty()
-                && !_spm.supportsIncrementalFlush())
-                throw new UnsupportedException(_loc.get
-                    ("savepoint-flush-not-supported"));
-
-            try {
-                flushSafe(FLUSH_INC);
-                _flags |= FLAG_FLUSHED;
-            } catch (OpenJPAException ke) {
-                // rollback on flush error; objects may be in inconsistent state
-                setRollbackOnly(ke);
-                throw ke.setFatal(true);
-            } catch (RuntimeException re) {
-                // rollback on flush error; objects may be in inconsistent state
-                setRollbackOnly(re);
-                throw new StoreException(re).setFatal(true);
-            }
-        }
-        finally {
-            endOperation();
-        }
-    }
-
-    public void preFlush() {
-        beginOperation(true);
-        try {
-            if ((_flags & FLAG_ACTIVE) != 0)
-                flushSafe(FLUSH_LOGICAL);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void validateChanges() {
-        beginOperation(true);
-        try {
-            // if no trans, just return; if active datastore trans, flush
-            if ((_flags & FLAG_ACTIVE) == 0)
-                return;
-            if ((_flags & FLAG_STORE_ACTIVE) != 0) {
-                flush();
-                return;
-            }
-
-            // make sure the runtime supports inc flush
-            if (!_conf.supportedOptions().contains(_conf.OPTION_INC_FLUSH))
-                throw new UnsupportedException(_loc.get
-                    ("incremental-flush-not-supported"));
-
-            try {
-                flushSafe(FLUSH_ROLLBACK);
-            } catch (OpenJPAException ke) {
-                throw ke;
-            } catch (RuntimeException re) {
-                throw new StoreException(re);
-            }
-        }
-        finally {
-            endOperation();
-        }
-    }
-
-    public boolean isActive() {
-        beginOperation(true);
-        try {
-            return (_flags & FLAG_ACTIVE) != 0;
-        } finally {
-            endOperation();
-        }
-    }
-
-    public boolean isStoreActive() {
-        // we need to lock here, because we might be in the middle of an
-        // atomic transaction process (e.g., commitAndResume)
-        beginOperation(true);
-        try {
-            return (_flags & FLAG_STORE_ACTIVE) != 0;
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Return whether the current transaction is ending, i.e. in the 2nd phase
-     * of a commit or rollback
-     */
-    boolean isTransactionEnding() {
-        return (_flags & FLAG_TRANS_ENDING) != 0;
-    }
-
-    public boolean beginOperation(boolean syncTrans) {
-        lock();
-        try {
-            assertOpen();
-
-            if (syncTrans && _operationCount == 0 && _syncManaged
-                && (_flags & FLAG_ACTIVE) == 0)
-                syncWithManagedTransaction();
-            return _operationCount++ == 1;
-        } catch (OpenJPAException ke) {
-            unlock();
-            throw ke;
-        } catch (RuntimeException re) {
-            unlock();
-            throw new GeneralException(re);
-        }
-    }
-
-    /**
-     * Mark the operation over. If outermost caller of stack, returns true
-     * and will detach managed instances if necessary.
-     */
-    public boolean endOperation() {
-        try {
-            if (_operationCount == 1 && (_autoDetach & DETACH_NONTXREAD) != 0
-                && (_flags & FLAG_ACTIVE) == 0) {
-                detachAllInternal(null);
-            }
-            if (_operationCount < 1)
-                throw new InternalException(_loc.get("multi-threaded-access"));
-            return _operationCount == 1;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            _operationCount--;
-            if (_operationCount == 0)
-                initializeOperatingSet();
-            unlock();
-        }
-    }
-
-    public Synchronization getSynchronization() {
-        return _sync;
-    }
-
-    public void setSynchronization(Synchronization sync) {
-        assertOpen();
-        _sync = sync;
-    }
-
-    ///////////////////////////////////////////////
-    // Implementation of Synchronization interface
-    ///////////////////////////////////////////////
-
-    public void beforeCompletion() {
-        beginOperation(false);
-        try {
-            // user-supplied synchronization
-            if (_sync != null)
-                _sync.beforeCompletion();
-
-            flushSafe(FLUSH_COMMIT);
-        } catch (OpenJPAException ke) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), ke);
-            throw translateManagedCompletionException(ke);
-        } catch (RuntimeException re) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), re);
-            throw translateManagedCompletionException(new StoreException(re));
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void afterCompletion(int status) {
-        beginOperation(false);
-        try {
-            assertActiveTransaction();
-
-            _flags |= FLAG_TRANS_ENDING;
-            endTransaction(status);
-            if (_sync != null)
-                _sync.afterCompletion(status);
-
-            if ((_autoDetach & DETACH_COMMIT) != 0)
-                detachAllInternal(null);
-            else if (status == Status.STATUS_ROLLEDBACK 
-                && (_autoDetach & DETACH_ROLLBACK) != 0) {
-                detachAllInternal(null);
-            }
-
-            // in an ee context, it's possible that the user tried to close
-            // us but we didn't actually close because we were waiting on this
-            // transaction; if that's true, then close now
-            if ((_flags & FLAG_CLOSE_INVOKED) != 0
-                && _compat.getCloseOnManagedCommit())
-                free();
-        } catch (OpenJPAException ke) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), ke);
-            throw translateManagedCompletionException(ke);
-        } catch (RuntimeException re) {
-            if (_log.isTraceEnabled())
-                _log.trace(_loc.get("end-trans-error"), re);
-            throw translateManagedCompletionException(new StoreException(re));
-        } finally {
-            _flags &= ~FLAG_ACTIVE;
-            _flags &= ~FLAG_FLUSHED;
-            _flags &= ~FLAG_TRANS_ENDING;
-
-            // event manager nulled if freed broker
-            if (_transEventManager != null 
-                && _transEventManager.hasEndListeners()) {
-                fireTransactionEvent(new TransactionEvent(this,
-                    status == Status.STATUS_COMMITTED
-                        ? TransactionEvent.AFTER_COMMIT_COMPLETE
-                        : TransactionEvent.AFTER_ROLLBACK_COMPLETE,
-                    null, null, null, null));
-            }
-
-            endOperation();
-        }
-    }
-
-    /**
-     * If we're in a managed transaction, use our implicit behavior exception
-     * translator to translate before/afterCompletion callback errors.
-     */
-    private RuntimeException translateManagedCompletionException
-        (RuntimeException re) {
-        return (!_managed || _extrans == null) ? re : _extrans.translate(re);
-    }
-
-    /**
-     * Flush safely, catching reentrant calls.
-     */
-    private void flushSafe(int reason) {
-        if ((_flags & FLAG_FLUSHING) != 0)
-            throw new InvalidStateException(_loc.get("reentrant-flush"));
-
-        _flags |= FLAG_FLUSHING;
-        try {
-            flush(reason);
-        } finally {
-            _flags &= ~FLAG_FLUSHING;
-        }
-    }
-
-    /**
-     * Flush the transactional state to the data store. Subclasses that
-     * customize commit behavior should override this method. The method
-     * assumes that the persistence manager is locked, is not closed,
-     * and has an active transaction.
-     *
-     * @param reason one of {@link #FLUSH_INC}, {@link #FLUSH_COMMIT},
-     * {@link #FLUSH_ROLLBACK}, or {@link #FLUSH_LOGICAL}
-     * @since 0.2.5
-     */
-    protected void flush(int reason) {
-        // this will enlist proxied states as necessary so we know whether we
-        // have anything to flush
-        Collection transactional = getTransactionalStates();
-
-        // do we actually have to flush?  only if our flags say so, or if
-        // we have transaction listeners that need to be invoked for commit
-        // (no need to invoke them on inc flush if nothing is dirty).  we
-        // special case the remote commit listener used by the datacache cause
-        // we know it doesn't require the commit event when nothing changes
-        boolean flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
-        boolean listeners = (_transEventManager.hasFlushListeners()
-            || _transEventManager.hasEndListeners())
-            && ((_flags & FLAG_REMOTE_LISTENER) == 0
-            || _transEventManager.getListeners().size() > 1);
-        if (!flush && (reason != FLUSH_COMMIT || !listeners))
-            return;
-
-        Collection mobjs = null;
-        _flags |= FLAG_PRESTORING;
-        try {
-            if (flush) {
-                // call pre store on all currently transactional objs
-                for (Iterator itr = transactional.iterator(); itr.hasNext();)
-                    ((StateManagerImpl) itr.next()).beforeFlush(reason, _call);
-                flushAdditions(transactional, reason);
-            }
-
-            // hopefully now all dependent instances that are going to end
-            // up referenced have been marked as such; delete unrefed
-            // dependents
-            _flags |= FLAG_DEREFDELETING;
-            if (flush && _derefCache != null && !_derefCache.isEmpty()) {
-                for (Iterator itr = _derefCache.iterator(); itr.hasNext();)
-                    deleteDeref((StateManagerImpl) itr.next());
-                flushAdditions(transactional, reason);
-            }
-
-            if (reason != FLUSH_LOGICAL) {
-                // if no datastore transaction, start one; even if we don't
-                // think we'll need to flush at this point, our transaction
-                // listeners might introduce some dirty objects or interact
-                // directly with the database
-                if ((_flags & FLAG_STORE_ACTIVE) == 0)
-                    beginStoreManagerTransaction(false);
-
-                if ((_transEventManager.hasFlushListeners()
-                    || _transEventManager.hasEndListeners())
-                    && (flush || reason == FLUSH_COMMIT)) {
-                    // fire events
-                    mobjs = new ManagedObjectCollection(transactional);
-                    if (reason == FLUSH_COMMIT
-                        && _transEventManager.hasEndListeners()) {
-                        fireTransactionEvent(new TransactionEvent(this, 
-                            TransactionEvent.BEFORE_COMMIT, mobjs,
-                            _persistedClss, _updatedClss, _deletedClss));
-
-                        flushAdditions(transactional, reason);
-                        flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
-                    }
-
-                    if (flush && _transEventManager.hasFlushListeners()) {
-                        fireTransactionEvent(new TransactionEvent(this, 
-                            TransactionEvent.BEFORE_FLUSH, mobjs,
-                            _persistedClss, _updatedClss, _deletedClss));
-                        flushAdditions(transactional, reason);
-                    }
-                }
-            }
-        }
-        finally {
-            _flags &= ~FLAG_PRESTORING;
-            _flags &= ~FLAG_DEREFDELETING;
-            _transAdditions = null;
-            _derefAdditions = null;
-
-            // also clear derefed set; the deletes have been recorded
-            if (_derefCache != null)
-                _derefCache = null;
-        }
-
-        // flush to store manager
-        List exceps = null;
-        try {
-            if (flush && reason != FLUSH_LOGICAL) {
-                _flags |= FLAG_STORE_FLUSHING;
-                exceps = add(exceps,
-                    newFlushException(_store.flush(transactional)));
-            }
-        } finally {
-            _flags &= ~FLAG_STORE_FLUSHING;
-
-            if (reason == FLUSH_ROLLBACK)
-                exceps = add(exceps, endStoreManagerTransaction(true));
-            else if (reason != FLUSH_LOGICAL)
-                _flags &= ~FLAG_FLUSH_REQUIRED;
-
-            // mark states as flushed
-            if (flush) {
-                StateManagerImpl sm;
-                for (Iterator itr = transactional.iterator(); itr.hasNext();) {
-                    sm = (StateManagerImpl) itr.next();
-                    try {
-                        // the state may have become transient, such as if
-                        // it is embedded and the owner has been deleted during
-                        // this flush process; bug #1100
-                        if (sm.getPCState() == PCState.TRANSIENT)
-                            continue;
-
-                        sm.afterFlush(reason);
-                        if (reason == FLUSH_INC) {
-                            // if not about to clear trans cache for commit 
-                            // anyway, re-cache dirty objects with default soft
-                            // refs; we don't need hard refs now that the 
-                            // changes have been flushed
-                            sm.proxyFields(true, false);
-                            _transCache.flushed(sm);
-                        }
-                    } catch (Exception e) {
-                        exceps = add(exceps, e);
-                    }
-                }
-            }
-        }
-
-        // throw any exceptions to shortcut listeners on fail
-        throwNestedExceptions(exceps, true);
-
-        if (flush && reason != FLUSH_ROLLBACK && reason != FLUSH_LOGICAL
-            && _transEventManager.hasFlushListeners()) {
-            fireTransactionEvent(new TransactionEvent(this,
-                TransactionEvent.AFTER_FLUSH, mobjs, _persistedClss,
-                _updatedClss, _deletedClss));
-        }
-    }
-
-    /**
-     * Flush newly-transactional objects.
-     */
-    private void flushAdditions(Collection transactional, int reason) {
-        boolean loop;
-        do {
-            // flush new transactional instances; note logical or
-            loop = flushTransAdditions(transactional, reason)
-                | deleteDerefAdditions(_derefCache);
-        } while (loop);
-    }
-
-    /**
-     * Flush transactional additions.
-     */
-    private boolean flushTransAdditions(Collection transactional, int reason) {
-        if (_transAdditions == null || _transAdditions.isEmpty())
-            return false;
-
-        // keep local transactional list copy up to date
-        transactional.addAll(_transAdditions);
-
-        // copy the change set, then clear it for the next iteration
-        StateManagerImpl[] states = (StateManagerImpl[]) _transAdditions.
-            toArray(new StateManagerImpl[_transAdditions.size()]);
-        _transAdditions = null;
-
-        for (int i = 0; i < states.length; i++)
-            states[i].beforeFlush(reason, _call);
-        return true;
-    }
-
-    /**
-     * Delete new dereferenced objects.
-     */
-    private boolean deleteDerefAdditions(Collection derefs) {
-        if (_derefAdditions == null || _derefAdditions.isEmpty())
-            return false;
-
-        // remember these additions in case one becomes derefed again later
-        derefs.addAll(_derefAdditions);
-
-        StateManagerImpl[] states = (StateManagerImpl[]) _derefAdditions.
-            toArray(new StateManagerImpl[_derefAdditions.size()]);
-        _derefAdditions = null;
-
-        for (int i = 0; i < states.length; i++)
-            deleteDeref(states[i]);
-        return true;
-    }
-
-    /**
-     * Delete a dereferenced dependent.
-     */
-    private void deleteDeref(StateManagerImpl sm) {
-        int action = processArgument(OpCallbacks.OP_DELETE,
-            sm.getManagedInstance(), sm, null);
-        if ((action & OpCallbacks.ACT_RUN) != 0)
-            sm.delete();
-        if ((action & OpCallbacks.ACT_CASCADE) != 0)
-            sm.cascadeDelete(_call);
-    }
-
-    /**
-     * Determine the action to take based on the user's given callbacks and
-     * our implicit behavior.
-     */
-    private int processArgument(int op, Object obj, OpenJPAStateManager sm,
-        OpCallbacks call) {
-        if (call != null)
-            return call.processArgument(op, obj, sm);
-        if (_call != null)
-            return _call.processArgument(op, obj, sm);
-        return OpCallbacks.ACT_RUN | OpCallbacks.ACT_CASCADE;
-    }
-
-    /**
-     * Throw the proper exception based on the given set of flush errors, or
-     * do nothing if no errors occurred.
-     */
-    private OpenJPAException newFlushException(Collection exceps) {
-        if (exceps == null || exceps.isEmpty())
-            return null;
-
-        Throwable[] t = (Throwable[]) exceps.toArray
-            (new Throwable[exceps.size()]);
-        List failed = new ArrayList(t.length);
-
-        // create fatal exception with nested exceptions for all the failed
-        // objects; if all OL exceptions, throw a top-level OL exception
-        boolean opt = true;
-        for (int i = 0; opt && i < t.length; i++) {
-            opt = t[i] instanceof OptimisticException;
-            if (opt) {
-                Object f = ((OptimisticException) t[i]).getFailedObject();
-                if (f != null)
-                    failed.add(f);
-            }
-        }
-        if (opt && !failed.isEmpty())
-            return new OptimisticException(failed, t);
-        if (opt)
-            return new OptimisticException(t);
-        return new StoreException(_loc.get("rolled-back")).
-            setNestedThrowables(t).setFatal(true);
-    }
-
-    /**
-     * End the current transaction, making appropriate state transitions.
-     */
-    protected void endTransaction(int status) {
-        // if a data store transaction was in progress, do the
-        // appropriate transaction change
-        boolean rollback = status != Status.STATUS_COMMITTED;
-        List exceps = null;
-
-        try {
-            exceps = add(exceps, endStoreManagerTransaction(rollback));
-        } catch (RuntimeException re) {
-            rollback = true;
-            exceps = add(exceps, re);
-        }
-
-        // go back to default none lock level
-        _fc.setReadLockLevel(LOCK_NONE);
-        _fc.setWriteLockLevel(LOCK_NONE);
-        _fc.setLockTimeout(-1);
-
-        Collection transStates;
-        if (hasTransactionalObjects())
-            transStates = _transCache;
-        else
-            transStates = Collections.EMPTY_LIST;
-
-        // fire after rollback/commit event
-        Collection mobjs = null;
-        if (_transEventManager.hasEndListeners()) {
-            mobjs = new ManagedObjectCollection(transStates);
-            int eventType = (rollback) ? TransactionEvent.AFTER_ROLLBACK
-                : TransactionEvent.AFTER_COMMIT;
-            fireTransactionEvent(new TransactionEvent(this, eventType, mobjs, 
-                _persistedClss, _updatedClss, _deletedClss));
-        }
-
-        // null transactional caches now so that all the removeFromTransaction
-        // calls as we transition each object don't have to do any work; don't
-        // clear trans cache object because we still need the transStates
-        // reference to it below
-        _transCache = null;
-        if (_persistedClss != null)
-            _persistedClss = null;
-        if (_updatedClss != null)
-            _updatedClss = null;
-        if (_deletedClss != null)
-            _deletedClss = null;
-
-        // new cache would get cleared anyway during transitions, but doing so
-        // immediately saves us some lookups
-        _cache.clearNew();
-
-        // tell all derefed instances they're no longer derefed; we can't
-        // rely on rollback and commit calls below cause some instances might
-        // not be transactional
-        if (_derefCache != null && !_derefCache.isEmpty()) {
-            for (Iterator itr = _derefCache.iterator(); itr.hasNext();)
-                ((StateManagerImpl) itr.next()).setDereferencedDependent
-                    (false, false);
-            _derefCache = null;
-        }
-
-        // peform commit or rollback state transitions on each instance
-        StateManagerImpl sm;
-        for (Iterator itr = transStates.iterator(); itr.hasNext();) {
-            sm = (StateManagerImpl) itr.next();
-            try {
-                if (rollback) {
-                    // tell objects that may have been derefed then flushed
-                    // (and therefore deleted) to un-deref
-                    sm.setDereferencedDependent(false, false);
-                    sm.rollback();
-                } else
-                    sm.commit();
-            } catch (RuntimeException re) {
-                exceps = add(exceps, re);
-            }
-        }
-
-        // notify the lock manager to clean up and release remaining locks
-        _lm.endTransaction();
-
-        // clear old savepoints in reverse
-        OpenJPASavepoint save;
-        while (_savepoints != null && _savepoints.size() > 0) {
-            save =
-                (OpenJPASavepoint) _savepoints.remove(_savepoints.size() - 1);
-            save.release(false);
-        }
-        _savepoints = null;
-        _savepointCache = null;
-
-        // fire after state change event
-        if (_transEventManager.hasEndListeners())
-            fireTransactionEvent(new TransactionEvent(this, TransactionEvent.
-                AFTER_STATE_TRANSITIONS, mobjs, null, null, null));
-
-        // now clear trans cache; keep cleared version rather than
-        // null to avoid having to re-create the set later; more efficient
-        if (transStates != Collections.EMPTY_LIST) {
-            _transCache = (TransactionalCache) transStates;
-            _transCache.clear();
-        }
-
-        throwNestedExceptions(exceps, true);
-    }
-
-    ////////////////////
-    // Object lifecycle
-    ////////////////////
-
-    public void persist(Object obj, OpCallbacks call) {
-        persist(obj, null, true, call);
-    }
-
-    public OpenJPAStateManager persist(Object obj, Object id,
-        OpCallbacks call) {
-        return persist(obj, id, true, call);
-    }
-
-    public void persistAll(Collection objs, OpCallbacks call) {
-        persistAll(objs, true, call);
-    }
-
-    /**
-     * Persist the given objects.  Indicate whether this was an explicit persist
-     * (PNEW) or a provisonal persist (PNEWPROVISIONAL).
-     */
-    public void persistAll(Collection objs, boolean explicit, 
-        OpCallbacks call) {
-        if (objs.isEmpty())
-            return;
-
-        beginOperation(true);
-        List exceps = null;
-        try {
-            assertWriteOperation();
-
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                try {
-                    persist(itr.next(), explicit, call);
-                } catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-        } finally {
-            endOperation();
-        }
-        throwNestedExceptions(exceps, false);
-    }
-
-    /**
-     * If the given element is not null, add it to the given list,
-     * creating the list if necessary.
-     */
-    private List add(List l, Object o) {
-        if (o == null)
-            return l;
-        if (l == null)
-            l = new LinkedList();
-        l.add(o);
-        return l;
-    }
-
-    /**
-     * Throw an exception wrapping the given nested exceptions.
-     */
-    private void throwNestedExceptions(List exceps, boolean datastore) {
-        if (exceps == null || exceps.isEmpty())
-            return;
-        if (datastore && exceps.size() == 1)
-            throw (RuntimeException) exceps.get(0);
-
-        boolean fatal = false;
-        Throwable[] t = (Throwable[]) exceps.toArray
-            (new Throwable[exceps.size()]);
-        for (int i = 0; i < t.length; i++) {
-            if (t[i] instanceof OpenJPAException
-                && ((OpenJPAException) t[i]).isFatal())
-                fatal = true;
-        }
-        OpenJPAException err;
-        if (datastore)
-            err = new StoreException(_loc.get("nested-exceps"));
-        else
-            err = new UserException(_loc.get("nested-exceps"));
-        throw err.setNestedThrowables(t).setFatal(fatal);
-    }
-
-    /**
-     * Persist the given object.  Indicate whether this was an explicit persist
-     * (PNEW) or a provisonal persist (PNEWPROVISIONAL)
-     */
-    public void persist(Object obj, boolean explicit, OpCallbacks call) {
-        persist(obj, null, explicit, call);
-    }
-
-    /**
-     * Persist the given object.  Indicate whether this was an explicit persist
-     * (PNEW) or a provisonal persist (PNEWPROVISIONAL).
-     * See {@link Broker} for details on this method.
-     */
-    public OpenJPAStateManager persist(Object obj, Object id, boolean explicit,
-        OpCallbacks call) {
-        if (obj == null)
-            return null;
-
-        beginOperation(true);
-        try {
-            assertWriteOperation();
-
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if (!_operating.add(obj))
-                return sm;
-
-            int action = processArgument(OpCallbacks.OP_PERSIST, obj, sm, call);
-            if (action == OpCallbacks.ACT_NONE)
-                return sm;
-
-            // ACT_CASCADE
-            if ((action & OpCallbacks.ACT_RUN) == 0) {
-                if (sm != null)
-                    sm.cascadePersist(call);
-                else
-                    cascadeTransient(OpCallbacks.OP_PERSIST, obj, call,
-                        "persist");
-                return sm;
-            }
-
-            // ACT_RUN
-            PersistenceCapable pc;
-            if (sm != null) {
-                if (sm.isDetached())
-                    throw new ObjectExistsException(_loc.get
-                        ("persist-detached", Exceptions.toString(obj))).
-                        setFailedObject(obj);
-
-                if (!sm.isEmbedded()) {
-                    sm.persist();
-                    _cache.persist(sm);
-                    if ((action & OpCallbacks.ACT_CASCADE) != 0)
-                        sm.cascadePersist(call);
-                    return sm;
-                }
-
-                // an embedded field; notify the owner that the value has
-                // changed by becoming independently persistent
-                sm.getOwner().dirty(sm.getOwnerIndex());
-                _cache.persist(sm);
-                pc = sm.getPersistenceCapable();
-            } else {
-                pc = assertPersistenceCapable(obj);
-                if (pc.pcIsDetached() == Boolean.TRUE)
-                    throw new ObjectExistsException(_loc.get
-                        ("persist-detached", Exceptions.toString(obj))).
-                        setFailedObject(obj);
-            }
-
-            ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
-                getMetaData(obj.getClass(), _loader, true);
-            fireLifecycleEvent(obj, null, meta, LifecycleEvent.BEFORE_PERSIST);
-
-            // create id for instance
-            if (id == null) {
-                if (meta.getIdentityType() == ClassMetaData.ID_APPLICATION)
-                    id = ApplicationIds.create(pc, meta);
-                else if (meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
-                    throw new UserException(_loc.get("meta-unknownid", meta));
-                else
-                    id = StateManagerId.newInstance(this);
-            }
-
-            // make sure we don't already have the instance cached
-            checkForDuplicateId(id, obj);
-
-            // if had embedded sm, null it
-            if (sm != null)
-                pc.pcReplaceStateManager(null);
-
-            // create new sm
-            sm = new StateManagerImpl(id, meta, this);
-            if ((_flags & FLAG_ACTIVE) != 0) {
-                if (explicit)
-                    sm.initialize(pc, PCState.PNEW);
-                else
-                    sm.initialize(pc, PCState.PNEWPROVISIONAL);
-            } else
-                sm.initialize(pc, PCState.PNONTRANSNEW);
-            if ((action & OpCallbacks.ACT_CASCADE) != 0)
-                sm.cascadePersist(call);
-            return sm;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Temporarily manage the given instance in order to cascade the given
-     * operation through it.
-     */
-    private void cascadeTransient(int op, Object obj, OpCallbacks call,
-        String errOp) {
-        PersistenceCapable pc = assertPersistenceCapable(obj);
-
-        // if using detached state manager, don't replace
-        if (pc.pcGetStateManager() != null)
-            throw newDetachedException(obj, errOp);
-
-        ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
-            getMetaData(obj.getClass(), _loader, true);
-        StateManagerImpl sm = new StateManagerImpl(StateManagerId.
-            newInstance(this), meta, this);
-        sm.initialize(pc, PCState.TLOADED);
-        try {
-            switch (op) {
-                case OpCallbacks.OP_PERSIST:
-                    sm.cascadePersist(call);
-                    break;
-                case OpCallbacks.OP_DELETE:
-                    sm.cascadeDelete(call);
-                    break;
-                case OpCallbacks.OP_REFRESH:
-                    sm.gatherCascadeRefresh(call);
-                    break;
-                default:
-                    throw new InternalException(String.valueOf(op));
-            }
-        }
-        finally {
-            sm.release(true);
-        }
-    }
-
-    public void deleteAll(Collection objs, OpCallbacks call) {
-        beginOperation(true);
-        try {
-            assertWriteOperation();
-
-            List exceps = null;
-            Object obj;
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                try {
-                    obj = itr.next();
-                    if (obj != null)
-                        delete(obj, getStateManagerImpl(obj, true), call);
-                } catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-            throwNestedExceptions(exceps, false);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void delete(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true);
-        try {
-            assertWriteOperation();
-            delete(obj, getStateManagerImpl(obj, true), call);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Internal delete.
-     */
-    void delete(Object obj, StateManagerImpl sm, OpCallbacks call) {
-        if (!_operating.add(obj))
-            return;
-
-        int action = processArgument(OpCallbacks.OP_DELETE, obj, sm, call);
-        if (action == OpCallbacks.ACT_NONE)
-            return;
-
-        // ACT_CASCADE
-        if ((action & OpCallbacks.ACT_RUN) == 0) {
-            if (sm != null)
-                sm.cascadeDelete(call);
-            else
-                cascadeTransient(OpCallbacks.OP_DELETE, obj, call, "delete");
-            return;
-        }
-
-        // ACT_RUN
-        if (sm != null) {
-            if (sm.isDetached())
-                throw newDetachedException(obj, "delete");
-            if ((action & OpCallbacks.ACT_CASCADE) != 0)
-                sm.cascadeDelete(call);
-            sm.delete();
-        } else if (assertPersistenceCapable(obj).pcIsDetached() == Boolean.TRUE)
-            throw newDetachedException(obj, "delete");
-    }
-
-    /**
-     * Throw an exception indicating that the current action can't be
-     * performed on a detached object.
-     */
-    private OpenJPAException newDetachedException(Object obj,
-        String operation) {
-        throw new UserException(_loc.get("bad-detached-op", operation,
-            Exceptions.toString(obj))).setFailedObject(obj);
-    }
-
-    public void releaseAll(Collection objs, OpCallbacks call) {
-        beginOperation(false);
-        try {
-            List exceps = null;
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                try {
-                    release(itr.next(), call);
-                } catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-            throwNestedExceptions(exceps, false);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void release(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(false);
-        try {
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            int action = processArgument(OpCallbacks.OP_RELEASE, obj, sm, call);
-
-            if (sm == null)
-                return;
-            if ((action & OpCallbacks.ACT_RUN) != 0 && sm.isPersistent()) {
-                boolean pending = sm.isPendingTransactional();
-                sm.release(true);
-                if (pending)
-                    removeFromPendingTransaction(sm);
-            }
-        }
-        catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public OpenJPAStateManager embed(Object obj, Object id,
-        OpenJPAStateManager owner, ValueMetaData ownerMeta) {
-        beginOperation(true);
-        try {
-            StateManagerImpl orig = getStateManagerImpl(obj, true);
-            if (orig != null) {
-                // if already embedded, nothing to do
-                if (orig.getOwner() == owner && orig.getMetaData().
-                    getEmbeddingMetaData() == ownerMeta)
-                    return orig;
-
-                // otherwise make sure pc is fully loaded for when we copy its
-                // data below
-                orig.load(_fc, StateManagerImpl.LOAD_ALL, null, null, false);
-            }
-
-            // create new state manager with embedded metadata
-            ClassMetaData meta = ownerMeta.getEmbeddedMetaData();
-            if (meta == null)
-                throw new InternalException(_loc.get("bad-embed", ownerMeta));
-
-            if (id == null)
-                id = StateManagerId.newInstance(this);
-
-            StateManagerImpl sm = new StateManagerImpl(id, meta, this);
-            sm.setOwner((StateManagerImpl) owner, ownerMeta);
-
-            PersistenceCapable copy;
-            PCState state;
-            Class type = meta.getDescribedType();
-            if (obj != null) {
-                // give copy and the original instance the same state manager
-                // so that we can copy fields from one to the other
-                StateManagerImpl copySM;
-                PersistenceCapable pc;
-                if (orig == null) {
-                    copySM = sm;
-                    pc = assertPersistenceCapable(obj);
-                    pc.pcReplaceStateManager(sm);
-                } else {
-                    copySM = orig;
-                    pc = orig.getPersistenceCapable();
-                }
-
-                try {
-                    // copy the instance.  we do this even if it doesn't already
-                    // have a state manager in case it is later assigned to a
-                    // PC field; at that point it's too late to copy
-                    copy = PCRegistry.newInstance(type, copySM, false);
-                    int[] fields = new int[meta.getFields().length];
-                    for (int i = 0; i < fields.length; i++)
-                        fields[i] = i;
-                    copy.pcCopyFields(pc, fields);
-                    state = PCState.ECOPY;
-                    copy.pcReplaceStateManager(null);
-                } finally {
-                    // if the instance didn't have a state manager to start,
-                    // revert it to being transient
-                    if (orig == null)
-                        pc.pcReplaceStateManager(null);
-                }
-            } else {
-                copy = PCRegistry.newInstance(type, sm, false);
-                if ((_flags & FLAG_ACTIVE) != 0 && !_optimistic)
-                    state = PCState.ECLEAN;
-                else
-                    state = PCState.ENONTRANS;
-            }
-
-            sm.initialize(copy, state);
-            return sm;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * If not already cached, create an empty copy of the given state
-     * manager in the given state.
-     */
-    OpenJPAStateManager copy(OpenJPAStateManager copy, PCState state) {
-        beginOperation(true);
-        try {
-            assertOpen();
-            Object oid = copy.fetchObjectId();
-            Class type = copy.getManagedInstance().getClass();
-            if (oid == null)
-                throw new InternalException();
-            // cached instance?
-            StateManagerImpl sm = null;
-            if (!copy.isEmbedded())
-                sm = getStateManagerImplById(oid, true);
-            if (sm == null) {
-                MetaDataRepository repos = _conf.
-                    getMetaDataRepositoryInstance();
-                ClassMetaData meta = repos.getMetaData(type, _loader, true);
-                // construct a new state manager with all info known
-                sm = new StateManagerImpl(oid, meta, this);
-                sm.setObjectId(oid);
-                sm.initialize(sm.getMetaData().getDescribedType(), state);
-            }
-            return sm;
-        } finally {
-            endOperation();
-        }
-    }
-    
-    public void refreshAll(Collection objs, OpCallbacks call) {
-        if (objs == null || objs.isEmpty())
-            return;
-
-        beginOperation(true);
-        try {
-            assertNontransactionalRead();
-
-            for (Iterator itr = objs.iterator(); itr.hasNext();) 
-                gatherCascadeRefresh(itr.next(), call);
-            if (_operating.isEmpty())
-            	return;
-            if (_operating.size() == 1)
-            	refreshInternal(_operating.iterator().next(), call);
-            else
-            	refreshInternal(_operating, call);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void refresh(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true);
-        try {
-            assertNontransactionalRead();
-
-            gatherCascadeRefresh(obj, call);
-            if (_operating.isEmpty())
-            	return;
-            if (_operating.size() == 1)
-            	refreshInternal(_operating.iterator().next(), call);
-            else
-            	refreshInternal(_operating, call);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Gathers all objects reachable through cascade-refresh relations
-     * into the operating set.
-     */
-    void gatherCascadeRefresh(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-        if (!_operating.add(obj))
-            return;
-
-        StateManagerImpl sm = getStateManagerImpl(obj, false);
-        int action = processArgument(OpCallbacks.OP_REFRESH, obj, sm, call);
-        if ((action & OpCallbacks.ACT_CASCADE) == 0)
-            return;
-
-        if (sm != null)
-            sm.gatherCascadeRefresh(call);
-        else
-            cascadeTransient(OpCallbacks.OP_REFRESH, obj, call, "refresh");
-    }
-
-    /**
-     * This method is called with the full set of objects reachable via
-     * cascade-refresh relations from the user-given instances.
-     */
-    protected void refreshInternal(Collection objs, OpCallbacks call) {
-    	if (objs == null || objs.isEmpty())
-    		return;
-        List exceps = null;
-        try {
-            // collect instances that need a refresh
-            Collection load = null;
-            StateManagerImpl sm;
-            Object obj;
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                obj = itr.next();
-                if (obj == null)
-                    continue;
-
-                try {
-                    sm = getStateManagerImpl(obj, true);
-                    if ((processArgument(OpCallbacks.OP_REFRESH, obj, sm, call)
-                        & OpCallbacks.ACT_RUN) == 0)
-                        continue;
-
-                    if (sm != null) {
-                        if (sm.isDetached()) 
-                            throw newDetachedException(obj, "refresh");
-                        else if (sm.beforeRefresh(true)) {
-                        	if (load == null)
-                        		load = new ArrayList(objs.size());
-                            load.add(sm);
-                        }
-                    } else if (assertPersistenceCapable(obj).pcIsDetached()
-                        == Boolean.TRUE)
-                        throw newDetachedException(obj, "refresh");
-                } catch (OpenJPAException ke) {
-                    exceps = add(exceps, ke);
-                }
-            }
-
-            // refresh all
-            if (load != null) {
-                Collection failed = _store.loadAll(load, null,
-                    StoreManager.FORCE_LOAD_REFRESH, _fc, null);
-                if (failed != null && !failed.isEmpty())
-                    exceps = add(exceps, newObjectNotFoundException(failed));
-
-                // perform post-refresh transitions and make sure all fetch
-                // group fields are loaded
-                for (Iterator itr = load.iterator(); itr.hasNext();) {
-                    sm = (StateManagerImpl) itr.next();
-                    if (failed != null && failed.contains(sm.getId()))
-                        continue;
-
-                    try {
-                        sm.afterRefresh();
-                        sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, 
-                            false);
-                    } catch (OpenJPAException ke) {
-                        exceps = add(exceps, ke);
-                    }
-                }
-            }
-
-            // now invoke postRefresh on all the instances
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                try {
-                    sm = getStateManagerImpl(itr.next(), true);
-                    if (sm != null && !sm.isDetached())
-                        fireLifecycleEvent(sm.getManagedInstance(), null,
-                            sm.getMetaData(), LifecycleEvent.AFTER_REFRESH);
-                } catch (OpenJPAException ke) {
-                    exceps = add(exceps, ke);
-                }
-            }
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        }
-        throwNestedExceptions(exceps, false);
-    }
-
-    /**
-     * Optimization for single-object refresh.
-     */
-    protected void refreshInternal(Object obj, OpCallbacks call) {
-        try {
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if ((processArgument(OpCallbacks.OP_REFRESH, obj, sm, call)
-                & OpCallbacks.ACT_RUN) == 0)
-                return;
-
-            if (sm != null) {
-                if (sm.isDetached())
-                    throw newDetachedException(obj, "refresh");
-                else if (sm.beforeRefresh(false)) {
-                    sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
-                    sm.afterRefresh();
-                }
-                fireLifecycleEvent(sm.getManagedInstance(), null,
-                    sm.getMetaData(), LifecycleEvent.AFTER_REFRESH);
-            } else if (assertPersistenceCapable(obj).pcIsDetached()
-                == Boolean.TRUE)
-                throw newDetachedException(obj, "refresh");
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        }
-    }
-    
-    
-    public void retrieveAll(Collection objs, boolean dfgOnly,
-        OpCallbacks call) {
-        if (objs == null || objs.isEmpty())
-            return;
-        if (objs.size() == 1) {
-            retrieve(objs.iterator().next(), dfgOnly, call);
-            return;
-        }
-
-        List exceps = null;
-        beginOperation(true);
-        try {
-            assertOpen();
-            assertNontransactionalRead();
-
-            // collect all hollow instances for load
-            Object obj;
-            Collection load = null;
-            StateManagerImpl sm;
-            Collection sms = new ArrayList(objs.size());
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                obj = itr.next();
-                if (obj == null)
-                    continue;
-
-                try {
-                    sm = getStateManagerImpl(obj, true);
-                    if ((processArgument(OpCallbacks.OP_RETRIEVE, obj, sm, call)
-                        & OpCallbacks.ACT_RUN) == 0)
-                        continue;
-
-                    if (sm != null) {
-                        if (sm.isDetached())
-                            throw newDetachedException(obj, "retrieve");
-                        if (sm.isPersistent()) {
-                            sms.add(sm);
-                            if (sm.getPCState() == PCState.HOLLOW) {
-                                if (load == null)
-                                    load = new ArrayList();
-                                load.add(sm);
-                            }
-                        }
-                    } else if (assertPersistenceCapable(obj).pcIsDetached()
-                        == Boolean.TRUE)
-                        throw newDetachedException(obj, "retrieve");
-                } catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-
-            // load all hollow instances
-            Collection failed = null;
-            if (load != null) {
-                int mode = (dfgOnly) ? _store.FORCE_LOAD_DFG
-                    : _store.FORCE_LOAD_ALL;
-                failed = _store.loadAll(load, null, mode, _fc, null);
-                if (failed != null && !failed.isEmpty())
-                    exceps = add(exceps, newObjectNotFoundException(failed));
-            }
-
-            // retrieve all non-failed instances
-            for (Iterator itr = sms.iterator(); itr.hasNext();) {
-                sm = (StateManagerImpl) itr.next();
-                if (failed != null && failed.contains(sm.getId()))
-                    continue;
-
-                int mode = (dfgOnly) ? StateManagerImpl.LOAD_FGS
-                    : StateManagerImpl.LOAD_ALL;
-                try {
-                    sm.beforeRead(-1);
-                    sm.load(_fc, mode, null, null, false);
-                } catch (OpenJPAException ke) {
-                    exceps = add(exceps, ke);
-                }
-            }
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-        throwNestedExceptions(exceps, false);
-    }
-
-    public void retrieve(Object obj, boolean dfgOnly, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true);
-        try {
-            assertOpen();
-            assertNontransactionalRead();
-
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if ((processArgument(OpCallbacks.OP_RETRIEVE, obj, sm, call)
-                & OpCallbacks.ACT_RUN) == 0)
-                return;
-
-            if (sm != null) {
-                if (sm.isDetached())
-                    throw newDetachedException(obj, "retrieve");
-                if (sm.isPersistent()) {
-                    int mode = (dfgOnly) ? StateManagerImpl.LOAD_FGS
-                        : StateManagerImpl.LOAD_ALL;
-                    sm.beforeRead(-1);
-                    sm.load(_fc, mode, null, null, false);
-                }
-            } else if (assertPersistenceCapable(obj).pcIsDetached()
-                == Boolean.TRUE)
-                throw newDetachedException(obj, "retrieve");
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void evictAll(OpCallbacks call) {
-        beginOperation(false);
-        try {
-            // evict all PClean and PNonTrans objects
-            Collection c = getManagedStates();
-            StateManagerImpl sm;
-            for (Iterator itr = c.iterator(); itr.hasNext();) {
-                sm = (StateManagerImpl) itr.next();
-                if (sm.isPersistent() && !sm.isDirty())
-                    evict(sm.getManagedInstance(), call);
-            }
-        }
-        finally {
-            endOperation();
-        }
-    }
-
-    public void evictAll(Collection objs, OpCallbacks call) {
-        List exceps = null;
-        beginOperation(false);
-        try {
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                try {
-                    evict(itr.next(), call);
-                } catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-        } finally {
-            endOperation();
-        }
-        throwNestedExceptions(exceps, false);
-    }
-
-    public void evictAll(Extent extent, OpCallbacks call) {
-        if (extent == null)
-            return;
-
-        beginOperation(false);
-        try {
-            // evict all PClean and PNonTrans objects in extent
-            Collection c = getManagedStates();
-            StateManagerImpl sm;
-            Class cls;
-            for (Iterator itr = c.iterator(); itr.hasNext();) {
-                sm = (StateManagerImpl) itr.next();
-                if (sm.isPersistent() && !sm.isDirty()) {
-                    cls = sm.getMetaData().getDescribedType();
-                    if (cls == extent.getElementType()
-                        || (extent.hasSubclasses()
-                        && extent.getElementType().isAssignableFrom(cls)))
-                        evict(sm.getManagedInstance(), call);
-                }
-            }
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void evict(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(false);
-        try {
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if ((processArgument(OpCallbacks.OP_EVICT, obj, sm, call)
-                & OpCallbacks.ACT_RUN) == 0)
-                return;
-            if (sm == null)
-                return;
-
-            sm.evict();
-            if (_evictDataCache && sm.getObjectId() != null) {
-                DataCache cache = sm.getMetaData().getDataCache();
-                if (cache != null)
-                    cache.remove(sm.getObjectId());
-            }
-        }
-        catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Object detach(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return null;
-        if (call == null)
-            call = _call;
-
-        beginOperation(true);
-        try {
-            return new DetachManager(this, false, call).detach(obj);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Object[] detachAll(Collection objs, OpCallbacks call) {
-        if (objs == null)
-            return null;
-        if (objs.isEmpty())
-            return EMPTY_OBJECTS;
-        if (call == null)
-            call = _call;
-
-        beginOperation(true);
-        try {
-            return new DetachManager(this, false, call).detachAll(objs);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void detachAll(OpCallbacks call) {
-        detachAll(call, true);
-    }
-
-    public void detachAll(OpCallbacks call, boolean flush) {
-        beginOperation(true);
-        try {
-            // If a flush is desired (based on input parm), then check if the
-            //   "dirty" flag is set before calling flush().
-            if ((flush) && ((_flags & FLAG_FLUSH_REQUIRED) != 0))
-                flush();
-            detachAllInternal(call);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    private void detachAllInternal(OpCallbacks call) {
-        Collection states = getManagedStates();
-        StateManagerImpl sm;
-        for (Iterator itr = states.iterator(); itr.hasNext();) {
-            sm = (StateManagerImpl) itr.next();
-            if (!sm.isPersistent())
-                itr.remove();
-            else if (!sm.getMetaData().isDetachable()) {
-                sm.release(true);
-                itr.remove();
-            }
-        }
-        if (states.isEmpty())
-            return;
-
-        if (call == null)
-            call = _call;
-        new DetachManager(this, true, call).detachAll
-            (new ManagedObjectCollection(states));
-    }
-
-    public Object attach(Object obj, boolean copyNew, OpCallbacks call) {
-        if (obj == null)
-            return null;
-
-        beginOperation(true);
-        try {
-            // make sure not to try to set rollback only if this fails
-            assertWriteOperation();
-            try {
-                return new AttachManager(this, copyNew, call).attach(obj);
-            } catch (OptimisticException oe) {
-                setRollbackOnly(oe);
-                throw oe.setFatal(true);
-            } catch (OpenJPAException ke) {
-                throw ke;
-            } catch (RuntimeException re) {
-                throw new GeneralException(re);
-            }
-        }
-        finally {
-            endOperation();
-        }
-    }
-
-    public Object[] attachAll(Collection objs, boolean copyNew,
-        OpCallbacks call) {
-        if (objs == null)
-            return null;
-        if (objs.isEmpty())
-            return EMPTY_OBJECTS;
-
-        beginOperation(true);
-        try {
-            // make sure not to try to set rollback only if this fails
-            assertWriteOperation();
-            try {
-                return new AttachManager(this, copyNew, call).attachAll(objs);
-            } catch (OptimisticException oe) {
-                setRollbackOnly(oe);
-                throw oe.setFatal(true);
-            } catch (OpenJPAException ke) {
-                throw ke;
-            } catch (RuntimeException re) {
-                throw new GeneralException(re);
-            }
-        }
-        finally {
-            endOperation();
-        }
-    }
-
-    public void nontransactionalAll(Collection objs, OpCallbacks call) {
-        beginOperation(true);
-        try {
-            List exceps = null;
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                try {
-                    nontransactional(itr.next(), call);
-                } catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-            throwNestedExceptions(exceps, false);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void nontransactional(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true);
-        try {
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if ((processArgument(OpCallbacks.OP_NONTRANSACTIONAL, obj, sm, call)
-                & OpCallbacks.ACT_RUN) == 0)
-                return;
-            if (sm != null)
-                sm.nontransactional();
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Make the given instances transactional.
-     */
-    public void transactionalAll(Collection objs, boolean updateVersion,
-        OpCallbacks call) {
-        if (objs.isEmpty())
-            return;
-        if (objs.size() == 1) {
-            transactional(objs.iterator().next(), updateVersion, call);
-            return;
-        }
-
-        beginOperation(true);
-        try {
-            // collect all hollow instances for load, and make unmananged
-            // instances transient-transactional
-            Collection load = null;
-            Object obj;
-            StateManagerImpl sm;
-            ClassMetaData meta;
-            Collection sms = new ArrayList(objs.size());
-            List exceps = null;
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                obj = itr.next();
-                if (obj == null)
-                    continue;
-
-                try {
-                    sm = getStateManagerImpl(obj, true);
-                    if ((processArgument(OpCallbacks.OP_TRANSACTIONAL, obj, sm,
-                        call) & OpCallbacks.ACT_RUN) == 0)
-                        continue;
-
-                    if (sm == null) {
-                        // manage transient instance
-                        meta = _conf.getMetaDataRepositoryInstance().
-                            getMetaData(obj.getClass(), _loader, true);
-
-                        sm = new StateManagerImpl
-                            (StateManagerId.newInstance(this), meta, this);
-                        sm.initialize(assertPersistenceCapable(obj),
-                            PCState.TCLEAN);
-                    } else if (sm.isPersistent()) {
-                        assertActiveTransaction();
-                        sms.add(sm);
-                        if (sm.getPCState() == PCState.HOLLOW) {
-                            if (load == null)
-                                load = new ArrayList();
-                            load.add(sm);
-                        }
-
-                        sm.setCheckVersion(true);
-                        if (updateVersion)
-                            sm.setUpdateVersion(true);
-                        _flags |= FLAG_FLUSH_REQUIRED; // version check/up
-                    }
-                }
-                catch (UserException ue) {
-                    exceps = add(exceps, ue);
-                }
-            }
-
-            // load all hollow instances
-            Collection failed = null;
-            if (load != null) {
-                failed = _store.loadAll(load, null, _store.FORCE_LOAD_NONE,
-                    _fc, null);
-                if (failed != null && !failed.isEmpty())
-                    exceps = add(exceps,
-                        newObjectNotFoundException(failed));
-            }
-
-            transactionalStatesAll(sms, failed, exceps);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Make the given instances transactional.
-     */
-    public void transactional(Object obj, boolean updateVersion,
-        OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true);
-        try {
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if ((processArgument(OpCallbacks.OP_TRANSACTIONAL, obj, sm, call)
-                & OpCallbacks.ACT_RUN) == 0)
-                return;
-
-            if (sm != null && sm.isPersistent()) {
-                assertActiveTransaction();
-                sm.transactional();
-                sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
-                sm.setCheckVersion(true);
-                if (updateVersion)
-                    sm.setUpdateVersion(true);
-                _flags |= FLAG_FLUSH_REQUIRED; // version check/up
-            } else if (sm == null) {
-                // manage transient instance
-                ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
-                    getMetaData(obj.getClass(), _loader, true);
-                Object id = StateManagerId.newInstance(this);
-                sm = new StateManagerImpl(id, meta, this);
-                sm.initialize(assertPersistenceCapable(obj),
-                    PCState.TCLEAN);
-            }
-        }
-        catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Transition the given state managers to transactional.
-     */
-    private void transactionalStatesAll(Collection sms, Collection failed,
-        List exceps) {
-        // make instances transactional and make sure they are loaded
-        StateManagerImpl sm;
-        for (Iterator itr = sms.iterator(); itr.hasNext();) {
-            sm = (StateManagerImpl) itr.next();
-            if (failed != null && failed.contains(sm.getId()))
-                continue;
-
-            try {
-                sm.transactional();
-                sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
-            } catch (OpenJPAException ke) {
-                exceps = add(exceps, ke);
-            }
-        }
-        throwNestedExceptions(exceps, false);
-    }
-
-    /////////////////
-    // Extent, Query
-    /////////////////
-
-    public Extent newExtent(Class type, boolean subclasses) {
-        return newExtent(type, subclasses, null);
-    }
-
-    private Extent newExtent(Class type, boolean subclasses,
-        FetchConfiguration fetch) {
-        beginOperation(true);
-        try {
-            ExtentImpl extent = new ExtentImpl(this, type, subclasses, fetch);
-            if (_extents == null)
-                _extents = new ReferenceHashSet(ReferenceHashSet.WEAK);
-            _extents.add(extent);
-
-            return extent;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Iterator extentIterator(Class type, boolean subclasses,
-        FetchConfiguration fetch, boolean ignoreChanges) {
-        Extent extent = newExtent(type, subclasses, fetch);
-        extent.setIgnoreChanges(ignoreChanges);
-        return extent.iterator();
-    }
-
-    public Query newQuery(String lang, Class cls, Object query) {
-        Query q = newQuery(lang, query);
-        q.setCandidateType(cls, true);
-        return q;
-    }
-
-    public Query newQuery(String lang, Object query) {
-        // common mistakes
-        if (query instanceof Extent || query instanceof Class)
-            throw new UserException(_loc.get("bad-new-query"));
-
-        beginOperation(false);
-        try {
-            StoreQuery sq = _store.newQuery(lang);
-            if (sq == null) {
-                ExpressionParser ep = QueryLanguages.parserForLanguage(lang);
-                if (ep != null)
-                    sq = new ExpressionStoreQuery(ep);
-                else if (QueryLanguages.LANG_METHODQL.equals(lang))
-                    sq = new MethodStoreQuery();
-                else
-                    throw new UnsupportedException(lang);
-            }
-
-            Query q = newQueryImpl(lang, sq);
-            q.setIgnoreChanges(_ignoreChanges);
-            if (query != null)
-                q.setQuery(query);
-
-            // track queries
-            if (_queries == null)
-                _queries = new ReferenceHashSet(ReferenceHashSet.WEAK);
-            _queries.add(q);
-            return q;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Create a new query.
-     */
-    protected QueryImpl newQueryImpl(String lang, StoreQuery sq) {
-        return new QueryImpl(this, lang, sq);
-    }
-
-    public Seq getIdentitySequence(ClassMetaData meta) {
-        if (meta == null)
-            return null;
-        return getSequence(meta, null);
-    }
-
-    public Seq getValueSequence(FieldMetaData fmd) {
-        if (fmd == null)
-            return null;
-        return getSequence(fmd.getDefiningMetaData(), fmd);
-    }
-
-    /**
-     * Return a sequence for the given class and optional field.
-     */
-    private Seq getSequence(ClassMetaData meta, FieldMetaData fmd) {
-        // get sequence strategy from metadata
-        int strategy;
-        if (fmd == null)
-            strategy = meta.getIdentityStrategy();
-        else
-            strategy = fmd.getValueStrategy();
-
-        // we can handle non-native strategies without the store manager
-        switch (strategy) {
-            case ValueStrategies.UUID_HEX:
-                return UUIDHexSeq.getInstance();
-            case ValueStrategies.UUID_STRING:
-                return UUIDStringSeq.getInstance();
-            case ValueStrategies.UUID_TYPE4_HEX:
-                return UUIDType4HexSeq.getInstance();
-            case ValueStrategies.UUID_TYPE4_STRING:
-                return UUIDType4StringSeq.getInstance();
-            case ValueStrategies.SEQUENCE:
-                SequenceMetaData smd = (fmd == null)
-                    ? meta.getIdentitySequenceMetaData()
-                    : fmd.getValueSequenceMetaData();
-                return smd.getInstance(_loader);
-            default:
-                // use store manager for native sequence
-                if (fmd == null) {
-                    // this will return a sequence even for app id classes,
-                    // which is what we want for backwards-compatibility
-                    return _store.getDataStoreIdSequence(meta);
-                }
-                return _store.getValueSequence(fmd);
-        }
-    }
-
-    ///////////
-    // Locking
-    ///////////
-
-    public void lock(Object obj, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true); // have to sync or lock level always NONE
-        try {
-            lock(obj, _fc.getWriteLockLevel(), _fc.getLockTimeout(), call);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void lock(Object obj, int level, int timeout, OpCallbacks call) {
-        if (obj == null)
-            return;
-
-        beginOperation(true);
-        try {
-            assertActiveTransaction();
-
-            StateManagerImpl sm = getStateManagerImpl(obj, true);
-            if ((processArgument(OpCallbacks.OP_LOCK, obj, sm, call)
-                & OpCallbacks.ACT_RUN) == 0)
-                return;
-            if (sm == null || !sm.isPersistent())
-                return;
-
-            _lm.lock(sm, level, timeout, null);
-            sm.readLocked(level, level); // use same level for future write
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void lockAll(Collection objs, OpCallbacks call) {
-        if (objs.isEmpty())
-            return;
-
-        beginOperation(true); // have to sync or lock level always NONE
-        try {
-            lockAll(objs, _fc.getWriteLockLevel(), _fc.getLockTimeout(),
-                call);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public void lockAll(Collection objs, int level, int timeout,
-        OpCallbacks call) {
-        if (objs.isEmpty())
-            return;
-        if (objs.size() == 1) {
-            lock(objs.iterator().next(), level, timeout, call);
-            return;
-        }
-
-        beginOperation(true);
-        try {
-            assertActiveTransaction();
-
-            Collection sms = new ArrayList(objs.size());
-            Object obj;
-            StateManagerImpl sm;
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
-                obj = itr.next();
-                if (obj == null)
-                    continue;
-
-                sm = getStateManagerImpl(obj, true);
-                if ((processArgument(OpCallbacks.OP_LOCK, obj, sm, call)
-                    & OpCallbacks.ACT_RUN) == 0)
-                    continue;
-                if (sm != null && sm.isPersistent())
-                    sms.add(sm);
-            }
-
-            _lm.lockAll(sms, level, timeout, null);
-            for (Iterator itr = sms.iterator(); itr.hasNext();)
-                ((StateManagerImpl) itr.next()).readLocked(level, level);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            endOperation();
-        }
-    }
-
-    //////////////
-    // Connection
-    //////////////
-
-    public boolean cancelAll() {
-        // this method does not lock, since we want to allow a different
-        // thread to be able to cancel on a locked-up persistence manager
-
-        assertOpen();
-        try {
-            // if we're flushing, have to set rollback only -- do this before we
-            // attempt to cancel, because otherwise the cancel might case the
-            // transaction to complete before we have a chance to set the
-            // rollback only flag
-            if ((_flags & FLAG_STORE_FLUSHING) != 0)
-                setRollbackOnlyInternal(new UserException());
-            return _store.cancelAll();
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new StoreException(re);
-        }
-    }
-
-    public Object getConnection() {
-        assertOpen();
-        if (!_conf.supportedOptions().contains
-            (_conf.OPTION_DATASTORE_CONNECTION))
-            throw new UnsupportedException(_loc.get("conn-not-supported"));
-
-        return _store.getClientConnection();
-    }
-
-    public boolean hasConnection() {
-        assertOpen();
-        return (_flags & FLAG_RETAINED_CONN) != 0;
-    }
-
-    /**
-     * Tell store to retain connection if we haven't already.
-     */
-    private void retainConnection() {
-        if ((_flags & FLAG_RETAINED_CONN) == 0) {
-            _store.retainConnection();
-            _flags |= FLAG_RETAINED_CONN;
-        }
-    }
-
-    /**
-     * Tell store to release connection if we have retained one.
-     */
-    private void releaseConnection() {
-        if ((_flags & FLAG_RETAINED_CONN) != 0) {
-            _store.releaseConnection();
-            _flags &= ~FLAG_RETAINED_CONN;
-        }
-    }
-
-    /////////
-    // Cache
-    /////////
-
-    public Collection getManagedObjects() {
-        beginOperation(false);
-        try {
-            return new ManagedObjectCollection(getManagedStates());
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Collection getTransactionalObjects() {
-        beginOperation(false);
-        try {
-            return new ManagedObjectCollection(getTransactionalStates());
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Collection getPendingTransactionalObjects() {
-        beginOperation(false);
-        try {
-            return new ManagedObjectCollection
-                (getPendingTransactionalStates());
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Collection getDirtyObjects() {
-        beginOperation(false);
-        try {
-            return new ManagedObjectCollection(getDirtyStates());
-        } finally {
-            endOperation();
-        }
-    }
-
-    public boolean getOrderDirtyObjects() {
-        return _orderDirty;
-    }
-
-    public void setOrderDirtyObjects(boolean order) {
-        _orderDirty = order;
-    }
-
-    /**
-     * Return a copy of all managed state managers.
-     */
-    protected Collection getManagedStates() {
-        return _cache.copy();
-    }
-
-    /**
-     * Return a copy of all transactional state managers.
-     */
-    protected Collection getTransactionalStates() {
-        if (!hasTransactionalObjects())
-            return Collections.EMPTY_LIST;
-        return _transCache.copy();
-    }
-
-    /**
-     * Whether or not there are any transactional objects in the current
-     * persistence context. If there are any instances with untracked state,
-     * this method will cause those instances to be scanned.
-     */
-    private boolean hasTransactionalObjects() {
-        _cache.dirtyCheck();
-        return _transCache != null;
-    }
-
-    /**
-     * Return a copy of all dirty state managers.
-     */
-    protected Collection getDirtyStates() {
-        if (!hasTransactionalObjects())
-            return Collections.EMPTY_LIST;
-
-        return _transCache.copyDirty();
-    }
-
-    /**
-     * Return a copy of all state managers which will become
-     * transactional upon the next transaction.
-     */
-    protected Collection getPendingTransactionalStates() {
-        if (_pending == null)
-            return Collections.EMPTY_LIST;
-        return new ArrayList(_pending);
-    }
-
-    /**
-     * Set the cached StateManager for the instance that had the given oid.
-     * This method must not be called multiple times for new instances.
-     *
-     * @param id the id previously used by the instance
-     * @param sm the state manager for the instance; if the state
-     * manager is transient, we'll stop managing the instance;
-     * if it has updated its oid, we'll re-cache under the new oid
-     * @param status one of our STATUS constants describing why we're
-     * setting the state manager
-     */
-    void setStateManager(Object id, StateManagerImpl sm, int status) {
-        lock();
-        try {
-            switch (status) {
-                case STATUS_INIT:
-                    _cache.add(sm);
-                    break;
-                case STATUS_TRANSIENT:
-                    _cache.remove(id, sm);
-                    break;
-                case STATUS_OID_ASSIGN:
-                    assignObjectId(_cache, id, sm);
-                    break;
-                case STATUS_COMMIT_NEW:
-                    _cache.commitNew(id, sm);
-                    break;
-                default:
-                    throw new InternalException();
-            }
-        }
-        finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Notify the broker that the given state manager should
-     * be added to the set of instances involved in the current transaction.
-     */
-    void addToTransaction(StateManagerImpl sm) {
-        // we only add clean instances now; dirty instances are added in
-        // the setDirty callback
-        if (sm.isDirty())
-            return;
-
-        lock();
-        try {
-            if (!hasTransactionalObjects())
-                _transCache = new TransactionalCache(_orderDirty);
-            _transCache.addClean(sm);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Notify the persistence manager that the given state manager should
-     * be removed from the set of instances involved in the current transaction.
-     */
-    void removeFromTransaction(StateManagerImpl sm) {
-        lock();
-        try {
-            if (_transCache != null)
-                // intentional direct access; we don't want to recompute
-                // dirtiness while removing instances from the transaction
-                _transCache.remove(sm);
-            if (_derefCache != null && !sm.isPersistent())
-                _derefCache.remove(sm);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Notification that the given instance has been dirtied. This
-     * notification is given when an object first transitions to a dirty state,
-     * and every time the object is modified by the user thereafter.
-     */
-    void setDirty(StateManagerImpl sm, boolean firstDirty) {
-        if (sm.isPersistent())
-            _flags |= FLAG_FLUSH_REQUIRED;
-
-        if (_savepoints != null && !_savepoints.isEmpty()) {
-            if (_savepointCache == null)
-                _savepointCache = new HashSet();
-            _savepointCache.add(sm);
-        }
-
-        if (firstDirty && sm.isTransactional()) {
-            lock();
-            try {
-                // cache dirty instance
-                if (!hasTransactionalObjects())
-                    _transCache = new TransactionalCache(_orderDirty);
-                _transCache.addDirty(sm);
-
-                // also record that the class is dirty
-                if (sm.isNew()) {
-                    if (_persistedClss == null)
-                        _persistedClss = new HashSet();
-                    _persistedClss.add(sm.getMetaData().getDescribedType());
-                } else if (sm.isDeleted()) {
-                    if (_deletedClss == null)
-                        _deletedClss = new HashSet();
-                    _deletedClss.add(sm.getMetaData().getDescribedType());
-                } else {
-                    if (_updatedClss == null)
-                        _updatedClss = new HashSet();
-                    _updatedClss.add(sm.getMetaData().getDescribedType());
-                }
-
-                // if tracking changes and this instance wasn't already dirty,
-                // add to changed set; we use this for detecting instances that
-                // enter the transaction during pre store
-                if ((_flags & FLAG_PRESTORING) != 0) {
-                    if (_transAdditions == null)
-                        _transAdditions = new HashSet();
-                    _transAdditions.add(sm);
-                }
-            } finally {
-                unlock();
-            }
-        }
-    }
-
-    /**
-     * Notify the broker that the given state manager should
-     * be added to the set of instances that will become transactional
-     * on the next transaction
-     */
-    void addToPendingTransaction(StateManagerImpl sm) {
-        lock();
-        try {
-            if (_pending == null)
-                _pending = new HashSet();
-            _pending.add(sm);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Notify the persistence manager that the given state manager should
-     * be removed from the set of instances involved in the next transaction.
-     */
-    void removeFromPendingTransaction(StateManagerImpl sm) {
-        lock();
-        try {
-            if (_pending != null)
-                _pending.remove(sm);
-            if (_derefCache != null && !sm.isPersistent())
-                _derefCache.remove(sm);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Add a dereferenced dependent object to the persistence manager's cache.
-     * On flush, these objects will be deleted.
-     */
-    void addDereferencedDependent(StateManagerImpl sm) {
-        lock();
-        try {
-            // if we're in the middle of flush and introducing more derefs
-            // via instance callbacks, add them to the special additions set
-            if ((_flags & FLAG_DEREFDELETING) != 0) {
-                if (_derefAdditions == null)
-                    _derefAdditions = new HashSet();
-                _derefAdditions.add(sm);
-            } else {
-                if (_derefCache == null)
-                    _derefCache = new HashSet();
-                _derefCache.add(sm);
-            }
-        }
-        finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Remove the given previously dereferenced dependent object from the
-     * cache. It is now referenced.
-     */
-    void removeDereferencedDependent(StateManagerImpl sm) {
-        lock();
-        try {
-            boolean removed = false;
-            if (_derefAdditions != null)
-                removed = _derefAdditions.remove(sm);
-            if (!removed && (_derefCache == null || !_derefCache.remove(sm)))
-                throw new InvalidStateException(_loc.get("not-derefed",
-                    Exceptions.toString(sm.getManagedInstance()))).
-                    setFailedObject(sm.getManagedInstance()).
-                    setFatal(true);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void dirtyType(Class cls) {
-        if (cls == null)
-            return;
-
-        beginOperation(false);
-        try {
-            if (_updatedClss == null)
-                _updatedClss = new HashSet();
-            _updatedClss.add(cls);
-        } finally {
-            endOperation();
-        }
-    }
-
-    public Collection getPersistedTypes() {
-        if (_persistedClss == null || _persistedClss.isEmpty())
-            return Collections.EMPTY_LIST;
-        return Collections.unmodifiableCollection(_persistedClss);
-    }
-
-    public Collection getUpdatedTypes() {
-        if (_updatedClss == null || _updatedClss.isEmpty())
-            return Collections.EMPTY_LIST;
-        return Collections.unmodifiableCollection(_updatedClss);
-    }
-
-    public Collection getDeletedTypes() {
-        if (_deletedClss == null || _deletedClss.isEmpty())
-            return Collections.EMPTY_LIST;
-        return Collections.unmodifiableCollection(_deletedClss);
-    }
-
-    ///////////
-    // Closing
-    ///////////
-
-    public boolean isClosed() {
-        return _closed;
-    }
-
-    public boolean isCloseInvoked() {
-        return _closed || (_flags & FLAG_CLOSE_INVOKED) != 0;
-    }
-
-    public void close() {
-        beginOperation(false);
-        try {
-            // throw an exception if closing in an active local trans
-            if (!_managed && (_flags & FLAG_ACTIVE) != 0)
-                throw new InvalidStateException(_loc.get("active"));
-
-            // only close if not active; if active managed trans wait
-            // for completion
-            _flags |= FLAG_CLOSE_INVOKED;
-
-            if ((_flags & FLAG_ACTIVE) == 0)
-                free();
-        } finally {
-            endOperation();
-        }
-    }
-
-    /**
-     * Free the resources used by this persistence manager.
-     */
-    protected void free() {
-        RuntimeException err = null;
-        if ((_autoDetach & DETACH_CLOSE) != 0) {
-            try {
-                detachAllInternal(_call);
-            } catch (RuntimeException re) {
-                err = re;
-            }
-        }
-
-        _sync = null;
-        _userObjects = null;
-        _cache.clear();
-        _transCache = null;
-        _persistedClss = null;
-        _updatedClss = null;
-        _deletedClss = null;
-        _derefCache = null;
-        _pending = null;
-        _loader = null;
-        _transEventManager = null;
-        _lifeEventManager = null;
-
-        OpenJPASavepoint save;
-        while (_savepoints != null && !_savepoints.isEmpty()) {
-            save =
-                (OpenJPASavepoint) _savepoints.remove(_savepoints.size() - 1);
-            save.release(false);
-        }
-        _savepoints = null;
-        _savepointCache = null;
-
-        if (_queries != null) {
-            for (Iterator itr = _queries.iterator(); itr.hasNext();) {
-                try {
-                    ((Query) itr.next()).closeResources();
-                } catch (RuntimeException re) {
-                }
-            }
-            _queries = null;
-        }
-
-        if (_extents != null) {
-            Extent e;
-            for (Iterator itr = _extents.iterator(); itr.hasNext();) {
-                e = (Extent) itr.next();
-                try {
-                    e.closeAll();
-                } catch (RuntimeException re) {
-                }
-            }
-            _extents = null;
-        }
-
-        try { releaseConnection(); } catch (RuntimeException re) {}
-
-        _lm.close();
-        _store.close();
-        _flags = 0;
-        _closed = true;
-        if (_log.isTraceEnabled())
-            _closedException = new IllegalStateException();
-
-        _factory.releaseBroker(this);
-
-        if (err != null)
-            throw err;
-    }
-
-    ///////////////////
-    // Synchronization
-    ///////////////////
-
-    public void lock() {
-        if (_lock != null)
-            _lock.lock();
-    }
-
-    public void unlock() {
-        if (_lock != null)
-            _lock.unlock();
-    }
-
-    ////////////////////
-    // State management
-    ////////////////////
-
-    public Object newInstance(Class cls) {
-        assertOpen();
-
-        if (!cls.isInterface() && Modifier.isAbstract(cls.getModifiers()))
-            throw new UnsupportedOperationException(_loc.get
-                ("new-abstract", cls).getMessage());
-
-        // 1.5 doesn't initialize classes without a true Class.forName
-        if (!PCRegistry.isRegistered(cls)) {
-            try {
-                Class.forName(cls.getName(), true, 
-                    (ClassLoader) AccessController.doPrivileged(
-                        J2DoPrivHelper.getClassLoaderAction(cls)));
-            } catch (Throwable t) {
-            }
-        }
-
-        if (_conf.getMetaDataRepositoryInstance().getMetaData(cls,
-            getClassLoader(), false) == null)
-            throw new IllegalArgumentException(
-                _loc.get("no-interface-metadata", cls.getName()).getMessage());
-
-        try {
-            return PCRegistry.newInstance(cls, null, false);
-        } catch (IllegalStateException ise) {
-            IllegalArgumentException iae =
-                new IllegalArgumentException(ise.getMessage());
-            iae.setStackTrace(ise.getStackTrace());
-            throw iae;
-        }
-    }
-
-    public Object getObjectId(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj))
-            return (ImplHelper.toPersistenceCapable(obj, _conf))
-                .pcFetchObjectId();
-        return null;
-    }
-
-    public int getLockLevel(Object o) {
-        assertOpen();
-        if (o == null)
-            return LockLevels.LOCK_NONE;
-
-        OpenJPAStateManager sm = getStateManager(o);
-        if (sm == null)
-            return LockLevels.LOCK_NONE;
-        return getLockManager().getLockLevel(sm);
-    }
-
-    public Object getVersion(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj))
-            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcGetVersion();
-        return null;
-    }
-
-    public boolean isDirty(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj)) {
-            PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
-            return pc.pcIsDirty();
-        }
-        return false;
-    }
-
-    public boolean isTransactional(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj))
-            return (ImplHelper.toPersistenceCapable(obj, _conf))
-                .pcIsTransactional();
-        return false;
-    }
-
-    public boolean isPersistent(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj))
-            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcIsPersistent();
-        return false;
-    }
-
-    public boolean isNew(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj))
-            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcIsNew();
-        return false;
-    }
-
-    public boolean isDeleted(Object obj) {
-        assertOpen();
-        if (ImplHelper.isManageable(obj))
-            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcIsDeleted();
-        return false;
-    }
-
-    public boolean isDetached(Object obj) {
-        if (!(ImplHelper.isManageable(obj)))
-            return false;
-
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
-        Boolean detached = pc.pcIsDetached();
-        if (detached != null)
-            return detached.booleanValue();
-
-        // last resort: instance is detached if it has a store record
-        ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
-            getMetaData(ImplHelper.getManagedInstance(pc).getClass(),
-                _loader, true);
-        Object oid = ApplicationIds.create(pc, meta);
-        if (oid == null)
-            return false;
-        return find(oid, null, EXCLUDE_ALL, null, 0) != null;
-    }
-
-    public OpenJPAStateManager getStateManager(Object obj) {
-        assertOpen();
-        return getStateManagerImpl(obj, false);
-    }
-
-    /**
-     * Return the state manager for the given instance, or null.
-     *
-     * @param assertThisContext if true, thow an exception if the given
-     * object is managed by another broker
-     */
-    protected StateManagerImpl getStateManagerImpl(Object obj,
-        boolean assertThisContext) {
-        if (ImplHelper.isManageable(obj)) {
-            PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
-            if (pc.pcGetGenericContext() == this)
-                return (StateManagerImpl) pc.pcGetStateManager();
-            if (assertThisContext && pc.pcGetGenericContext() != null)
-                throw new UserException(_loc.get("not-managed",
-                    Exceptions.toString(obj))).setFailedObject(obj);
-        }
-        return null;
-    }
-
-    /**
-     * Return the state manager for the given oid.
-     *
-     * @param allowNew if true, objects made persistent in the current
-     * transaction will be included in the search; if
-     * multiple new objects match the given oid, it is
-     * undefined which will be returned
-     */
-    protected StateManagerImpl getStateManagerImplById(Object oid,
-        boolean allowNew) {
-        return _cache.getById(oid, allowNew);
-    }
-
-    /**
-     * Return the given instance as a {@link PersistenceCapable}.
-     * If the instance is not manageable throw the proper exception.
-     */
-    protected PersistenceCapable assertPersistenceCapable(Object obj) {
-        if (obj == null)
-            return null;
-        if (ImplHelper.isManageable(obj))
-            return ImplHelper.toPersistenceCapable(obj, _conf);
-
-        // check for different instances of the PersistenceCapable interface
-        // and throw a better error that mentions the class loaders
-        Class[] intfs = obj.getClass().getInterfaces();
-        for (int i = 0; intfs != null && i < intfs.length; i++) {
-            if (intfs[i].getName().equals(PersistenceCapable.class.getName())) {
-                throw new UserException(_loc.get("pc-loader-different",
-                    Exceptions.toString(obj),
-                    (ClassLoader) AccessController.doPrivileged(
-                        J2DoPrivHelper.getClassLoaderAction(
-                            PersistenceCapable.class)),
-                    (ClassLoader) AccessController.doPrivileged(
-                        J2DoPrivHelper.getClassLoaderAction(intfs[i]))))
-                    .setFailedObject(obj);
-            }
-        }
-
-        // not enhanced
-        throw new UserException(_loc.get("pc-cast",
-            Exceptions.toString(obj))).setFailedObject(obj);
-    }
-
-    /////////
-    // Utils
-    /////////
-    /**
-     * Throw an exception if the context is closed.  The exact message and
-     * content of the exception varies whether TRACE is enabled or not.
-     */
-    public void assertOpen() {
-        if (_closed) {
-            if (_closedException == null)  // TRACE not enabled
-                throw new InvalidStateException(_loc.get("closed-notrace"))
-                        .setFatal(true);
-            else {
-                OpenJPAException e = new InvalidStateException(
-                    _loc.get("closed"), _closedException).setFatal(true);
-                e.setCause(_closedException);
-                throw e;
-            }
-        }
-    }
-
-    public void assertActiveTransaction() {
-        if ((_flags & FLAG_ACTIVE) == 0)
-            throw new NoTransactionException(_loc.get("not-active"));
-    }
-
-    /**
-     * Throw exception if a transaction-related operation is attempted and
-     * no transaction is active.
-     */
-    private void assertTransactionOperation() {
-        if ((_flags & FLAG_ACTIVE) == 0)
-            throw new InvalidStateException(_loc.get("not-active"));
-    }
-
-    public void assertNontransactionalRead() {
-        if ((_flags & FLAG_ACTIVE) == 0 && !_nontransRead)
-            throw new InvalidStateException(_loc.get("non-trans-read"));
-    }
-
-    public void assertWriteOperation() {
-        if ((_flags & FLAG_ACTIVE) == 0 && (!_nontransWrite
-            || (_autoDetach & DETACH_NONTXREAD) != 0))
-            throw new NoTransactionException(_loc.get("write-operation"));
-    }
-
-    /**
-     * Return an object not found exception containing nested exceptions
-     * for all of the given failed objects.
-     */
-    private static ObjectNotFoundException newObjectNotFoundException
-        (Collection failed) {
-        Throwable[] t = new Throwable[failed.size()];
-        int idx = 0;
-        for (Iterator itr = failed.iterator(); itr.hasNext(); idx++)
-            t[idx] = new ObjectNotFoundException(itr.next());
-        return new ObjectNotFoundException(failed, t);
-    }
-
-    ////////////////////////////////
-    // FindCallbacks implementation
-    ////////////////////////////////
-
-    public Object processArgument(Object oid) {
-        return oid;
-    }
-
-    public Object processReturn(Object oid, OpenJPAStateManager sm) {
-        return (sm == null) ? null : sm.getManagedInstance();
-    }
-
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        assertOpen();
-        lock();
-        try {
-            if (isActive()) {
-                if (!getOptimistic())
-                    throw new InvalidStateException(
-                        _loc.get("cant-serialize-pessimistic-broker"));
-                if (hasFlushed())
-                    throw new InvalidStateException(
-                        _loc.get("cant-serialize-flushed-broker"));
-                if (hasConnection())
-                    throw new InvalidStateException(
-                        _loc.get("cant-serialize-connected-broker"));
-            }
-
-            try {
-                _isSerializing = true;
-                out.writeObject(_factory.getPoolKey());
-                out.defaultWriteObject();
-            } finally {
-                _isSerializing = false;
-            }
-        } finally {
-            unlock();
-        }
-    }
-
-    private void readObject(ObjectInputStream in)
-        throws ClassNotFoundException, IOException {
-        Object factoryKey = in.readObject();
-        AbstractBrokerFactory factory =
-            AbstractBrokerFactory.getPooledFactoryForKey(factoryKey);
-
-        // this needs to happen before defaultReadObject so that it's
-        // available for calls to broker.getConfiguration() during
-        // StateManager deserialization
-        _conf = factory.getConfiguration();
-        
-        in.defaultReadObject();
-        factory.initializeBroker(_managed, _connRetainMode, this, true);
-
-        // re-initialize the lock if needed.
-        setMultithreaded(_multithreaded);
-
-        if (isActive() && _runtime instanceof LocalManagedRuntime)
-            ((LocalManagedRuntime) _runtime).begin();
-    }
-
-    /**
-     * Whether or not this broker is in the midst of being serialized.
-     *
-     * @since 1.1.0 
-     */
-    boolean isSerializing() {
-        return _isSerializing;
-    }
-
-    /**
-     * Transactional cache that holds soft refs to clean instances.
-     */
-    static class TransactionalCache
-        implements Set, Serializable {
-
-        private final boolean _orderDirty;
-        private Set _dirty = null;
-        private Set _clean = null;
-
-        public TransactionalCache(boolean orderDirty) {
-            _orderDirty = orderDirty;
-        }
-
-        /**
-         * Return a copy of all transactional state managers.
-         */
-        public Collection copy() {
-            if (isEmpty())
-                return Collections.EMPTY_LIST;
-
-            // size may not be entirely accurate due to refs expiring, so
-            // manually copy each object; doesn't matter this way if size too
-            // big by some
-            List copy = new ArrayList(size());
-            if (_dirty != null)
-                for (Iterator itr = _dirty.iterator(); itr.hasNext();)
-                    copy.add(itr.next());
-            if (_clean != null)
-                for (Iterator itr = _clean.iterator(); itr.hasNext();)
-                    copy.add(itr.next());
-            return copy;
-        }
-
-        /**
-         * Return a copy of all dirty state managers.
-         */
-        public Collection copyDirty() {
-            if (_dirty == null || _dirty.isEmpty())
-                return Collections.EMPTY_LIST;
-            return new ArrayList(_dirty);
-        }
-
-        /**
-         * Transfer the given instance from the dirty cache to the clean cache.
-         */
-        public void flushed(StateManagerImpl sm) {
-            if (sm.isDirty() && _dirty != null && _dirty.remove(sm))
-                addCleanInternal(sm);
-        }
-
-        /**
-         * Add the given instance to the clean cache.
-         */
-        public void addClean(StateManagerImpl sm) {
-            if (addCleanInternal(sm) && _dirty != null)
-                _dirty.remove(sm);
-        }
-
-        private boolean addCleanInternal(StateManagerImpl sm) {
-            if (_clean == null)
-                _clean = new ReferenceHashSet(ReferenceHashSet.SOFT);
-            return _clean.add(sm);
-        }
-
-        /**
-         * Add the given instance to the dirty cache.
-         */
-        public void addDirty(StateManagerImpl sm) {
-            if (_dirty == null) {
-                if (_orderDirty)
-                    _dirty = MapBackedSet.decorate(new LinkedMap());
-                else
-                    _dirty = new HashSet();
-            }
-            if (_dirty.add(sm))
-                removeCleanInternal(sm);
-        }
-
-        /**
-         * Remove the given instance from the cache.
-         */
-        public boolean remove(StateManagerImpl sm) {
-            return removeCleanInternal(sm)
-                || (_dirty != null && _dirty.remove(sm));
-        }
-
-        private boolean removeCleanInternal(StateManagerImpl sm) {
-            return _clean != null && _clean.remove(sm);
-        }
-
-        public Iterator iterator() {
-            IteratorChain chain = new IteratorChain();
-            if (_dirty != null && !_dirty.isEmpty())
-                chain.addIterator(_dirty.iterator());
-            if (_clean != null && !_clean.isEmpty())
-                chain.addIterator(_clean.iterator());
-            return chain;
-        }
-
-        public boolean contains(Object obj) {
-            return (_dirty != null && _dirty.contains(obj))
-                || (_clean != null && _clean.contains(obj));
-        }
-
-        public boolean containsAll(Collection coll) {
-            for (Iterator itr = coll.iterator(); itr.hasNext();)
-                if (!contains(itr.next()))
-                    return false;
-            return true;
-        }
-
-        public void clear() {
-            if (_dirty != null)
-                _dirty = null;
-            if (_clean != null)
-                _clean = null;
-        }
-
-        public boolean isEmpty() {
-            return (_dirty == null || _dirty.isEmpty())
-                && (_clean == null || _clean.isEmpty());
-        }
-
-        public int size() {
-            int size = 0;
-            if (_dirty != null)
-                size += _dirty.size();
-            if (_clean != null)
-                size += _clean.size();
-            return size;
-        }
-
-        public boolean add(Object obj) {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean addAll(Collection coll) {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean remove(Object obj) {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean removeAll(Collection coll) {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean retainAll(Collection c) {
-            throw new UnsupportedOperationException();
-        }
-
-        public Object[] toArray() {
-            throw new UnsupportedOperationException();
-        }
-
-        public Object[] toArray(Object[] arr) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    /**
-     * Unique id for state managers of new datastore instances without assigned
-     * object ids.
-     */
-    private static class StateManagerId
-        implements Serializable {
-
-        public static final String STRING_PREFIX = "openjpasm:";
-
-        private static long _generator = 0;
-
-        private final int _bhash;
-        private final long _id;
-
-        public static StateManagerId newInstance(Broker b) {
-            return new StateManagerId(System.identityHashCode(b), _generator++);
-        }
-
-        private StateManagerId(int bhash, long id) {
-            _bhash = bhash;
-            _id = id;
-        }
-
-        public StateManagerId(String str) {
-            str = str.substring(STRING_PREFIX.length());
-            int idx = str.indexOf(':');
-            _bhash = Integer.parseInt(str.substring(0, idx));
-            _id = Long.parseLong(str.substring(idx + 1));
-        }
-
-        public boolean equals(Object other) {
-            if (other == this)
-                return true;
-            if (!(other instanceof StateManagerId))
-                return false;
-            StateManagerId sid = (StateManagerId) other;
-            return _bhash == sid._bhash && _id == sid._id;
-        }
-
-        public int hashCode() {
-            return (int) (_id ^ (_id >>> 32));
-        }
-
-        public String toString() {
-            return STRING_PREFIX + _bhash + ":" + _id;
-        }
-    }
-
-    /**
-     * Collection type that holds state managers but whose interface deals
-     * with the corresponding managed objects.
-     */
-    private static class ManagedObjectCollection
-        extends AbstractCollection {
-
-        private final Collection _states;
-
-        public ManagedObjectCollection(Collection states) {
-            _states = states;
-        }
-
-        public Collection getStateManagers() {
-            return _states;
-        }
-
-        public int size() {
-            return _states.size();
-        }
-
-        public Iterator iterator() {
-            return new Iterator() {
-                private final Iterator _itr = _states.iterator();
-
-                public boolean hasNext() {
-                    return _itr.hasNext();
-                }
-
-                public Object next() {
-                    return ((OpenJPAStateManager) _itr.next()).
-                        getManagedInstance();
-                }
-
-                public void remove() {
-                    throw new UnsupportedException();
-                }
-            };
-        }
-    }
-
-    /**
-     * Assign the object id to the cache. Exception will be
-     * thrown if the id already exists in the cache. 
-     */
-    protected void assignObjectId(Object cache, Object id, 
-        StateManagerImpl sm) {
-        ((ManagedCache) cache).assignObjectId(id, sm); 
-    }
-
-    /** 
-     * This method makes sure we don't already have the instance cached
-     */
-    protected void checkForDuplicateId(Object id, Object obj) {
-        StateManagerImpl other = getStateManagerImplById(id, false);
-        if (other != null && !other.isDeleted() && !other.isNew())
-            throw new ObjectExistsException(_loc.get("cache-exists",
-                obj.getClass().getName(), id)).setFailedObject(obj);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.commons.collections.map.IdentityMap;
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.commons.collections.set.MapBackedSet;
+import org.apache.openjpa.conf.Compatibility;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.enhance.PCRegistry;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.LifecycleEventManager;
+import org.apache.openjpa.event.RemoteCommitEventManager;
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.event.TransactionEventManager;
+import org.apache.openjpa.kernel.exps.ExpressionParser;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.ReferenceHashMap;
+import org.apache.openjpa.lib.util.ReferenceHashSet;
+import org.apache.openjpa.lib.util.ReferenceMap;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.SequenceMetaData;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.util.ApplicationIds;
+import org.apache.openjpa.util.CallbackException;
+import org.apache.openjpa.util.Exceptions;
+import org.apache.openjpa.util.GeneralException;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.InvalidStateException;
+import org.apache.openjpa.util.NoTransactionException;
+import org.apache.openjpa.util.ObjectExistsException;
+import org.apache.openjpa.util.ObjectId;
+import org.apache.openjpa.util.ObjectNotFoundException;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.OptimisticException;
+import org.apache.openjpa.util.RuntimeExceptionTranslator;
+import org.apache.openjpa.util.StoreException;
+import org.apache.openjpa.util.UnsupportedException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Concrete {@link Broker}. The broker handles object-level behavior,
+ * but leaves all interaction with the data store to a {@link StoreManager}
+ * that must be supplied at initialization.
+ *
+ * @author Abe White
+ */
+public class BrokerImpl
+    implements Broker, FindCallbacks, Cloneable, Serializable {
+
+    /**
+     * Incremental flush.
+     */
+    protected static final int FLUSH_INC = 0;
+
+    /**
+     * Flush in preparation of commit.
+     */
+    protected static final int FLUSH_COMMIT = 1;
+
+    /**
+     * Flush to check consistency of cache, then immediately rollback changes.
+     */
+    protected static final int FLUSH_ROLLBACK = 2;
+
+    /**
+     * Run persistence-by-reachability and other flush-time operations without
+     * accessing the database.
+     */
+    protected static final int FLUSH_LOGICAL = 3;
+
+    static final int STATUS_INIT = 0;
+    static final int STATUS_TRANSIENT = 1;
+    static final int STATUS_OID_ASSIGN = 2;
+    static final int STATUS_COMMIT_NEW = 3;
+
+    private static final int FLAG_ACTIVE = 2 << 0;
+    private static final int FLAG_STORE_ACTIVE = 2 << 1;
+    private static final int FLAG_CLOSE_INVOKED = 2 << 2;
+    private static final int FLAG_PRESTORING = 2 << 3;
+    private static final int FLAG_DEREFDELETING = 2 << 4;
+    private static final int FLAG_FLUSHING = 2 << 5;
+    private static final int FLAG_STORE_FLUSHING = 2 << 6;
+    private static final int FLAG_FLUSHED = 2 << 7;
+    private static final int FLAG_FLUSH_REQUIRED = 2 << 8;
+    private static final int FLAG_REMOTE_LISTENER = 2 << 9;
+    private static final int FLAG_RETAINED_CONN = 2 << 10;
+    private static final int FLAG_TRANS_ENDING = 2 << 11;
+
+    private static final Object[] EMPTY_OBJECTS = new Object[0];
+
+    private static final Localizer _loc =
+        Localizer.forPackage(BrokerImpl.class);
+
+    //	the store manager in use; this may be a decorator such as a
+    //	data cache store manager around the native store manager
+    private transient DelegatingStoreManager _store = null;
+
+    private FetchConfiguration _fc = null;
+    private String _user = null;
+    private String _pass = null;
+
+    // these must be rebuilt by the facade layer during its deserialization
+    private transient Log _log = null;
+    private transient Compatibility _compat = null;
+    private transient ManagedRuntime _runtime = null;
+    private transient LockManager _lm = null;
+    private transient InverseManager _im = null;
+    private transient ReentrantLock _lock = null;
+    private transient OpCallbacks _call = null;
+    private transient RuntimeExceptionTranslator _extrans = null;
+
+    // ref to producing factory and configuration
+    private transient AbstractBrokerFactory _factory = null;
+    private transient OpenJPAConfiguration _conf = null;
+
+    // cache class loader associated with the broker
+    private transient ClassLoader _loader = null;
+
+    // user state
+    private Synchronization _sync = null;
+    private Map _userObjects = null;
+
+    // managed object caches
+    private ManagedCache _cache = null;
+    private TransactionalCache _transCache = null;
+    private Set _transAdditions = null;
+    private Set _derefCache = null;
+    private Set _derefAdditions = null;
+
+    // these are used for method-internal state only
+    private transient Map _loading = null;
+    private transient Set _operating = null;
+
+    private Set _persistedClss = null;
+    private Set _updatedClss = null;
+    private Set _deletedClss = null;
+    private Set _pending = null;
+    private int findAllDepth = 0;
+
+    // track instances that become transactional after the first savepoint
+    // (the first uses the transactional cache)
+    private Set _savepointCache = null;
+    private LinkedMap _savepoints = null;
+    private transient SavepointManager _spm = null;
+
+    // track open queries and extents so we can free their resources on close
+    private transient ReferenceHashSet _queries = null;
+    private transient ReferenceHashSet _extents = null;
+
+    // track operation stack depth. Transient because operations cannot
+    // span serialization.
+    private transient int _operationCount = 0;
+
+    // options
+    private boolean _nontransRead = false;
+    private boolean _nontransWrite = false;
+    private boolean _retainState = false;
+    private int _autoClear = CLEAR_DATASTORE;
+    private int _restoreState = RESTORE_IMMUTABLE;
+    private boolean _optimistic = false;
+    private boolean _ignoreChanges = false;
+    private boolean _multithreaded = false;
+    private boolean _managed = false;
+    private boolean _syncManaged = false;
+    private int _connRetainMode = CONN_RETAIN_DEMAND;
+    private boolean _evictDataCache = false;
+    private boolean _populateDataCache = true;
+    private boolean _largeTransaction = false;
+    private int _autoDetach = 0;
+    private int _detachState = DETACH_LOADED;
+    private boolean _detachedNew = true;
+    private boolean _orderDirty = false;
+    private boolean _suppressBatchOLELogging = false;
+
+    // status
+    private int _flags = 0;
+
+    // this is not in status because it should not be serialized
+    private transient boolean _isSerializing = false;
+
+    // transient because closed brokers can't be serialized
+    private transient boolean _closed = false;
+    private transient RuntimeException _closedException = null;
+
+    // event managers
+    private TransactionEventManager _transEventManager = null;
+    private int _transCallbackMode = 0;
+    private LifecycleEventManager _lifeEventManager = null;
+    private int _lifeCallbackMode = 0;
+
+    private transient boolean _initializeWasInvoked = false;
+    private LinkedList _fcs;
+
+    /**
+     * Set the persistence manager's authentication. This is the first
+     * method called after construction.
+     *
+     * @param user the username this broker represents; used when pooling
+     * brokers to make sure that a request to the factory for
+     * a connection with an explicit user is delegated to a suitable broker
+     * @param pass the password for the above user
+     */
+    public void setAuthentication(String user, String pass) {
+        _user = user;
+        _pass = pass;
+    }
+
+    /**
+     * Initialize the persistence manager. This method is called
+     * automatically by the factory before use.
+     *
+     * @param factory the factory used to create this broker
+     * @param sm a concrete StoreManager implementation to
+     * handle interaction with the data store
+     * @param managed the transaction mode
+     * @param connMode the connection retain mode
+     * @param fromDeserialization whether this call happened because of a
+     * deserialization or creation of a new BrokerImpl.
+     */
+    public void initialize(AbstractBrokerFactory factory,
+        DelegatingStoreManager sm, boolean managed, int connMode,
+        boolean fromDeserialization) {
+        _initializeWasInvoked = true;
+        _loader = (ClassLoader) AccessController.doPrivileged(
+            J2DoPrivHelper.getContextClassLoaderAction());
+        if (!fromDeserialization)
+            _conf = factory.getConfiguration();
+        _compat = _conf.getCompatibilityInstance();
+        _factory = factory;
+        _log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
+        if (!fromDeserialization)
+            _cache = new ManagedCache(this);
+        initializeOperatingSet();
+        _connRetainMode = connMode;
+        _managed = managed;
+        if (managed)
+            _runtime = _conf.getManagedRuntimeInstance();
+        else
+            _runtime = new LocalManagedRuntime(this);
+
+        if (!fromDeserialization) {
+            _lifeEventManager = new LifecycleEventManager();
+            _transEventManager = new TransactionEventManager();
+            int cmode = _conf.getMetaDataRepositoryInstance().
+                getMetaDataFactory().getDefaults().getCallbackMode();
+            setLifecycleListenerCallbackMode(cmode);
+            setTransactionListenerCallbackMode(cmode);
+
+            // setup default options
+            _factory.configureBroker(this);
+        }
+
+        // make sure to do this after configuring broker so that store manager
+        // can look to broker configuration; we set both store and lock managers
+        // before initializing them because they may each try to access the
+        // other in thier initialization
+        _store = sm;
+        _lm = _conf.newLockManagerInstance();
+        _im = _conf.newInverseManagerInstance();
+        _spm = _conf.getSavepointManagerInstance();
+        _store.setContext(this);
+        _lm.setContext(this);
+
+        if (_connRetainMode == CONN_RETAIN_ALWAYS)
+            retainConnection();
+        if (!fromDeserialization) {
+            _fc = _store.newFetchConfiguration();
+            _fc.setContext(this);
+        }
+
+        // synch with the global transaction in progress, if any
+        if (_factory.syncWithManagedTransaction(this, false))
+            beginInternal();
+    }
+
+    private void initializeOperatingSet() {
+        _operating = MapBackedSet.decorate(new IdentityMap());
+    }
+    
+    /**
+     * Gets the unmodifiable set of instances being operated.
+     */
+    protected Set getOperatingSet() {
+    	return Collections.unmodifiableSet(_operating);
+    }
+
+    public Object clone()
+        throws CloneNotSupportedException {
+        if (_initializeWasInvoked)
+            throw new CloneNotSupportedException();
+        else {
+            return super.clone();
+        }
+    }
+
+    /**
+     * Create a {@link Map} to be used for the primary managed object cache.
+     * Maps oids to state managers. By default, this creates a
+     * {@link ReferenceMap} with soft values.
+     */
+    protected Map newManagedObjectCache() {
+        return new ReferenceHashMap(ReferenceMap.HARD, ReferenceMap.SOFT);
+    }
+
+    //////////////////////////////////
+    // Implementation of StoreContext
+    //////////////////////////////////
+
+    public Broker getBroker() {
+        return this;
+    }
+
+    //////////////
+    // Properties
+    //////////////
+
+    public void setImplicitBehavior(OpCallbacks call,
+        RuntimeExceptionTranslator ex) {
+        if (_call == null)
+            _call = call;
+        if (_extrans == null)
+            _extrans = ex;
+    }
+
+    RuntimeExceptionTranslator getInstanceExceptionTranslator() {
+        return (_operationCount == 0) ? _extrans : null;
+    }
+
+    public BrokerFactory getBrokerFactory() {
+        return _factory;
+    }
+
+    public OpenJPAConfiguration getConfiguration() {
+        return _conf;
+    }
+
+    public FetchConfiguration getFetchConfiguration() {
+        return _fc;
+    }
+
+    public FetchConfiguration pushFetchConfiguration() {
+        if (_fcs == null)
+            _fcs = new LinkedList();
+        _fcs.add(_fc);
+        _fc = (FetchConfiguration) _fc.clone();
+        return _fc;
+    }
+
+    public void popFetchConfiguration() {
+        if (_fcs == null || _fcs.isEmpty())
+            throw new UserException(_loc.get("fetch-configuration-stack-empty"));
+        _fc = (FetchConfiguration) _fcs.removeLast();
+    }
+
+    public int getConnectionRetainMode() {
+        return _connRetainMode;
+    }
+
+    public boolean isManaged() {
+        return _managed;
+    }
+
+    public ManagedRuntime getManagedRuntime() {
+        return _runtime;
+    }
+
+    public ClassLoader getClassLoader() {
+        return _loader;
+    }
+
+    public DelegatingStoreManager getStoreManager() {
+        return _store;
+    }
+
+    public LockManager getLockManager() {
+        return _lm;
+    }
+
+    public InverseManager getInverseManager() {
+        return _im;
+    }
+
+    public String getConnectionUserName() {
+        return _user;
+    }
+
+    public String getConnectionPassword() {
+        return _pass;
+    }
+
+    public boolean getMultithreaded() {
+        return _multithreaded;
+    }
+
+    public void setMultithreaded(boolean multithreaded) {
+        assertOpen();
+        _multithreaded = multithreaded;
+        if (multithreaded && _lock == null)
+            _lock = new ReentrantLock();
+        else if (!multithreaded)
+            _lock = null;
+    }
+
+    public boolean getIgnoreChanges() {
+        return _ignoreChanges;
+    }
+
+    public void setIgnoreChanges(boolean val) {
+        assertOpen();
+        _ignoreChanges = val;
+    }
+
+    public boolean getNontransactionalRead() {
+        return _nontransRead;
+    }
+
+    public void setNontransactionalRead(boolean val) {
+        assertOpen();
+        if ((_flags & FLAG_PRESTORING) != 0)
+            throw new UserException(_loc.get("illegal-op-in-prestore"));
+
+        // make sure the runtime supports it
+        if (val && !_conf.supportedOptions().contains
+            (_conf.OPTION_NONTRANS_READ))
+            throw new UnsupportedException(_loc.get
+                ("nontrans-read-not-supported"));
+
+        _nontransRead = val;
+    }
+
+    public boolean getNontransactionalWrite() {
+        return _nontransWrite;
+    }
+
+    public void setNontransactionalWrite(boolean val) {
+        assertOpen();
+        if ((_flags & FLAG_PRESTORING) != 0)
+            throw new UserException(_loc.get("illegal-op-in-prestore"));
+
+        _nontransWrite = val;
+    }
+
+    public boolean getOptimistic() {
+        return _optimistic;
+    }
+
+    public void setOptimistic(boolean val) {
+        assertOpen();
+        if ((_flags & FLAG_ACTIVE) != 0)
+            throw new InvalidStateException(_loc.get("trans-active",
+                "Optimistic"));
+
+        // make sure the runtime supports it
+        if (val && !_conf.supportedOptions().contains(_conf.OPTION_OPTIMISTIC))
+            throw new UnsupportedException(_loc.get
+                ("optimistic-not-supported"));
+
+        _optimistic = val;
+    }
+
+    public int getRestoreState() {
+        return _restoreState;
+    }
+
+    public void setRestoreState(int val) {
+        assertOpen();
+        if ((_flags & FLAG_ACTIVE) != 0)
+            throw new InvalidStateException(_loc.get("trans-active",
+                "Restore"));
+
+        _restoreState = val;
+    }
+
+    public boolean getRetainState() {
+        return _retainState;
+    }
+
+    public void setRetainState(boolean val) {
+        assertOpen();
+        if ((_flags & FLAG_PRESTORING) != 0)
+            throw new UserException(_loc.get("illegal-op-in-prestore"));
+        _retainState = val;
+    }
+
+    public int getAutoClear() {
+        return _autoClear;
+    }
+
+    public void setAutoClear(int val) {
+        assertOpen();
+        _autoClear = val;
+    }
+
+    public int getAutoDetach() {
+        return _autoDetach;
+    }
+
+    public void setAutoDetach(int detachFlags) {
+        assertOpen();
+        _autoDetach = detachFlags;
+    }
+
+    public void setAutoDetach(int detachFlag, boolean on) {
+        assertOpen();
+        if (on)
+            _autoDetach |= detachFlag;
+        else
+            _autoDetach &= ~detachFlag;
+    }
+
+    public int getDetachState() {
+        return _detachState;
+    }
+
+    public void setDetachState(int mode) {
+        assertOpen();
+        _detachState = mode;
+    }
+
+    public boolean isDetachedNew() {
+        return _detachedNew;
+    }
+
+    public void setDetachedNew(boolean isNew) {
+        assertOpen();
+        _detachedNew = isNew;
+    }
+
+    public boolean getSyncWithManagedTransactions() {
+        return _syncManaged;
+    }
+
+    public void setSyncWithManagedTransactions(boolean sync) {
+        assertOpen();
+        _syncManaged = sync;
+    }
+
+    public boolean getEvictFromDataCache() {
+        return _evictDataCache;
+    }
+
+    public void setEvictFromDataCache(boolean evict) {
+        assertOpen();
+        _evictDataCache = evict;
+    }
+
+    public boolean getPopulateDataCache() {
+        return _populateDataCache;
+    }
+
+    public void setPopulateDataCache(boolean cache) {
+        assertOpen();
+        _populateDataCache = cache;
+    }
+
+    public boolean isTrackChangesByType() {
+        return _largeTransaction;
+    }
+
+    public void setTrackChangesByType(boolean largeTransaction) {
+        assertOpen();
+        _largeTransaction = largeTransaction;
+    }
+
+    public Object getUserObject(Object key) {
+        beginOperation(false);
+        try {
+            return (_userObjects == null) ? null : _userObjects.get(key);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Object putUserObject(Object key, Object val) {
+        beginOperation(false);
+        try {
+            if (val == null)
+                return (_userObjects == null) ? null : _userObjects.remove(key);
+
+            if (_userObjects == null)
+                _userObjects = new HashMap();
+            return _userObjects.put(key, val);
+        } finally {
+            endOperation();
+        }
+    }
+
+    //////////
+    // Events
+    //////////
+
+    public void addLifecycleListener(Object listener, Class[] classes) {
+        beginOperation(false);
+        try {
+            _lifeEventManager.addListener(listener, classes);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void removeLifecycleListener(Object listener) {
+        beginOperation(false);
+        try {
+            _lifeEventManager.removeListener(listener);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public int getLifecycleListenerCallbackMode() {
+        return _lifeCallbackMode;
+    }
+
+    public void setLifecycleListenerCallbackMode(int mode) {
+        beginOperation(false);
+        try {
+            _lifeCallbackMode = mode;
+            _lifeEventManager.setFailFast((mode & CALLBACK_FAIL_FAST) != 0);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Give state managers access to the lifecycle event manager.
+     */
+    public LifecycleEventManager getLifecycleEventManager() {
+        return _lifeEventManager;
+    }
+
+    /**
+     * Fire given lifecycle event, handling any exceptions appropriately.
+     *
+     * @return whether events are being processed at this time
+     */
+    boolean fireLifecycleEvent(Object src, Object related, ClassMetaData meta,
+        int eventType) {
+        if (_lifeEventManager == null)
+            return false;
+        handleCallbackExceptions(_lifeEventManager.fireEvent(src, related, 
+            meta, eventType), _lifeCallbackMode);
+        return true;
+    }
+
+    /**
+     * Take actions on callback exceptions depending on callback mode.
+     */
+    private void handleCallbackExceptions(Exception[] exceps, int mode) {
+        if (exceps.length == 0 || (mode & CALLBACK_IGNORE) != 0)
+            return;
+
+        OpenJPAException ce;
+        if (exceps.length == 1)
+            ce = new CallbackException(exceps[0]);
+        else 
+            ce = new CallbackException(_loc.get("callback-err")).
+                setNestedThrowables(exceps);
+        if ((mode & CALLBACK_ROLLBACK) != 0 && (_flags & FLAG_ACTIVE) != 0) {
+            ce.setFatal(true);
+            setRollbackOnlyInternal(ce);
+        }
+        if ((mode & CALLBACK_LOG) != 0 && _log.isWarnEnabled())
+            _log.warn(ce);
+        if ((mode & CALLBACK_RETHROW) != 0)
+            throw ce;
+    }
+
+    public void addTransactionListener(Object tl) {
+        beginOperation(false);
+        try {
+            _transEventManager.addListener(tl);
+            if (tl instanceof RemoteCommitEventManager)
+                _flags |= FLAG_REMOTE_LISTENER;
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void removeTransactionListener(Object tl) {
+        beginOperation(false);
+        try {
+            if (_transEventManager.removeListener(tl)
+                && (tl instanceof RemoteCommitEventManager))
+                _flags &= ~FLAG_REMOTE_LISTENER;
+        } finally {
+            endOperation();
+        }
+    }
+
+    public int getTransactionListenerCallbackMode() {
+        return _transCallbackMode;
+    }
+
+    public void setTransactionListenerCallbackMode(int mode) {
+        beginOperation(false);
+        try {
+            _transCallbackMode = mode;
+            _transEventManager.setFailFast((mode & CALLBACK_FAIL_FAST) != 0);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Fire given transaction event, handling any exceptions appropriately.
+     */
+    private void fireTransactionEvent(TransactionEvent trans) {
+        if (_transEventManager != null)
+            handleCallbackExceptions(_transEventManager.fireEvent(trans),
+                _transCallbackMode);
+    }
+
+    /**
+     * Set whether this Broker will generate verbose optimistic lock exceptions when batching
+     * operations. Defaults to true.
+     * 
+     * @param b
+     */
+    public void setSuppressBatchOLELogging(boolean b) {
+        _suppressBatchOLELogging = b;
+    }
+    
+    /**
+     * Return whether this Broker will generate verbose optimistic lock exceptions when batching
+     * operations.
+     */
+    public boolean getSuppressBatchOLELogging() {
+        return _suppressBatchOLELogging;
+    }
+    ///////////
+    // Lookups
+    ///////////
+
+    public Object find(Object oid, boolean validate, FindCallbacks call) {
+        int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
+        if (!validate)
+            flags |= OID_NOVALIDATE;
+        return find(oid, _fc, null, null, flags, call);
+    }
+
+    public Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
+        Object edata, int flags) {
+        return find(oid, fetch, exclude, edata, flags, null);
+    }
+
+    /**
+     * Internal finder.
+     */
+    protected Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
+        Object edata, int flags, FindCallbacks call) {
+        if (call == null)
+            call = this;
+        oid = call.processArgument(oid);
+        if (oid == null) {
+            if ((flags & OID_NOVALIDATE) == 0)
+                throw new ObjectNotFoundException(_loc.get("null-oid"));
+            return call.processReturn(oid, null);
+        }
+        if (fetch == null)
+            fetch = _fc;
+
+        beginOperation(true);
+        try {
+            assertNontransactionalRead();
+
+            // cached instance?
+            StateManagerImpl sm = getStateManagerImplById(oid,
+                (flags & OID_ALLOW_NEW) != 0 || hasFlushed());
+            if (sm != null) {
+                if (!requiresLoad(sm, true, fetch, edata, flags))
+                    return call.processReturn(oid, sm);
+
+                if (!sm.isLoading()) {
+                    // make sure all the configured fields are loaded; do this
+                    // after making instance transactional for locking
+                    if (!sm.isTransactional() && useTransactionalState(fetch))
+                        sm.transactional();
+                    boolean loaded;
+                    try {
+                        loaded = sm.load(fetch, StateManagerImpl.LOAD_FGS, 
+                            exclude, edata, false);
+                    } catch (ObjectNotFoundException onfe) {
+                        if ((flags & OID_NODELETED) != 0
+                            || (flags & OID_NOVALIDATE) != 0)
+                            throw onfe;
+                        return call.processReturn(oid, null);
+                    }
+
+                    // if no data needed to be loaded and the user wants to
+                    // validate, just make sure the object exists
+                    if (!loaded && (flags & OID_NOVALIDATE) == 0
+                        && _compat.getValidateTrueChecksStore()
+                        && !sm.isTransactional()
+                        && !_store.exists(sm, edata)) {
+                        if ((flags & OID_NODELETED) == 0)
+                            return call.processReturn(oid, null);
+                        throw new ObjectNotFoundException(_loc.get
+                            ("del-instance", sm.getManagedInstance(), oid)).
+                            setFailedObject(sm.getManagedInstance());
+                    }
+                }
+
+                // since the object was cached, we may need to upgrade lock
+                // if current level is higher than level of initial load
+                if ((_flags & FLAG_ACTIVE) != 0) {
+                    int level = fetch.getReadLockLevel();
+                    _lm.lock(sm, level, fetch.getLockTimeout(), edata);
+                    sm.readLocked(level, fetch.getWriteLockLevel());
+                }
+                return call.processReturn(oid, sm);
+            }
+
+            // if there's no cached sm for a new/transient id type, we
+            // it definitely doesn't exist
+            if (oid instanceof StateManagerId)
+                return call.processReturn(oid, null);
+
+            // initialize a new state manager for the datastore instance
+            sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
+            boolean load = requiresLoad(sm, false, fetch, edata, flags);
+            sm = initialize(sm, load, fetch, edata);
+            if (sm == null) {
+                if ((flags & OID_NOVALIDATE) != 0)
+                    throw new ObjectNotFoundException(oid);
+                return call.processReturn(oid, null);
+            }
+
+            // make sure all configured fields were loaded
+            if (load) {
+                try {
+                    sm.load(fetch, StateManagerImpl.LOAD_FGS, exclude,
+                        edata, false);
+                } catch (ObjectNotFoundException onfe) {
+                    if ((flags & OID_NODELETED) != 0
+                        || (flags & OID_NOVALIDATE) != 0)
+                        throw onfe;
+                    return call.processReturn(oid, null);
+                }
+            }
+            return call.processReturn(oid, sm);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Initialize a newly-constructed state manager.
+     */
+    protected StateManagerImpl initialize(StateManagerImpl sm, boolean load,
+        FetchConfiguration fetch, Object edata) {
+        if (!load) {
+            sm.initialize(sm.getMetaData().getDescribedType(),
+                PCState.HOLLOW);
+        } else {
+            PCState state = (useTransactionalState(fetch))
+                ? PCState.PCLEAN : PCState.PNONTRANS;
+            sm.setLoading(true);
+            try {
+                if (!_store.initialize(sm, state, fetch, edata))
+                    return null;
+            } finally {
+                sm.setLoading(false);
+            }
+        }
+        return sm;
+    }
+
+    public Object[] findAll(Collection oids, boolean validate,
+        FindCallbacks call) {
+        int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
+        if (!validate)
+            flags |= OID_NOVALIDATE;
+        return findAll(oids, _fc, null, null, flags, call);
+    }
+
+    public Object[] findAll(Collection oids, FetchConfiguration fetch,
+        BitSet exclude, Object edata, int flags) {
+        return findAll(oids, fetch, exclude, edata, flags, null);
+    }
+
+    /**
+     * Internal finder.
+     */
+    protected Object[] findAll(Collection oids, FetchConfiguration fetch,
+        BitSet exclude, Object edata, int flags, FindCallbacks call) {
+        findAllDepth ++;
+
+        // throw any exceptions for null oids up immediately
+        if (oids == null)
+            throw new NullPointerException("oids == null");
+        if ((flags & OID_NOVALIDATE) != 0 && oids.contains(null))
+            throw new UserException(_loc.get("null-oids"));
+
+        // we have to use a map of oid->sm rather than a simple
+        // array, so that we make sure not to create multiple sms for equivalent
+        // oids if the user has duplicates in the given array
+        if (_loading == null)
+            _loading = new HashMap((int) (oids.size() * 1.33 + 1));
+
+        if (call == null)
+            call = this;
+        if (fetch == null)
+            fetch = _fc;
+
+        beginOperation(true);
+        try {
+            assertNontransactionalRead();
+
+            // collection of state managers to pass to store manager
+            List load = null;
+            StateManagerImpl sm;
+            boolean initialized;
+            boolean transState = useTransactionalState(fetch);
+            Object obj, oid;
+            int idx = 0;
+            for (Iterator itr = oids.iterator(); itr.hasNext(); idx++) {
+                // if we've already seen this oid, skip repeats
+                obj = itr.next();
+                oid = call.processArgument(obj);
+                if (oid == null || _loading.containsKey(obj))
+                    continue;
+
+                // if we don't have a cached instance or it is not transactional
+                // and is hollow or we need to validate, load it
+                sm = getStateManagerImplById(oid, (flags & OID_ALLOW_NEW) != 0
+                    || hasFlushed());
+                initialized = sm != null;
+                if (!initialized)
+                    sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
+
+                _loading.put(obj, sm);
+                if (requiresLoad(sm, initialized, fetch, edata, flags)) {
+                    transState = transState || useTransactionalState(fetch);
+                    if (initialized && !sm.isTransactional() && transState)
+                        sm.transactional();
+                    if (load == null)
+                        load = new ArrayList(oids.size() - idx);
+                    load.add(sm);
+                } else if (!initialized)
+                    sm.initialize(sm.getMetaData().getDescribedType(),
+                        PCState.HOLLOW);
+            }
+
+            // pass all state managers in need of loading or validation to the
+            // store manager
+            if (load != null) {
+                PCState state = (transState) ? PCState.PCLEAN
+                    : PCState.PNONTRANS;
+                Collection failed = _store.loadAll(load, state,
+                    StoreManager.FORCE_LOAD_NONE, fetch, edata);
+
+                // set failed instances to null
+                if (failed != null && !failed.isEmpty()) {
+                    if ((flags & OID_NOVALIDATE) != 0)
+                        throw newObjectNotFoundException(failed);
+                    for (Iterator itr = failed.iterator(); itr.hasNext();)
+                        _loading.put(itr.next(), null);
+                }
+            }
+
+            // create results array; make sure all configured fields are
+            // loaded in each instance
+            Object[] results = new Object[oids.size()];
+            boolean active = (_flags & FLAG_ACTIVE) != 0;
+            int level = fetch.getReadLockLevel();
+            idx = 0;
+            for (Iterator itr = oids.iterator(); itr.hasNext(); idx++) {
+                oid = itr.next();
+                sm = (StateManagerImpl) _loading.get(oid);
+                if (sm != null && requiresLoad(sm, true, fetch, edata, flags)) {
+                    try {
+                        sm.load(fetch, StateManagerImpl.LOAD_FGS,
+                        	exclude, edata, false);
+                        if (active) {
+                            _lm.lock(sm, level, fetch.getLockTimeout(), edata);
+                            sm.readLocked(level, fetch.getWriteLockLevel());
+                        }
+                    }
+                    catch (ObjectNotFoundException onfe) {
+                        if ((flags & OID_NODELETED) != 0
+                            || (flags & OID_NOVALIDATE) != 0)
+                            throw onfe;
+                        sm = null;
+                    }
+                }
+                results[idx] = call.processReturn(oid, sm);
+            }
+            return results;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            findAllDepth--;
+            if (findAllDepth == 0)
+                _loading = null;
+            endOperation();
+        }
+    }
+
+    private boolean hasFlushed() {
+        return (_flags & FLAG_FLUSHED) != 0;
+    }
+
+    /**
+     * Return whether the given instance needs loading before being returned
+     * to the user.
+     */
+    private boolean requiresLoad(OpenJPAStateManager sm, boolean initialized,
+        FetchConfiguration fetch, Object edata, int flags) {
+        if (!fetch.requiresLoad())
+            return false;
+        if ((flags & OID_NOVALIDATE) == 0)
+            return true;
+        if (edata != null) // take advantage of existing result
+            return true;
+        if (initialized && sm.getPCState() != PCState.HOLLOW)
+            return false;
+        if (!initialized && sm.getMetaData().getPCSubclasses().length > 0)
+            return true;
+        return !_compat.getValidateFalseReturnsHollow();
+    }
+
+    /**
+     * Return whether to use a transactional state.
+     */
+    private boolean useTransactionalState(FetchConfiguration fetch) {
+        return (_flags & FLAG_ACTIVE) != 0 && (!_optimistic
+            || _autoClear == CLEAR_ALL
+            || fetch.getReadLockLevel() != LOCK_NONE);
+    }
+
+    public Object findCached(Object oid, FindCallbacks call) {
+        if (call == null)
+            call = this;
+        oid = call.processArgument(oid);
+        if (oid == null)
+            return call.processReturn(oid, null);
+
+        beginOperation(true);
+        try {
+            StateManagerImpl sm = getStateManagerImplById(oid, true);
+            return call.processReturn(oid, sm);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Class getObjectIdType(Class cls) {
+        if (cls == null)
+            return null;
+
+        beginOperation(false);
+        try {
+            ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
+                getMetaData(cls, _loader, false);
+            if (meta == null
+                || meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
+                return null;
+            if (meta.getIdentityType() == ClassMetaData.ID_APPLICATION)
+                return meta.getObjectIdType();
+
+            return _store.getDataStoreIdType(meta);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Object newObjectId(Class cls, Object val) {
+        if (val == null)
+            return null;
+
+        beginOperation(false);
+        try {
+            ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
+                getMetaData(cls, _loader, true);
+            switch (meta.getIdentityType()) {
+            case ClassMetaData.ID_DATASTORE:
+                // delegate to store manager for datastore ids
+                if (val instanceof String
+                    && ((String) val).startsWith(StateManagerId.STRING_PREFIX))
+                    return new StateManagerId((String) val);
+                return _store.newDataStoreId(val, meta);
+            case ClassMetaData.ID_APPLICATION:
+                if (ImplHelper.isAssignable(meta.getObjectIdType(), 
+                    val.getClass())) {
+                    if (!meta.isOpenJPAIdentity() 
+                        && meta.isObjectIdTypeShared())
+                        return new ObjectId(cls, val);
+                    return val;
+                }
+
+                // stringified app id?
+                if (val instanceof String 
+                    && !_conf.getCompatibilityInstance().
+                        getStrictIdentityValues()
+                    && !Modifier.isAbstract(cls.getModifiers()))
+                    return PCRegistry.newObjectId(cls, (String) val);
+
+                Object[] arr = (val instanceof Object[]) ? (Object[]) val
+                    : new Object[]{ val };
+                return ApplicationIds.fromPKValues(arr, meta);
+            default:
+                throw new UserException(_loc.get("meta-unknownid", cls));
+            }
+        } catch (IllegalArgumentException iae) {
+        	throw new UserException(_loc.get("bad-id-value", val,
+                val.getClass().getName(), cls)).setCause(iae);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (ClassCastException cce) {
+            throw new UserException(_loc.get("bad-id-value", val,
+                val.getClass().getName(), cls)).setCause(cce);
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Create a new state manager for the given oid.
+     */
+    private StateManagerImpl newStateManagerImpl(Object oid, boolean copy) {
+        // see if we're in the process of loading this oid in a loadAll call
+        StateManagerImpl sm;
+        if (_loading != null) {
+            sm = (StateManagerImpl) _loading.get(oid);
+            if (sm != null && sm.getPersistenceCapable() == null)
+                return sm;
+        }
+
+        // find metadata for the oid
+        Class pcType = _store.getManagedType(oid);
+        MetaDataRepository repos = _conf.getMetaDataRepositoryInstance();
+        ClassMetaData meta;
+        if (pcType != null)
+            meta = repos.getMetaData(pcType, _loader, true);
+        else
+            meta = repos.getMetaData(oid, _loader, true);
+
+        // copy the oid if needed
+        if (copy && _compat.getCopyObjectIds()) {
+            if (meta.getIdentityType() == ClassMetaData.ID_APPLICATION)
+                oid = ApplicationIds.copy(oid, meta);
+            else if (meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
+                throw new UserException(_loc.get("meta-unknownid", meta));
+            else
+                oid = _store.copyDataStoreId(oid, meta);
+        }
+
+        sm = newStateManagerImpl(oid, meta);
+        sm.setObjectId(oid);
+        return sm;
+    }
+
+    /**
+     * Create a state manager for the given oid and metadata.
+     */
+    protected StateManagerImpl newStateManagerImpl(Object oid,
+        ClassMetaData meta) {
+        return new StateManagerImpl(oid, meta, this);
+    }
+
+    ///////////////
+    // Transaction
+    ///////////////
+
+    public void begin() {
+        beginOperation(true);
+        try {
+            if ((_flags & FLAG_ACTIVE) != 0)
+                throw new InvalidStateException(_loc.get("active"));
+            _factory.syncWithManagedTransaction(this, true);
+            beginInternal();
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Notify the store manager of a transaction.
+     */
+    private void beginInternal() {
+        try {
+            beginStoreManagerTransaction(_optimistic);
+            _flags |= FLAG_ACTIVE;
+
+            // start locking
+            if (!_optimistic) {
+                _fc.setReadLockLevel(_conf.getReadLockLevelConstant());
+                _fc.setWriteLockLevel(_conf.getWriteLockLevelConstant());
+                _fc.setLockTimeout(_conf.getLockTimeout());
+            }
+            _lm.beginTransaction();
+
+            if (_transEventManager.hasBeginListeners())
+                fireTransactionEvent(new TransactionEvent(this,
+                    TransactionEvent.AFTER_BEGIN, null, null, null, null));
+        } catch (OpenJPAException ke) {
+            // if we already started the transaction, don't let it commit
+            if ((_flags & FLAG_ACTIVE) != 0)
+                setRollbackOnlyInternal(ke);
+            throw ke.setFatal(true);
+        } catch (RuntimeException re) {
+            // if we already started the transaction, don't let it commit
+            if ((_flags & FLAG_ACTIVE) != 0)
+                setRollbackOnlyInternal(re);
+            throw new StoreException(re).setFatal(true);
+        }
+
+        if (_pending != null) {
+            StateManagerImpl sm;
+            for (Iterator it = _pending.iterator(); it.hasNext();) {
+                sm = (StateManagerImpl) it.next();
+                sm.transactional();
+                if (sm.isDirty())
+                    setDirty(sm, true);
+            }
+            _pending = null;
+        }
+    }
+
+    public void beginStore() {
+        beginOperation(true);
+        try {
+            assertTransactionOperation();
+            if ((_flags & FLAG_STORE_ACTIVE) == 0)
+                beginStoreManagerTransaction(false);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new StoreException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Begin a store manager transaction.
+     */
+    private void beginStoreManagerTransaction(boolean optimistic) {
+        if (!optimistic) {
+            retainConnection();
+            _store.begin();
+            _flags |= FLAG_STORE_ACTIVE;
+        } else {
+            if (_connRetainMode == CONN_RETAIN_TRANS)
+                retainConnection();
+            _store.beginOptimistic();
+        }
+    }
+
+    /**
+     * End the current store manager transaction. Throws an
+     * exception to signal a forced rollback after failed commit, otherwise
+     * returns any exception encountered during the end process.
+     */
+    private RuntimeException endStoreManagerTransaction(boolean rollback) {
+        boolean forcedRollback = false;
+        boolean releaseConn = false;
+        RuntimeException err = null;
+        try {
+            if ((_flags & FLAG_STORE_ACTIVE) != 0) {
+                releaseConn = _connRetainMode != CONN_RETAIN_ALWAYS;
+                if (rollback)
+                    _store.rollback();
+                else
+                    _store.commit();
+            } else {
+                releaseConn = _connRetainMode == CONN_RETAIN_TRANS;
+                _store.rollbackOptimistic();
+            }
+        }
+        catch (RuntimeException re) {
+            if (!rollback) {
+                forcedRollback = true;
+                try { _store.rollback(); } catch (RuntimeException re2) {}
+            }
+            err = re;
+        } finally {
+            _flags &= ~FLAG_STORE_ACTIVE;
+        }
+
+        if (releaseConn) {
+            try {
+                releaseConnection();
+            } catch (RuntimeException re) {
+                if (err == null)
+                    err = re;
+            }
+        }
+
+        if (forcedRollback)
+            throw err;
+        return err;
+    }
+
+    public void commit() {
+        beginOperation(false);
+        try {
+            assertTransactionOperation();
+
+            javax.transaction.Transaction trans =
+                _runtime.getTransactionManager().getTransaction();
+            if (trans == null)
+                throw new InvalidStateException(_loc.get("null-trans"));
+
+            // this commit on the transaction will cause our
+            // beforeCompletion method to be invoked
+            trans.commit();
+        } catch (OpenJPAException ke) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), ke);
+            throw ke;
+        } catch (Exception e) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), e);
+            throw new StoreException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void rollback() {
+        beginOperation(false);
+        try {
+            assertTransactionOperation();
+
+            javax.transaction.Transaction trans =
+                _runtime.getTransactionManager().getTransaction();
+            if (trans != null)
+                trans.rollback();
+        } catch (OpenJPAException ke) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), ke);
+            throw ke;
+        } catch (Exception e) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), e);
+            throw new StoreException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public boolean syncWithManagedTransaction() {
+        assertOpen();
+        lock();
+        try {
+            if ((_flags & FLAG_ACTIVE) != 0)
+                return true;
+            if (!_managed)
+                throw new InvalidStateException(_loc.get("trans-not-managed"));
+            if (_factory.syncWithManagedTransaction(this, false)) {
+                beginInternal();
+                return true;
+            }
+            return false;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void commitAndResume() {
+        endAndResume(true);
+    }
+
+    public void rollbackAndResume() {
+        endAndResume(false);
+    }
+
+    private void endAndResume(boolean commit) {
+        beginOperation(false);
+        try {
+            if (commit)
+                commit();
+            else
+                rollback();
+            begin();
+        } finally {
+            endOperation();
+        }
+    }
+
+    public boolean getRollbackOnly() {
+        beginOperation(true);
+        try {
+            if ((_flags & FLAG_ACTIVE) == 0)
+                return false;
+
+            javax.transaction.Transaction trans =
+                _runtime.getTransactionManager().getTransaction();
+            if (trans == null)
+                return false;
+            return trans.getStatus() == Status.STATUS_MARKED_ROLLBACK;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Throwable getRollbackCause() {
+        beginOperation(true);
+        try {
+            if ((_flags & FLAG_ACTIVE) == 0)
+                return null;
+
+            javax.transaction.Transaction trans =
+                _runtime.getTransactionManager().getTransaction();
+            if (trans == null)
+                return null;
+            if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
+                return _runtime.getRollbackCause();
+
+            return null;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void setRollbackOnly() {
+        setRollbackOnly(new UserException());
+    }
+
+    public void setRollbackOnly(Throwable cause) {
+        beginOperation(true);
+        try {
+            assertTransactionOperation();
+            setRollbackOnlyInternal(cause);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Mark the current transaction as rollback-only.
+     */
+    private void setRollbackOnlyInternal(Throwable cause) {
+        try {
+            javax.transaction.Transaction trans =
+                _runtime.getTransactionManager().getTransaction();
+            if (trans == null)
+                throw new InvalidStateException(_loc.get("null-trans"));
+            // ensure tran is in a valid state to accept the setRollbackOnly
+            int tranStatus = trans.getStatus();
+            if ((tranStatus != Status.STATUS_NO_TRANSACTION)
+                    && (tranStatus != Status.STATUS_ROLLEDBACK)
+                    && (tranStatus != Status.STATUS_COMMITTED))
+                _runtime.setRollbackOnly(cause);
+            else if (_log.isTraceEnabled())
+                _log.trace(_loc.get("invalid-tran-status", new Integer(
+                        tranStatus), "setRollbackOnly"));
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        }
+    }
+
+    public void setSavepoint(String name) {
+        beginOperation(true);
+        try {
+            assertActiveTransaction();
+            if (_savepoints != null && _savepoints.containsKey(name))
+                throw new UserException(_loc.get("savepoint-exists", name));
+
+            if (hasFlushed() && !_spm.supportsIncrementalFlush())
+                throw new UnsupportedException(_loc.get
+                    ("savepoint-flush-not-supported"));
+
+            OpenJPASavepoint save = _spm.newSavepoint(name, this);
+            if (_savepoints == null || _savepoints.isEmpty()) {
+                save.save(getTransactionalStates());
+                _savepoints = new LinkedMap();
+            } else {
+                if (_savepointCache == null)
+                    save.save(Collections.EMPTY_SET);
+                else {
+                    save.save(_savepointCache);
+                    _savepointCache.clear();
+                }
+            }
+            _savepoints.put(name, save);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void releaseSavepoint() {
+        beginOperation(false);
+        try {
+            if (_savepoints == null || _savepoints.isEmpty())
+                throw new UserException(_loc.get("no-lastsavepoint"));
+            releaseSavepoint((String) _savepoints.get
+                (_savepoints.size() - 1));
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void releaseSavepoint(String savepoint) {
+        beginOperation(false);
+        try {
+            assertActiveTransaction();
+
+            int index = (_savepoints == null) ? -1
+                : _savepoints.indexOf(savepoint);
+            if (index < 0)
+                throw new UserException(_loc.get("no-savepoint", savepoint));
+
+            // clear old in reverse
+            OpenJPASavepoint save;
+            while (_savepoints.size() > index + 1) {
+                save = (OpenJPASavepoint) _savepoints.remove
+                    (_savepoints.size() - 1);
+                save.release(false);
+            }
+
+            save = (OpenJPASavepoint) _savepoints.remove(index);
+            save.release(true);
+            if (_savepointCache != null)
+                _savepointCache.clear();
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void rollbackToSavepoint() {
+        beginOperation(false);
+        try {
+            if (_savepoints == null || _savepoints.isEmpty())
+                throw new UserException(_loc.get("no-lastsavepoint"));
+            rollbackToSavepoint((String) _savepoints.get
+                (_savepoints.size() - 1));
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void rollbackToSavepoint(String savepoint) {
+        beginOperation(false);
+        try {
+            assertActiveTransaction();
+
+            int index = (_savepoints == null) ? -1
+                : _savepoints.indexOf(savepoint);
+            if (index < 0)
+                throw new UserException(_loc.get("no-savepoint", savepoint));
+
+            // clear old in reverse
+            OpenJPASavepoint save;
+            while (_savepoints.size() > index + 1) {
+                save = (OpenJPASavepoint) _savepoints.remove
+                    (_savepoints.size() - 1);
+                save.release(false);
+            }
+
+            save = (OpenJPASavepoint) _savepoints.remove(index);
+            Collection saved = save.rollback(_savepoints.values());
+            if (_savepointCache != null)
+                _savepointCache.clear();
+            if (hasTransactionalObjects()) {
+                // build up a new collection of states
+                TransactionalCache oldTransCache = _transCache;
+                TransactionalCache newTransCache = new TransactionalCache
+                    (_orderDirty);
+                _transCache = null;
+
+                // currently there is the assumption that incremental
+                // flush is either a) not allowed, or b) required
+                // pre-savepoint.  this solves a number of issues including
+                // storing flushed states as well as OID handling.
+                // if future plugins do not follow this, we need to cache
+                // more info per state
+                SavepointFieldManager fm;
+                StateManagerImpl sm;
+                for (Iterator itr = saved.iterator(); itr.hasNext();) {
+                    fm = (SavepointFieldManager) itr.next();
+                    sm = fm.getStateManager();
+                    sm.rollbackToSavepoint(fm);
+                    oldTransCache.remove(sm);
+                    if (sm.isDirty())
+                        newTransCache.addDirty(sm);
+                    else
+                        newTransCache.addClean(sm);
+                }
+                for (Iterator itr = oldTransCache.iterator(); itr.hasNext();) {
+                    sm = (StateManagerImpl) itr.next();
+                    sm.rollback();
+                    removeFromTransaction(sm);
+                }
+                _transCache = newTransCache;
+            }
+        }
+        catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void flush() {
+        beginOperation(true);
+        try {
+            // return silently if no trans is active, or if this is a reentrant
+            // call, which can happen if the store manager tries to get an
+            // auto-inc oid during flush
+            if ((_flags & FLAG_ACTIVE) == 0
+                || (_flags & FLAG_STORE_FLUSHING) != 0)
+                return;
+
+            // make sure the runtime supports it
+            if (!_conf.supportedOptions().contains(_conf.OPTION_INC_FLUSH))
+                throw new UnsupportedException(_loc.get
+                    ("incremental-flush-not-supported"));
+            if (_savepoints != null && !_savepoints.isEmpty()
+                && !_spm.supportsIncrementalFlush())
+                throw new UnsupportedException(_loc.get
+                    ("savepoint-flush-not-supported"));
+
+            try {
+                flushSafe(FLUSH_INC);
+                _flags |= FLAG_FLUSHED;
+            } catch (OpenJPAException ke) {
+                // rollback on flush error; objects may be in inconsistent state
+                setRollbackOnly(ke);
+                throw ke.setFatal(true);
+            } catch (RuntimeException re) {
+                // rollback on flush error; objects may be in inconsistent state
+                setRollbackOnly(re);
+                throw new StoreException(re).setFatal(true);
+            }
+        }
+        finally {
+            endOperation();
+        }
+    }
+
+    public void preFlush() {
+        beginOperation(true);
+        try {
+            if ((_flags & FLAG_ACTIVE) != 0)
+                flushSafe(FLUSH_LOGICAL);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void validateChanges() {
+        beginOperation(true);
+        try {
+            // if no trans, just return; if active datastore trans, flush
+            if ((_flags & FLAG_ACTIVE) == 0)
+                return;
+            if ((_flags & FLAG_STORE_ACTIVE) != 0) {
+                flush();
+                return;
+            }
+
+            // make sure the runtime supports inc flush
+            if (!_conf.supportedOptions().contains(_conf.OPTION_INC_FLUSH))
+                throw new UnsupportedException(_loc.get
+                    ("incremental-flush-not-supported"));
+
+            try {
+                flushSafe(FLUSH_ROLLBACK);
+            } catch (OpenJPAException ke) {
+                throw ke;
+            } catch (RuntimeException re) {
+                throw new StoreException(re);
+            }
+        }
+        finally {
+            endOperation();
+        }
+    }
+
+    public boolean isActive() {
+        beginOperation(true);
+        try {
+            return (_flags & FLAG_ACTIVE) != 0;
+        } finally {
+            endOperation();
+        }
+    }
+
+    public boolean isStoreActive() {
+        // we need to lock here, because we might be in the middle of an
+        // atomic transaction process (e.g., commitAndResume)
+        beginOperation(true);
+        try {
+            return (_flags & FLAG_STORE_ACTIVE) != 0;
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Return whether the current transaction is ending, i.e. in the 2nd phase
+     * of a commit or rollback
+     */
+    boolean isTransactionEnding() {
+        return (_flags & FLAG_TRANS_ENDING) != 0;
+    }
+
+    public boolean beginOperation(boolean syncTrans) {
+        lock();
+        try {
+            assertOpen();
+
+            if (syncTrans && _operationCount == 0 && _syncManaged
+                && (_flags & FLAG_ACTIVE) == 0)
+                syncWithManagedTransaction();
+            return _operationCount++ == 1;
+        } catch (OpenJPAException ke) {
+            unlock();
+            throw ke;
+        } catch (RuntimeException re) {
+            unlock();
+            throw new GeneralException(re);
+        }
+    }
+
+    /**
+     * Mark the operation over. If outermost caller of stack, returns true
+     * and will detach managed instances if necessary.
+     */
+    public boolean endOperation() {
+        try {
+            if (_operationCount == 1 && (_autoDetach & DETACH_NONTXREAD) != 0
+                && (_flags & FLAG_ACTIVE) == 0) {
+                detachAllInternal(null);
+            }
+            if (_operationCount < 1)
+                throw new InternalException(_loc.get("multi-threaded-access"));
+            return _operationCount == 1;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            _operationCount--;
+            if (_operationCount == 0)
+                initializeOperatingSet();
+            unlock();
+        }
+    }
+
+    public Synchronization getSynchronization() {
+        return _sync;
+    }
+
+    public void setSynchronization(Synchronization sync) {
+        assertOpen();
+        _sync = sync;
+    }
+
+    ///////////////////////////////////////////////
+    // Implementation of Synchronization interface
+    ///////////////////////////////////////////////
+
+    public void beforeCompletion() {
+        beginOperation(false);
+        try {
+            // user-supplied synchronization
+            if (_sync != null)
+                _sync.beforeCompletion();
+
+            flushSafe(FLUSH_COMMIT);
+        } catch (OpenJPAException ke) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), ke);
+            throw translateManagedCompletionException(ke);
+        } catch (RuntimeException re) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), re);
+            throw translateManagedCompletionException(new StoreException(re));
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void afterCompletion(int status) {
+        beginOperation(false);
+        try {
+            assertActiveTransaction();
+
+            _flags |= FLAG_TRANS_ENDING;
+            endTransaction(status);
+            if (_sync != null)
+                _sync.afterCompletion(status);
+
+            if ((_autoDetach & DETACH_COMMIT) != 0)
+                detachAllInternal(null);
+            else if (status == Status.STATUS_ROLLEDBACK 
+                && (_autoDetach & DETACH_ROLLBACK) != 0) {
+                detachAllInternal(null);
+            }
+
+            // in an ee context, it's possible that the user tried to close
+            // us but we didn't actually close because we were waiting on this
+            // transaction; if that's true, then close now
+            if ((_flags & FLAG_CLOSE_INVOKED) != 0
+                && _compat.getCloseOnManagedCommit())
+                free();
+        } catch (OpenJPAException ke) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), ke);
+            throw translateManagedCompletionException(ke);
+        } catch (RuntimeException re) {
+            if (_log.isTraceEnabled())
+                _log.trace(_loc.get("end-trans-error"), re);
+            throw translateManagedCompletionException(new StoreException(re));
+        } finally {
+            _flags &= ~FLAG_ACTIVE;
+            _flags &= ~FLAG_FLUSHED;
+            _flags &= ~FLAG_TRANS_ENDING;
+
+            // event manager nulled if freed broker
+            if (_transEventManager != null 
+                && _transEventManager.hasEndListeners()) {
+                fireTransactionEvent(new TransactionEvent(this,
+                    status == Status.STATUS_COMMITTED
+                        ? TransactionEvent.AFTER_COMMIT_COMPLETE
+                        : TransactionEvent.AFTER_ROLLBACK_COMPLETE,
+                    null, null, null, null));
+            }
+
+            endOperation();
+        }
+    }
+
+    /**
+     * If we're in a managed transaction, use our implicit behavior exception
+     * translator to translate before/afterCompletion callback errors.
+     */
+    private RuntimeException translateManagedCompletionException
+        (RuntimeException re) {
+        return (!_managed || _extrans == null) ? re : _extrans.translate(re);
+    }
+
+    /**
+     * Flush safely, catching reentrant calls.
+     */
+    private void flushSafe(int reason) {
+        if ((_flags & FLAG_FLUSHING) != 0)
+            throw new InvalidStateException(_loc.get("reentrant-flush"));
+
+        _flags |= FLAG_FLUSHING;
+        try {
+            flush(reason);
+        } finally {
+            _flags &= ~FLAG_FLUSHING;
+        }
+    }
+
+    /**
+     * Flush the transactional state to the data store. Subclasses that
+     * customize commit behavior should override this method. The method
+     * assumes that the persistence manager is locked, is not closed,
+     * and has an active transaction.
+     *
+     * @param reason one of {@link #FLUSH_INC}, {@link #FLUSH_COMMIT},
+     * {@link #FLUSH_ROLLBACK}, or {@link #FLUSH_LOGICAL}
+     * @since 0.2.5
+     */
+    protected void flush(int reason) {
+        // this will enlist proxied states as necessary so we know whether we
+        // have anything to flush
+        Collection transactional = getTransactionalStates();
+
+        // do we actually have to flush?  only if our flags say so, or if
+        // we have transaction listeners that need to be invoked for commit
+        // (no need to invoke them on inc flush if nothing is dirty).  we
+        // special case the remote commit listener used by the datacache cause
+        // we know it doesn't require the commit event when nothing changes
+        boolean flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
+        boolean listeners = (_transEventManager.hasFlushListeners()
+            || _transEventManager.hasEndListeners())
+            && ((_flags & FLAG_REMOTE_LISTENER) == 0
+            || _transEventManager.getListeners().size() > 1);
+        if (!flush && (reason != FLUSH_COMMIT || !listeners))
+            return;
+
+        Collection mobjs = null;
+        _flags |= FLAG_PRESTORING;
+        try {
+            if (flush) {
+                // call pre store on all currently transactional objs
+                for (Iterator itr = transactional.iterator(); itr.hasNext();)
+                    ((StateManagerImpl) itr.next()).beforeFlush(reason, _call);
+                flushAdditions(transactional, reason);
+            }
+
+            // hopefully now all dependent instances that are going to end
+            // up referenced have been marked as such; delete unrefed
+            // dependents
+            _flags |= FLAG_DEREFDELETING;
+            if (flush && _derefCache != null && !_derefCache.isEmpty()) {
+                for (Iterator itr = _derefCache.iterator(); itr.hasNext();)
+                    deleteDeref((StateManagerImpl) itr.next());
+                flushAdditions(transactional, reason);
+            }
+
+            if (reason != FLUSH_LOGICAL) {
+                // if no datastore transaction, start one; even if we don't
+                // think we'll need to flush at this point, our transaction
+                // listeners might introduce some dirty objects or interact
+                // directly with the database
+                if ((_flags & FLAG_STORE_ACTIVE) == 0)
+                    beginStoreManagerTransaction(false);
+
+                if ((_transEventManager.hasFlushListeners()
+                    || _transEventManager.hasEndListeners())
+                    && (flush || reason == FLUSH_COMMIT)) {
+                    // fire events
+                    mobjs = new ManagedObjectCollection(transactional);
+                    if (reason == FLUSH_COMMIT
+                        && _transEventManager.hasEndListeners()) {
+                        fireTransactionEvent(new TransactionEvent(this, 
+                            TransactionEvent.BEFORE_COMMIT, mobjs,
+                            _persistedClss, _updatedClss, _deletedClss));
+
+                        flushAdditions(transactional, reason);
+                        flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
+                    }
+
+                    if (flush && _transEventManager.hasFlushListeners()) {
+                        fireTransactionEvent(new TransactionEvent(this, 
+                            TransactionEvent.BEFORE_FLUSH, mobjs,
+                            _persistedClss, _updatedClss, _deletedClss));
+                        flushAdditions(transactional, reason);
+                    }
+                }
+            }
+        }
+        finally {
+            _flags &= ~FLAG_PRESTORING;
+            _flags &= ~FLAG_DEREFDELETING;
+            _transAdditions = null;
+            _derefAdditions = null;
+
+            // also clear derefed set; the deletes have been recorded
+            if (_derefCache != null)
+                _derefCache = null;
+        }
+
+        // flush to store manager
+        List exceps = null;
+        try {
+            if (flush && reason != FLUSH_LOGICAL) {
+                _flags |= FLAG_STORE_FLUSHING;
+                exceps = add(exceps,
+                    newFlushException(_store.flush(transactional)));
+            }
+        } finally {
+            _flags &= ~FLAG_STORE_FLUSHING;
+
+            if (reason == FLUSH_ROLLBACK)
+                exceps = add(exceps, endStoreManagerTransaction(true));
+            else if (reason != FLUSH_LOGICAL)
+                _flags &= ~FLAG_FLUSH_REQUIRED;
+
+            // mark states as flushed
+            if (flush) {
+                StateManagerImpl sm;
+                for (Iterator itr = transactional.iterator(); itr.hasNext();) {
+                    sm = (StateManagerImpl) itr.next();
+                    try {
+                        // the state may have become transient, such as if
+                        // it is embedded and the owner has been deleted during
+                        // this flush process; bug #1100
+                        if (sm.getPCState() == PCState.TRANSIENT)
+                            continue;
+
+                        sm.afterFlush(reason);
+                        if (reason == FLUSH_INC) {
+                            // if not about to clear trans cache for commit 
+                            // anyway, re-cache dirty objects with default soft
+                            // refs; we don't need hard refs now that the 
+                            // changes have been flushed
+                            sm.proxyFields(true, false);
+                            _transCache.flushed(sm);
+                        }
+                    } catch (Exception e) {
+                        exceps = add(exceps, e);
+                    }
+                }
+            }
+        }
+
+        // throw any exceptions to shortcut listeners on fail
+        throwNestedExceptions(exceps, true);
+
+        if (flush && reason != FLUSH_ROLLBACK && reason != FLUSH_LOGICAL
+            && _transEventManager.hasFlushListeners()) {
+            fireTransactionEvent(new TransactionEvent(this,
+                TransactionEvent.AFTER_FLUSH, mobjs, _persistedClss,
+                _updatedClss, _deletedClss));
+        }
+    }
+
+    /**
+     * Flush newly-transactional objects.
+     */
+    private void flushAdditions(Collection transactional, int reason) {
+        boolean loop;
+        do {
+            // flush new transactional instances; note logical or
+            loop = flushTransAdditions(transactional, reason)
+                | deleteDerefAdditions(_derefCache);
+        } while (loop);
+    }
+
+    /**
+     * Flush transactional additions.
+     */
+    private boolean flushTransAdditions(Collection transactional, int reason) {
+        if (_transAdditions == null || _transAdditions.isEmpty())
+            return false;
+
+        // keep local transactional list copy up to date
+        transactional.addAll(_transAdditions);
+
+        // copy the change set, then clear it for the next iteration
+        StateManagerImpl[] states = (StateManagerImpl[]) _transAdditions.
+            toArray(new StateManagerImpl[_transAdditions.size()]);
+        _transAdditions = null;
+
+        for (int i = 0; i < states.length; i++)
+            states[i].beforeFlush(reason, _call);
+        return true;
+    }
+
+    /**
+     * Delete new dereferenced objects.
+     */
+    private boolean deleteDerefAdditions(Collection derefs) {
+        if (_derefAdditions == null || _derefAdditions.isEmpty())
+            return false;
+
+        // remember these additions in case one becomes derefed again later
+        derefs.addAll(_derefAdditions);
+
+        StateManagerImpl[] states = (StateManagerImpl[]) _derefAdditions.
+            toArray(new StateManagerImpl[_derefAdditions.size()]);
+        _derefAdditions = null;
+
+        for (int i = 0; i < states.length; i++)
+            deleteDeref(states[i]);
+        return true;
+    }
+
+    /**
+     * Delete a dereferenced dependent.
+     */
+    private void deleteDeref(StateManagerImpl sm) {
+        int action = processArgument(OpCallbacks.OP_DELETE,
+            sm.getManagedInstance(), sm, null);
+        if ((action & OpCallbacks.ACT_RUN) != 0)
+            sm.delete();
+        if ((action & OpCallbacks.ACT_CASCADE) != 0)
+            sm.cascadeDelete(_call);
+    }
+
+    /**
+     * Determine the action to take based on the user's given callbacks and
+     * our implicit behavior.
+     */
+    private int processArgument(int op, Object obj, OpenJPAStateManager sm,
+        OpCallbacks call) {
+        if (call != null)
+            return call.processArgument(op, obj, sm);
+        if (_call != null)
+            return _call.processArgument(op, obj, sm);
+        return OpCallbacks.ACT_RUN | OpCallbacks.ACT_CASCADE;
+    }
+
+    /**
+     * Throw the proper exception based on the given set of flush errors, or
+     * do nothing if no errors occurred.
+     */
+    private OpenJPAException newFlushException(Collection exceps) {
+        if (exceps == null || exceps.isEmpty())
+            return null;
+
+        Throwable[] t = (Throwable[]) exceps.toArray
+            (new Throwable[exceps.size()]);
+        List failed = new ArrayList(t.length);
+
+        // create fatal exception with nested exceptions for all the failed
+        // objects; if all OL exceptions, throw a top-level OL exception
+        boolean opt = true;
+        for (int i = 0; opt && i < t.length; i++) {
+            opt = t[i] instanceof OptimisticException;
+            if (opt) {
+                Object f = ((OptimisticException) t[i]).getFailedObject();
+                if (f != null)
+                    failed.add(f);
+            }
+        }
+        if (opt && !failed.isEmpty()) {
+            if(_suppressBatchOLELogging == true){
+                return new OptimisticException(_loc.get("broker-suppressing-exceptions",t.length));
+            }else{
+                return new OptimisticException(failed, t);
+            }
+        }
+        if (opt)
+            return new OptimisticException(t);
+        return new StoreException(_loc.get("rolled-back")).
+            setNestedThrowables(t).setFatal(true);
+    }
+
+    /**
+     * End the current transaction, making appropriate state transitions.
+     */
+    protected void endTransaction(int status) {
+        // if a data store transaction was in progress, do the
+        // appropriate transaction change
+        boolean rollback = status != Status.STATUS_COMMITTED;
+        List exceps = null;
+
+        try {
+            exceps = add(exceps, endStoreManagerTransaction(rollback));
+        } catch (RuntimeException re) {
+            rollback = true;
+            exceps = add(exceps, re);
+        }
+
+        // go back to default none lock level
+        _fc.setReadLockLevel(LOCK_NONE);
+        _fc.setWriteLockLevel(LOCK_NONE);
+        _fc.setLockTimeout(-1);
+
+        Collection transStates;
+        if (hasTransactionalObjects())
+            transStates = _transCache;
+        else
+            transStates = Collections.EMPTY_SET;
+
+        // fire after rollback/commit event
+        Collection mobjs = null;
+        if (_transEventManager.hasEndListeners()) {
+            mobjs = new ManagedObjectCollection(transStates);
+            int eventType = (rollback) ? TransactionEvent.AFTER_ROLLBACK
+                : TransactionEvent.AFTER_COMMIT;
+            fireTransactionEvent(new TransactionEvent(this, eventType, mobjs, 
+                _persistedClss, _updatedClss, _deletedClss));
+        }
+
+        // null transactional caches now so that all the removeFromTransaction
+        // calls as we transition each object don't have to do any work; don't
+        // clear trans cache object because we still need the transStates
+        // reference to it below
+        _transCache = null;
+        if (_persistedClss != null)
+            _persistedClss = null;
+        if (_updatedClss != null)
+            _updatedClss = null;
+        if (_deletedClss != null)
+            _deletedClss = null;
+
+        // new cache would get cleared anyway during transitions, but doing so
+        // immediately saves us some lookups
+        _cache.clearNew();
+
+        // tell all derefed instances they're no longer derefed; we can't
+        // rely on rollback and commit calls below cause some instances might
+        // not be transactional
+        if (_derefCache != null && !_derefCache.isEmpty()) {
+            for (Iterator itr = _derefCache.iterator(); itr.hasNext();)
+                ((StateManagerImpl) itr.next()).setDereferencedDependent
+                    (false, false);
+            _derefCache = null;
+        }
+
+        // peform commit or rollback state transitions on each instance
+        StateManagerImpl sm;
+        for (Iterator itr = transStates.iterator(); itr.hasNext();) {
+            sm = (StateManagerImpl) itr.next();
+            try {
+                if (rollback) {
+                    // tell objects that may have been derefed then flushed
+                    // (and therefore deleted) to un-deref
+                    sm.setDereferencedDependent(false, false);
+                    sm.rollback();
+                } else
+                    sm.commit();
+            } catch (RuntimeException re) {
+                exceps = add(exceps, re);
+            }
+        }
+
+        // notify the lock manager to clean up and release remaining locks
+        _lm.endTransaction();
+
+        // clear old savepoints in reverse
+        OpenJPASavepoint save;
+        while (_savepoints != null && _savepoints.size() > 0) {
+            save =
+                (OpenJPASavepoint) _savepoints.remove(_savepoints.size() - 1);
+            save.release(false);
+        }
+        _savepoints = null;
+        _savepointCache = null;
+
+        // fire after state change event
+        if (_transEventManager.hasEndListeners())
+            fireTransactionEvent(new TransactionEvent(this, TransactionEvent.
+                AFTER_STATE_TRANSITIONS, mobjs, null, null, null));
+
+        // now clear trans cache; keep cleared version rather than
+        // null to avoid having to re-create the set later; more efficient
+        if (transStates != Collections.EMPTY_SET) {
+            _transCache = (TransactionalCache) transStates;
+            _transCache.clear();
+        }
+
+        throwNestedExceptions(exceps, true);
+    }
+
+    ////////////////////
+    // Object lifecycle
+    ////////////////////
+
+    public void persist(Object obj, OpCallbacks call) {
+        persist(obj, null, true, call);
+    }
+
+    public OpenJPAStateManager persist(Object obj, Object id,
+        OpCallbacks call) {
+        return persist(obj, id, true, call);
+    }
+
+    public void persistAll(Collection objs, OpCallbacks call) {
+        persistAll(objs, true, call);
+    }
+
+    /**
+     * Persist the given objects.  Indicate whether this was an explicit persist
+     * (PNEW) or a provisonal persist (PNEWPROVISIONAL).
+     */
+    public void persistAll(Collection objs, boolean explicit, 
+        OpCallbacks call) {
+        if (objs.isEmpty())
+            return;
+
+        beginOperation(true);
+        List exceps = null;
+        try {
+            assertWriteOperation();
+
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                try {
+                    persist(itr.next(), explicit, call);
+                } catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+        } finally {
+            endOperation();
+        }
+        throwNestedExceptions(exceps, false);
+    }
+
+    /**
+     * If the given element is not null, add it to the given list,
+     * creating the list if necessary.
+     */
+    private List add(List l, Object o) {
+        if (o == null)
+            return l;
+        if (l == null)
+            l = new LinkedList();
+        l.add(o);
+        return l;
+    }
+
+    /**
+     * Throw an exception wrapping the given nested exceptions.
+     */
+    private void throwNestedExceptions(List exceps, boolean datastore) {
+        if (exceps == null || exceps.isEmpty())
+            return;
+        if (datastore && exceps.size() == 1)
+            throw (RuntimeException) exceps.get(0);
+
+        boolean fatal = false;
+        Throwable[] t = (Throwable[]) exceps.toArray
+            (new Throwable[exceps.size()]);
+        for (int i = 0; i < t.length; i++) {
+            if (t[i] instanceof OpenJPAException
+                && ((OpenJPAException) t[i]).isFatal())
+                fatal = true;
+        }
+        OpenJPAException err;
+        if (datastore)
+            err = new StoreException(_loc.get("nested-exceps"));
+        else
+            err = new UserException(_loc.get("nested-exceps"));
+        throw err.setNestedThrowables(t).setFatal(fatal);
+    }
+
+    /**
+     * Persist the given object.  Indicate whether this was an explicit persist
+     * (PNEW) or a provisonal persist (PNEWPROVISIONAL)
+     */
+    public void persist(Object obj, boolean explicit, OpCallbacks call) {
+        persist(obj, null, explicit, call);
+    }
+
+    /**
+     * Persist the given object.  Indicate whether this was an explicit persist
+     * (PNEW) or a provisonal persist (PNEWPROVISIONAL).
+     * See {@link Broker} for details on this method.
+     */
+    public OpenJPAStateManager persist(Object obj, Object id, boolean explicit,
+        OpCallbacks call) {
+        if (obj == null)
+            return null;
+
+        beginOperation(true);
+        try {
+            assertWriteOperation();
+
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if (!_operating.add(obj))
+                return sm;
+
+            int action = processArgument(OpCallbacks.OP_PERSIST, obj, sm, call);
+            if (action == OpCallbacks.ACT_NONE)
+                return sm;
+
+            // ACT_CASCADE
+            if ((action & OpCallbacks.ACT_RUN) == 0) {
+                if (sm != null)
+                    sm.cascadePersist(call);
+                else
+                    cascadeTransient(OpCallbacks.OP_PERSIST, obj, call,
+                        "persist");
+                return sm;
+            }
+
+            // ACT_RUN
+            PersistenceCapable pc;
+            if (sm != null) {
+                if (sm.isDetached())
+                    throw new ObjectExistsException(_loc.get
+                        ("persist-detached", Exceptions.toString(obj))).
+                        setFailedObject(obj);
+
+                if (!sm.isEmbedded()) {
+                    sm.persist();
+                    _cache.persist(sm);
+                    if ((action & OpCallbacks.ACT_CASCADE) != 0)
+                        sm.cascadePersist(call);
+                    return sm;
+                }
+
+                // an embedded field; notify the owner that the value has
+                // changed by becoming independently persistent
+                sm.getOwner().dirty(sm.getOwnerIndex());
+                _cache.persist(sm);
+                pc = sm.getPersistenceCapable();
+            } else {
+                pc = assertPersistenceCapable(obj);
+                if (pc.pcIsDetached() == Boolean.TRUE)
+                    throw new ObjectExistsException(_loc.get
+                        ("persist-detached", Exceptions.toString(obj))).
+                        setFailedObject(obj);
+            }
+
+            ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
+                getMetaData(obj.getClass(), _loader, true);
+            fireLifecycleEvent(obj, null, meta, LifecycleEvent.BEFORE_PERSIST);
+
+            // create id for instance
+            if (id == null) {
+                if (meta.getIdentityType() == ClassMetaData.ID_APPLICATION)
+                    id = ApplicationIds.create(pc, meta);
+                else if (meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
+                    throw new UserException(_loc.get("meta-unknownid", meta));
+                else
+                    id = StateManagerId.newInstance(this);
+            }
+
+            // make sure we don't already have the instance cached
+            checkForDuplicateId(id, obj);
+
+            // if had embedded sm, null it
+            if (sm != null)
+                pc.pcReplaceStateManager(null);
+
+            // create new sm
+            sm = new StateManagerImpl(id, meta, this);
+            if ((_flags & FLAG_ACTIVE) != 0) {
+                if (explicit)
+                    sm.initialize(pc, PCState.PNEW);
+                else
+                    sm.initialize(pc, PCState.PNEWPROVISIONAL);
+            } else
+                sm.initialize(pc, PCState.PNONTRANSNEW);
+            if ((action & OpCallbacks.ACT_CASCADE) != 0)
+                sm.cascadePersist(call);
+            return sm;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Temporarily manage the given instance in order to cascade the given
+     * operation through it.
+     */
+    private void cascadeTransient(int op, Object obj, OpCallbacks call,
+        String errOp) {
+        PersistenceCapable pc = assertPersistenceCapable(obj);
+
+        // if using detached state manager, don't replace
+        if (pc.pcGetStateManager() != null)
+            throw newDetachedException(obj, errOp);
+
+        ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
+            getMetaData(obj.getClass(), _loader, true);
+        StateManagerImpl sm = new StateManagerImpl(StateManagerId.
+            newInstance(this), meta, this);
+        sm.initialize(pc, PCState.TLOADED);
+        try {
+            switch (op) {
+                case OpCallbacks.OP_PERSIST:
+                    sm.cascadePersist(call);
+                    break;
+                case OpCallbacks.OP_DELETE:
+                    sm.cascadeDelete(call);
+                    break;
+                case OpCallbacks.OP_REFRESH:
+                    sm.gatherCascadeRefresh(call);
+                    break;
+                default:
+                    throw new InternalException(String.valueOf(op));
+            }
+        }
+        finally {
+            sm.release(true);
+        }
+    }
+
+    public void deleteAll(Collection objs, OpCallbacks call) {
+        beginOperation(true);
+        try {
+            assertWriteOperation();
+
+            List exceps = null;
+            Object obj;
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                try {
+                    obj = itr.next();
+                    if (obj != null)
+                        delete(obj, getStateManagerImpl(obj, true), call);
+                } catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+            throwNestedExceptions(exceps, false);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void delete(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true);
+        try {
+            assertWriteOperation();
+            delete(obj, getStateManagerImpl(obj, true), call);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Internal delete.
+     */
+    void delete(Object obj, StateManagerImpl sm, OpCallbacks call) {
+        if (!_operating.add(obj))
+            return;
+
+        int action = processArgument(OpCallbacks.OP_DELETE, obj, sm, call);
+        if (action == OpCallbacks.ACT_NONE)
+            return;
+
+        // ACT_CASCADE
+        if ((action & OpCallbacks.ACT_RUN) == 0) {
+            if (sm != null)
+                sm.cascadeDelete(call);
+            else
+                cascadeTransient(OpCallbacks.OP_DELETE, obj, call, "delete");
+            return;
+        }
+
+        // ACT_RUN
+        if (sm != null) {
+            if (sm.isDetached())
+                throw newDetachedException(obj, "delete");
+            if ((action & OpCallbacks.ACT_CASCADE) != 0)
+                sm.cascadeDelete(call);
+            sm.delete();
+        } else if (assertPersistenceCapable(obj).pcIsDetached() == Boolean.TRUE)
+            throw newDetachedException(obj, "delete");
+    }
+
+    /**
+     * Throw an exception indicating that the current action can't be
+     * performed on a detached object.
+     */
+    private OpenJPAException newDetachedException(Object obj,
+        String operation) {
+        throw new UserException(_loc.get("bad-detached-op", operation,
+            Exceptions.toString(obj))).setFailedObject(obj);
+    }
+
+    public void releaseAll(Collection objs, OpCallbacks call) {
+        beginOperation(false);
+        try {
+            List exceps = null;
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                try {
+                    release(itr.next(), call);
+                } catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+            throwNestedExceptions(exceps, false);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void release(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(false);
+        try {
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            int action = processArgument(OpCallbacks.OP_RELEASE, obj, sm, call);
+
+            if (sm == null)
+                return;
+            if ((action & OpCallbacks.ACT_RUN) != 0 && sm.isPersistent()) {
+                boolean pending = sm.isPendingTransactional();
+                sm.release(true);
+                if (pending)
+                    removeFromPendingTransaction(sm);
+            }
+        }
+        catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public OpenJPAStateManager embed(Object obj, Object id,
+        OpenJPAStateManager owner, ValueMetaData ownerMeta) {
+        beginOperation(true);
+        try {
+            StateManagerImpl orig = getStateManagerImpl(obj, true);
+            if (orig != null) {
+                // if already embedded, nothing to do
+                if (orig.getOwner() == owner && orig.getMetaData().
+                    getEmbeddingMetaData() == ownerMeta)
+                    return orig;
+
+                // otherwise make sure pc is fully loaded for when we copy its
+                // data below
+                orig.load(_fc, StateManagerImpl.LOAD_ALL, null, null, false);
+            }
+
+            // create new state manager with embedded metadata
+            ClassMetaData meta = ownerMeta.getEmbeddedMetaData();
+            if (meta == null)
+                throw new InternalException(_loc.get("bad-embed", ownerMeta));
+
+            if (id == null)
+                id = StateManagerId.newInstance(this);
+
+            StateManagerImpl sm = new StateManagerImpl(id, meta, this);
+            sm.setOwner((StateManagerImpl) owner, ownerMeta);
+
+            PersistenceCapable copy;
+            PCState state;
+            Class type = meta.getDescribedType();
+            if (obj != null) {
+                // give copy and the original instance the same state manager
+                // so that we can copy fields from one to the other
+                StateManagerImpl copySM;
+                PersistenceCapable pc;
+                if (orig == null) {
+                    copySM = sm;
+                    pc = assertPersistenceCapable(obj);
+                    pc.pcReplaceStateManager(sm);
+                } else {
+                    copySM = orig;
+                    pc = orig.getPersistenceCapable();
+                }
+
+                try {
+                    // copy the instance.  we do this even if it doesn't already
+                    // have a state manager in case it is later assigned to a
+                    // PC field; at that point it's too late to copy
+                    copy = PCRegistry.newInstance(type, copySM, false);
+                    int[] fields = new int[meta.getFields().length];
+                    for (int i = 0; i < fields.length; i++)
+                        fields[i] = i;
+                    copy.pcCopyFields(pc, fields);
+                    state = PCState.ECOPY;
+                    copy.pcReplaceStateManager(null);
+                } finally {
+                    // if the instance didn't have a state manager to start,
+                    // revert it to being transient
+                    if (orig == null)
+                        pc.pcReplaceStateManager(null);
+                }
+            } else {
+                copy = PCRegistry.newInstance(type, sm, false);
+                if ((_flags & FLAG_ACTIVE) != 0 && !_optimistic)
+                    state = PCState.ECLEAN;
+                else
+                    state = PCState.ENONTRANS;
+            }
+
+            sm.initialize(copy, state);
+            return sm;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * If not already cached, create an empty copy of the given state
+     * manager in the given state.
+     */
+    OpenJPAStateManager copy(OpenJPAStateManager copy, PCState state) {
+        beginOperation(true);
+        try {
+            assertOpen();
+            Object oid = copy.fetchObjectId();
+            Class type = copy.getManagedInstance().getClass();
+            if (oid == null)
+                throw new InternalException();
+            // cached instance?
+            StateManagerImpl sm = null;
+            if (!copy.isEmbedded())
+                sm = getStateManagerImplById(oid, true);
+            if (sm == null) {
+                MetaDataRepository repos = _conf.
+                    getMetaDataRepositoryInstance();
+                ClassMetaData meta = repos.getMetaData(type, _loader, true);
+                // construct a new state manager with all info known
+                sm = new StateManagerImpl(oid, meta, this);
+                sm.setObjectId(oid);
+                sm.initialize(sm.getMetaData().getDescribedType(), state);
+            }
+            return sm;
+        } finally {
+            endOperation();
+        }
+    }
+    
+    public void refreshAll(Collection objs, OpCallbacks call) {
+        if (objs == null || objs.isEmpty())
+            return;
+
+        beginOperation(true);
+        try {
+            assertNontransactionalRead();
+
+            for (Iterator itr = objs.iterator(); itr.hasNext();) 
+                gatherCascadeRefresh(itr.next(), call);
+            if (_operating.isEmpty())
+            	return;
+            if (_operating.size() == 1)
+            	refreshInternal(_operating.iterator().next(), call);
+            else
+            	refreshInternal(_operating, call);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void refresh(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true);
+        try {
+            assertNontransactionalRead();
+
+            gatherCascadeRefresh(obj, call);
+            if (_operating.isEmpty())
+            	return;
+            if (_operating.size() == 1)
+            	refreshInternal(_operating.iterator().next(), call);
+            else
+            	refreshInternal(_operating, call);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Gathers all objects reachable through cascade-refresh relations
+     * into the operating set.
+     */
+    void gatherCascadeRefresh(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+        if (!_operating.add(obj))
+            return;
+
+        StateManagerImpl sm = getStateManagerImpl(obj, false);
+        int action = processArgument(OpCallbacks.OP_REFRESH, obj, sm, call);
+        if ((action & OpCallbacks.ACT_CASCADE) == 0)
+            return;
+
+        if (sm != null)
+            sm.gatherCascadeRefresh(call);
+        else
+            cascadeTransient(OpCallbacks.OP_REFRESH, obj, call, "refresh");
+    }
+
+    /**
+     * This method is called with the full set of objects reachable via
+     * cascade-refresh relations from the user-given instances.
+     */
+    protected void refreshInternal(Collection objs, OpCallbacks call) {
+    	if (objs == null || objs.isEmpty())
+    		return;
+        List exceps = null;
+        try {
+            // collect instances that need a refresh
+            Collection load = null;
+            StateManagerImpl sm;
+            Object obj;
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                obj = itr.next();
+                if (obj == null)
+                    continue;
+
+                try {
+                    sm = getStateManagerImpl(obj, true);
+                    if ((processArgument(OpCallbacks.OP_REFRESH, obj, sm, call)
+                        & OpCallbacks.ACT_RUN) == 0)
+                        continue;
+
+                    if (sm != null) {
+                        if (sm.isDetached()) 
+                            throw newDetachedException(obj, "refresh");
+                        else if (sm.beforeRefresh(true)) {
+                        	if (load == null)
+                        		load = new ArrayList(objs.size());
+                            load.add(sm);
+                        }
+                    } else if (assertPersistenceCapable(obj).pcIsDetached()
+                        == Boolean.TRUE)
+                        throw newDetachedException(obj, "refresh");
+                } catch (OpenJPAException ke) {
+                    exceps = add(exceps, ke);
+                }
+            }
+
+            // refresh all
+            if (load != null) {
+                Collection failed = _store.loadAll(load, null,
+                    StoreManager.FORCE_LOAD_REFRESH, _fc, null);
+                if (failed != null && !failed.isEmpty())
+                    exceps = add(exceps, newObjectNotFoundException(failed));
+
+                // perform post-refresh transitions and make sure all fetch
+                // group fields are loaded
+                for (Iterator itr = load.iterator(); itr.hasNext();) {
+                    sm = (StateManagerImpl) itr.next();
+                    if (failed != null && failed.contains(sm.getId()))
+                        continue;
+
+                    try {
+                        sm.afterRefresh();
+                        sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, 
+                            false);
+                    } catch (OpenJPAException ke) {
+                        exceps = add(exceps, ke);
+                    }
+                }
+            }
+
+            // now invoke postRefresh on all the instances
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                try {
+                    sm = getStateManagerImpl(itr.next(), true);
+                    if (sm != null && !sm.isDetached())
+                        fireLifecycleEvent(sm.getManagedInstance(), null,
+                            sm.getMetaData(), LifecycleEvent.AFTER_REFRESH);
+                } catch (OpenJPAException ke) {
+                    exceps = add(exceps, ke);
+                }
+            }
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+        throwNestedExceptions(exceps, false);
+    }
+
+    /**
+     * Optimization for single-object refresh.
+     */
+    protected void refreshInternal(Object obj, OpCallbacks call) {
+        try {
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_REFRESH, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+
+            if (sm != null) {
+                if (sm.isDetached())
+                    throw newDetachedException(obj, "refresh");
+                else if (sm.beforeRefresh(false)) {
+                    sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
+                    sm.afterRefresh();
+                }
+                fireLifecycleEvent(sm.getManagedInstance(), null,
+                    sm.getMetaData(), LifecycleEvent.AFTER_REFRESH);
+            } else if (assertPersistenceCapable(obj).pcIsDetached()
+                == Boolean.TRUE)
+                throw newDetachedException(obj, "refresh");
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+    }
+    
+    
+    public void retrieveAll(Collection objs, boolean dfgOnly,
+        OpCallbacks call) {
+        if (objs == null || objs.isEmpty())
+            return;
+        if (objs.size() == 1) {
+            retrieve(objs.iterator().next(), dfgOnly, call);
+            return;
+        }
+
+        List exceps = null;
+        beginOperation(true);
+        try {
+            assertOpen();
+            assertNontransactionalRead();
+
+            // collect all hollow instances for load
+            Object obj;
+            Collection load = null;
+            StateManagerImpl sm;
+            Collection sms = new ArrayList(objs.size());
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                obj = itr.next();
+                if (obj == null)
+                    continue;
+
+                try {
+                    sm = getStateManagerImpl(obj, true);
+                    if ((processArgument(OpCallbacks.OP_RETRIEVE, obj, sm, call)
+                        & OpCallbacks.ACT_RUN) == 0)
+                        continue;
+
+                    if (sm != null) {
+                        if (sm.isDetached())
+                            throw newDetachedException(obj, "retrieve");
+                        if (sm.isPersistent()) {
+                            sms.add(sm);
+                            if (sm.getPCState() == PCState.HOLLOW) {
+                                if (load == null)
+                                    load = new ArrayList();
+                                load.add(sm);
+                            }
+                        }
+                    } else if (assertPersistenceCapable(obj).pcIsDetached()
+                        == Boolean.TRUE)
+                        throw newDetachedException(obj, "retrieve");
+                } catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+
+            // load all hollow instances
+            Collection failed = null;
+            if (load != null) {
+                int mode = (dfgOnly) ? _store.FORCE_LOAD_DFG
+                    : _store.FORCE_LOAD_ALL;
+                failed = _store.loadAll(load, null, mode, _fc, null);
+                if (failed != null && !failed.isEmpty())
+                    exceps = add(exceps, newObjectNotFoundException(failed));
+            }
+
+            // retrieve all non-failed instances
+            for (Iterator itr = sms.iterator(); itr.hasNext();) {
+                sm = (StateManagerImpl) itr.next();
+                if (failed != null && failed.contains(sm.getId()))
+                    continue;
+
+                int mode = (dfgOnly) ? StateManagerImpl.LOAD_FGS
+                    : StateManagerImpl.LOAD_ALL;
+                try {
+                    sm.beforeRead(-1);
+                    sm.load(_fc, mode, null, null, false);
+                } catch (OpenJPAException ke) {
+                    exceps = add(exceps, ke);
+                }
+            }
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+        throwNestedExceptions(exceps, false);
+    }
+
+    public void retrieve(Object obj, boolean dfgOnly, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true);
+        try {
+            assertOpen();
+            assertNontransactionalRead();
+
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_RETRIEVE, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+
+            if (sm != null) {
+                if (sm.isDetached())
+                    throw newDetachedException(obj, "retrieve");
+                if (sm.isPersistent()) {
+                    int mode = (dfgOnly) ? StateManagerImpl.LOAD_FGS
+                        : StateManagerImpl.LOAD_ALL;
+                    sm.beforeRead(-1);
+                    sm.load(_fc, mode, null, null, false);
+                }
+            } else if (assertPersistenceCapable(obj).pcIsDetached()
+                == Boolean.TRUE)
+                throw newDetachedException(obj, "retrieve");
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void evictAll(OpCallbacks call) {
+        beginOperation(false);
+        try {
+            // evict all PClean and PNonTrans objects
+            Collection c = getManagedStates();
+            StateManagerImpl sm;
+            for (Iterator itr = c.iterator(); itr.hasNext();) {
+                sm = (StateManagerImpl) itr.next();
+                if (sm.isPersistent() && !sm.isDirty())
+                    evict(sm.getManagedInstance(), call);
+            }
+        }
+        finally {
+            endOperation();
+        }
+    }
+
+    public void evictAll(Collection objs, OpCallbacks call) {
+        List exceps = null;
+        beginOperation(false);
+        try {
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                try {
+                    evict(itr.next(), call);
+                } catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+        } finally {
+            endOperation();
+        }
+        throwNestedExceptions(exceps, false);
+    }
+
+    public void evictAll(Extent extent, OpCallbacks call) {
+        if (extent == null)
+            return;
+
+        beginOperation(false);
+        try {
+            // evict all PClean and PNonTrans objects in extent
+            Collection c = getManagedStates();
+            StateManagerImpl sm;
+            Class cls;
+            for (Iterator itr = c.iterator(); itr.hasNext();) {
+                sm = (StateManagerImpl) itr.next();
+                if (sm.isPersistent() && !sm.isDirty()) {
+                    cls = sm.getMetaData().getDescribedType();
+                    if (cls == extent.getElementType()
+                        || (extent.hasSubclasses()
+                        && extent.getElementType().isAssignableFrom(cls)))
+                        evict(sm.getManagedInstance(), call);
+                }
+            }
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void evict(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(false);
+        try {
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_EVICT, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+            if (sm == null)
+                return;
+
+            sm.evict();
+            if (_evictDataCache && sm.getObjectId() != null) {
+                DataCache cache = sm.getMetaData().getDataCache();
+                if (cache != null)
+                    cache.remove(sm.getObjectId());
+            }
+        }
+        catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Object detach(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return null;
+        if (call == null)
+            call = _call;
+
+        beginOperation(true);
+        try {
+            return new DetachManager(this, false, call).detach(obj);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Object[] detachAll(Collection objs, OpCallbacks call) {
+        if (objs == null)
+            return null;
+        if (objs.isEmpty())
+            return EMPTY_OBJECTS;
+        if (call == null)
+            call = _call;
+
+        beginOperation(true);
+        try {
+            return new DetachManager(this, false, call).detachAll(objs);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void detachAll(OpCallbacks call) {
+        detachAll(call, true);
+    }
+
+    public void detachAll(OpCallbacks call, boolean flush) {
+        beginOperation(true);
+        try {
+            // If a flush is desired (based on input parm), then check if the
+            //   "dirty" flag is set before calling flush().
+            if ((flush) && ((_flags & FLAG_FLUSH_REQUIRED) != 0))
+                flush();
+            detachAllInternal(call);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    private void detachAllInternal(OpCallbacks call) {
+        Collection states = getManagedStates();
+        StateManagerImpl sm;
+        for (Iterator itr = states.iterator(); itr.hasNext();) {
+            sm = (StateManagerImpl) itr.next();
+            if (!sm.isPersistent())
+                itr.remove();
+            else if (!sm.getMetaData().isDetachable()) {
+                sm.release(true);
+                itr.remove();
+            }
+        }
+        if (states.isEmpty())
+            return;
+
+        if (call == null)
+            call = _call;
+        new DetachManager(this, true, call).detachAll
+            (new ManagedObjectCollection(states));
+    }
+
+    public Object attach(Object obj, boolean copyNew, OpCallbacks call) {
+        if (obj == null)
+            return null;
+
+        beginOperation(true);
+        try {
+            // make sure not to try to set rollback only if this fails
+            assertWriteOperation();
+            try {
+                return new AttachManager(this, copyNew, call).attach(obj);
+            } catch (OptimisticException oe) {
+                setRollbackOnly(oe);
+                throw oe.setFatal(true);
+            } catch (OpenJPAException ke) {
+                throw ke;
+            } catch (RuntimeException re) {
+                throw new GeneralException(re);
+            }
+        }
+        finally {
+            endOperation();
+        }
+    }
+
+    public Object[] attachAll(Collection objs, boolean copyNew,
+        OpCallbacks call) {
+        if (objs == null)
+            return null;
+        if (objs.isEmpty())
+            return EMPTY_OBJECTS;
+
+        beginOperation(true);
+        try {
+            // make sure not to try to set rollback only if this fails
+            assertWriteOperation();
+            try {
+                return new AttachManager(this, copyNew, call).attachAll(objs);
+            } catch (OptimisticException oe) {
+                setRollbackOnly(oe);
+                throw oe.setFatal(true);
+            } catch (OpenJPAException ke) {
+                throw ke;
+            } catch (RuntimeException re) {
+                throw new GeneralException(re);
+            }
+        }
+        finally {
+            endOperation();
+        }
+    }
+
+    public void nontransactionalAll(Collection objs, OpCallbacks call) {
+        beginOperation(true);
+        try {
+            List exceps = null;
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                try {
+                    nontransactional(itr.next(), call);
+                } catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+            throwNestedExceptions(exceps, false);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void nontransactional(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true);
+        try {
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_NONTRANSACTIONAL, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+            if (sm != null)
+                sm.nontransactional();
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Make the given instances transactional.
+     */
+    public void transactionalAll(Collection objs, boolean updateVersion,
+        OpCallbacks call) {
+        if (objs.isEmpty())
+            return;
+        if (objs.size() == 1) {
+            transactional(objs.iterator().next(), updateVersion, call);
+            return;
+        }
+
+        beginOperation(true);
+        try {
+            // collect all hollow instances for load, and make unmananged
+            // instances transient-transactional
+            Collection load = null;
+            Object obj;
+            StateManagerImpl sm;
+            ClassMetaData meta;
+            Collection sms = new LinkedHashSet(objs.size());
+            List exceps = null;
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                obj = itr.next();
+                if (obj == null)
+                    continue;
+
+                try {
+                    sm = getStateManagerImpl(obj, true);
+                    if ((processArgument(OpCallbacks.OP_TRANSACTIONAL, obj, sm,
+                        call) & OpCallbacks.ACT_RUN) == 0)
+                        continue;
+
+                    if (sm == null) {
+                        // manage transient instance
+                        meta = _conf.getMetaDataRepositoryInstance().
+                            getMetaData(obj.getClass(), _loader, true);
+
+                        sm = new StateManagerImpl
+                            (StateManagerId.newInstance(this), meta, this);
+                        sm.initialize(assertPersistenceCapable(obj),
+                            PCState.TCLEAN);
+                    } else if (sm.isPersistent()) {
+                        assertActiveTransaction();
+                        sms.add(sm);
+                        if (sm.getPCState() == PCState.HOLLOW) {
+                            if (load == null)
+                                load = new ArrayList();
+                            load.add(sm);
+                        }
+
+                        sm.setCheckVersion(true);
+                        if (updateVersion)
+                            sm.setUpdateVersion(true);
+                        _flags |= FLAG_FLUSH_REQUIRED; // version check/up
+                    }
+                }
+                catch (UserException ue) {
+                    exceps = add(exceps, ue);
+                }
+            }
+
+            // load all hollow instances
+            Collection failed = null;
+            if (load != null) {
+                failed = _store.loadAll(load, null, _store.FORCE_LOAD_NONE,
+                    _fc, null);
+                if (failed != null && !failed.isEmpty())
+                    exceps = add(exceps,
+                        newObjectNotFoundException(failed));
+            }
+
+            transactionalStatesAll(sms, failed, exceps);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Make the given instances transactional.
+     */
+    public void transactional(Object obj, boolean updateVersion,
+        OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true);
+        try {
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_TRANSACTIONAL, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+
+            if (sm != null && sm.isPersistent()) {
+                assertActiveTransaction();
+                sm.transactional();
+                sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
+                sm.setCheckVersion(true);
+                if (updateVersion)
+                    sm.setUpdateVersion(true);
+                _flags |= FLAG_FLUSH_REQUIRED; // version check/up
+            } else if (sm == null) {
+                // manage transient instance
+                ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
+                    getMetaData(obj.getClass(), _loader, true);
+                Object id = StateManagerId.newInstance(this);
+                sm = new StateManagerImpl(id, meta, this);
+                sm.initialize(assertPersistenceCapable(obj),
+                    PCState.TCLEAN);
+            }
+        }
+        catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Transition the given state managers to transactional.
+     */
+    private void transactionalStatesAll(Collection sms, Collection failed,
+        List exceps) {
+        // make instances transactional and make sure they are loaded
+        StateManagerImpl sm;
+        for (Iterator itr = sms.iterator(); itr.hasNext();) {
+            sm = (StateManagerImpl) itr.next();
+            if (failed != null && failed.contains(sm.getId()))
+                continue;
+
+            try {
+                sm.transactional();
+                sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
+            } catch (OpenJPAException ke) {
+                exceps = add(exceps, ke);
+            }
+        }
+        throwNestedExceptions(exceps, false);
+    }
+
+    /////////////////
+    // Extent, Query
+    /////////////////
+
+    public Extent newExtent(Class type, boolean subclasses) {
+        return newExtent(type, subclasses, null);
+    }
+
+    private Extent newExtent(Class type, boolean subclasses,
+        FetchConfiguration fetch) {
+        beginOperation(true);
+        try {
+            ExtentImpl extent = new ExtentImpl(this, type, subclasses, fetch);
+            if (_extents == null)
+                _extents = new ReferenceHashSet(ReferenceHashSet.WEAK);
+            _extents.add(extent);
+
+            return extent;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Iterator extentIterator(Class type, boolean subclasses,
+        FetchConfiguration fetch, boolean ignoreChanges) {
+        Extent extent = newExtent(type, subclasses, fetch);
+        extent.setIgnoreChanges(ignoreChanges);
+        return extent.iterator();
+    }
+
+    public Query newQuery(String lang, Class cls, Object query) {
+        Query q = newQuery(lang, query);
+        q.setCandidateType(cls, true);
+        return q;
+    }
+
+    public Query newQuery(String lang, Object query) {
+        // common mistakes
+        if (query instanceof Extent || query instanceof Class)
+            throw new UserException(_loc.get("bad-new-query"));
+
+        beginOperation(false);
+        try {
+            StoreQuery sq = _store.newQuery(lang);
+            if (sq == null) {
+                ExpressionParser ep = QueryLanguages.parserForLanguage(lang);
+                if (ep != null)
+                    sq = new ExpressionStoreQuery(ep);
+                else if (QueryLanguages.LANG_METHODQL.equals(lang))
+                    sq = new MethodStoreQuery();
+                else
+                    throw new UnsupportedException(lang);
+            }
+
+            Query q = newQueryImpl(lang, sq);
+            q.setIgnoreChanges(_ignoreChanges);
+            if (query != null)
+                q.setQuery(query);
+
+            // track queries
+            if (_queries == null)
+                _queries = new ReferenceHashSet(ReferenceHashSet.WEAK);
+            _queries.add(q);
+            return q;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Create a new query.
+     */
+    protected QueryImpl newQueryImpl(String lang, StoreQuery sq) {
+        return new QueryImpl(this, lang, sq);
+    }
+
+    public Seq getIdentitySequence(ClassMetaData meta) {
+        if (meta == null)
+            return null;
+        return getSequence(meta, null);
+    }
+
+    public Seq getValueSequence(FieldMetaData fmd) {
+        if (fmd == null)
+            return null;
+        return getSequence(fmd.getDefiningMetaData(), fmd);
+    }
+
+    /**
+     * Return a sequence for the given class and optional field.
+     */
+    private Seq getSequence(ClassMetaData meta, FieldMetaData fmd) {
+        // get sequence strategy from metadata
+        int strategy;
+        if (fmd == null)
+            strategy = meta.getIdentityStrategy();
+        else
+            strategy = fmd.getValueStrategy();
+
+        // we can handle non-native strategies without the store manager
+        switch (strategy) {
+            case ValueStrategies.UUID_HEX:
+                return UUIDHexSeq.getInstance();
+            case ValueStrategies.UUID_STRING:
+                return UUIDStringSeq.getInstance();
+            case ValueStrategies.UUID_TYPE4_HEX:
+                return UUIDType4HexSeq.getInstance();
+            case ValueStrategies.UUID_TYPE4_STRING:
+                return UUIDType4StringSeq.getInstance();
+            case ValueStrategies.SEQUENCE:
+                SequenceMetaData smd = (fmd == null)
+                    ? meta.getIdentitySequenceMetaData()
+                    : fmd.getValueSequenceMetaData();
+                return smd.getInstance(_loader);
+            default:
+                // use store manager for native sequence
+                if (fmd == null) {
+                    // this will return a sequence even for app id classes,
+                    // which is what we want for backwards-compatibility
+                    return _store.getDataStoreIdSequence(meta);
+                }
+                return _store.getValueSequence(fmd);
+        }
+    }
+
+    ///////////
+    // Locking
+    ///////////
+
+    public void lock(Object obj, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true); // have to sync or lock level always NONE
+        try {
+            lock(obj, _fc.getWriteLockLevel(), _fc.getLockTimeout(), call);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void lock(Object obj, int level, int timeout, OpCallbacks call) {
+        if (obj == null)
+            return;
+
+        beginOperation(true);
+        try {
+            assertActiveTransaction();
+
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_LOCK, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+            if (sm == null || !sm.isPersistent())
+                return;
+
+            _lm.lock(sm, level, timeout, null);
+            sm.readLocked(level, level); // use same level for future write
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void lockAll(Collection objs, OpCallbacks call) {
+        if (objs.isEmpty())
+            return;
+
+        beginOperation(true); // have to sync or lock level always NONE
+        try {
+            lockAll(objs, _fc.getWriteLockLevel(), _fc.getLockTimeout(),
+                call);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public void lockAll(Collection objs, int level, int timeout,
+        OpCallbacks call) {
+        if (objs.isEmpty())
+            return;
+        if (objs.size() == 1) {
+            lock(objs.iterator().next(), level, timeout, call);
+            return;
+        }
+
+        beginOperation(true);
+        try {
+            assertActiveTransaction();
+
+            Collection sms = new LinkedHashSet(objs.size());
+            Object obj;
+            StateManagerImpl sm;
+            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+                obj = itr.next();
+                if (obj == null)
+                    continue;
+
+                sm = getStateManagerImpl(obj, true);
+                if ((processArgument(OpCallbacks.OP_LOCK, obj, sm, call)
+                    & OpCallbacks.ACT_RUN) == 0)
+                    continue;
+                if (sm != null && sm.isPersistent())
+                    sms.add(sm);
+            }
+
+            _lm.lockAll(sms, level, timeout, null);
+            for (Iterator itr = sms.iterator(); itr.hasNext();)
+                ((StateManagerImpl) itr.next()).readLocked(level, level);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            endOperation();
+        }
+    }
+
+    //////////////
+    // Connection
+    //////////////
+
+    public boolean cancelAll() {
+        // this method does not lock, since we want to allow a different
+        // thread to be able to cancel on a locked-up persistence manager
+
+        assertOpen();
+        try {
+            // if we're flushing, have to set rollback only -- do this before we
+            // attempt to cancel, because otherwise the cancel might case the
+            // transaction to complete before we have a chance to set the
+            // rollback only flag
+            if ((_flags & FLAG_STORE_FLUSHING) != 0)
+                setRollbackOnlyInternal(new UserException());
+            return _store.cancelAll();
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new StoreException(re);
+        }
+    }
+
+    public Object getConnection() {
+        assertOpen();
+        if (!_conf.supportedOptions().contains
+            (_conf.OPTION_DATASTORE_CONNECTION))
+            throw new UnsupportedException(_loc.get("conn-not-supported"));
+
+        return _store.getClientConnection();
+    }
+
+    public boolean hasConnection() {
+        assertOpen();
+        return (_flags & FLAG_RETAINED_CONN) != 0;
+    }
+
+    /**
+     * Tell store to retain connection if we haven't already.
+     */
+    private void retainConnection() {
+        if ((_flags & FLAG_RETAINED_CONN) == 0) {
+            _store.retainConnection();
+            _flags |= FLAG_RETAINED_CONN;
+        }
+    }
+
+    /**
+     * Tell store to release connection if we have retained one.
+     */
+    private void releaseConnection() {
+        if ((_flags & FLAG_RETAINED_CONN) != 0) {
+            _store.releaseConnection();
+            _flags &= ~FLAG_RETAINED_CONN;
+        }
+    }
+
+    /////////
+    // Cache
+    /////////
+
+    public Collection getManagedObjects() {
+        beginOperation(false);
+        try {
+            return new ManagedObjectCollection(getManagedStates());
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Collection getTransactionalObjects() {
+        beginOperation(false);
+        try {
+            return new ManagedObjectCollection(getTransactionalStates());
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Collection getPendingTransactionalObjects() {
+        beginOperation(false);
+        try {
+            return new ManagedObjectCollection
+                (getPendingTransactionalStates());
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Collection getDirtyObjects() {
+        beginOperation(false);
+        try {
+            return new ManagedObjectCollection(getDirtyStates());
+        } finally {
+            endOperation();
+        }
+    }
+
+    public boolean getOrderDirtyObjects() {
+        return _orderDirty;
+    }
+
+    public void setOrderDirtyObjects(boolean order) {
+        _orderDirty = order;
+    }
+
+    /**
+     * Return a copy of all managed state managers.
+     */
+    protected Collection getManagedStates() {
+        return _cache.copy();
+    }
+
+    /**
+     * Return a copy of all transactional state managers.
+     */
+    protected Collection getTransactionalStates() {
+        if (!hasTransactionalObjects())
+            return Collections.EMPTY_SET;
+        return _transCache.copy();
+    }
+
+    /**
+     * Whether or not there are any transactional objects in the current
+     * persistence context. If there are any instances with untracked state,
+     * this method will cause those instances to be scanned.
+     */
+    private boolean hasTransactionalObjects() {
+        _cache.dirtyCheck();
+        return _transCache != null;
+    }
+
+    /**
+     * Return a copy of all dirty state managers.
+     */
+    protected Collection getDirtyStates() {
+        if (!hasTransactionalObjects())
+            return Collections.EMPTY_SET;
+
+        return _transCache.copyDirty();
+    }
+
+    /**
+     * Return a copy of all state managers which will become
+     * transactional upon the next transaction.
+     */
+    protected Collection getPendingTransactionalStates() {
+        if (_pending == null)
+            return Collections.EMPTY_SET;
+        return new LinkedHashSet(_pending);
+    }
+
+    /**
+     * Set the cached StateManager for the instance that had the given oid.
+     * This method must not be called multiple times for new instances.
+     *
+     * @param id the id previously used by the instance
+     * @param sm the state manager for the instance; if the state
+     * manager is transient, we'll stop managing the instance;
+     * if it has updated its oid, we'll re-cache under the new oid
+     * @param status one of our STATUS constants describing why we're
+     * setting the state manager
+     */
+    void setStateManager(Object id, StateManagerImpl sm, int status) {
+        lock();
+        try {
+            switch (status) {
+                case STATUS_INIT:
+                    _cache.add(sm);
+                    break;
+                case STATUS_TRANSIENT:
+                    _cache.remove(id, sm);
+                    break;
+                case STATUS_OID_ASSIGN:
+                    assignObjectId(_cache, id, sm);
+                    break;
+                case STATUS_COMMIT_NEW:
+                    _cache.commitNew(id, sm);
+                    break;
+                default:
+                    throw new InternalException();
+            }
+        }
+        finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Notify the broker that the given state manager should
+     * be added to the set of instances involved in the current transaction.
+     */
+    void addToTransaction(StateManagerImpl sm) {
+        // we only add clean instances now; dirty instances are added in
+        // the setDirty callback
+        if (sm.isDirty())
+            return;
+
+        lock();
+        try {
+            if (!hasTransactionalObjects())
+                _transCache = new TransactionalCache(_orderDirty);
+            _transCache.addClean(sm);
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Notify the persistence manager that the given state manager should
+     * be removed from the set of instances involved in the current transaction.
+     */
+    void removeFromTransaction(StateManagerImpl sm) {
+        lock();
+        try {
+            if (_transCache != null)
+                // intentional direct access; we don't want to recompute
+                // dirtiness while removing instances from the transaction
+                _transCache.remove(sm);
+            if (_derefCache != null && !sm.isPersistent())
+                _derefCache.remove(sm);
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Notification that the given instance has been dirtied. This
+     * notification is given when an object first transitions to a dirty state,
+     * and every time the object is modified by the user thereafter.
+     */
+    void setDirty(StateManagerImpl sm, boolean firstDirty) {
+        if (sm.isPersistent())
+            _flags |= FLAG_FLUSH_REQUIRED;
+
+        if (_savepoints != null && !_savepoints.isEmpty()) {
+            if (_savepointCache == null)
+                _savepointCache = new HashSet();
+            _savepointCache.add(sm);
+        }
+
+        if (firstDirty && sm.isTransactional()) {
+            lock();
+            try {
+                // cache dirty instance
+                if (!hasTransactionalObjects())
+                    _transCache = new TransactionalCache(_orderDirty);
+                _transCache.addDirty(sm);
+
+                // also record that the class is dirty
+                if (sm.isNew()) {
+                    if (_persistedClss == null)
+                        _persistedClss = new HashSet();
+                    _persistedClss.add(sm.getMetaData().getDescribedType());
+                } else if (sm.isDeleted()) {
+                    if (_deletedClss == null)
+                        _deletedClss = new HashSet();
+                    _deletedClss.add(sm.getMetaData().getDescribedType());
+                } else {
+                    if (_updatedClss == null)
+                        _updatedClss = new HashSet();
+                    _updatedClss.add(sm.getMetaData().getDescribedType());
+                }
+
+                // if tracking changes and this instance wasn't already dirty,
+                // add to changed set; we use this for detecting instances that
+                // enter the transaction during pre store
+                if ((_flags & FLAG_PRESTORING) != 0) {
+                    if (_transAdditions == null)
+                        _transAdditions = new HashSet();
+                    _transAdditions.add(sm);
+                }
+            } finally {
+                unlock();
+            }
+        }
+    }
+
+    /**
+     * Notify the broker that the given state manager should
+     * be added to the set of instances that will become transactional
+     * on the next transaction
+     */
+    void addToPendingTransaction(StateManagerImpl sm) {
+        lock();
+        try {
+            if (_pending == null)
+                _pending = new HashSet();
+            _pending.add(sm);
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Notify the persistence manager that the given state manager should
+     * be removed from the set of instances involved in the next transaction.
+     */
+    void removeFromPendingTransaction(StateManagerImpl sm) {
+        lock();
+        try {
+            if (_pending != null)
+                _pending.remove(sm);
+            if (_derefCache != null && !sm.isPersistent())
+                _derefCache.remove(sm);
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Add a dereferenced dependent object to the persistence manager's cache.
+     * On flush, these objects will be deleted.
+     */
+    void addDereferencedDependent(StateManagerImpl sm) {
+        lock();
+        try {
+            // if we're in the middle of flush and introducing more derefs
+            // via instance callbacks, add them to the special additions set
+            if ((_flags & FLAG_DEREFDELETING) != 0) {
+                if (_derefAdditions == null)
+                    _derefAdditions = new HashSet();
+                _derefAdditions.add(sm);
+            } else {
+                if (_derefCache == null)
+                    _derefCache = new HashSet();
+                _derefCache.add(sm);
+            }
+        }
+        finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Remove the given previously dereferenced dependent object from the
+     * cache. It is now referenced.
+     */
+    void removeDereferencedDependent(StateManagerImpl sm) {
+        lock();
+        try {
+            boolean removed = false;
+            if (_derefAdditions != null)
+                removed = _derefAdditions.remove(sm);
+            if (!removed && (_derefCache == null || !_derefCache.remove(sm)))
+                throw new InvalidStateException(_loc.get("not-derefed",
+                    Exceptions.toString(sm.getManagedInstance()))).
+                    setFailedObject(sm.getManagedInstance()).
+                    setFatal(true);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void dirtyType(Class cls) {
+        if (cls == null)
+            return;
+
+        beginOperation(false);
+        try {
+            if (_updatedClss == null)
+                _updatedClss = new HashSet();
+            _updatedClss.add(cls);
+        } finally {
+            endOperation();
+        }
+    }
+
+    public Collection getPersistedTypes() {
+        if (_persistedClss == null || _persistedClss.isEmpty())
+            return Collections.EMPTY_SET;
+        return Collections.unmodifiableCollection(_persistedClss);
+    }
+
+    public Collection getUpdatedTypes() {
+        if (_updatedClss == null || _updatedClss.isEmpty())
+            return Collections.EMPTY_SET;
+        return Collections.unmodifiableCollection(_updatedClss);
+    }
+
+    public Collection getDeletedTypes() {
+        if (_deletedClss == null || _deletedClss.isEmpty())
+            return Collections.EMPTY_SET;
+        return Collections.unmodifiableCollection(_deletedClss);
+    }
+
+    ///////////
+    // Closing
+    ///////////
+
+    public boolean isClosed() {
+        return _closed;
+    }
+
+    public boolean isCloseInvoked() {
+        return _closed || (_flags & FLAG_CLOSE_INVOKED) != 0;
+    }
+
+    public void close() {
+        beginOperation(false);
+        try {
+            // throw an exception if closing in an active local trans
+            if (!_managed && (_flags & FLAG_ACTIVE) != 0)
+                throw new InvalidStateException(_loc.get("active"));
+
+            // only close if not active; if active managed trans wait
+            // for completion
+            _flags |= FLAG_CLOSE_INVOKED;
+
+            if ((_flags & FLAG_ACTIVE) == 0)
+                free();
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Free the resources used by this persistence manager.
+     */
+    protected void free() {
+        RuntimeException err = null;
+        if ((_autoDetach & DETACH_CLOSE) != 0) {
+            try {
+                detachAllInternal(_call);
+            } catch (RuntimeException re) {
+                err = re;
+            }
+        }
+
+        _sync = null;
+        _userObjects = null;
+        _cache.clear();
+        _transCache = null;
+        _persistedClss = null;
+        _updatedClss = null;
+        _deletedClss = null;
+        _derefCache = null;
+        _pending = null;
+        _loader = null;
+        _transEventManager = null;
+        _lifeEventManager = null;
+
+        OpenJPASavepoint save;
+        while (_savepoints != null && !_savepoints.isEmpty()) {
+            save =
+                (OpenJPASavepoint) _savepoints.remove(_savepoints.size() - 1);
+            save.release(false);
+        }
+        _savepoints = null;
+        _savepointCache = null;
+
+        if (_queries != null) {
+            for (Iterator itr = _queries.iterator(); itr.hasNext();) {
+                try {
+                    ((Query) itr.next()).closeResources();
+                } catch (RuntimeException re) {
+                }
+            }
+            _queries = null;
+        }
+
+        if (_extents != null) {
+            Extent e;
+            for (Iterator itr = _extents.iterator(); itr.hasNext();) {
+                e = (Extent) itr.next();
+                try {
+                    e.closeAll();
+                } catch (RuntimeException re) {
+                }
+            }
+            _extents = null;
+        }
+
+        try { releaseConnection(); } catch (RuntimeException re) {}
+
+        _lm.close();
+        _store.close();
+        _flags = 0;
+        _closed = true;
+        if (_log.isTraceEnabled())
+            _closedException = new IllegalStateException();
+
+        _factory.releaseBroker(this);
+
+        if (err != null)
+            throw err;
+    }
+
+    ///////////////////
+    // Synchronization
+    ///////////////////
+
+    public void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    public void unlock() {
+        if (_lock != null)
+            _lock.unlock();
+    }
+
+    ////////////////////
+    // State management
+    ////////////////////
+
+    public Object newInstance(Class cls) {
+        assertOpen();
+
+        if (!cls.isInterface() && Modifier.isAbstract(cls.getModifiers()))
+            throw new UnsupportedOperationException(_loc.get
+                ("new-abstract", cls).getMessage());
+
+        // 1.5 doesn't initialize classes without a true Class.forName
+        if (!PCRegistry.isRegistered(cls)) {
+            try {
+                Class.forName(cls.getName(), true, 
+                    (ClassLoader) AccessController.doPrivileged(
+                        J2DoPrivHelper.getClassLoaderAction(cls)));
+            } catch (Throwable t) {
+            }
+        }
+
+        if (_conf.getMetaDataRepositoryInstance().getMetaData(cls,
+            getClassLoader(), false) == null)
+            throw new IllegalArgumentException(
+                _loc.get("no-interface-metadata", cls.getName()).getMessage());
+
+        try {
+            return PCRegistry.newInstance(cls, null, false);
+        } catch (IllegalStateException ise) {
+            IllegalArgumentException iae =
+                new IllegalArgumentException(ise.getMessage());
+            iae.setStackTrace(ise.getStackTrace());
+            throw iae;
+        }
+    }
+
+    public Object getObjectId(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj))
+            return (ImplHelper.toPersistenceCapable(obj, _conf))
+                .pcFetchObjectId();
+        return null;
+    }
+
+    public int getLockLevel(Object o) {
+        assertOpen();
+        if (o == null)
+            return LockLevels.LOCK_NONE;
+
+        OpenJPAStateManager sm = getStateManager(o);
+        if (sm == null)
+            return LockLevels.LOCK_NONE;
+        return getLockManager().getLockLevel(sm);
+    }
+
+    public Object getVersion(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj))
+            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcGetVersion();
+        return null;
+    }
+
+    public boolean isDirty(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj)) {
+            PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
+            return pc.pcIsDirty();
+        }
+        return false;
+    }
+
+    public boolean isTransactional(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj))
+            return (ImplHelper.toPersistenceCapable(obj, _conf))
+                .pcIsTransactional();
+        return false;
+    }
+
+    public boolean isPersistent(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj))
+            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcIsPersistent();
+        return false;
+    }
+
+    public boolean isNew(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj))
+            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcIsNew();
+        return false;
+    }
+
+    public boolean isDeleted(Object obj) {
+        assertOpen();
+        if (ImplHelper.isManageable(obj))
+            return (ImplHelper.toPersistenceCapable(obj, _conf)).pcIsDeleted();
+        return false;
+    }
+
+    public boolean isDetached(Object obj) {
+        if (!(ImplHelper.isManageable(obj)))
+            return false;
+
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
+        Boolean detached = pc.pcIsDetached();
+        if (detached != null)
+            return detached.booleanValue();
+
+        // last resort: instance is detached if it has a store record
+        ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
+            getMetaData(ImplHelper.getManagedInstance(pc).getClass(),
+                _loader, true);
+        Object oid = ApplicationIds.create(pc, meta);
+        if (oid == null)
+            return false;
+        return find(oid, null, EXCLUDE_ALL, null, 0) != null;
+    }
+
+    public OpenJPAStateManager getStateManager(Object obj) {
+        assertOpen();
+        return getStateManagerImpl(obj, false);
+    }
+
+    /**
+     * Return the state manager for the given instance, or null.
+     *
+     * @param assertThisContext if true, thow an exception if the given
+     * object is managed by another broker
+     */
+    protected StateManagerImpl getStateManagerImpl(Object obj,
+        boolean assertThisContext) {
+        if (ImplHelper.isManageable(obj)) {
+            PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
+            if (pc.pcGetGenericContext() == this)
+                return (StateManagerImpl) pc.pcGetStateManager();
+            if (assertThisContext && pc.pcGetGenericContext() != null)
+                throw new UserException(_loc.get("not-managed",
+                    Exceptions.toString(obj))).setFailedObject(obj);
+        }
+        return null;
+    }
+
+    /**
+     * Return the state manager for the given oid.
+     *
+     * @param allowNew if true, objects made persistent in the current
+     * transaction will be included in the search; if
+     * multiple new objects match the given oid, it is
+     * undefined which will be returned
+     */
+    protected StateManagerImpl getStateManagerImplById(Object oid,
+        boolean allowNew) {
+        return _cache.getById(oid, allowNew);
+    }
+
+    /**
+     * Return the given instance as a {@link PersistenceCapable}.
+     * If the instance is not manageable throw the proper exception.
+     */
+    protected PersistenceCapable assertPersistenceCapable(Object obj) {
+        if (obj == null)
+            return null;
+        if (ImplHelper.isManageable(obj))
+            return ImplHelper.toPersistenceCapable(obj, _conf);
+
+        // check for different instances of the PersistenceCapable interface
+        // and throw a better error that mentions the class loaders
+        Class[] intfs = obj.getClass().getInterfaces();
+        for (int i = 0; intfs != null && i < intfs.length; i++) {
+            if (intfs[i].getName().equals(PersistenceCapable.class.getName())) {
+                throw new UserException(_loc.get("pc-loader-different",
+                    Exceptions.toString(obj),
+                    (ClassLoader) AccessController.doPrivileged(
+                        J2DoPrivHelper.getClassLoaderAction(
+                            PersistenceCapable.class)),
+                    (ClassLoader) AccessController.doPrivileged(
+                        J2DoPrivHelper.getClassLoaderAction(intfs[i]))))
+                    .setFailedObject(obj);
+            }
+        }
+
+        // not enhanced
+        throw new UserException(_loc.get("pc-cast",
+            Exceptions.toString(obj))).setFailedObject(obj);
+    }
+
+    /////////
+    // Utils
+    /////////
+    /**
+     * Throw an exception if the context is closed.  The exact message and
+     * content of the exception varies whether TRACE is enabled or not.
+     */
+    public void assertOpen() {
+        if (_closed) {
+            if (_closedException == null)  // TRACE not enabled
+                throw new InvalidStateException(_loc.get("closed-notrace"))
+                        .setFatal(true);
+            else {
+                OpenJPAException e = new InvalidStateException(
+                    _loc.get("closed"), _closedException).setFatal(true);
+                e.setCause(_closedException);
+                throw e;
+            }
+        }
+    }
+
+    public void assertActiveTransaction() {
+        if ((_flags & FLAG_ACTIVE) == 0)
+            throw new NoTransactionException(_loc.get("not-active"));
+    }
+
+    /**
+     * Throw exception if a transaction-related operation is attempted and
+     * no transaction is active.
+     */
+    private void assertTransactionOperation() {
+        if ((_flags & FLAG_ACTIVE) == 0)
+            throw new InvalidStateException(_loc.get("not-active"));
+    }
+
+    public void assertNontransactionalRead() {
+        if ((_flags & FLAG_ACTIVE) == 0 && !_nontransRead)
+            throw new InvalidStateException(_loc.get("non-trans-read"));
+    }
+
+    public void assertWriteOperation() {
+        if ((_flags & FLAG_ACTIVE) == 0 && (!_nontransWrite
+            || (_autoDetach & DETACH_NONTXREAD) != 0))
+            throw new NoTransactionException(_loc.get("write-operation"));
+    }
+
+    /**
+     * Return an object not found exception containing nested exceptions
+     * for all of the given failed objects.
+     */
+    private static ObjectNotFoundException newObjectNotFoundException
+        (Collection failed) {
+        Throwable[] t = new Throwable[failed.size()];
+        int idx = 0;
+        for (Iterator itr = failed.iterator(); itr.hasNext(); idx++)
+            t[idx] = new ObjectNotFoundException(itr.next());
+        return new ObjectNotFoundException(failed, t);
+    }
+
+    ////////////////////////////////
+    // FindCallbacks implementation
+    ////////////////////////////////
+
+    public Object processArgument(Object oid) {
+        return oid;
+    }
+
+    public Object processReturn(Object oid, OpenJPAStateManager sm) {
+        return (sm == null) ? null : sm.getManagedInstance();
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        assertOpen();
+        lock();
+        try {
+            if (isActive()) {
+                if (!getOptimistic())
+                    throw new InvalidStateException(
+                        _loc.get("cant-serialize-pessimistic-broker"));
+                if (hasFlushed())
+                    throw new InvalidStateException(
+                        _loc.get("cant-serialize-flushed-broker"));
+                if (hasConnection())
+                    throw new InvalidStateException(
+                        _loc.get("cant-serialize-connected-broker"));
+            }
+
+            try {
+                _isSerializing = true;
+                out.writeObject(_factory.getPoolKey());
+                out.defaultWriteObject();
+            } finally {
+                _isSerializing = false;
+            }
+        } finally {
+            unlock();
+        }
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws ClassNotFoundException, IOException {
+        Object factoryKey = in.readObject();
+        AbstractBrokerFactory factory =
+            AbstractBrokerFactory.getPooledFactoryForKey(factoryKey);
+
+        // this needs to happen before defaultReadObject so that it's
+        // available for calls to broker.getConfiguration() during
+        // StateManager deserialization
+        _conf = factory.getConfiguration();
+        
+        in.defaultReadObject();
+        factory.initializeBroker(_managed, _connRetainMode, this, true);
+
+        // re-initialize the lock if needed.
+        setMultithreaded(_multithreaded);
+
+        if (isActive() && _runtime instanceof LocalManagedRuntime)
+            ((LocalManagedRuntime) _runtime).begin();
+    }
+
+    /**
+     * Whether or not this broker is in the midst of being serialized.
+     *
+     * @since 1.1.0 
+     */
+    boolean isSerializing() {
+        return _isSerializing;
+    }
+
+    /**
+     * Transactional cache that holds soft refs to clean instances.
+     */
+    static class TransactionalCache
+        implements Set, Serializable {
+
+        private final boolean _orderDirty;
+        private Set _dirty = null;
+        private Set _clean = null;
+
+        public TransactionalCache(boolean orderDirty) {
+            _orderDirty = orderDirty;
+        }
+
+        /**
+         * Return a copy of all transactional state managers.
+         */
+        public Collection copy() {
+            if (isEmpty())
+                return Collections.EMPTY_SET;
+
+            // size may not be entirely accurate due to refs expiring, so
+            // manually copy each object; doesn't matter this way if size too
+            // big by some
+            Set copy = new LinkedHashSet(size());
+            if (_dirty != null)
+                for (Iterator itr = _dirty.iterator(); itr.hasNext();)
+                    copy.add(itr.next());
+            if (_clean != null)
+                for (Iterator itr = _clean.iterator(); itr.hasNext();)
+                    copy.add(itr.next());
+            return copy;
+        }
+
+        /**
+         * Return a copy of all dirty state managers.
+         */
+        public Collection copyDirty() {
+            if (_dirty == null || _dirty.isEmpty())
+                return Collections.EMPTY_SET;
+            return new LinkedHashSet(_dirty);
+        }
+
+        /**
+         * Transfer the given instance from the dirty cache to the clean cache.
+         */
+        public void flushed(StateManagerImpl sm) {
+            if (sm.isDirty() && _dirty != null && _dirty.remove(sm))
+                addCleanInternal(sm);
+        }
+
+        /**
+         * Add the given instance to the clean cache.
+         */
+        public void addClean(StateManagerImpl sm) {
+            if (addCleanInternal(sm) && _dirty != null)
+                _dirty.remove(sm);
+        }
+
+        private boolean addCleanInternal(StateManagerImpl sm) {
+            if (_clean == null)
+                _clean = new ReferenceHashSet(ReferenceHashSet.SOFT);
+            return _clean.add(sm);
+        }
+
+        /**
+         * Add the given instance to the dirty cache.
+         */
+        public void addDirty(StateManagerImpl sm) {
+            if (_dirty == null) {
+                if (_orderDirty)
+                    _dirty = MapBackedSet.decorate(new LinkedMap());
+                else
+                    _dirty = new HashSet();
+            }
+            if (_dirty.add(sm))
+                removeCleanInternal(sm);
+        }
+
+        /**
+         * Remove the given instance from the cache.
+         */
+        public boolean remove(StateManagerImpl sm) {
+            return removeCleanInternal(sm)
+                || (_dirty != null && _dirty.remove(sm));
+        }
+
+        private boolean removeCleanInternal(StateManagerImpl sm) {
+            return _clean != null && _clean.remove(sm);
+        }
+
+        public Iterator iterator() {
+            IteratorChain chain = new IteratorChain();
+            if (_dirty != null && !_dirty.isEmpty())
+                chain.addIterator(_dirty.iterator());
+            if (_clean != null && !_clean.isEmpty())
+                chain.addIterator(_clean.iterator());
+            return chain;
+        }
+
+        public boolean contains(Object obj) {
+            return (_dirty != null && _dirty.contains(obj))
+                || (_clean != null && _clean.contains(obj));
+        }
+
+        public boolean containsAll(Collection coll) {
+            for (Iterator itr = coll.iterator(); itr.hasNext();)
+                if (!contains(itr.next()))
+                    return false;
+            return true;
+        }
+
+        public void clear() {
+            if (_dirty != null)
+                _dirty = null;
+            if (_clean != null)
+                _clean = null;
+        }
+
+        public boolean isEmpty() {
+            return (_dirty == null || _dirty.isEmpty())
+                && (_clean == null || _clean.isEmpty());
+        }
+
+        public int size() {
+            int size = 0;
+            if (_dirty != null)
+                size += _dirty.size();
+            if (_clean != null)
+                size += _clean.size();
+            return size;
+        }
+
+        public boolean add(Object obj) {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean addAll(Collection coll) {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean remove(Object obj) {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean removeAll(Collection coll) {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean retainAll(Collection c) {
+            throw new UnsupportedOperationException();
+        }
+
+        public Object[] toArray() {
+            throw new UnsupportedOperationException();
+        }
+
+        public Object[] toArray(Object[] arr) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * Unique id for state managers of new datastore instances without assigned
+     * object ids.
+     */
+    private static class StateManagerId
+        implements Serializable {
+
+        public static final String STRING_PREFIX = "openjpasm:";
+
+        private static long _generator = 0;
+
+        private final int _bhash;
+        private final long _id;
+
+        public static StateManagerId newInstance(Broker b) {
+            return new StateManagerId(System.identityHashCode(b), _generator++);
+        }
+
+        private StateManagerId(int bhash, long id) {
+            _bhash = bhash;
+            _id = id;
+        }
+
+        public StateManagerId(String str) {
+            str = str.substring(STRING_PREFIX.length());
+            int idx = str.indexOf(':');
+            _bhash = Integer.parseInt(str.substring(0, idx));
+            _id = Long.parseLong(str.substring(idx + 1));
+        }
+
+        public boolean equals(Object other) {
+            if (other == this)
+                return true;
+            if (!(other instanceof StateManagerId))
+                return false;
+            StateManagerId sid = (StateManagerId) other;
+            return _bhash == sid._bhash && _id == sid._id;
+        }
+
+        public int hashCode() {
+            return (int) (_id ^ (_id >>> 32));
+        }
+
+        public String toString() {
+            return STRING_PREFIX + _bhash + ":" + _id;
+        }
+    }
+
+    /**
+     * Collection type that holds state managers but whose interface deals
+     * with the corresponding managed objects.
+     */
+    private static class ManagedObjectCollection
+        extends AbstractCollection {
+
+        private final Collection _states;
+
+        public ManagedObjectCollection(Collection states) {
+            _states = states;
+        }
+
+        public Collection getStateManagers() {
+            return _states;
+        }
+
+        public int size() {
+            return _states.size();
+        }
+
+        public Iterator iterator() {
+            return new Iterator() {
+                private final Iterator _itr = _states.iterator();
+
+                public boolean hasNext() {
+                    return _itr.hasNext();
+                }
+
+                public Object next() {
+                    return ((OpenJPAStateManager) _itr.next()).
+                        getManagedInstance();
+                }
+
+                public void remove() {
+                    throw new UnsupportedException();
+                }
+            };
+        }
+    }
+
+    /**
+     * Assign the object id to the cache. Exception will be
+     * thrown if the id already exists in the cache. 
+     */
+    protected void assignObjectId(Object cache, Object id, 
+        StateManagerImpl sm) {
+        ((ManagedCache) cache).assignObjectId(id, sm); 
+    }
+
+    /** 
+     * This method makes sure we don't already have the instance cached
+     */
+    protected void checkForDuplicateId(Object id, Object obj) {
+        StateManagerImpl other = getStateManagerImplById(id, false);
+        if (other != null && !other.isDeleted() && !other.isNew())
+            throw new ObjectExistsException(_loc.get("cache-exists",
+                obj.getClass().getName(), id)).setFailedObject(obj);
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
index b821825..8a8afef 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
@@ -34,6 +34,7 @@
 import java.util.Map;
 
 import org.apache.commons.collections.map.IdentityMap;
+import org.apache.openjpa.conf.Compatibility;
 import org.apache.openjpa.conf.DetachOptions;
 import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.event.CallbackModes;
@@ -68,6 +69,7 @@
     private final boolean _failFast;
     private boolean _flushed = false;
     private boolean _flushBeforeDetach;
+    private boolean _reloadOnDetach;
 
     // if we're not detaching full, we need to track all detached objects;
     // if we are, then we use a special field manager for more efficient
@@ -92,7 +94,7 @@
         boolean setState = meta.getDetachedState() != null
             && !ClassMetaData.SYNTHETIC.equals(meta.getDetachedState());
         BitSet idxs = (setState) ? new BitSet(meta.getFields().length) : null;
-        preDetach(sm.getBroker(), sm, idxs);
+        preDetach(sm.getBroker(), sm, idxs, false, true);
 
         if (setState) {
             sm.getPersistenceCapable().pcSetDetachedState(getDetachedState
@@ -120,7 +122,7 @@
         flushDirty(sm);
 
         Broker broker = sm.getBroker();
-        preDetach(broker, sm, idxs);
+        preDetach(broker, sm, idxs, false, true);
 
         // write detached state object and state manager
         DetachOptions opts = broker.getConfiguration().
@@ -145,7 +147,8 @@
      * effect of this method
      */
     private static void preDetach(Broker broker, StateManagerImpl sm,
-        BitSet idxs) {
+        BitSet idxs, boolean full, 
+        boolean reloadOnDetach) {
         // make sure the existing object has the right fields fetched; call
         // even if using currently-loaded fields for detach to make sure
         // version is set
@@ -157,8 +160,12 @@
         else if (detachMode == DETACH_ALL)
             loadMode = StateManagerImpl.LOAD_ALL;
         try {
-            sm.load(broker.getFetchConfiguration(), loadMode, exclude, null, 
-                false);
+            if (detachMode != DETACH_LOADED || 
+                    reloadOnDetach ||
+                    (!reloadOnDetach && !full)) {
+                sm.load(broker.getFetchConfiguration(), loadMode, exclude,
+                    null, false);
+            }
         } catch (ObjectNotFoundException onfe) {
             // consume the exception
         }
@@ -274,9 +281,10 @@
             _detached = new IdentityMap();
             _fullFM = null;
         }
-        _flushBeforeDetach =
-                broker.getConfiguration().getCompatibilityInstance()
-                        .getFlushBeforeDetach();
+        Compatibility compatibility = 
+            broker.getConfiguration().getCompatibilityInstance();
+        _flushBeforeDetach = compatibility.getFlushBeforeDetach();
+        _reloadOnDetach = compatibility.getReloadOnDetach();
     }
 
     /**
@@ -431,7 +439,8 @@
         }
         
         BitSet fields = new BitSet();
-        preDetach(_broker, sm, fields);
+        preDetach(_broker, sm, fields, _full, 
+            _reloadOnDetach);
 
         // create and store new object before copy to avoid endless recursion
         PersistenceCapable pc = sm.getPersistenceCapable();
@@ -451,7 +460,9 @@
                 _opts.getAccessUnloaded(), _broker.getMultithreaded());
         if (_full) {
             _fullFM.setStateManager(sm);
-            _fullFM.detachVersion();
+            if (_copy || _reloadOnDetach) {
+                _fullFM.detachVersion();
+            }
             _fullFM.reproxy(detSM);
             _fullFM.setStateManager(null);
         } else {
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
index 5476ee0..24f2a95 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
@@ -1,949 +1,949 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.IOException;
-import java.io.ObjectOutput;
-import java.io.Serializable;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.StateManager;
-import org.apache.openjpa.lib.util.Localizer;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.ValueMetaData;
-import org.apache.openjpa.util.Exceptions;
-import org.apache.openjpa.util.Proxy;
-import org.apache.openjpa.util.UnsupportedException;
-import org.apache.openjpa.util.ImplHelper;
-
-/**
- * Internal state manager for detached instances. Does not fully
- * implement {@link OpenJPAStateManager} contract to allow for serialization.
- *
- * @author Steve Kim
- * @nojavadoc
- */
-public class DetachedStateManager
-    extends AttachStrategy
-    implements OpenJPAStateManager, Serializable {
-
-    private static final long serialVersionUID = 4112223665584731100L;
-
-    private static final Localizer _loc = Localizer.forPackage
-        (DetachedStateManager.class);
-
-    private final PersistenceCapable _pc;
-    private final boolean _embedded;
-    private final boolean _access;
-    private final BitSet _loaded;
-    private final BitSet _dirty;
-    private final Object _oid;
-    private final Object _version;
-    private final ReentrantLock _lock;
-
-    /**
-     * Constructor.
-     *
-     * @param pc the managed instance
-     * @param sm the instance's state manager
-     * @param load the set of detached field indexes
-     * @param access whether to allow access to unloaded fields
-     * @param multithreaded whether the instance will be used concurrently
-     * by multiple threads
-     */
-    public DetachedStateManager(PersistenceCapable pc, OpenJPAStateManager sm,
-        BitSet load, boolean access, boolean multithreaded) {
-        _pc = pc;
-        _embedded = sm.isEmbedded();
-        _loaded = load;
-        _access = access;
-        _dirty = new BitSet(_loaded.length());
-        _oid = sm.fetchObjectId();
-        _version = sm.getVersion();
-        if (multithreaded)
-            _lock = new ReentrantLock();
-        else
-            _lock = null;
-    }
-
-    /////////////////////////////////
-    // AttachStrategy implementation
-    /////////////////////////////////
-
-    public Object attach(AttachManager manager, Object toAttach,
-        ClassMetaData meta, PersistenceCapable into, OpenJPAStateManager owner,
-        ValueMetaData ownerMeta, boolean explicit) {
-        BrokerImpl broker = manager.getBroker();
-        StateManagerImpl sm;
-        if (_embedded) {
-            if (_dirty.length () > 0)
-                owner.dirty(ownerMeta.getFieldMetaData().getIndex());
-            sm = (StateManagerImpl) broker.embed(_pc, _oid, owner, ownerMeta);
-            ImplHelper.toPersistenceCapable(toAttach, broker.getConfiguration())
-                .pcReplaceStateManager(this);
-        } else {
-            PCState state = (_dirty.length() > 0) ? PCState.PDIRTY
-                : PCState.PCLEAN;
-            sm = (StateManagerImpl) broker.copy(this, state);
-        }
-        PersistenceCapable pc = sm.getPersistenceCapable();
-        manager.setAttachedCopy(toAttach, pc);
-
-        manager.fireBeforeAttach(toAttach, meta);
-
-        // pre-load for efficiency: current field values for restore, dependent
-        // for delete
-        FieldMetaData[] fields = meta.getFields();
-        int restore = broker.getRestoreState();
-        if (_dirty.length() > 0) {
-            BitSet load = new BitSet(fields.length);
-            for (int i = 0; i < fields.length; i++) {
-                if (!_dirty.get(i))
-                    continue;
-
-                switch (fields[i].getDeclaredTypeCode()) {
-                    case JavaTypes.ARRAY:
-                    case JavaTypes.COLLECTION:
-                        if (restore == RestoreState.RESTORE_ALL
-                            || fields[i].getElement().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                        break;
-                    case JavaTypes.MAP:
-                        if (restore == RestoreState.RESTORE_ALL
-                            || fields[i].getElement().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO
-                            || fields[i].getKey().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                        break;
-                    default:
-                        if (restore != RestoreState.RESTORE_NONE
-                            || fields[i].getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                }
-            }
-            FetchConfiguration fc = broker.getFetchConfiguration();
-            sm.loadFields(load, fc, fc.getWriteLockLevel(), null);
-        }        
-        Object origVersion = sm.getVersion();
-        sm.setVersion(_version);
-
-        BitSet loaded = sm.getLoaded();
-        int set = StateManager.SET_ATTACH;
-        for (int i = 0; i < fields.length; i++) {
-            if (!_loaded.get(i))
-                continue;
-            // don't reload already loaded non-mutable objects
-            if (!_dirty.get(i) && loaded.get(i) && ignoreLoaded(fields[i]))
-                continue;
-
-            provideField(i);
-            switch (fields[i].getDeclaredTypeCode()) {
-                case JavaTypes.BOOLEAN:
-                    if (_dirty.get(i))
-                        sm.settingBooleanField(pc, i,
-                            (loaded.get(i)) && sm.fetchBooleanField(i),
-                            longval == 1, set);
-                    else
-                        sm.storeBooleanField(i, longval == 1);
-                    break;
-                case JavaTypes.BYTE:
-                    if (_dirty.get(i))
-                        sm.settingByteField(pc, i, (!loaded.get(i)) ? (byte) 0
-                            : sm.fetchByteField(i), (byte) longval, set);
-                    else
-                        sm.storeByteField(i, (byte) longval);
-                    break;
-                case JavaTypes.CHAR:
-                    if (_dirty.get(i))
-                        sm.settingCharField(pc, i, (!loaded.get(i)) ? (char) 0
-                            : sm.fetchCharField(i), (char) longval, set);
-                    else
-                        sm.storeCharField(i, (char) longval);
-                    break;
-                case JavaTypes.INT:
-                    if (_dirty.get(i))
-                        sm.settingIntField(pc, i, (!loaded.get(i)) ? 0
-                            : sm.fetchIntField(i), (int) longval, set);
-                    else
-                        sm.storeIntField(i, (int) longval);
-                    break;
-                case JavaTypes.LONG:
-                    if (_dirty.get(i))
-                        sm.settingLongField(pc, i, (!loaded.get(i)) ? 0L
-                            : sm.fetchLongField(i), longval, set);
-                    else
-                        sm.storeLongField(i, longval);
-                    break;
-                case JavaTypes.SHORT:
-                    if (_dirty.get(i))
-                        sm.settingShortField(pc, i, (!loaded.get(i)) ? (short) 0
-                            : sm.fetchShortField(i), (short) longval, set);
-                    else
-                        sm.storeShortField(i, (short) longval);
-                    break;
-                case JavaTypes.FLOAT:
-                    if (_dirty.get(i))
-                        sm.settingFloatField(pc, i, (!loaded.get(i)) ? 0F
-                            : sm.fetchFloatField(i), (float) dblval, set);
-                    else
-                        sm.storeFloatField(i, (float) dblval);
-                    break;
-                case JavaTypes.DOUBLE:
-                    if (_dirty.get(i))
-                        sm.settingDoubleField(pc, i, (!loaded.get(i)) ? 0D
-                            : sm.fetchDoubleField(i), dblval, set);
-                    else
-                        sm.storeDoubleField(i, dblval);
-                    break;
-                case JavaTypes.STRING:
-                    if (_dirty.get(i))
-                        sm.settingStringField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchStringField(i), (String) objval, set);
-                    else
-                        sm.storeStringField(i, (String) objval);
-                    objval = null;
-                    break;
-                case JavaTypes.PC:
-                case JavaTypes.PC_UNTYPED:
-                    if (fields[i].getCascadeAttach() == ValueMetaData
-                        .CASCADE_NONE)
-                        objval = getReference(manager, objval, sm, fields[i]);
-                    else {
-                        PersistenceCapable toPC = null;
-                        if (objval != null && fields[i].isEmbeddedPC())
-                            toPC = ImplHelper.toPersistenceCapable(objval,
-                                broker.getConfiguration());
-                        objval = manager.attach(objval, toPC, sm, fields[i],
-                            false);
-                    }
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), objval, set);
-                    else
-                        sm.storeObjectField(i, objval);
-                    objval = null;
-                    break;
-                case JavaTypes.COLLECTION:
-                    Collection coll = (Collection) objval;
-                    objval = null;
-                    if (coll != null)
-                        coll = attachCollection(manager, coll, sm, fields[i]);
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), coll, set);
-                    else
-                        sm.storeObjectField(i, coll);
-                    break;
-                case JavaTypes.MAP:
-                    Map map = (Map) objval;
-                    objval = null;
-                    if (map != null)
-                        map = attachMap(manager, map, sm, fields[i]);
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), map, set);
-                    else
-                        sm.storeObjectField(i, map);
-                    break;
-                default:
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), objval, set);
-                    else
-                        sm.storeObjectField(i, objval);
-                    objval = null;
-            }
-        }
-        pc.pcReplaceStateManager(sm);
-
-        // if we were clean at least make sure a version check is done to
-        // prevent using old state
-        if (!sm.isVersionCheckRequired() && broker.isActive()
-            && _version != origVersion && (origVersion == null 
-            || broker.getStoreManager().compareVersion(sm, _version, 
-            origVersion) != StoreManager.VERSION_SAME)) {
-            broker.transactional(sm.getManagedInstance(), false, 
-                manager.getBehavior());
-        }
-
-        return sm.getManagedInstance();
-    }
-
-    protected Object getDetachedObjectId(AttachManager manager,
-        Object toAttach) {
-        return _oid;
-    }
-
-    void provideField(int field) {
-        _pc.pcProvideField(field);
-    }
-
-    protected void provideField(Object toAttach, StateManagerImpl sm,
-        int field) {
-        provideField(field);
-    }
-
-    /**
-     * Ignore if the field is not dirty but loaded
-     */
-    protected static boolean ignoreLoaded(FieldMetaData fmd) {
-        switch (fmd.getTypeCode()) {
-            case JavaTypes.BOOLEAN:
-            case JavaTypes.BOOLEAN_OBJ:
-            case JavaTypes.BYTE:
-            case JavaTypes.BYTE_OBJ:
-            case JavaTypes.INT:
-            case JavaTypes.INT_OBJ:
-            case JavaTypes.LONG:
-            case JavaTypes.LONG_OBJ:
-            case JavaTypes.SHORT:
-            case JavaTypes.SHORT_OBJ:
-            case JavaTypes.DOUBLE:
-            case JavaTypes.DOUBLE_OBJ:
-            case JavaTypes.FLOAT:
-            case JavaTypes.FLOAT_OBJ:
-            case JavaTypes.CHAR:
-            case JavaTypes.CHAR_OBJ:
-            case JavaTypes.STRING:
-                return true;
-        }
-        return false;
-    }
-
-    ///////////////////////////////
-    // StateManager implementation
-    ///////////////////////////////
-
-    public Object getGenericContext() {
-        return null;
-    }
-
-    public Object getPCPrimaryKey(Object oid, int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public StateManager replaceStateManager(StateManager sm) {
-        return sm;
-    }
-
-    public Object getVersion() {
-        return _version;
-    }
-
-    public void setVersion(Object version) {
-        throw new UnsupportedException();
-    }
-
-    public boolean isDirty() {
-        return _dirty.length() != 0;
-    }
-
-    public boolean isTransactional() {
-        return false;
-    }
-
-    public boolean isPersistent() {
-        return false;
-    }
-
-    public boolean isNew() {
-        return false;
-    }
-
-    public boolean isDeleted() {
-        return false;
-    }
-
-    public boolean isDetached() {
-        return true;
-    }
-
-    public boolean isVersionUpdateRequired() {
-        return false;
-    }
-
-    public boolean isVersionCheckRequired() {
-        return false;
-    }
-
-    public void dirty(String field) {
-        // should we store ClassMetaData?
-        throw new UnsupportedException();
-    }
-
-    public Object fetchObjectId() {
-        return _oid;
-    }
-
-    public void accessingField(int idx) {
-        if (!_access && !_loaded.get(idx))
-        	// do not access the pc fields by implictly invoking _pc.toString()
-        	// may cause infinite loop if again tries to access unloaded field 
-            throw new IllegalStateException(_loc.get("unloaded-detached",
-               Exceptions.toString(_pc)).getMessage());
-    }
-
-    public boolean serializing() {
-        return false;
-    }
-
-    public boolean writeDetached(ObjectOutput out)
-        throws IOException {
-        out.writeObject(_pc.pcGetDetachedState());
-        out.writeObject(this);
-        return false;
-    }
-
-    public void proxyDetachedDeserialized(int idx) {
-        lock();
-        try {
-            _pc.pcProvideField(idx);
-            if (objval instanceof Proxy)
-                ((Proxy) objval).setOwner(this, idx);
-            objval = null;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingBooleanField(PersistenceCapable pc, int idx,
-        boolean cur, boolean next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next ? 1 : 0;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingCharField(PersistenceCapable pc, int idx, char cur,
-        char next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingByteField(PersistenceCapable pc, int idx, byte cur,
-        byte next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingShortField(PersistenceCapable pc, int idx, short cur,
-        short next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingIntField(PersistenceCapable pc, int idx, int cur,
-        int next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingLongField(PersistenceCapable pc, int idx, long cur,
-        long next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingFloatField(PersistenceCapable pc, int idx, float cur,
-        float next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            dblval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingDoubleField(PersistenceCapable pc, int idx, double cur,
-        double next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            dblval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingStringField(PersistenceCapable pc, int idx, String cur,
-        String next, int set) {
-        accessingField(idx);
-        if (cur == next || (cur != null && cur.equals(next))
-                || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            objval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-            objval = null;
-        }
-    }
-
-    public void settingObjectField(PersistenceCapable pc, int idx, Object cur,
-        Object next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            objval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-            objval = null;
-        }
-    }
-
-    public void providedBooleanField(PersistenceCapable pc, int idx,
-        boolean cur) {
-        longval = cur ? 1 : 0;
-    }
-
-    public void providedCharField(PersistenceCapable pc, int idx, char cur) {
-        longval = cur;
-    }
-
-    public void providedByteField(PersistenceCapable pc, int idx, byte cur) {
-        longval = cur;
-    }
-
-    public void providedShortField(PersistenceCapable pc, int idx, short cur) {
-        longval = cur;
-    }
-
-    public void providedIntField(PersistenceCapable pc, int idx, int cur) {
-        longval = cur;
-    }
-
-    public void providedLongField(PersistenceCapable pc, int idx, long cur) {
-        longval = cur;
-    }
-
-    public void providedFloatField(PersistenceCapable pc, int idx, float cur) {
-        dblval = cur;
-    }
-
-    public void providedDoubleField(PersistenceCapable pc, int idx,
-        double cur) {
-        dblval = cur;
-    }
-
-    public void providedStringField(PersistenceCapable pc, int idx,
-        String cur) {
-        objval = cur;
-    }
-
-    public void providedObjectField(PersistenceCapable pc, int idx,
-        Object cur) {
-        objval = cur;
-    }
-
-    public boolean replaceBooleanField(PersistenceCapable pc, int idx) {
-        return longval == 1;
-    }
-
-    public char replaceCharField(PersistenceCapable pc, int idx) {
-        return (char) longval;
-    }
-
-    public byte replaceByteField(PersistenceCapable pc, int idx) {
-        return (byte) longval;
-    }
-
-    public short replaceShortField(PersistenceCapable pc, int idx) {
-        return (short) longval;
-    }
-
-    public int replaceIntField(PersistenceCapable pc, int idx) {
-        return (int) longval;
-    }
-
-    public long replaceLongField(PersistenceCapable pc, int idx) {
-        return longval;
-    }
-
-    public float replaceFloatField(PersistenceCapable pc, int idx) {
-        return (float) dblval;
-    }
-
-    public double replaceDoubleField(PersistenceCapable pc, int idx) {
-        return dblval;
-    }
-
-    public String replaceStringField(PersistenceCapable pc, int idx) {
-        String str = (String) objval;
-        objval = null;
-        return str;
-    }
-
-    public Object replaceObjectField(PersistenceCapable pc, int idx) {
-        Object ret = objval;
-        objval = null;
-        return ret;
-    }
-
-    //////////////////////////////////////
-    // OpenJPAStateManager implementation
-    //////////////////////////////////////
-
-    public void initialize(Class forType, PCState state) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void load(FetchConfiguration fetch) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getManagedInstance() {
-        return _pc;
-    }
-
-    public PersistenceCapable getPersistenceCapable() {
-        return _pc;
-    }
-
-    public ClassMetaData getMetaData() {
-        throw new UnsupportedOperationException();
-    }
-
-    public OpenJPAStateManager getOwner() {
-        throw new UnsupportedOperationException();
-    }
-
-    public int getOwnerIndex() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isEmbedded() {
-        return _embedded;
-    }
-
-    public boolean isFlushed() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isFlushedDirty() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isProvisional() {
-        throw new UnsupportedOperationException();
-    }
-
-    public BitSet getLoaded() {
-        return _loaded;
-    }
-
-    public BitSet getDirty() {
-        return _dirty;
-    }
-
-    public BitSet getFlushed() {
-        throw new UnsupportedOperationException();
-    }
-
-    public BitSet getUnloaded(FetchConfiguration fetch) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object newProxy(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object newFieldProxy(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isDefaultValue(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public StoreContext getContext() {
-        return null;
-    }
-
-    public PCState getPCState() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getObjectId() {
-        return _oid;
-    }
-
-    public void setObjectId(Object oid) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean assignObjectId(boolean flush) {
-        return true;
-    }
-
-    public Object getId() {
-        return getObjectId();
-    }
-
-    public Object getLock() {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setLock(Object lock) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setNextVersion(Object version) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getImplData() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object setImplData(Object data, boolean cacheable) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isImplDataCacheable() {
-        return false;
-    }
-
-    public Object getImplData(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object setImplData(int field, Object data) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isImplDataCacheable(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getIntermediate(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setIntermediate(int field, Object data) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void removed(int field, Object removed, boolean key) {
-        dirty(field);
-    }
-
-    public boolean beforeRefresh(boolean all) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void dirty(int field) {
-        lock();
-        try {
-            _dirty.set(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeBoolean(int field, boolean extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeByte(int field, byte extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeChar(int field, char extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeInt(int field, int extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeShort(int field, short extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeLong(int field, long extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeFloat(int field, float extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeDouble(int field, double extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeString(int field, String extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeObject(int field, Object extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void store(int field, Object extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeField(int field, Object value) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean fetchBoolean(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public byte fetchByte(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public char fetchChar(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public short fetchShort(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public int fetchInt(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public long fetchLong(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public float fetchFloat(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public double fetchDouble(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public String fetchString(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetchObject(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetch(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetchField(int field, boolean transitions) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetchInitialField(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setRemote(int field, Object value) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void lock() {
-        if (_lock != null)
-            _lock.lock();
-    }
-
-    public void unlock() {
-        if (_lock != null)
-            _lock.unlock();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.util.Exceptions;
+import org.apache.openjpa.util.Proxy;
+import org.apache.openjpa.util.UnsupportedException;
+import org.apache.openjpa.util.ImplHelper;
+
+/**
+ * Internal state manager for detached instances. Does not fully
+ * implement {@link OpenJPAStateManager} contract to allow for serialization.
+ *
+ * @author Steve Kim
+ * @nojavadoc
+ */
+public class DetachedStateManager
+    extends AttachStrategy
+    implements OpenJPAStateManager, Serializable {
+
+    private static final long serialVersionUID = 4112223665584731100L;
+
+    private static final Localizer _loc = Localizer.forPackage
+        (DetachedStateManager.class);
+
+    private final PersistenceCapable _pc;
+    private final boolean _embedded;
+    private final boolean _access;
+    private final BitSet _loaded;
+    private final BitSet _dirty;
+    private final Object _oid;
+    private final Object _version;
+    private final ReentrantLock _lock;
+
+    /**
+     * Constructor.
+     *
+     * @param pc the managed instance
+     * @param sm the instance's state manager
+     * @param load the set of detached field indexes
+     * @param access whether to allow access to unloaded fields
+     * @param multithreaded whether the instance will be used concurrently
+     * by multiple threads
+     */
+    public DetachedStateManager(PersistenceCapable pc, OpenJPAStateManager sm,
+        BitSet load, boolean access, boolean multithreaded) {
+        _pc = pc;
+        _embedded = sm.isEmbedded();
+        _loaded = load;
+        _access = access;
+        _dirty = new BitSet(_loaded.length());
+        _oid = sm.fetchObjectId();
+        _version = sm.getVersion();
+        if (multithreaded)
+            _lock = new ReentrantLock();
+        else
+            _lock = null;
+    }
+
+    /////////////////////////////////
+    // AttachStrategy implementation
+    /////////////////////////////////
+
+    public Object attach(AttachManager manager, Object toAttach,
+        ClassMetaData meta, PersistenceCapable into, OpenJPAStateManager owner,
+        ValueMetaData ownerMeta, boolean explicit) {
+        BrokerImpl broker = manager.getBroker();
+        StateManagerImpl sm;
+        if (_embedded) {
+            if (_dirty.length () > 0)
+                owner.dirty(ownerMeta.getFieldMetaData().getIndex());
+            sm = (StateManagerImpl) broker.embed(_pc, _oid, owner, ownerMeta);
+            ImplHelper.toPersistenceCapable(toAttach, broker.getConfiguration())
+                .pcReplaceStateManager(this);
+        } else {
+            PCState state = (_dirty.length() > 0) ? PCState.PDIRTY
+                : PCState.PCLEAN;
+            sm = (StateManagerImpl) broker.copy(this, state);
+        }
+        PersistenceCapable pc = sm.getPersistenceCapable();
+        manager.setAttachedCopy(toAttach, pc);
+
+        manager.fireBeforeAttach(toAttach, meta);
+
+        // pre-load for efficiency: current field values for restore, dependent
+        // for delete
+        FieldMetaData[] fields = meta.getFields();
+        int restore = broker.getRestoreState();
+        if (_dirty.length() > 0) {
+            BitSet load = new BitSet(fields.length);
+            for (int i = 0; i < fields.length; i++) {
+                if (!_dirty.get(i))
+                    continue;
+
+                switch (fields[i].getDeclaredTypeCode()) {
+                    case JavaTypes.ARRAY:
+                    case JavaTypes.COLLECTION:
+                        if (restore == RestoreState.RESTORE_ALL
+                            || fields[i].getElement().getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO)
+                            load.set(i);
+                        break;
+                    case JavaTypes.MAP:
+                        if (restore == RestoreState.RESTORE_ALL
+                            || fields[i].getElement().getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO
+                            || fields[i].getKey().getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO)
+                            load.set(i);
+                        break;
+                    default:
+                        if (restore != RestoreState.RESTORE_NONE
+                            || fields[i].getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO)
+                            load.set(i);
+                }
+            }
+            FetchConfiguration fc = broker.getFetchConfiguration();
+            sm.loadFields(load, fc, fc.getWriteLockLevel(), null);
+        }        
+        Object origVersion = sm.getVersion();
+        sm.setVersion(_version);
+
+        BitSet loaded = sm.getLoaded();
+        int set = StateManager.SET_ATTACH;
+        for (int i = 0; i < fields.length; i++) {
+            if (!_loaded.get(i))
+                continue;
+            // don't reload already loaded non-mutable objects
+            if (!_dirty.get(i) && loaded.get(i) && ignoreLoaded(fields[i]))
+                continue;
+
+            provideField(i);
+            switch (fields[i].getDeclaredTypeCode()) {
+                case JavaTypes.BOOLEAN:
+                    if (_dirty.get(i))
+                        sm.settingBooleanField(pc, i,
+                            (loaded.get(i)) && sm.fetchBooleanField(i),
+                            longval == 1, set);
+                    else
+                        sm.storeBooleanField(i, longval == 1);
+                    break;
+                case JavaTypes.BYTE:
+                    if (_dirty.get(i))
+                        sm.settingByteField(pc, i, (!loaded.get(i)) ? (byte) 0
+                            : sm.fetchByteField(i), (byte) longval, set);
+                    else
+                        sm.storeByteField(i, (byte) longval);
+                    break;
+                case JavaTypes.CHAR:
+                    if (_dirty.get(i))
+                        sm.settingCharField(pc, i, (!loaded.get(i)) ? (char) 0
+                            : sm.fetchCharField(i), (char) longval, set);
+                    else
+                        sm.storeCharField(i, (char) longval);
+                    break;
+                case JavaTypes.INT:
+                    if (_dirty.get(i))
+                        sm.settingIntField(pc, i, (!loaded.get(i)) ? 0
+                            : sm.fetchIntField(i), (int) longval, set);
+                    else
+                        sm.storeIntField(i, (int) longval);
+                    break;
+                case JavaTypes.LONG:
+                    if (_dirty.get(i))
+                        sm.settingLongField(pc, i, (!loaded.get(i)) ? 0L
+                            : sm.fetchLongField(i), longval, set);
+                    else
+                        sm.storeLongField(i, longval);
+                    break;
+                case JavaTypes.SHORT:
+                    if (_dirty.get(i))
+                        sm.settingShortField(pc, i, (!loaded.get(i)) ? (short) 0
+                            : sm.fetchShortField(i), (short) longval, set);
+                    else
+                        sm.storeShortField(i, (short) longval);
+                    break;
+                case JavaTypes.FLOAT:
+                    if (_dirty.get(i))
+                        sm.settingFloatField(pc, i, (!loaded.get(i)) ? 0F
+                            : sm.fetchFloatField(i), (float) dblval, set);
+                    else
+                        sm.storeFloatField(i, (float) dblval);
+                    break;
+                case JavaTypes.DOUBLE:
+                    if (_dirty.get(i))
+                        sm.settingDoubleField(pc, i, (!loaded.get(i)) ? 0D
+                            : sm.fetchDoubleField(i), dblval, set);
+                    else
+                        sm.storeDoubleField(i, dblval);
+                    break;
+                case JavaTypes.STRING:
+                    if (_dirty.get(i))
+                        sm.settingStringField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchStringField(i), (String) objval, set);
+                    else
+                        sm.storeStringField(i, (String) objval);
+                    objval = null;
+                    break;
+                case JavaTypes.PC:
+                case JavaTypes.PC_UNTYPED:
+                    if (fields[i].getCascadeAttach() == ValueMetaData
+                        .CASCADE_NONE)
+                        objval = getReference(manager, objval, sm, fields[i]);
+                    else {
+                        PersistenceCapable toPC = null;
+                        if (objval != null && fields[i].isEmbeddedPC())
+                            toPC = ImplHelper.toPersistenceCapable(objval,
+                                broker.getConfiguration());
+                        objval = manager.attach(objval, toPC, sm, fields[i],
+                            false);
+                    }
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), objval, set);
+                    else
+                        sm.storeObjectField(i, objval);
+                    objval = null;
+                    break;
+                case JavaTypes.COLLECTION:
+                    Collection coll = (Collection) objval;
+                    objval = null;
+                    if (coll != null)
+                        coll = attachCollection(manager, coll, sm, fields[i]);
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), coll, set);
+                    else
+                        sm.storeObjectField(i, coll);
+                    break;
+                case JavaTypes.MAP:
+                    Map map = (Map) objval;
+                    objval = null;
+                    if (map != null)
+                        map = attachMap(manager, map, sm, fields[i]);
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), map, set);
+                    else
+                        sm.storeObjectField(i, map);
+                    break;
+                default:
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), objval, set);
+                    else
+                        sm.storeObjectField(i, objval);
+                    objval = null;
+            }
+        }
+        pc.pcReplaceStateManager(sm);
+
+        // if we were clean at least make sure a version check is done to
+        // prevent using old state
+        if (!sm.isVersionCheckRequired() && broker.isActive()
+            && _version != origVersion && (origVersion == null 
+            || broker.getStoreManager().compareVersion(sm, _version, 
+            origVersion) != StoreManager.VERSION_SAME)) {
+            broker.transactional(sm.getManagedInstance(), false, 
+                manager.getBehavior());
+        }
+
+        return sm.getManagedInstance();
+    }
+
+    protected Object getDetachedObjectId(AttachManager manager,
+        Object toAttach) {
+        return _oid;
+    }
+
+    void provideField(int field) {
+        _pc.pcProvideField(field);
+    }
+
+    protected void provideField(Object toAttach, StateManagerImpl sm,
+        int field) {
+        provideField(field);
+    }
+
+    /**
+     * Ignore if the field is not dirty but loaded
+     */
+    protected static boolean ignoreLoaded(FieldMetaData fmd) {
+        switch (fmd.getTypeCode()) {
+            case JavaTypes.BOOLEAN:
+            case JavaTypes.BOOLEAN_OBJ:
+            case JavaTypes.BYTE:
+            case JavaTypes.BYTE_OBJ:
+            case JavaTypes.INT:
+            case JavaTypes.INT_OBJ:
+            case JavaTypes.LONG:
+            case JavaTypes.LONG_OBJ:
+            case JavaTypes.SHORT:
+            case JavaTypes.SHORT_OBJ:
+            case JavaTypes.DOUBLE:
+            case JavaTypes.DOUBLE_OBJ:
+            case JavaTypes.FLOAT:
+            case JavaTypes.FLOAT_OBJ:
+            case JavaTypes.CHAR:
+            case JavaTypes.CHAR_OBJ:
+            case JavaTypes.STRING:
+                return true;
+        }
+        return false;
+    }
+
+    ///////////////////////////////
+    // StateManager implementation
+    ///////////////////////////////
+
+    public Object getGenericContext() {
+        return null;
+    }
+
+    public Object getPCPrimaryKey(Object oid, int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public StateManager replaceStateManager(StateManager sm) {
+        return sm;
+    }
+
+    public Object getVersion() {
+        return _version;
+    }
+
+    public void setVersion(Object version) {
+        throw new UnsupportedException();
+    }
+
+    public boolean isDirty() {
+        return _dirty.length() != 0;
+    }
+
+    public boolean isTransactional() {
+        return false;
+    }
+
+    public boolean isPersistent() {
+        return false;
+    }
+
+    public boolean isNew() {
+        return false;
+    }
+
+    public boolean isDeleted() {
+        return false;
+    }
+
+    public boolean isDetached() {
+        return true;
+    }
+
+    public boolean isVersionUpdateRequired() {
+        return false;
+    }
+
+    public boolean isVersionCheckRequired() {
+        return false;
+    }
+
+    public void dirty(String field) {
+        // should we store ClassMetaData?
+        throw new UnsupportedException();
+    }
+
+    public Object fetchObjectId() {
+        return _oid;
+    }
+
+    public void accessingField(int idx) {
+        if (!_access && !_loaded.get(idx))
+        	// do not access the pc fields by implictly invoking _pc.toString()
+        	// may cause infinite loop if again tries to access unloaded field 
+            throw new IllegalStateException(_loc.get("unloaded-detached",
+               Exceptions.toString(_pc)).getMessage());
+    }
+
+    public boolean serializing() {
+        return false;
+    }
+
+    public boolean writeDetached(ObjectOutput out)
+        throws IOException {
+        out.writeObject(_pc.pcGetDetachedState());
+        out.writeObject(this);
+        return false;
+    }
+
+    public void proxyDetachedDeserialized(int idx) {
+        lock();
+        try {
+            _pc.pcProvideField(idx);
+            if (objval instanceof Proxy)
+                ((Proxy) objval).setOwner(this, idx);
+            objval = null;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingBooleanField(PersistenceCapable pc, int idx,
+        boolean cur, boolean next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next ? 1 : 0;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingCharField(PersistenceCapable pc, int idx, char cur,
+        char next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingByteField(PersistenceCapable pc, int idx, byte cur,
+        byte next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingShortField(PersistenceCapable pc, int idx, short cur,
+        short next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingIntField(PersistenceCapable pc, int idx, int cur,
+        int next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingLongField(PersistenceCapable pc, int idx, long cur,
+        long next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingFloatField(PersistenceCapable pc, int idx, float cur,
+        float next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            dblval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingDoubleField(PersistenceCapable pc, int idx, double cur,
+        double next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            dblval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingStringField(PersistenceCapable pc, int idx, String cur,
+        String next, int set) {
+        accessingField(idx);
+        if (cur == next || (cur != null && cur.equals(next))
+                || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            objval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+            objval = null;
+        }
+    }
+
+    public void settingObjectField(PersistenceCapable pc, int idx, Object cur,
+        Object next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            objval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+            objval = null;
+        }
+    }
+
+    public void providedBooleanField(PersistenceCapable pc, int idx,
+        boolean cur) {
+        longval = cur ? 1 : 0;
+    }
+
+    public void providedCharField(PersistenceCapable pc, int idx, char cur) {
+        longval = cur;
+    }
+
+    public void providedByteField(PersistenceCapable pc, int idx, byte cur) {
+        longval = cur;
+    }
+
+    public void providedShortField(PersistenceCapable pc, int idx, short cur) {
+        longval = cur;
+    }
+
+    public void providedIntField(PersistenceCapable pc, int idx, int cur) {
+        longval = cur;
+    }
+
+    public void providedLongField(PersistenceCapable pc, int idx, long cur) {
+        longval = cur;
+    }
+
+    public void providedFloatField(PersistenceCapable pc, int idx, float cur) {
+        dblval = cur;
+    }
+
+    public void providedDoubleField(PersistenceCapable pc, int idx,
+        double cur) {
+        dblval = cur;
+    }
+
+    public void providedStringField(PersistenceCapable pc, int idx,
+        String cur) {
+        objval = cur;
+    }
+
+    public void providedObjectField(PersistenceCapable pc, int idx,
+        Object cur) {
+        objval = cur;
+    }
+
+    public boolean replaceBooleanField(PersistenceCapable pc, int idx) {
+        return longval == 1;
+    }
+
+    public char replaceCharField(PersistenceCapable pc, int idx) {
+        return (char) longval;
+    }
+
+    public byte replaceByteField(PersistenceCapable pc, int idx) {
+        return (byte) longval;
+    }
+
+    public short replaceShortField(PersistenceCapable pc, int idx) {
+        return (short) longval;
+    }
+
+    public int replaceIntField(PersistenceCapable pc, int idx) {
+        return (int) longval;
+    }
+
+    public long replaceLongField(PersistenceCapable pc, int idx) {
+        return longval;
+    }
+
+    public float replaceFloatField(PersistenceCapable pc, int idx) {
+        return (float) dblval;
+    }
+
+    public double replaceDoubleField(PersistenceCapable pc, int idx) {
+        return dblval;
+    }
+
+    public String replaceStringField(PersistenceCapable pc, int idx) {
+        String str = (String) objval;
+        objval = null;
+        return str;
+    }
+
+    public Object replaceObjectField(PersistenceCapable pc, int idx) {
+        Object ret = objval;
+        objval = null;
+        return ret;
+    }
+
+    //////////////////////////////////////
+    // OpenJPAStateManager implementation
+    //////////////////////////////////////
+
+    public void initialize(Class forType, PCState state) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void load(FetchConfiguration fetch) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getManagedInstance() {
+        return _pc;
+    }
+
+    public PersistenceCapable getPersistenceCapable() {
+        return _pc;
+    }
+
+    public ClassMetaData getMetaData() {
+        throw new UnsupportedOperationException();
+    }
+
+    public OpenJPAStateManager getOwner() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getOwnerIndex() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isEmbedded() {
+        return _embedded;
+    }
+
+    public boolean isFlushed() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isFlushedDirty() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isProvisional() {
+        throw new UnsupportedOperationException();
+    }
+
+    public BitSet getLoaded() {
+        return _loaded;
+    }
+
+    public BitSet getDirty() {
+        return _dirty;
+    }
+
+    public BitSet getFlushed() {
+        throw new UnsupportedOperationException();
+    }
+
+    public BitSet getUnloaded(FetchConfiguration fetch) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object newProxy(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object newFieldProxy(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isDefaultValue(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public StoreContext getContext() {
+        return null;
+    }
+
+    public PCState getPCState() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getObjectId() {
+        return _oid;
+    }
+
+    public void setObjectId(Object oid) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean assignObjectId(boolean flush) {
+        return true;
+    }
+
+    public Object getId() {
+        return getObjectId();
+    }
+
+    public Object getLock() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setLock(Object lock) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setNextVersion(Object version) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getImplData() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object setImplData(Object data, boolean cacheable) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isImplDataCacheable() {
+        return false;
+    }
+
+    public Object getImplData(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object setImplData(int field, Object data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isImplDataCacheable(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getIntermediate(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setIntermediate(int field, Object data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removed(int field, Object removed, boolean key) {
+        dirty(field);
+    }
+
+    public boolean beforeRefresh(boolean all) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void dirty(int field) {
+        lock();
+        try {
+            _dirty.set(field);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void storeBoolean(int field, boolean extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeByte(int field, byte extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeChar(int field, char extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeInt(int field, int extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeShort(int field, short extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeLong(int field, long extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeFloat(int field, float extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeDouble(int field, double extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeString(int field, String extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeObject(int field, Object extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void store(int field, Object extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeField(int field, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean fetchBoolean(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public byte fetchByte(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public char fetchChar(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public short fetchShort(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int fetchInt(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public long fetchLong(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public float fetchFloat(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public double fetchDouble(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String fetchString(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetchObject(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetch(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetchField(int field, boolean transitions) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetchInitialField(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setRemote(int field, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    public void unlock() {
+        if (_lock != null)
+            _lock.unlock();
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java
index dd7a8a7..5d300f9 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java
@@ -1,353 +1,353 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.iterators.FilterIterator;
-import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultObjectProviderIterator;
-import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.lib.util.ReferenceHashSet;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.GeneralException;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.OpenJPAException;
-
-/**
- * Representation of all members of a persistent class.
- *
- * @author Abe White
- * @author Patrick Linskey
- * @nojavadoc
- */
-public class ExtentImpl
-    implements Extent {
-
-    private static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
-
-    private final Broker _broker;
-    private final Class _type;
-    private final boolean _subs;
-    private final FetchConfiguration _fc;
-    private final ReentrantLock _lock;
-    private boolean _ignore = false;
-
-    // set of open iterators
-    private ReferenceHashSet _openItrs = null;
-
-    /**
-     * Constructor.
-     *
-     * @param broker the owning broker
-     * @param type the candidate class
-     * @param subs whether subclasses are included in the extent
-     */
-    ExtentImpl(Broker broker, Class type, boolean subs,
-        FetchConfiguration fetch) {
-        _broker = broker;
-        _type = type;
-        _subs = subs;
-        if (fetch != null)
-            _fc = fetch;
-        else
-            _fc = (FetchConfiguration) broker.getFetchConfiguration().clone();
-        _ignore = broker.getIgnoreChanges();
-        if (broker.getMultithreaded())
-            _lock = new ReentrantLock();
-        else
-            _lock = null;
-    }
-
-    public FetchConfiguration getFetchConfiguration() {
-        return _fc;
-    }
-
-    public boolean getIgnoreChanges() {
-        return _ignore;
-    }
-
-    public void setIgnoreChanges(boolean ignoreChanges) {
-        _broker.assertOpen();
-        _ignore = ignoreChanges;
-    }
-
-    public List list() {
-        List list = new ArrayList();
-        Iterator itr = iterator();
-        try {
-            while (itr.hasNext())
-                list.add(itr.next());
-            return list;
-        } finally {
-            ImplHelper.close(itr);
-        }
-    }
-
-    public Iterator iterator() {
-        _broker.assertNontransactionalRead();
-        CloseableIterator citr = null;
-        try {
-            // create an iterator chain; add pnew objects if transactional
-            CloseableIteratorChain chain = new CloseableIteratorChain();
-            boolean trans = !_ignore && _broker.isActive();
-            if (trans)
-                chain.addIterator(new FilterNewIterator());
-
-            // add database iterators for each implementing class
-            MetaDataRepository repos = _broker.getConfiguration().
-                getMetaDataRepositoryInstance();
-            ClassMetaData meta = repos.getMetaData(_type,
-                _broker.getClassLoader(), false);
-
-            ClassMetaData[] metas;
-            if (meta != null && (!_subs || !meta.isManagedInterface())
-                && (meta.isMapped() || (_subs
-                && meta.getMappedPCSubclassMetaDatas().length > 0)))
-                metas = new ClassMetaData[]{ meta };
-            else if (_subs && (meta == null || meta.isManagedInterface()))
-                metas = repos.getImplementorMetaDatas(_type,
-                    _broker.getClassLoader(), false);
-            else
-                metas = EMPTY_METAS;
-
-            ResultObjectProvider rop;
-            for (int i = 0; i < metas.length; i++) {
-                rop = _broker.getStoreManager().executeExtent(metas[i],
-                    _subs, _fc);
-                if (rop != null)
-                    chain.addIterator(new ResultObjectProviderIterator(rop));
-            }
-
-            // filter deleted objects if transactional
-            if (trans)
-                citr = new FilterDeletedIterator(chain);
-            else
-                citr = chain;
-            citr.setRemoveOnClose(this);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        }
-
-        lock();
-        try {
-            if (_openItrs == null)
-                _openItrs = new ReferenceHashSet(ReferenceHashSet.WEAK);
-            _openItrs.add(citr);
-        } finally {
-            unlock();
-        }
-        return citr;
-    }
-
-    public Broker getBroker() {
-        return _broker;
-    }
-
-    public Class getElementType() {
-        return _type;
-    }
-
-    public boolean hasSubclasses() {
-        return _subs;
-    }
-
-    public void closeAll() {
-        if (_openItrs == null)
-            return;
-
-        lock();
-        try {
-            CloseableIterator citr;
-            for (Iterator itr = _openItrs.iterator(); itr.hasNext();) {
-                citr = (CloseableIterator) itr.next();
-                citr.setRemoveOnClose(null);
-                try {
-                    citr.close();
-                } catch (Exception e) {
-                }
-            }
-            _openItrs.clear();
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void lock() {
-        if (_lock != null)
-            _lock.lock();
-    }
-
-    public void unlock() {
-        if (_lock != null)
-            _lock.unlock();
-    }
-
-    /**
-     * Closeable iterator.
-     */
-    private static interface CloseableIterator
-        extends Closeable, Iterator {
-
-        /**
-         * Set the extent to remove self from on close.
-         */
-        public void setRemoveOnClose(ExtentImpl extent);
-    }
-
-    /**
-     * Closeable {@link IteratorChain}.
-     */
-    private static class CloseableIteratorChain
-        extends IteratorChain
-        implements CloseableIterator {
-
-        private ExtentImpl _extent = null;
-        private boolean _closed = false;
-
-        public boolean hasNext() {
-            return (_closed) ? false : super.hasNext();
-        }
-
-        public Object next() {
-            if (_closed)
-                throw new NoSuchElementException();
-            return super.next();
-        }
-
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-        public void setRemoveOnClose(ExtentImpl extent) {
-            _extent = extent;
-        }
-
-        public void close()
-            throws Exception {
-            if (_extent != null && _extent._openItrs != null) {
-                _extent.lock();
-                try {
-                    _extent._openItrs.remove(this);
-                } finally {
-                    _extent.unlock();
-                }
-            }
-
-            _closed = true;
-            for (Iterator itr = getIterators().iterator(); itr.hasNext();)
-                ((Closeable) itr.next()).close();
-        }
-    }
-
-    /**
-     * {@link FilterIterator} that skips deleted objects.
-     */
-    private static class FilterDeletedIterator
-        extends FilterIterator
-        implements CloseableIterator, Predicate {
-
-        private ExtentImpl _extent = null;
-        private boolean _closed = false;
-
-        public FilterDeletedIterator(Iterator itr) {
-            super(itr);
-            setPredicate(this);
-        }
-
-        public boolean hasNext() {
-            return (_closed) ? false : super.hasNext();
-        }
-
-        public Object next() {
-            if (_closed)
-                throw new NoSuchElementException();
-            return super.next();
-        }
-
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-        public void setRemoveOnClose(ExtentImpl extent) {
-            _extent = extent;
-        }
-
-        public void close()
-            throws Exception {
-            if (_extent != null && _extent._openItrs != null) {
-                _extent.lock();
-                try {
-                    _extent._openItrs.remove(this);
-                } finally {
-                    _extent.unlock();
-                }
-            }
-
-            _closed = true;
-            ((Closeable) getIterator()).close();
-        }
-
-        public boolean evaluate(Object o) {
-            return !_extent._broker.isDeleted(o);
-        }
-    }
-
-    /**
-     * Iterator over all new objects in this extent. This iterator is always
-     * wrapped, so it doesn't need to keep track of whether it's closed.
-     */
-    private class FilterNewIterator
-        extends FilterIterator
-        implements Closeable, Predicate {
-
-        public FilterNewIterator() {
-            super(_broker.getTransactionalObjects().iterator());
-            setPredicate(this);
-        }
-
-        public void close() {
-        }
-
-        public boolean evaluate(Object o) {
-            if (!_broker.isNew(o))
-                return false;
-
-            Class type = o.getClass();
-            if (!_subs && type != _type)
-                return false;
-            if (_subs && !_type.isAssignableFrom(type))
-                return false;
-            return true;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.iterators.FilterIterator;
+import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProviderIterator;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.ReferenceHashSet;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.GeneralException;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.OpenJPAException;
+
+/**
+ * Representation of all members of a persistent class.
+ *
+ * @author Abe White
+ * @author Patrick Linskey
+ * @nojavadoc
+ */
+public class ExtentImpl
+    implements Extent {
+
+    private static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
+
+    private final Broker _broker;
+    private final Class _type;
+    private final boolean _subs;
+    private final FetchConfiguration _fc;
+    private final ReentrantLock _lock;
+    private boolean _ignore = false;
+
+    // set of open iterators
+    private ReferenceHashSet _openItrs = null;
+
+    /**
+     * Constructor.
+     *
+     * @param broker the owning broker
+     * @param type the candidate class
+     * @param subs whether subclasses are included in the extent
+     */
+    ExtentImpl(Broker broker, Class type, boolean subs,
+        FetchConfiguration fetch) {
+        _broker = broker;
+        _type = type;
+        _subs = subs;
+        if (fetch != null)
+            _fc = fetch;
+        else
+            _fc = (FetchConfiguration) broker.getFetchConfiguration().clone();
+        _ignore = broker.getIgnoreChanges();
+        if (broker.getMultithreaded())
+            _lock = new ReentrantLock();
+        else
+            _lock = null;
+    }
+
+    public FetchConfiguration getFetchConfiguration() {
+        return _fc;
+    }
+
+    public boolean getIgnoreChanges() {
+        return _ignore;
+    }
+
+    public void setIgnoreChanges(boolean ignoreChanges) {
+        _broker.assertOpen();
+        _ignore = ignoreChanges;
+    }
+
+    public List list() {
+        List list = new ArrayList();
+        Iterator itr = iterator();
+        try {
+            while (itr.hasNext())
+                list.add(itr.next());
+            return list;
+        } finally {
+            ImplHelper.close(itr);
+        }
+    }
+
+    public Iterator iterator() {
+        _broker.assertNontransactionalRead();
+        CloseableIterator citr = null;
+        try {
+            // create an iterator chain; add pnew objects if transactional
+            CloseableIteratorChain chain = new CloseableIteratorChain();
+            boolean trans = !_ignore && _broker.isActive();
+            if (trans)
+                chain.addIterator(new FilterNewIterator());
+
+            // add database iterators for each implementing class
+            MetaDataRepository repos = _broker.getConfiguration().
+                getMetaDataRepositoryInstance();
+            ClassMetaData meta = repos.getMetaData(_type,
+                _broker.getClassLoader(), false);
+
+            ClassMetaData[] metas;
+            if (meta != null && (!_subs || !meta.isManagedInterface())
+                && (meta.isMapped() || (_subs
+                && meta.getMappedPCSubclassMetaDatas().length > 0)))
+                metas = new ClassMetaData[]{ meta };
+            else if (_subs && (meta == null || meta.isManagedInterface()))
+                metas = repos.getImplementorMetaDatas(_type,
+                    _broker.getClassLoader(), false);
+            else
+                metas = EMPTY_METAS;
+
+            ResultObjectProvider rop;
+            for (int i = 0; i < metas.length; i++) {
+                rop = _broker.getStoreManager().executeExtent(metas[i],
+                    _subs, _fc);
+                if (rop != null)
+                    chain.addIterator(new ResultObjectProviderIterator(rop));
+            }
+
+            // filter deleted objects if transactional
+            if (trans)
+                citr = new FilterDeletedIterator(chain);
+            else
+                citr = chain;
+            citr.setRemoveOnClose(this);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+
+        lock();
+        try {
+            if (_openItrs == null)
+                _openItrs = new ReferenceHashSet(ReferenceHashSet.WEAK);
+            _openItrs.add(citr);
+        } finally {
+            unlock();
+        }
+        return citr;
+    }
+
+    public Broker getBroker() {
+        return _broker;
+    }
+
+    public Class getElementType() {
+        return _type;
+    }
+
+    public boolean hasSubclasses() {
+        return _subs;
+    }
+
+    public void closeAll() {
+        if (_openItrs == null)
+            return;
+
+        lock();
+        try {
+            CloseableIterator citr;
+            for (Iterator itr = _openItrs.iterator(); itr.hasNext();) {
+                citr = (CloseableIterator) itr.next();
+                citr.setRemoveOnClose(null);
+                try {
+                    citr.close();
+                } catch (Exception e) {
+                }
+            }
+            _openItrs.clear();
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    public void unlock() {
+        if (_lock != null)
+            _lock.unlock();
+    }
+
+    /**
+     * Closeable iterator.
+     */
+    private static interface CloseableIterator
+        extends Closeable, Iterator {
+
+        /**
+         * Set the extent to remove self from on close.
+         */
+        public void setRemoveOnClose(ExtentImpl extent);
+    }
+
+    /**
+     * Closeable {@link IteratorChain}.
+     */
+    private static class CloseableIteratorChain
+        extends IteratorChain
+        implements CloseableIterator {
+
+        private ExtentImpl _extent = null;
+        private boolean _closed = false;
+
+        public boolean hasNext() {
+            return (_closed) ? false : super.hasNext();
+        }
+
+        public Object next() {
+            if (_closed)
+                throw new NoSuchElementException();
+            return super.next();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void setRemoveOnClose(ExtentImpl extent) {
+            _extent = extent;
+        }
+
+        public void close()
+            throws Exception {
+            if (_extent != null && _extent._openItrs != null) {
+                _extent.lock();
+                try {
+                    _extent._openItrs.remove(this);
+                } finally {
+                    _extent.unlock();
+                }
+            }
+
+            _closed = true;
+            for (Iterator itr = getIterators().iterator(); itr.hasNext();)
+                ((Closeable) itr.next()).close();
+        }
+    }
+
+    /**
+     * {@link FilterIterator} that skips deleted objects.
+     */
+    private static class FilterDeletedIterator
+        extends FilterIterator
+        implements CloseableIterator, Predicate {
+
+        private ExtentImpl _extent = null;
+        private boolean _closed = false;
+
+        public FilterDeletedIterator(Iterator itr) {
+            super(itr);
+            setPredicate(this);
+        }
+
+        public boolean hasNext() {
+            return (_closed) ? false : super.hasNext();
+        }
+
+        public Object next() {
+            if (_closed)
+                throw new NoSuchElementException();
+            return super.next();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void setRemoveOnClose(ExtentImpl extent) {
+            _extent = extent;
+        }
+
+        public void close()
+            throws Exception {
+            if (_extent != null && _extent._openItrs != null) {
+                _extent.lock();
+                try {
+                    _extent._openItrs.remove(this);
+                } finally {
+                    _extent.unlock();
+                }
+            }
+
+            _closed = true;
+            ((Closeable) getIterator()).close();
+        }
+
+        public boolean evaluate(Object o) {
+            return !_extent._broker.isDeleted(o);
+        }
+    }
+
+    /**
+     * Iterator over all new objects in this extent. This iterator is always
+     * wrapped, so it doesn't need to keep track of whether it's closed.
+     */
+    private class FilterNewIterator
+        extends FilterIterator
+        implements Closeable, Predicate {
+
+        public FilterNewIterator() {
+            super(_broker.getTransactionalObjects().iterator());
+            setPredicate(this);
+        }
+
+        public void close() {
+        }
+
+        public boolean evaluate(Object o) {
+            if (!_broker.isNew(o))
+                return false;
+
+            Class type = o.getClass();
+            if (!_subs && type != _type)
+                return false;
+            if (_subs && !_type.isAssignableFrom(type))
+                return false;
+            return true;
+		}
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ManagedCache.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ManagedCache.java
index 3637178..a6527f7 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ManagedCache.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ManagedCache.java
@@ -1,309 +1,309 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.ReferenceHashSet;
-import org.apache.openjpa.util.Exceptions;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Cache of managed objects. Must be static for serialization reasons.
- */
-class ManagedCache implements Serializable {
-
-    private static final Localizer _loc =
-        Localizer.forPackage(ManagedCache.class);
-
-    private Map _main; // oid -> sm
-    private Map _conflicts = null; // conflict oid -> new sm
-    private Map _news = null; // tmp id -> new sm
-    private Collection _embeds = null; // embedded/non-persistent sms
-    private Collection _untracked = null; // hard refs to untracked sms
-    private BrokerImpl broker;
-
-    /**
-     * Constructor; supply primary cache map.
-     */
-    ManagedCache(BrokerImpl broker) {
-        this.broker = broker;
-        _main = broker.newManagedObjectCache();
-    }
-
-    /**
-     * Return the instance for the given oid, optionally allowing
-     * new instances.
-     */
-    public StateManagerImpl getById(Object oid, boolean allowNew) {
-        if (oid == null)
-            return null;
-
-        // check main cache for oid
-        StateManagerImpl sm = (StateManagerImpl) _main.get(oid);
-        StateManagerImpl sm2;
-        if (sm != null) {
-            // if it's a new instance, we know it's the only match, because
-            // other pers instances override new instances in _cache
-            if (sm.isNew() && !sm.isDeleted())
-                return (allowNew) ? sm : null;
-            if (!allowNew || !sm.isDeleted())
-                return sm;
-
-            // sm is deleted; check conflict cache
-            if (_conflicts != null) {
-                sm2 = (StateManagerImpl) _conflicts.get(oid);
-                if (sm2 != null)
-                    return sm2;
-            }
-        }
-
-        // at this point sm is null or deleted; check the new cache for
-        // any matches. this allows us to match app id objects to new
-        // instances without permanant oids
-        if (allowNew && _news != null && !_news.isEmpty()) {
-            sm2 = (StateManagerImpl) _news.get(oid);
-            if (sm2 != null)
-                return sm2;
-        }
-        return sm;
-    }
-
-    /**
-     * Call this method when a new state manager initializes itself.
-     */
-    public void add(StateManagerImpl sm) {
-        if (!sm.isIntercepting()) {
-            if (_untracked == null)
-                _untracked = new HashSet();
-            _untracked.add(sm);
-        }
-
-        if (!sm.isPersistent() || sm.isEmbedded()) {
-            if (_embeds == null)
-                _embeds = new ReferenceHashSet(ReferenceHashSet.WEAK);
-            _embeds.add(sm);
-            return;
-        }
-
-        // initializing new instance; put in new cache because won't have
-        // permanent oid yet
-        if (sm.isNew()) {
-            if (_news == null)
-                _news = new HashMap();
-            _news.put(sm.getId(), sm);
-            return;
-        }
-
-        // initializing persistent instance; put in main cache
-        StateManagerImpl orig = (StateManagerImpl) _main.put
-            (sm.getObjectId(), sm);
-        if (orig != null) {
-            _main.put(sm.getObjectId(), orig);
-            throw new UserException(_loc.get("dup-load", sm.getObjectId(),
-                Exceptions.toString(orig.getManagedInstance())))
-                .setFailedObject(sm.getManagedInstance());
-        }
-    }
-
-    /**
-     * Remove the given state manager from the cache when it transitions
-     * to transient.
-     */
-    public void remove(Object id, StateManagerImpl sm) {
-        // if it has a permanent oid, remove from main / conflict cache,
-        // else remove from embedded/nontrans cache, and if not there
-        // remove from new cache
-        Object orig;
-        if (sm.getObjectId() != null) {
-            orig = _main.remove(id);
-            if (orig != sm) {
-                if (orig != null)
-                    _main.put(id, orig); // put back
-                if (_conflicts != null) {
-                    orig = _conflicts.remove(id);
-                    if (orig != null && orig != sm)
-                        _conflicts.put(id, orig); // put back
-                }
-            }
-        } else if ((_embeds == null || !_embeds.remove(sm))
-            && _news != null) {
-            orig = _news.remove(id);
-            if (orig != null && orig != sm)
-                _news.put(id, orig); // put back
-        }
-
-        if (_untracked != null)
-            _untracked.remove(sm);
-    }
-
-    /**
-     * An embedded or nonpersistent managed instance has been persisted.
-     */
-    public void persist(StateManagerImpl sm) {
-        if (_embeds != null)
-            _embeds.remove(sm);
-    }
-
-    /**
-     * A new instance has just been assigned a permanent oid.
-     */
-    public void assignObjectId(Object id, StateManagerImpl sm) {
-        // if assigning oid, remove from new cache and put in primary; may
-        // not be in new cache if another new instance had same id
-        StateManagerImpl orig = null;
-        if (_news != null) {
-            orig = (StateManagerImpl) _news.remove(id);
-            if (orig != null && orig != sm)
-                _news.put(id, orig); // put back
-        }
-
-        // put in main cache, but make sure we don't replace another
-        // instance with the same oid
-        orig = (StateManagerImpl) _main.put(sm.getObjectId(), sm);
-        if (orig != null) {
-            _main.put(sm.getObjectId(), orig);
-            if (!orig.isDeleted())
-                throw new UserException(_loc.get("dup-oid-assign",
-                    sm.getObjectId(),
-                    Exceptions.toString(sm.getManagedInstance())))
-                    .setFailedObject(sm.getManagedInstance());
-
-            // same oid as deleted instance; put in conflict cache
-            if (_conflicts == null)
-                _conflicts = new HashMap();
-            _conflicts.put(sm.getObjectId(), sm);
-        }
-    }
-
-    /**
-     * A new instance has committed; recache under permanent oid.
-     */
-    public void commitNew(Object id, StateManagerImpl sm) {
-        // if the id didn't change, the instance was already assigned an
-        // id, but it could have been in conflict cache
-        StateManagerImpl orig;
-        if (sm.getObjectId() == id) {
-            orig = (_conflicts == null) ? null
-                : (StateManagerImpl) _conflicts.remove(id);
-            if (orig == sm) {
-                orig = (StateManagerImpl) _main.put(id, sm);
-                if (orig != null && !orig.isDeleted()) {
-                    _main.put(sm.getObjectId(), orig);
-                    throw new UserException(_loc.get("dup-oid-assign",
-                        sm.getObjectId(), Exceptions.toString(
-                            sm.getManagedInstance())))
-                        .setFailedObject(sm.getManagedInstance())
-                        .setFatal(true);
-                }
-            }
-            return;
-        }
-
-        // oid changed, so it must previously have been a new instance
-        // without an assigned oid.  remove it from the new cache; ok if
-        // we end up removing another instance with same id
-        if (_news != null)
-            _news.remove(id);
-
-        // and put into main cache now that id is asssigned
-        orig = (StateManagerImpl) _main.put(sm.getObjectId(), sm);
-        if (orig != null && orig != sm && !orig.isDeleted()) {
-            // put back orig and throw error
-            _main.put(sm.getObjectId(), orig);
-            throw new UserException(_loc.get("dup-oid-assign",
-                sm.getObjectId(), Exceptions.toString(sm.getManagedInstance())))
-                    .setFailedObject(sm.getManagedInstance()).setFatal(true);
-        }
-    }
-
-    /**
-     * Return a copy of all cached persistent objects.
-     */
-    public Collection copy() {
-        // proxies not included here because the state manager is always
-        // present in other caches too
-
-        int size = _main.size();
-        if (_conflicts != null)
-            size += _conflicts.size();
-        if (_news != null)
-            size += _news.size();
-        if (_embeds != null)
-            size += _embeds.size();
-        if (size == 0)
-            return Collections.EMPTY_LIST;
-
-        List copy = new ArrayList(size);
-        for (Iterator itr = _main.values().iterator(); itr.hasNext();)
-            copy.add(itr.next());
-        if (_conflicts != null && !_conflicts.isEmpty())
-            for (Iterator itr = _conflicts.values().iterator();
-                itr.hasNext();)
-                copy.add(itr.next());
-        if (_news != null && !_news.isEmpty())
-            for (Iterator itr = _news.values().iterator(); itr.hasNext();)
-                copy.add(itr.next());
-        if (_embeds != null && !_embeds.isEmpty())
-            for (Iterator itr = _embeds.iterator(); itr.hasNext();)
-                copy.add(itr.next());
-        return copy;
-    }
-
-    /**
-     * Clear the cache.
-     */
-    public void clear() {
-        _main = broker.newManagedObjectCache();
-        if (_conflicts != null)
-            _conflicts = null;
-        if (_news != null)
-            _news = null;
-        if (_embeds != null)
-            _embeds = null;
-        if (_untracked != null)
-            _untracked = null;
-    }
-
-    /**
-     * Clear new instances without permanent oids.
-     */
-    public void clearNew() {
-        if (_news != null)
-            _news = null;
-    }
-
-    void dirtyCheck() {
-        if (_untracked == null)
-            return;
-
-        for (Iterator iter = _untracked.iterator(); iter.hasNext(); )
-            ((StateManagerImpl) iter.next()).dirtyCheck();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.ReferenceHashSet;
+import org.apache.openjpa.util.Exceptions;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Cache of managed objects. Must be static for serialization reasons.
+ */
+class ManagedCache implements Serializable {
+
+    private static final Localizer _loc =
+        Localizer.forPackage(ManagedCache.class);
+
+    private Map _main; // oid -> sm
+    private Map _conflicts = null; // conflict oid -> new sm
+    private Map _news = null; // tmp id -> new sm
+    private Collection _embeds = null; // embedded/non-persistent sms
+    private Collection _untracked = null; // hard refs to untracked sms
+    private BrokerImpl broker;
+
+    /**
+     * Constructor; supply primary cache map.
+     */
+    ManagedCache(BrokerImpl broker) {
+        this.broker = broker;
+        _main = broker.newManagedObjectCache();
+    }
+
+    /**
+     * Return the instance for the given oid, optionally allowing
+     * new instances.
+     */
+    public StateManagerImpl getById(Object oid, boolean allowNew) {
+        if (oid == null)
+            return null;
+
+        // check main cache for oid
+        StateManagerImpl sm = (StateManagerImpl) _main.get(oid);
+        StateManagerImpl sm2;
+        if (sm != null) {
+            // if it's a new instance, we know it's the only match, because
+            // other pers instances override new instances in _cache
+            if (sm.isNew() && !sm.isDeleted())
+                return (allowNew) ? sm : null;
+            if (!allowNew || !sm.isDeleted())
+                return sm;
+
+            // sm is deleted; check conflict cache
+            if (_conflicts != null) {
+                sm2 = (StateManagerImpl) _conflicts.get(oid);
+                if (sm2 != null)
+                    return sm2;
+            }
+        }
+
+        // at this point sm is null or deleted; check the new cache for
+        // any matches. this allows us to match app id objects to new
+        // instances without permanant oids
+        if (allowNew && _news != null && !_news.isEmpty()) {
+            sm2 = (StateManagerImpl) _news.get(oid);
+            if (sm2 != null)
+                return sm2;
+        }
+        return sm;
+    }
+
+    /**
+     * Call this method when a new state manager initializes itself.
+     */
+    public void add(StateManagerImpl sm) {
+        if (!sm.isIntercepting()) {
+            if (_untracked == null)
+                _untracked = new HashSet();
+            _untracked.add(sm);
+        }
+
+        if (!sm.isPersistent() || sm.isEmbedded()) {
+            if (_embeds == null)
+                _embeds = new ReferenceHashSet(ReferenceHashSet.WEAK);
+            _embeds.add(sm);
+            return;
+        }
+
+        // initializing new instance; put in new cache because won't have
+        // permanent oid yet
+        if (sm.isNew()) {
+            if (_news == null)
+                _news = new HashMap();
+            _news.put(sm.getId(), sm);
+            return;
+        }
+
+        // initializing persistent instance; put in main cache
+        StateManagerImpl orig = (StateManagerImpl) _main.put
+            (sm.getObjectId(), sm);
+        if (orig != null) {
+            _main.put(sm.getObjectId(), orig);
+            throw new UserException(_loc.get("dup-load", sm.getObjectId(),
+                Exceptions.toString(orig.getManagedInstance())))
+                .setFailedObject(sm.getManagedInstance());
+        }
+    }
+
+    /**
+     * Remove the given state manager from the cache when it transitions
+     * to transient.
+     */
+    public void remove(Object id, StateManagerImpl sm) {
+        // if it has a permanent oid, remove from main / conflict cache,
+        // else remove from embedded/nontrans cache, and if not there
+        // remove from new cache
+        Object orig;
+        if (sm.getObjectId() != null) {
+            orig = _main.remove(id);
+            if (orig != sm) {
+                if (orig != null)
+                    _main.put(id, orig); // put back
+                if (_conflicts != null) {
+                    orig = _conflicts.remove(id);
+                    if (orig != null && orig != sm)
+                        _conflicts.put(id, orig); // put back
+                }
+            }
+        } else if ((_embeds == null || !_embeds.remove(sm))
+            && _news != null) {
+            orig = _news.remove(id);
+            if (orig != null && orig != sm)
+                _news.put(id, orig); // put back
+        }
+
+        if (_untracked != null)
+            _untracked.remove(sm);
+    }
+
+    /**
+     * An embedded or nonpersistent managed instance has been persisted.
+     */
+    public void persist(StateManagerImpl sm) {
+        if (_embeds != null)
+            _embeds.remove(sm);
+    }
+
+    /**
+     * A new instance has just been assigned a permanent oid.
+     */
+    public void assignObjectId(Object id, StateManagerImpl sm) {
+        // if assigning oid, remove from new cache and put in primary; may
+        // not be in new cache if another new instance had same id
+        StateManagerImpl orig = null;
+        if (_news != null) {
+            orig = (StateManagerImpl) _news.remove(id);
+            if (orig != null && orig != sm)
+                _news.put(id, orig); // put back
+        }
+
+        // put in main cache, but make sure we don't replace another
+        // instance with the same oid
+        orig = (StateManagerImpl) _main.put(sm.getObjectId(), sm);
+        if (orig != null) {
+            _main.put(sm.getObjectId(), orig);
+            if (!orig.isDeleted())
+                throw new UserException(_loc.get("dup-oid-assign",
+                    sm.getObjectId(),
+                    Exceptions.toString(sm.getManagedInstance())))
+                    .setFailedObject(sm.getManagedInstance());
+
+            // same oid as deleted instance; put in conflict cache
+            if (_conflicts == null)
+                _conflicts = new HashMap();
+            _conflicts.put(sm.getObjectId(), sm);
+        }
+    }
+
+    /**
+     * A new instance has committed; recache under permanent oid.
+     */
+    public void commitNew(Object id, StateManagerImpl sm) {
+        // if the id didn't change, the instance was already assigned an
+        // id, but it could have been in conflict cache
+        StateManagerImpl orig;
+        if (sm.getObjectId() == id) {
+            orig = (_conflicts == null) ? null
+                : (StateManagerImpl) _conflicts.remove(id);
+            if (orig == sm) {
+                orig = (StateManagerImpl) _main.put(id, sm);
+                if (orig != null && !orig.isDeleted()) {
+                    _main.put(sm.getObjectId(), orig);
+                    throw new UserException(_loc.get("dup-oid-assign",
+                        sm.getObjectId(), Exceptions.toString(
+                            sm.getManagedInstance())))
+                        .setFailedObject(sm.getManagedInstance())
+                        .setFatal(true);
+                }
+            }
+            return;
+        }
+
+        // oid changed, so it must previously have been a new instance
+        // without an assigned oid.  remove it from the new cache; ok if
+        // we end up removing another instance with same id
+        if (_news != null)
+            _news.remove(id);
+
+        // and put into main cache now that id is asssigned
+        orig = (StateManagerImpl) _main.put(sm.getObjectId(), sm);
+        if (orig != null && orig != sm && !orig.isDeleted()) {
+            // put back orig and throw error
+            _main.put(sm.getObjectId(), orig);
+            throw new UserException(_loc.get("dup-oid-assign",
+                sm.getObjectId(), Exceptions.toString(sm.getManagedInstance())))
+                    .setFailedObject(sm.getManagedInstance()).setFatal(true);
+        }
+    }
+
+    /**
+     * Return a copy of all cached persistent objects.
+     */
+    public Collection copy() {
+        // proxies not included here because the state manager is always
+        // present in other caches too
+
+        int size = _main.size();
+        if (_conflicts != null)
+            size += _conflicts.size();
+        if (_news != null)
+            size += _news.size();
+        if (_embeds != null)
+            size += _embeds.size();
+        if (size == 0)
+            return Collections.EMPTY_LIST;
+
+        List copy = new ArrayList(size);
+        for (Iterator itr = _main.values().iterator(); itr.hasNext();)
+            copy.add(itr.next());
+        if (_conflicts != null && !_conflicts.isEmpty())
+            for (Iterator itr = _conflicts.values().iterator();
+                itr.hasNext();)
+                copy.add(itr.next());
+        if (_news != null && !_news.isEmpty())
+            for (Iterator itr = _news.values().iterator(); itr.hasNext();)
+                copy.add(itr.next());
+        if (_embeds != null && !_embeds.isEmpty())
+            for (Iterator itr = _embeds.iterator(); itr.hasNext();)
+                copy.add(itr.next());
+        return copy;
+    }
+
+    /**
+     * Clear the cache.
+     */
+    public void clear() {
+        _main = broker.newManagedObjectCache();
+        if (_conflicts != null)
+            _conflicts = null;
+        if (_news != null)
+            _news = null;
+        if (_embeds != null)
+            _embeds = null;
+        if (_untracked != null)
+            _untracked = null;
+    }
+
+    /**
+     * Clear new instances without permanent oids.
+     */
+    public void clearNew() {
+        if (_news != null)
+            _news = null;
+    }
+
+    void dirtyCheck() {
+        if (_untracked == null)
+            return;
+
+        for (Iterator iter = _untracked.iterator(); iter.hasNext(); )
+            ((StateManagerImpl) iter.next()).dirtyCheck();
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
index b23f5b9..5f7faa8 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
@@ -1,2162 +1,2162 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.Serializable;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.apache.commons.collections.map.LinkedMap;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.kernel.exps.AggregateListener;
-import org.apache.openjpa.kernel.exps.FilterListener;
-import org.apache.openjpa.kernel.exps.Constant;
-import org.apache.openjpa.kernel.exps.Literal;
-import org.apache.openjpa.kernel.exps.Path;
-import org.apache.openjpa.kernel.exps.Val;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.rop.EagerResultList;
-import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
-import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultList;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.ReferenceHashSet;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.GeneralException;
-import org.apache.openjpa.util.InvalidStateException;
-import org.apache.openjpa.util.NonUniqueResultException;
-import org.apache.openjpa.util.NoResultException;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.UnsupportedException;
-import org.apache.openjpa.util.UserException;
-import org.apache.openjpa.util.ImplHelper;
-import serp.util.Numbers;
-import serp.util.Strings;
-
-/**
- * Implementation of the {@link Query} interface.
- *
- * @author Abe White
- * @nojavadoc
- */
-public class QueryImpl
-    implements Query {
-
-    private static final Localizer _loc = Localizer.forPackage(QueryImpl.class);
-
-    private final String _language;
-    private final StoreQuery _storeQuery;
-    private transient final BrokerImpl _broker;
-    private transient final Log _log;
-    private transient ClassLoader _loader = null;
-
-    // query has its own internal lock
-    private final ReentrantLock _lock;
-
-    // unparsed state
-    private Class _class = null;
-    private boolean _subclasses = true;
-    private boolean _readOnly = false;
-    private String _query = null;
-    private String _params = null;
-
-    // parsed state
-    private transient Compilation _compiled = null;
-    private transient boolean _compiling = false;
-    private transient ResultPacker _packer = null;
-
-    // candidates
-    private transient Collection _collection = null;
-    private transient Extent _extent = null;
-
-    // listeners
-    private Map _filtListeners = null;
-    private Map _aggListeners = null;
-
-    // configuration for loading objects
-    private FetchConfiguration _fc = null;
-    private boolean _ignoreChanges = false;
-    private Class _resultMappingScope = null;
-    private String _resultMappingName = null;
-
-    // these fields should only be used directly after we have a compilation,
-    // because their values may be encoded in the query string
-    private Boolean _unique = null;
-    private Class _resultClass = null;
-    private transient long _startIdx = 0;
-    private transient long _endIdx = Long.MAX_VALUE;
-    private transient boolean _rangeSet = false;
-
-    // remember the list of all the results we have returned so we
-    // can free their resources when close or closeAll is called
-    private transient final Collection _resultLists = new ReferenceHashSet
-        (ReferenceHashSet.WEAK);
-
-    /**
-     * Construct a query managed by the given broker.
-     */
-    public QueryImpl(Broker broker, String language, StoreQuery storeQuery) {
-        _broker = (BrokerImpl) broker;
-        _language = language;
-        _storeQuery = storeQuery;
-        _fc = (FetchConfiguration) broker.getFetchConfiguration().clone();
-        _log = broker.getConfiguration().getLog(OpenJPAConfiguration.LOG_QUERY);
-        _storeQuery.setContext(this);
-
-        if (_broker != null && _broker.getMultithreaded())
-            _lock = new ReentrantLock();
-        else
-            _lock = null;
-    }
-
-    /**
-     * Internal store query.
-     */
-    public StoreQuery getStoreQuery() {
-        return _storeQuery;
-    }
-
-    public Broker getBroker() {
-        return _broker;
-    }
-
-    public Query getQuery() {
-        return this;
-    }
-
-    public StoreContext getStoreContext() {
-        return _broker;
-    }
-
-    public String getLanguage() {
-        return _language;
-    }
-
-    public FetchConfiguration getFetchConfiguration() {
-        return _fc;
-    }
-
-    public String getQueryString() {
-        return _query;
-    }
-
-    public boolean getIgnoreChanges() {
-        assertOpen();
-        return _ignoreChanges;
-    }
-
-    public void setIgnoreChanges(boolean flag) {
-        lock();
-        try {
-            assertOpen();
-            // allowed modification: no read-only check
-            _ignoreChanges = flag;
-        } finally {
-            unlock();
-        }
-    }
-
-    public boolean isReadOnly() {
-        assertOpen();
-        return _readOnly;
-    }
-
-    public void setReadOnly(boolean flag) {
-        lock();
-        try {
-            assertOpen();
-            _readOnly = flag;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void addFilterListener(FilterListener listener) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            if (_filtListeners == null)
-                _filtListeners = new HashMap(5);
-            _filtListeners.put(listener.getTag(), listener);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void removeFilterListener(FilterListener listener) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            if (_filtListeners != null)
-                _filtListeners.remove(listener.getTag());
-        } finally {
-            unlock();
-        }
-    }
-
-    public Collection getFilterListeners() {
-        return (_filtListeners == null) ? Collections.EMPTY_LIST
-            : _filtListeners.values();
-    }
-
-    public FilterListener getFilterListener(String tag) {
-        // first check listeners for this query
-        if (_filtListeners != null) {
-            FilterListener listen = (FilterListener) _filtListeners.get(tag);
-            if (listen != null)
-                return listen;
-        }
-
-        // check user-defined listeners from configuration
-        FilterListener[] confListeners = _broker.getConfiguration().
-            getFilterListenerInstances();
-        for (int i = 0; i < confListeners.length; i++)
-            if (confListeners[i].getTag().equals(tag))
-                return confListeners[i];
-
-        // check store listeners
-        return _storeQuery.getFilterListener(tag);
-    }
-
-    public void addAggregateListener(AggregateListener listener) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            if (_aggListeners == null)
-                _aggListeners = new HashMap(5);
-            _aggListeners.put(listener.getTag(), listener);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void removeAggregateListener(AggregateListener listener) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            if (_aggListeners != null)
-                _aggListeners.remove(listener.getTag());
-        } finally {
-            unlock();
-        }
-    }
-
-    public Collection getAggregateListeners() {
-        return (_aggListeners == null) ? Collections.EMPTY_LIST
-            : _aggListeners.values();
-    }
-
-    public AggregateListener getAggregateListener(String tag) {
-        // first check listeners for this query
-        if (_aggListeners != null) {
-            AggregateListener listen = (AggregateListener) _aggListeners.
-                get(tag);
-            if (listen != null)
-                return listen;
-        }
-
-        // check user-defined listeners from configuration
-        AggregateListener[] confListeners = _broker.getConfiguration().
-            getAggregateListenerInstances();
-        for (int i = 0; i < confListeners.length; i++)
-            if (confListeners[i].getTag().equals(tag))
-                return confListeners[i];
-
-        // check store listeners
-        return _storeQuery.getAggregateListener(tag);
-    }
-
-    public Extent getCandidateExtent() {
-        // if just the class is set, fetch the corresponding extent; if the
-        // extent is already set but its ignore cache setting is wrong,
-        // get a new extent with the correct setting (don't modify orig extent
-        // in case the user has a reference to it and might use it)
-        lock();
-        try {
-            Class cls = getCandidateType();
-            if (_extent == null && _collection == null && _broker != null
-                && cls != null) {
-                _extent = _broker.newExtent(cls, _subclasses);
-                _extent.setIgnoreChanges(_ignoreChanges);
-            } else if (_extent != null
-                && _extent.getIgnoreChanges() != _ignoreChanges && cls != null){
-                _extent = _broker.newExtent(cls, _extent.hasSubclasses());
-                _extent.setIgnoreChanges(_ignoreChanges);
-            }
-            return _extent;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void setCandidateExtent(Extent candidateExtent) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-
-            if (candidateExtent == _extent)
-                return;
-            if (candidateExtent == null) {
-                _extent = null;
-                return;
-            }
-
-            // if extent then not collection
-            _extent = candidateExtent;
-            _collection = null;
-
-            boolean invalidate = false;
-            if (_extent.getElementType() != _class) {
-                _class = _extent.getElementType();
-                _loader = null;
-                invalidate = true;
-            }
-            if (_extent.hasSubclasses() != _subclasses) {
-                _subclasses = _extent.hasSubclasses();
-                invalidate = true;
-            }
-            if (invalidate)
-                invalidateCompilation();
-        } finally {
-            unlock();
-        }
-    }
-
-    public Collection getCandidateCollection() {
-        assertOpen();
-        return _collection;
-    }
-
-    public void setCandidateCollection(Collection candidateCollection) {
-        if (!_storeQuery.supportsInMemoryExecution())
-            throw new UnsupportedException(_loc.get("query-nosupport",
-                _language));
-
-        lock();
-        try {
-            assertOpen();
-
-            // if collection then not extent
-            _collection = candidateCollection;
-            if (_collection != null)
-                _extent = null;
-        } finally {
-            unlock();
-        }
-    }
-
-    public Class getCandidateType() {
-        lock();
-        try {
-            assertOpen();
-            if (_class != null || _compiled != null || _query == null
-                || _broker == null)
-                return _class;
-
-            // check again after compilation; maybe encoded in string
-            compileForCompilation();
-            return _class;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void setCandidateType(Class candidateClass, boolean subs) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            _class = candidateClass;
-            _subclasses = subs;
-            _loader = null;
-            invalidateCompilation();
-        } finally {
-            unlock();
-        }
-    }
-
-    public boolean hasSubclasses() {
-        return _subclasses;
-    }
-
-    public String getResultMappingName() {
-        assertOpen();
-        return _resultMappingName;
-    }
-
-    public Class getResultMappingScope() {
-        assertOpen();
-        return _resultMappingScope;
-    }
-
-    public void setResultMapping(Class scope, String name) {
-        lock();
-        try {
-            assertOpen();
-            _resultMappingScope = scope;
-            _resultMappingName = name;
-            _packer = null;
-        } finally {
-            unlock();
-        }
-    }
-
-    public boolean isUnique() {
-        lock();
-        try {
-            assertOpen();
-            if (_unique != null)
-                return _unique.booleanValue();
-            if (_query == null || _compiling || _broker == null)
-                return false;
-
-            // check again after compilation; maybe encoded in string
-            if (_compiled == null) {
-                compileForCompilation();
-                if (_unique != null)
-                    return _unique.booleanValue();
-            }
-
-            // no explicit setting; default
-            StoreQuery.Executor ex = compileForExecutor();
-            if (!ex.isAggregate(_storeQuery))
-                return false;
-            return !ex.hasGrouping(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void setUnique(boolean unique) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            _unique = (unique) ? Boolean.TRUE : Boolean.FALSE;
-        } finally {
-            unlock();
-        }
-    }
-
-    public Class getResultType() {
-        lock();
-        try {
-            assertOpen();
-            if (_resultClass != null || _compiled != null || _query == null
-                || _broker == null)
-                return _resultClass;
-
-            // check again after compilation; maybe encoded in string
-            compileForCompilation();
-            return _resultClass;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void setResultType(Class cls) {
-        lock();
-        try {
-            assertOpen();
-            // allowed modification: no read-only check
-            _resultClass = cls;
-            _packer = null;
-        } finally {
-            unlock();
-        }
-    }
-
-    public long getStartRange() {
-        assertOpen();
-        return _startIdx;
-    }
-
-    public long getEndRange() {
-        assertOpen();
-        return _endIdx;
-    }
-
-    public void setRange(long start, long end) {
-        if (start < 0 || end < 0)
-            throw new UserException(_loc.get("invalid-range",
-                String.valueOf(start), String.valueOf(end)));
-
-        if (end - start > Integer.MAX_VALUE && end != Long.MAX_VALUE)
-            throw new UserException(_loc.get("range-too-big",
-                String.valueOf(start), String.valueOf(end)));
-
-        lock();
-        try {
-            assertOpen();
-            // allowed modification: no read-only check
-            _startIdx = start;
-            _endIdx = end;
-            _rangeSet = true;
-        } finally {
-            unlock();
-        }
-    }
-
-    public String getParameterDeclaration() {
-        lock();
-        try {
-            assertOpen();
-            if (_params != null || _compiled != null || _compiling
-                || _broker == null)
-                return _params;
-
-            // check again after compilation; maybe encoded in string
-            compileForCompilation();
-            return _params;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void declareParameters(String params) {
-        if (!_storeQuery.supportsParameterDeclarations())
-            throw new UnsupportedException(_loc.get("query-nosupport",
-                _language));
-
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-            _params = StringUtils.trimToNull(params);
-            invalidateCompilation();
-        } finally {
-            unlock();
-        }
-    }
-
-    public void compile() {
-        lock();
-        try {
-            assertOpen();
-            StoreQuery.Executor ex = compileForExecutor();
-            getResultPacker(_storeQuery, ex);
-            ex.validate(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public Object getCompilation() {
-        lock();
-        try {
-            return compileForCompilation().storeData;
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Compile query properties.
-     */
-    private Compilation compileForCompilation() {
-        if (_compiled != null || _compiling)
-            return _compiled;
-
-        assertNotSerialized();
-        assertOpen();
-
-        boolean readOnly = _readOnly;
-        _readOnly = false;
-        _compiling = true;
-        try {
-            _compiled = compilationFromCache();
-            return _compiled;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            _compiling = false;
-            _readOnly = readOnly;
-        }
-    }
-
-    /**
-     * Find the cached compilation for the current query, creating one if it
-     * does not exist.
-     */
-    protected Compilation compilationFromCache() {
-        Map compCache =
-            _broker.getConfiguration().getQueryCompilationCacheInstance();
-        if (compCache == null) {
-            return newCompilation();
-        } else {
-            CompilationKey key = new CompilationKey();
-            key.queryType = _storeQuery.getClass();
-            key.candidateType = getCandidateType();
-            key.subclasses = hasSubclasses();
-            key.query = getQueryString();
-            key.language = getLanguage();
-            key.storeKey = _storeQuery.newCompilationKey();
-            Compilation comp = (Compilation) compCache.get(key);
-
-            // parse declarations if needed
-            boolean cache = false;
-            if (comp == null) {
-                comp = newCompilation();
-                // only cache those queries that can be compiled
-                cache = comp.storeData != null;
-            } else
-                _storeQuery.populateFromCompilation(comp.storeData);
-
-            // cache parsed state if needed
-            if (cache)
-                compCache.put(key, comp);
-            return comp;
-        }
-    }
-    
-    /**
-     * Create and populate a new compilation.
-     */
-    private Compilation newCompilation() {
-        Compilation comp = new Compilation();
-        comp.storeData = _storeQuery.newCompilation();
-        _storeQuery.populateFromCompilation(comp.storeData);
-        return comp;
-    }
-
-    /**
-     * Compile for execution, choosing between datastore and in-mem
-     * compilation based on what we support and our settings.
-     */
-    private StoreQuery.Executor compileForExecutor() {
-        Compilation comp = compileForCompilation();
-        if (_collection == null) {
-            if (comp.datastore != null)
-                return comp.datastore;
-            if (comp.memory != null)
-                return comp.memory;
-            if (_storeQuery.supportsDataStoreExecution())
-                return compileForDataStore(comp);
-            return compileForInMemory(comp);
-        }
-
-        if (comp.memory != null)
-            return comp.memory;
-        if (comp.datastore != null)
-            return comp.datastore;
-        if (_storeQuery.supportsInMemoryExecution())
-            return compileForInMemory(comp);
-        return compileForDataStore(comp);
-    }
-
-    /**
-     * Create an expression tree for datastore execution.
-     */
-    private StoreQuery.Executor compileForDataStore(Compilation comp) {
-        if (comp.datastore == null)
-            comp.datastore = createExecutor(false);
-        return comp.datastore;
-    }
-
-    /**
-     * Create an expression tree for in-memory execution.
-     */
-    private StoreQuery.Executor compileForInMemory(Compilation comp) {
-        if (comp.memory == null)
-            comp.memory = createExecutor(true);
-        return comp.memory;
-    }
-
-    /**
-     * Return a query executor of the proper type.
-     */
-    private StoreQuery.Executor createExecutor(boolean inMem) {
-        assertCandidateType();
-
-        MetaDataRepository repos = _broker.getConfiguration().
-            getMetaDataRepositoryInstance();
-        ClassMetaData meta = repos.getMetaData(_class,
-            _broker.getClassLoader(), false);
-
-        ClassMetaData[] metas;
-        if (_class == null || _storeQuery.supportsAbstractExecutors())
-            metas = new ClassMetaData[]{ meta };
-        else if (_subclasses && (meta == null || meta.isManagedInterface()))
-            metas = repos.getImplementorMetaDatas(_class,
-                _broker.getClassLoader(), true);
-        else if (meta != null && (_subclasses || meta.isMapped()))
-            metas = new ClassMetaData[]{ meta };
-        else
-            metas = StoreQuery.EMPTY_METAS;
-
-        if (metas.length == 0)
-            throw new UserException(_loc.get("no-impls", _class));
-        try {
-            if (metas.length == 1) {
-                if (inMem)
-                    return _storeQuery.newInMemoryExecutor(metas[0],
-                        _subclasses);
-                return _storeQuery.newDataStoreExecutor(metas[0], _subclasses);
-            }
-
-            // multiple implementors
-            StoreQuery.Executor[] es = new StoreQuery.Executor[metas.length];
-            for (int i = 0; i < es.length; i++) {
-                if (inMem)
-                    es[i] = _storeQuery.newInMemoryExecutor(metas[i], true);
-                else
-                    es[i] = _storeQuery.newDataStoreExecutor(metas[i], true);
-            }
-            return new MergedExecutor(es);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        }
-    }
-
-    /**
-     * Clear any compilation, forcing this query to be recompiled
-     * next time it's executed. This should be invoked whenever any
-     * state changes that would cause the underlying query
-     * representation to change.
-     *
-     * @since 0.3.0
-     */
-    private boolean invalidateCompilation() {
-        if (_compiling)
-            return false;
-        _storeQuery.invalidateCompilation();
-        _compiled = null;
-        _packer = null;
-        return true;
-    }
-
-    public Object execute() {
-        return execute((Object[]) null);
-    }
-
-    public Object execute(Object[] params) {
-        return execute(OP_SELECT, params);
-    }
-
-    public Object execute(Map params) {
-        return execute(OP_SELECT, params);
-    }
-
-    private Object execute(int operation, Object[] params) {
-        if (params == null)
-            params = StoreQuery.EMPTY_OBJECTS;
-
-        lock();
-        try {
-            assertNotSerialized();
-            _broker.beginOperation(true);
-            try {
-                assertOpen();
-                _broker.assertNontransactionalRead();
-
-                // get executor
-                Compilation comp = compileForCompilation();
-                StoreQuery.Executor ex = (isInMemory(operation))
-                    ? compileForInMemory(comp) : compileForDataStore(comp);
-
-                assertParameters(_storeQuery, ex, params);
-                if (_log.isTraceEnabled())
-                    logExecution(operation, ex.getParameterTypes(_storeQuery),
-                        params);
-
-                if (operation == OP_SELECT)
-                    return execute(_storeQuery, ex, params);
-                if (operation == OP_DELETE)
-                    return delete(_storeQuery, ex, params);
-                if (operation == OP_UPDATE)
-                    return update(_storeQuery, ex, params);
-                throw new UnsupportedException();
-            } catch (OpenJPAException ke) {
-                throw ke;
-            } catch (Exception e) {
-                throw new UserException(e);
-            } finally {
-                _broker.endOperation();
-            }
-        }
-        finally {
-            unlock();
-        }
-    }
-
-    private Object execute(int operation, Map params) {
-        if (params == null)
-            params = Collections.EMPTY_MAP;
-
-        lock();
-        try {
-            _broker.beginOperation(true);
-            try {
-                assertNotSerialized();
-                assertOpen();
-                _broker.assertNontransactionalRead();
-
-                // get executor
-                Compilation comp = compileForCompilation();
-                StoreQuery.Executor ex = (isInMemory(operation))
-                    ? compileForInMemory(comp) : compileForDataStore(comp);
-
-                Object[] arr = (params.isEmpty()) ? StoreQuery.EMPTY_OBJECTS :
-                    toParameterArray(ex.getParameterTypes(_storeQuery), params);
-                assertParameters(_storeQuery, ex, arr);
-                if (_log.isTraceEnabled())
-                    logExecution(operation, params);
-
-                if (operation == OP_SELECT)
-                    return execute(_storeQuery, ex, arr);
-                if (operation == OP_DELETE)
-                    return delete(_storeQuery, ex, arr);
-                if (operation == OP_UPDATE)
-                    return update(_storeQuery, ex, arr);
-                throw new UnsupportedException();
-            } catch (OpenJPAException ke) {
-                throw ke;
-            } catch (Exception e) {
-                throw new UserException(e);
-            } finally {
-                _broker.endOperation();
-            }
-        }
-        finally {
-            unlock();
-        }
-    }
-
-    public long deleteAll() {
-        return deleteAll((Object[]) null);
-    }
-
-    public long deleteAll(Object[] params) {
-        return ((Number) execute(OP_DELETE, params)).longValue();
-    }
-
-    public long deleteAll(Map params) {
-        return ((Number) execute(OP_DELETE, params)).longValue();
-    }
-
-    public long updateAll() {
-        return updateAll((Object[]) null);
-    }
-
-    public long updateAll(Object[] params) {
-        return ((Number) execute(OP_UPDATE, params)).longValue();
-    }
-
-    public long updateAll(Map params) {
-        return ((Number) execute(OP_UPDATE, params)).longValue();
-    }
-
-    private Object[] toParameterArray(LinkedMap paramTypes, Map params) {
-        if (params == null || params.isEmpty())
-            return StoreQuery.EMPTY_OBJECTS;
-
-        Object[] arr = new Object[params.size()];
-        Map.Entry entry;
-        Object key;
-        int idx;
-        int base = -1;
-        for (Iterator itr = params.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            key = entry.getKey();
-            idx = (paramTypes == null) ? -1 : paramTypes.indexOf(key);
-
-            // allow positional parameters and natural order parameters
-            if (idx != -1)
-                arr[idx] = entry.getValue();
-            else if (key instanceof Number) {
-                if (base == -1)
-                    base = positionalParameterBase(params.keySet());
-                arr[((Number) key).intValue() - base] = entry.getValue();
-            } else
-                throw new UserException(_loc.get("bad-param-name", key));
-        }
-        return arr;
-    }
-
-    /**
-     * Return the base (generally 0 or 1) to use for positional parameters.
-     */
-    private static int positionalParameterBase(Collection params) {
-        int low = Integer.MAX_VALUE;
-        Object obj;
-        int val;
-        for (Iterator itr = params.iterator(); itr.hasNext();) {
-            obj = itr.next();
-            if (!(obj instanceof Number))
-                return 0; // use 0 base when params are mixed types
-
-            val = ((Number) obj).intValue();
-            if (val == 0)
-                return val;
-            if (val < low)
-                low = val;
-        }
-        return low;
-    }
-
-    /**
-     * Return whether we should execute this query in memory.
-     */
-    private boolean isInMemory(int operation) {
-        // if there are any dirty instances in the current trans that are
-        // involved in this query, we have to execute in memory or flush
-        boolean inMem = !_storeQuery.supportsDataStoreExecution()
-            || _collection != null;
-        if (!inMem && (!_ignoreChanges || operation != OP_SELECT)
-            && _broker.isActive() && isAccessPathDirty()) {
-            int flush = _fc.getFlushBeforeQueries();
-            if ((flush == FLUSH_TRUE
-                || (flush == FLUSH_WITH_CONNECTION && _broker.hasConnection())
-                || operation != OP_SELECT
-                || !_storeQuery.supportsInMemoryExecution())
-                && _broker.getConfiguration().supportedOptions().
-                contains(OpenJPAConfiguration.OPTION_INC_FLUSH)) {
-                _broker.flush();
-            } else {
-                if (_log.isInfoEnabled())
-                    _log.info(_loc.get("force-in-mem", _class));
-                inMem = true;
-            }
-        }
-
-        if (inMem && !_storeQuery.supportsInMemoryExecution())
-            throw new InvalidStateException(_loc.get("cant-exec-inmem",
-                _language));
-        return inMem;
-    }
-
-    /**
-     * Execute the query using the given compilation, executor, and parameter
-     * values. All other execute methods delegate to this one or to
-     * {@link #execute(StoreQuery.Executor,Map)} after validation and locking.
-     */
-    private Object execute(StoreQuery q, StoreQuery.Executor ex, 
-        Object[] params)
-        throws Exception {
-        // if this is an impossible result range, return null / empty list
-        StoreQuery.Range range = new StoreQuery.Range(_startIdx, _endIdx);
-        if (!_rangeSet)
-            ex.getRange(q, params, range);
-        if (range.start >= range.end)
-            return emptyResult(q, ex);
-
-        // execute; if we have a result class or we have only one result
-        // and so need to remove it from its array, wrap in a packing rop
-        range.lrs = isLRS(range.start, range.end);
-        ResultObjectProvider rop = ex.executeQuery(q, params, range);
-        try {
-            return toResult(q, ex, rop, range);
-        } catch (Exception e) {
-            if (rop != null)
-                try { rop.close(); } catch (Exception e2) {}
-            throw e;
-        }
-    }
-
-    /**
-     * Delete the query using the given executor, and parameter
-     * values. All other execute methods delegate to this one or to
-     * {@link #delete(StoreQuery.Executor,Map)} after validation and locking.
-     * The return value will be a Number indicating the number of
-     * instances deleted.
-     */
-    private Number delete(StoreQuery q, StoreQuery.Executor ex, Object[] params)
-        throws Exception {
-        assertBulkModify(q, ex, params);
-        return ex.executeDelete(q, params);
-    }
-
-    public Number deleteInMemory(StoreQuery q, StoreQuery.Executor executor,
-        Object[] params) {
-        try {
-            Object o = execute(q, executor, params);
-            if (!(o instanceof Collection))
-                o = Collections.singleton(o);
-
-            int size = 0;
-            for (Iterator i = ((Collection) o).iterator(); i.hasNext(); size++)
-                _broker.delete(i.next(), null);
-            return Numbers.valueOf(size);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new UserException(e);
-        }
-    }
-
-    /**
-     * Update the query using the given compilation, executor, and parameter
-     * values. All other execute methods delegate to this one or to
-     * {@link #update(StoreQuery.Executor,Map)} after validation and locking.
-     * The return value will be a Number indicating the number of
-     * instances updated.
-     */
-    private Number update(StoreQuery q, StoreQuery.Executor ex, Object[] params)
-        throws Exception {
-        assertBulkModify(q, ex, params);
-        return ex.executeUpdate(q, params);
-    }
-
-    public Number updateInMemory(StoreQuery q, StoreQuery.Executor executor,
-        Object[] params) {
-        try {
-            Object o = execute(q, executor, params);
-            if (!(o instanceof Collection))
-                o = Collections.singleton(o);
-
-            int size = 0;
-            for (Iterator i = ((Collection) o).iterator(); i.hasNext(); size++)
-                updateInMemory(i.next(), params, q);
-            return Numbers.valueOf(size);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new UserException(e);
-        }
-    }
-
-    /**
-     * Set the values for the updates in memory.
-     *
-     * @param ob the persistent instance to change
-     * @param params the parameters passed to the query
-     */
-    private void updateInMemory(Object ob, Object[] params, StoreQuery q) {
-        for (Iterator it = getUpdates().entrySet().iterator();
-            it.hasNext();) {
-            Map.Entry e = (Map.Entry) it.next();
-            Path path = (Path) e.getKey();
-            FieldMetaData fmd = (FieldMetaData) path.last();
-            OpenJPAStateManager sm = _broker.getStateManager(ob);
-
-            Object val;
-            Object value = e.getValue();
-            if (value instanceof Val) {
-                val = ((Val) value).
-                    evaluate(ob, null, getStoreContext(), params);
-            } else if (value instanceof Literal) {
-                val = ((Literal) value).getValue();
-            } else if (value instanceof Constant) {
-                val = ((Constant) value).getValue(params);
-            } else {
-                try {
-                    val = q.evaluate(value, ob, params, sm);
-                } catch (UnsupportedException e1) {
-                    throw new UserException(_loc.get("fail-to-get-update-value"));
-                }
-            }
-
-            int i = fmd.getIndex();
-            PersistenceCapable into = ImplHelper.toPersistenceCapable(ob,
-                _broker.getConfiguration());
-
-            // set the actual field in the instance
-            int set = OpenJPAStateManager.SET_USER;
-            switch (fmd.getDeclaredTypeCode()) {
-                case JavaTypes.BOOLEAN:
-                    sm.settingBooleanField(into, i, sm.fetchBooleanField(i),
-                        val == null ? false : ((Boolean) val).booleanValue(),
-                        set);
-                    break;
-                case JavaTypes.BYTE:
-                    sm.settingByteField(into, i, sm.fetchByteField(i),
-                        val == null ? 0 : ((Number) val).byteValue(), set);
-                    break;
-                case JavaTypes.CHAR:
-                    sm.settingCharField(into, i, sm.fetchCharField(i),
-                        val == null ? 0 : val.toString().charAt(0), set);
-                    break;
-                case JavaTypes.DOUBLE:
-                    sm.settingDoubleField(into, i, sm.fetchDoubleField(i),
-                        val == null ? 0 : ((Number) val).doubleValue(), set);
-                    break;
-                case JavaTypes.FLOAT:
-                    sm.settingFloatField(into, i, sm.fetchFloatField(i),
-                        val == null ? 0 : ((Number) val).floatValue(), set);
-                    break;
-                case JavaTypes.INT:
-                    sm.settingIntField(into, i, sm.fetchIntField(i),
-                        val == null ? 0 : ((Number) val).intValue(), set);
-                    break;
-                case JavaTypes.LONG:
-                    sm.settingLongField(into, i, sm.fetchLongField(i),
-                        val == null ? 0 : ((Number) val).longValue(), set);
-                    break;
-                case JavaTypes.SHORT:
-                    sm.settingShortField(into, i, sm.fetchShortField(i),
-                        val == null ? 0 : ((Number) val).shortValue(), set);
-                    break;
-                case JavaTypes.STRING:
-                    sm.settingStringField(into, i, sm.fetchStringField(i),
-                        val == null ? null : val.toString(), set);
-                    break;
-                case JavaTypes.DATE:
-                case JavaTypes.NUMBER:
-                case JavaTypes.BOOLEAN_OBJ:
-                case JavaTypes.BYTE_OBJ:
-                case JavaTypes.CHAR_OBJ:
-                case JavaTypes.DOUBLE_OBJ:
-                case JavaTypes.FLOAT_OBJ:
-                case JavaTypes.INT_OBJ:
-                case JavaTypes.LONG_OBJ:
-                case JavaTypes.SHORT_OBJ:
-                case JavaTypes.BIGDECIMAL:
-                case JavaTypes.BIGINTEGER:
-                case JavaTypes.LOCALE:
-                case JavaTypes.OBJECT:
-                case JavaTypes.OID:
-                    sm.settingObjectField(into, i, sm.fetchObjectField(i), val,
-                        set);
-                    break;
-                default:
-                    throw new UserException(_loc.get("only-update-primitives"));
-            }
-        }
-    }
-
-    /**
-     * Trace log that the query is executing.
-     */
-    private void logExecution(int op, LinkedMap types, Object[] params) {
-        Map pmap = Collections.EMPTY_MAP;
-        if (params.length > 0) {
-            pmap = new HashMap((int) (params.length * 1.33 + 1));
-            if (types != null && types.size() == params.length) {
-                int i = 0;
-                for (Iterator itr = types.keySet().iterator(); itr.hasNext();)
-                    pmap.put(itr.next(), params[i++]);
-            } else {
-                for (int i = 0; i < params.length; i++)
-                    pmap.put(String.valueOf(i), params[i]);
-            }
-        }
-        logExecution(op, pmap);
-    }
-
-    /**
-     * Trace log that the query is executing.
-     */
-    private void logExecution(int op, Map params) {
-        String s = _query;
-        if (StringUtils.isEmpty(s))
-            s = toString();
-
-        String msg = "executing-query";
-        if (!params.isEmpty())
-            msg += "-with-params";
-
-        _log.trace(_loc.get(msg, s, params));
-    }
-
-    /**
-     * Return whether this should be treated as a potential large result set.
-     */
-    private boolean isLRS(long start, long end) {
-        long range = end - start;
-        return _fc.getFetchBatchSize() >= 0
-            && !(range <= _fc.getFetchBatchSize()
-            || (_fc.getFetchBatchSize() == 0 && range <= 50));
-    }
-
-    /**
-     * Return the query result for the given result object provider.
-     */
-    protected Object toResult(StoreQuery q, StoreQuery.Executor ex, 
-        ResultObjectProvider rop, StoreQuery.Range range)
-        throws Exception {
-        // pack projections if necessary
-        String[] aliases = ex.getProjectionAliases(q);
-        if (!ex.isPacking(q)) {
-            ResultPacker packer = getResultPacker(q, ex);
-            if (packer != null || aliases.length == 1)
-                rop = new PackingResultObjectProvider(rop, packer,
-                    aliases.length);
-        }
-
-        // if single result, extract it
-        if (_unique == Boolean.TRUE || (aliases.length > 0
-            && !ex.hasGrouping(q) && ex.isAggregate(q)))
-            return singleResult(rop, range);
-
-        // now that we've executed the query, we can call isAggregate and
-        // hasGrouping efficiently
-        boolean detach = (_broker.getAutoDetach() &
-            AutoDetach.DETACH_NONTXREAD) > 0 && !_broker.isActive();
-        boolean lrs = range.lrs && !ex.isAggregate(q) && !ex.hasGrouping(q);
-        ResultList res = (!detach && lrs) ? _fc.newResultList(rop)
-            : new EagerResultList(rop);
-
-        _resultLists.add(decorateResultList(res));
-        return res;
-    }
-
-    /**
-     * Optionally decorate the native result.
-     */
-    protected ResultList decorateResultList(ResultList res) {
-        return new RemoveOnCloseResultList(res);
-    }
-
-    /**
-     * Return a result packer for this projection, or null.
-     */
-    private ResultPacker getResultPacker(StoreQuery q, StoreQuery.Executor ex) {
-        if (_packer != null)
-            return _packer;
-
-        Class resultClass = (_resultClass != null) ? _resultClass
-            : ex.getResultClass(q);
-        if (resultClass == null)
-            return null;
-
-        String[] aliases = ex.getProjectionAliases(q);
-        if (aliases.length == 0) {
-            // result class but no result; means candidate is being set
-            // into some result class
-            _packer = new ResultPacker(_class, getAlias(), resultClass);
-        } else if (resultClass != null) {
-            // projection
-            Class[] types = ex.getProjectionTypes(q);
-            _packer = new ResultPacker(types, aliases, resultClass);
-        }
-        return _packer;
-    }
-
-    /**
-     * Create an empty result for this query.
-     */
-    private Object emptyResult(StoreQuery q, StoreQuery.Executor ex) {
-        if (_unique == Boolean.TRUE || (_unique == null
-            && !ex.hasGrouping(q) && ex.isAggregate(q)))
-            return null;
-        return Collections.EMPTY_LIST;
-    }
-
-    /**
-     * Extract an expected single result from the given provider. Used when
-     * the result is an ungrouped aggregate or the unique flag is set to true.
-     */
-    private Object singleResult(ResultObjectProvider rop, 
-        StoreQuery.Range range)
-        throws Exception {
-        rop.open();
-        try {
-            // move to expected result
-            boolean next = rop.next();
-
-            // extract single result; throw an exception if multiple results
-            // match and not constrainted by range, or if a unique query with
-            // no results
-            Object single = null;
-            if (next) {
-                single = rop.getResultObject();
-                if (range.end != range.start + 1 && rop.next())
-                    throw new NonUniqueResultException(_loc.get("not-unique",
-                        _class, _query));
-            } else if (_unique == Boolean.TRUE)
-                throw new NoResultException(_loc.get("no-result", 
-                    _class, _query));
-
-            // if unique set to false, use collection
-            if (_unique == Boolean.FALSE) {
-                if (!next)
-                    return Collections.EMPTY_LIST;
-                // Collections.singletonList is JDK 1.3, so...
-                return Arrays.asList(new Object[]{ single });
-            }
-            
-            // return single result
-            return single;
-        } finally {
-            rop.close();
-        }
-    }
-
-    /**
-     * Calculates whether the access path of this query intersects with
-     * any dirty objects in the transaction.
-     */
-    private boolean isAccessPathDirty() {
-        return isAccessPathDirty(_broker, getAccessPathMetaDatas());
-    }
-
-    public static boolean isAccessPathDirty(Broker broker,
-        ClassMetaData[] accessMetas) {
-        Collection persisted = broker.getPersistedTypes();
-        Collection updated = broker.getUpdatedTypes();
-        Collection deleted = broker.getDeletedTypes();
-        if (persisted.isEmpty() && updated.isEmpty() && deleted.isEmpty())
-            return false;
-
-        // if no access metas, assume every dirty object affects path just
-        // to be safe
-        if (accessMetas.length == 0)
-            return true;
-
-        // compare dirty classes to the access path classes
-        Class accClass;
-        for (int i = 0; i < accessMetas.length; i++) {
-            // shortcut if actual class is dirty
-            accClass = accessMetas[i].getDescribedType();
-            if (persisted.contains(accClass) || updated.contains(accClass)
-                || deleted.contains(accClass))
-                return true;
-
-            // check for dirty subclass
-            for (Iterator dirty = persisted.iterator(); dirty.hasNext();)
-                if (accClass.isAssignableFrom((Class) dirty.next()))
-                    return true;
-            for (Iterator dirty = updated.iterator(); dirty.hasNext();)
-                if (accClass.isAssignableFrom((Class) dirty.next()))
-                    return true;
-            for (Iterator dirty = deleted.iterator(); dirty.hasNext();)
-                if (accClass.isAssignableFrom((Class) dirty.next()))
-                    return true;
-        }
-
-        // no intersection
-        return false;
-    }
-
-    public void closeAll() {
-        closeResults(true);
-    }
-
-    public void closeResources() {
-        closeResults(false);
-    }
-
-    /**
-     * Close open results.
-     */
-    private void closeResults(boolean force) {
-        lock();
-        try {
-            assertOpen();
-
-            RemoveOnCloseResultList res;
-            for (Iterator itr = _resultLists.iterator(); itr.hasNext();) {
-                res = (RemoveOnCloseResultList) itr.next();
-                if (force || res.isProviderOpen())
-                    res.close(false);
-            }
-            _resultLists.clear();
-        } finally {
-            unlock();
-        }
-    }
-
-    public String[] getDataStoreActions(Map params) {
-        if (params == null)
-            params = Collections.EMPTY_MAP;
-
-        lock();
-        try {
-            assertNotSerialized();
-            assertOpen();
-
-            StoreQuery.Executor ex = compileForExecutor();
-            Object[] arr = toParameterArray(ex.getParameterTypes(_storeQuery),
-                params);
-            assertParameters(_storeQuery, ex, arr);
-            StoreQuery.Range range = new StoreQuery.Range(_startIdx, _endIdx);
-            if (!_rangeSet)
-                ex.getRange(_storeQuery, arr, range);
-            return ex.getDataStoreActions(_storeQuery, arr, range);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            throw new UserException(e);
-        } finally {
-            unlock();
-        }
-    }
-
-    public boolean setQuery(Object query) {
-        lock();
-        try {
-            assertOpen();
-            assertNotReadOnly();
-
-            if (query == null || query instanceof String) {
-                invalidateCompilation();
-                _query = (String) query;
-                if (_query != null)
-                    _query = _query.trim();
-                return true;
-            }
-            if (!(query instanceof QueryImpl))
-                return _storeQuery.setQuery(query);
-
-            // copy all non-transient state from the given query
-            invalidateCompilation();
-            QueryImpl q = (QueryImpl) query;
-            _class = q._class;
-            _subclasses = q._subclasses;
-            _query = q._query;
-            _ignoreChanges = q._ignoreChanges;
-            _unique = q._unique;
-            _resultClass = q._resultClass;
-            _params = q._params;
-            _resultMappingScope = q._resultMappingScope;
-            _resultMappingName = q._resultMappingName;
-            _readOnly = q._readOnly;
-
-            // don't share mutable objects
-            _fc.copy(q._fc);
-            if (q._filtListeners != null)
-                _filtListeners = new HashMap(q._filtListeners);
-            if (q._aggListeners != null)
-                _aggListeners = new HashMap(q._aggListeners);
-            return true;
-        } finally {
-            unlock();
-        }
-    }
-
-    public String getAlias() {
-        lock();
-        try {
-            String alias = compileForExecutor().getAlias(_storeQuery);
-            if (alias == null)
-                alias = Strings.getClassName(_class);
-            return alias;
-        } finally {
-            unlock();
-        }
-    }
-
-    public String[] getProjectionAliases() {
-        lock();
-        try {
-            return compileForExecutor().getProjectionAliases(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public Class[] getProjectionTypes() {
-        lock();
-        try {
-            return compileForExecutor().getProjectionTypes(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public int getOperation() {
-        lock();
-        try {
-            return compileForExecutor().getOperation(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public boolean isAggregate() {
-        lock();
-        try {
-            return compileForExecutor().isAggregate(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public boolean hasGrouping() {
-        lock();
-        try {
-            return compileForExecutor().hasGrouping(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public ClassMetaData[] getAccessPathMetaDatas() {
-        lock();
-        try {
-            ClassMetaData[] metas = compileForExecutor().
-                getAccessPathMetaDatas(_storeQuery);
-            return (metas == null) ? StoreQuery.EMPTY_METAS : metas;
-        } finally {
-            unlock();
-        }
-    }
-
-    public LinkedMap getParameterTypes() {
-        lock();
-        try {
-            return compileForExecutor().getParameterTypes(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public Map getUpdates() {
-        lock();
-        try {
-            return compileForExecutor().getUpdates(_storeQuery);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void lock() {
-        if (_lock != null)
-            _lock.lock();
-    }
-
-    public void unlock() {
-        if (_lock != null && _lock.isLocked())
-            _lock.unlock();
-    }
-
-    /////////
-    // Utils
-    /////////
-
-    public Class classForName(String name, String[] imports) {
-        // full class name or primitive type?
-        Class type = toClass(name);
-        if (type != null)
-            return type;
-
-        // first check the aliases map in the MetaDataRepository
-        ClassLoader loader = (_class == null) ? _loader
-            : (ClassLoader) AccessController.doPrivileged(
-                J2DoPrivHelper.getClassLoaderAction(_class)); 
-        ClassMetaData meta = _broker.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(name, loader, false);
-        if (meta != null)
-            return meta.getDescribedType();
-
-        // try the name in the package of the candidate class
-        if (_class != null) {
-            String fullName = _class.getName().substring
-                (0, _class.getName().lastIndexOf('.') + 1) + name;
-            type = toClass(fullName);
-            if (type != null)
-                return type;
-        }
-
-        // try java.lang
-        type = toClass("java.lang." + name);
-        if (type != null)
-            return type;
-
-        // try each import
-        if (imports != null && imports.length > 0) {
-            String dotName = "." + name;
-            String importName;
-            for (int i = 0; i < imports.length; i++) {
-                importName = imports[i];
-
-                // full class name import
-                if (importName.endsWith(dotName))
-                    type = toClass(importName);
-                    // wildcard; strip to package
-                else if (importName.endsWith(".*")) {
-                    importName = importName.substring
-                        (0, importName.length() - 1);
-                    type = toClass(importName + name);
-                }
-                if (type != null)
-                    return type;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the {@link Class} for the given name, or null if name not valid.
-     */
-    private Class toClass(String name) {
-        if (_loader == null)
-            _loader = _broker.getConfiguration().getClassResolverInstance().
-                getClassLoader(_class, _broker.getClassLoader());
-        try {
-            return Strings.toClass(name, _loader);
-        } catch (RuntimeException re) {
-        } catch (NoClassDefFoundError ncdfe) {
-        }
-        return null;
-    }
-
-    public void assertOpen() {
-        if (_broker != null)
-            _broker.assertOpen();
-    }
-
-    public void assertNotReadOnly() {
-        if (_readOnly)
-            throw new InvalidStateException(_loc.get("read-only"));
-    }
-
-    public void assertNotSerialized() {
-        if (_broker == null)
-            throw new InvalidStateException(_loc.get("serialized"));
-    }
-
-    /**
-     * Check that a candidate class has been set for the query.
-     */
-    private void assertCandidateType() {
-        if (_class == null && _storeQuery.requiresCandidateType())
-            throw new InvalidStateException(_loc.get("no-class"));
-    }
-
-    /**
-     * Check that we are in a state to be able to perform a bulk operation;
-     * also flush the current modfications if any elements are currently dirty.
-     */
-    private void assertBulkModify(StoreQuery q, StoreQuery.Executor ex, 
-        Object[] params) {
-        _broker.assertActiveTransaction();
-        if (_startIdx != 0 || _endIdx != Long.MAX_VALUE)
-            throw new UserException(_loc.get("no-modify-range"));
-        if (_resultClass != null)
-            throw new UserException(_loc.get("no-modify-resultclass"));
-        StoreQuery.Range range = new StoreQuery.Range();
-        ex.getRange(q, params, range);
-        if (range.start != 0 || range.end != Long.MAX_VALUE)
-            throw new UserException(_loc.get("no-modify-range"));
-    }
-
-    /**
-     * Checks that the passed parameters match the declarations.
-     */
-    protected void assertParameters(StoreQuery q, StoreQuery.Executor ex, 
-        Object[] params) {
-        if (!q.requiresParameterDeclarations())
-            return;
-
-        LinkedMap paramTypes = ex.getParameterTypes(q);
-        int typeCount = paramTypes.size();
-        if (typeCount > params.length)
-            throw new UserException(_loc.get("unbound-params",
-                paramTypes.keySet()));
-
-        Iterator itr = paramTypes.entrySet().iterator();
-        Map.Entry entry;
-        for (int i = 0; itr.hasNext(); i++) {
-            entry = (Map.Entry) itr.next();
-            if (((Class) entry.getValue()).isPrimitive() && params[i] == null)
-                throw new UserException(_loc.get("null-primitive-param",
-                    entry.getKey()));
-        }
-    }
-
-    public String toString() {
-        StringBuffer buf = new StringBuffer(64);
-        buf.append("Query: ").append(super.toString());
-        buf.append("; candidate class: ").append(_class);
-        buf.append("; query: ").append(_query);
-        return buf.toString();
-    }
-
-    /**
-     * Struct of compiled query properties.
-     */
-    protected static class Compilation
-        implements Serializable {
-
-        public StoreQuery.Executor memory = null;
-        public StoreQuery.Executor datastore = null;
-        public Object storeData = null;
-    }
-
-    /**
-     * Struct to hold the unparsed properties associated with a query.
-     */
-    private static class CompilationKey
-        implements Serializable {
-
-        public Class queryType = null;
-        public Class candidateType = null;
-        public boolean subclasses = true;
-        public String query = null;
-        public String language = null;
-        public Object storeKey = null;
-
-        public int hashCode() {
-            int rs = 17;
-            rs = 37 * rs + ((queryType == null) ? 0 : queryType.hashCode());
-            rs = 37 * rs + ((query == null) ? 0 : query.hashCode());
-            rs = 37 * rs + ((language == null) ? 0 : language.hashCode());
-            rs = 37 * rs + ((storeKey == null) ? 0 : storeKey.hashCode());
-            if (subclasses)
-              rs++;
-            return rs;
-        }
-
-        public boolean equals(Object other) {
-            if (other == this)
-                return true;
-            if (other == null || other.getClass() != getClass())
-                return false;
-
-            CompilationKey key = (CompilationKey) other;
-            if (key.queryType != queryType
-                || !StringUtils.equals(key.query, query)
-                || !StringUtils.equals(key.language, language))
-                return false;
-            if (key.subclasses != subclasses)
-                return false;
-            if (!ObjectUtils.equals(key.storeKey, storeKey))
-                return false;
-
-            // allow either candidate type to be null because it might be
-            // encoded in the query string, but if both are set then they
-            // must be equal
-            return key.candidateType == null || candidateType == null
-                || key.candidateType == candidateType;
-        }
-    }
-
-    /**
-     * A merged executor executes multiple Queries and returns
-     * a merged result list with the appropriate ordering (if more than
-     * one query needs to be executed). This executor has the following
-     * limitations:
-     * <ul>
-     * <li>It cannot combine aggregates.
-     * <li>It cannot collate the result lists if ordering is specified and
-     * a result string is given, but does not include the ordering
-     * criteria.</li>
-     * <li>It cannot filter duplicate results from different result lists if
-     * the result is marked distinct. This would require tracking all
-     * previous results, which would interfere with large result set
-     * handling.</li>
-     * </ul>
-     *
-     * @author Marc Prud'hommeaux
-     * @nojavadoc
-     */
-    private static class MergedExecutor
-        implements StoreQuery.Executor {
-
-        private final StoreQuery.Executor[] _executors;
-
-        public MergedExecutor(StoreQuery.Executor[] executors) {
-            _executors = executors;
-        }
-
-        public ResultObjectProvider executeQuery(StoreQuery q,
-            Object[] params, StoreQuery.Range range) {
-            if (_executors.length == 1)
-                return _executors[0].executeQuery(q, params, range);
-
-            // use lrs settings if we couldn't take advantage of the start index
-            // so that hopefully the skip to the start will be efficient
-            StoreQuery.Range ropRange = new StoreQuery.Range(0, range.end);
-            ropRange.lrs = range.lrs || (range.start > 0 && q.getContext().
-                getFetchConfiguration().getFetchBatchSize() >= 0);
-
-            // execute the query; we cannot use the lower bound of the result
-            // range, but we can take advantage of the upper bound
-            ResultObjectProvider[] rops =
-                new ResultObjectProvider[_executors.length];
-            for (int i = 0; i < _executors.length; i++)
-                rops[i] = _executors[i].executeQuery(q, params, ropRange);
-
-            boolean[] asc = _executors[0].getAscending(q);
-            ResultObjectProvider rop;
-            if (asc.length == 0)
-                rop = new MergedResultObjectProvider(rops);
-            else
-                rop = new OrderingMergedResultObjectProvider(rops, asc,
-                    _executors, q, params);
-
-            // if there is a lower bound, wrap in range rop
-            if (range.start != 0)
-                rop = new RangeResultObjectProvider(rop, range.start, 
-                    range.end);
-            return rop;
-        }
-
-        public Number executeDelete(StoreQuery q, Object[] params) {
-            long num = 0;
-            for (int i = 0; i < _executors.length; i++)
-                num += _executors[i].executeDelete(q, params).longValue();
-            return Numbers.valueOf(num);
-        }
-
-        public Number executeUpdate(StoreQuery q, Object[] params) {
-            long num = 0;
-            for (int i = 0; i < _executors.length; i++)
-                num += _executors[i].executeUpdate(q, params).longValue();
-            return Numbers.valueOf(num);
-        }
-
-        public String[] getDataStoreActions(StoreQuery q, Object[] params,
-            StoreQuery.Range range) {
-            if (_executors.length == 1)
-                return _executors[0].getDataStoreActions(q, params, range);
-
-            List results = new ArrayList(_executors.length);
-            StoreQuery.Range ropRange = new StoreQuery.Range(0L, range.end);
-            String[] actions;
-            for (int i = 0; i < _executors.length; i++) {
-                actions = _executors[i].getDataStoreActions(q, params,ropRange);
-                if (actions != null && actions.length > 0)
-                    results.addAll(Arrays.asList(actions));
-            }
-            return (String[]) results.toArray(new String[results.size()]);
-        }
-
-        public void validate(StoreQuery q) {
-            _executors[0].validate(q);
-        }
-
-        public void getRange(StoreQuery q, Object[] params, 
-            StoreQuery.Range range) {
-            _executors[0].getRange(q, params, range);
-        }
-
-        public Object getOrderingValue(StoreQuery q, Object[] params,
-            Object resultObject, int idx) {
-            // unfortunately, at this point (must be a merged rop containing
-            // other merged rops) we have no idea which executor to extract
-            // the value from
-            return _executors[0].getOrderingValue(q, params, resultObject, idx);
-        }
-
-        public boolean[] getAscending(StoreQuery q) {
-            return _executors[0].getAscending(q);
-        }
-
-        public String getAlias(StoreQuery q) {
-            return _executors[0].getAlias(q);
-        }
-
-        public String[] getProjectionAliases(StoreQuery q) {
-            return _executors[0].getProjectionAliases(q);
-        }
-
-        public Class getResultClass(StoreQuery q) {
-            return _executors[0].getResultClass(q);
-        }
-
-        public Class[] getProjectionTypes(StoreQuery q) {
-            return _executors[0].getProjectionTypes(q);
-        }
-
-        public boolean isPacking(StoreQuery q) {
-            return _executors[0].isPacking(q);
-        }
-
-        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q) {
-            if (_executors.length == 1)
-                return _executors[0].getAccessPathMetaDatas(q);
-
-            // create set of base class metadatas in access path
-            List metas = null;
-            for (int i = 0; i < _executors.length; i++)
-                metas = Filters.addAccessPathMetaDatas(metas, _executors[i].
-                    getAccessPathMetaDatas(q));
-            if (metas == null)
-                return StoreQuery.EMPTY_METAS;
-            return (ClassMetaData[]) metas.toArray
-                (new ClassMetaData[metas.size()]);
-        }
-
-        public boolean isAggregate(StoreQuery q) {
-            if (!_executors[0].isAggregate(q))
-                return false;
-
-            // we can't merge aggregates
-            throw new UnsupportedException(_loc.get("merged-aggregate",
-                q.getContext().getCandidateType(),
-                q.getContext().getQueryString()));
-        }
-
-        public int getOperation(StoreQuery q) {
-            return _executors[0].getOperation(q);
-        }
-
-        public boolean hasGrouping(StoreQuery q) {
-            return _executors[0].hasGrouping(q);
-        }
-
-        public LinkedMap getParameterTypes(StoreQuery q) {
-            return _executors[0].getParameterTypes(q);
-        }
-
-        public Map getUpdates(StoreQuery q) {
-            return _executors[0].getUpdates(q);
-        }
-    }
-
-    /**
-     * Result object provider that packs results before returning them.
-     */
-    private static class PackingResultObjectProvider
-        implements ResultObjectProvider {
-
-        private final ResultObjectProvider _delegate;
-        private final ResultPacker _packer;
-        private final int _len;
-
-        public PackingResultObjectProvider(ResultObjectProvider delegate,
-            ResultPacker packer, int resultLength) {
-            _delegate = delegate;
-            _packer = packer;
-            _len = resultLength;
-        }
-
-        public boolean supportsRandomAccess() {
-            return _delegate.supportsRandomAccess();
-        }
-
-        public void open()
-            throws Exception {
-            _delegate.open();
-        }
-
-        public Object getResultObject()
-            throws Exception {
-            Object ob = _delegate.getResultObject();
-            if (_packer == null && _len == 1)
-                return ((Object[]) ob)[0];
-            if (_packer == null)
-                return ob;
-            if (_len == 0)
-                return _packer.pack(ob);
-            return _packer.pack((Object[]) ob);
-        }
-
-        public boolean next()
-            throws Exception {
-            return _delegate.next();
-        }
-
-        public boolean absolute(int pos)
-            throws Exception {
-            return _delegate.absolute(pos);
-        }
-
-        public int size()
-            throws Exception {
-            return _delegate.size();
-        }
-
-        public void reset()
-            throws Exception {
-            _delegate.reset();
-        }
-
-        public void close()
-            throws Exception {
-            _delegate.close();
-        }
-
-        public void handleCheckedException(Exception e) {
-            _delegate.handleCheckedException(e);
-        }
-    }
-
-    /**
-     * Result list that removes itself from the query's open result list
-     * when it is closed. Public for testing.
-     */
-    public class RemoveOnCloseResultList
-        implements ResultList {
-
-        private final ResultList _res;
-
-        public RemoveOnCloseResultList(ResultList res) {
-            _res = res;
-        }
-
-        public ResultList getDelegate() {
-            return _res;
-        }
-
-        public boolean isProviderOpen() {
-            return _res.isProviderOpen();
-        }
-
-        public boolean isClosed() {
-            return _res.isClosed();
-        }
-
-        public void close() {
-            close(true);
-        }
-
-        public void close(boolean remove) {
-            if (isClosed())
-                return;
-
-            _res.close();
-            if (!remove)
-                return;
-
-            lock();
-            try {
-                // don't use standard _resultLists.remove method b/c relies on
-                // collection equality, which relies on element equality, which
-                // means we end up traversing entire result lists!
-                for (Iterator itr = _resultLists.iterator(); itr.hasNext();) {
-                    if (itr.next() == this) {
-                        itr.remove();
-                        break;
-                    }
-                }
-            } finally {
-                unlock();
-            }
-        }
-
-        public int size() {
-            return _res.size();
-        }
-
-        public boolean isEmpty() {
-            return _res.isEmpty();
-        }
-
-        public boolean contains(Object o) {
-            return _res.contains(o);
-        }
-
-        public Iterator iterator() {
-            return _res.iterator();
-        }
-
-        public Object[] toArray() {
-            return _res.toArray();
-        }
-
-        public Object[] toArray(Object[] a) {
-            return _res.toArray(a);
-        }
-
-        public boolean add(Object o) {
-            return _res.add(o);
-        }
-
-        public boolean remove(Object o) {
-            return _res.remove(o);
-        }
-
-        public boolean containsAll(Collection c) {
-            return _res.containsAll(c);
-        }
-
-        public boolean addAll(Collection c) {
-            return _res.addAll(c);
-        }
-
-        public boolean addAll(int idx, Collection c) {
-            return _res.addAll(idx, c);
-        }
-
-        public boolean removeAll(Collection c) {
-            return _res.removeAll(c);
-        }
-
-        public boolean retainAll(Collection c) {
-            return _res.retainAll(c);
-        }
-
-        public void clear() {
-            _res.clear();
-        }
-
-        public Object get(int idx) {
-            return _res.get(idx);
-        }
-
-        public Object set(int idx, Object o) {
-            return _res.set(idx, o);
-        }
-
-        public void add(int idx, Object o) {
-            _res.add(idx, o);
-        }
-
-        public Object remove(int idx) {
-            return _res.remove(idx);
-        }
-
-        public int indexOf(Object o) {
-            return _res.indexOf(o);
-        }
-
-        public int lastIndexOf(Object o) {
-            return _res.lastIndexOf(o);
-        }
-
-        public ListIterator listIterator() {
-            return _res.listIterator();
-        }
-
-        public ListIterator listIterator(int idx) {
-            return _res.listIterator(idx);
-        }
-
-        public List subList(int start, int end) {
-            return _res.subList(start, end);
-        }
-
-        public boolean equals(Object o) {
-            return _res.equals(o);
-        }
-
-        public int hashCode() {
-            return _res.hashCode();
-        }
-
-        public String toString ()
-		{
-			return _res.toString ();
-		}
-
-		public Object writeReplace ()
-		{
-			return _res;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.Serializable;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.exps.AggregateListener;
+import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.kernel.exps.Constant;
+import org.apache.openjpa.kernel.exps.Literal;
+import org.apache.openjpa.kernel.exps.Path;
+import org.apache.openjpa.kernel.exps.Val;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.rop.EagerResultList;
+import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
+import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultList;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.ReferenceHashSet;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.GeneralException;
+import org.apache.openjpa.util.InvalidStateException;
+import org.apache.openjpa.util.NonUniqueResultException;
+import org.apache.openjpa.util.NoResultException;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.UnsupportedException;
+import org.apache.openjpa.util.UserException;
+import org.apache.openjpa.util.ImplHelper;
+import serp.util.Numbers;
+import serp.util.Strings;
+
+/**
+ * Implementation of the {@link Query} interface.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public class QueryImpl
+    implements Query {
+
+    private static final Localizer _loc = Localizer.forPackage(QueryImpl.class);
+
+    private final String _language;
+    private final StoreQuery _storeQuery;
+    private transient final BrokerImpl _broker;
+    private transient final Log _log;
+    private transient ClassLoader _loader = null;
+
+    // query has its own internal lock
+    private final ReentrantLock _lock;
+
+    // unparsed state
+    private Class _class = null;
+    private boolean _subclasses = true;
+    private boolean _readOnly = false;
+    private String _query = null;
+    private String _params = null;
+
+    // parsed state
+    private transient Compilation _compiled = null;
+    private transient boolean _compiling = false;
+    private transient ResultPacker _packer = null;
+
+    // candidates
+    private transient Collection _collection = null;
+    private transient Extent _extent = null;
+
+    // listeners
+    private Map _filtListeners = null;
+    private Map _aggListeners = null;
+
+    // configuration for loading objects
+    private FetchConfiguration _fc = null;
+    private boolean _ignoreChanges = false;
+    private Class _resultMappingScope = null;
+    private String _resultMappingName = null;
+
+    // these fields should only be used directly after we have a compilation,
+    // because their values may be encoded in the query string
+    private Boolean _unique = null;
+    private Class _resultClass = null;
+    private transient long _startIdx = 0;
+    private transient long _endIdx = Long.MAX_VALUE;
+    private transient boolean _rangeSet = false;
+
+    // remember the list of all the results we have returned so we
+    // can free their resources when close or closeAll is called
+    private transient final Collection _resultLists = new ReferenceHashSet
+        (ReferenceHashSet.WEAK);
+
+    /**
+     * Construct a query managed by the given broker.
+     */
+    public QueryImpl(Broker broker, String language, StoreQuery storeQuery) {
+        _broker = (BrokerImpl) broker;
+        _language = language;
+        _storeQuery = storeQuery;
+        _fc = (FetchConfiguration) broker.getFetchConfiguration().clone();
+        _log = broker.getConfiguration().getLog(OpenJPAConfiguration.LOG_QUERY);
+        _storeQuery.setContext(this);
+
+        if (_broker != null && _broker.getMultithreaded())
+            _lock = new ReentrantLock();
+        else
+            _lock = null;
+    }
+
+    /**
+     * Internal store query.
+     */
+    public StoreQuery getStoreQuery() {
+        return _storeQuery;
+    }
+
+    public Broker getBroker() {
+        return _broker;
+    }
+
+    public Query getQuery() {
+        return this;
+    }
+
+    public StoreContext getStoreContext() {
+        return _broker;
+    }
+
+    public String getLanguage() {
+        return _language;
+    }
+
+    public FetchConfiguration getFetchConfiguration() {
+        return _fc;
+    }
+
+    public String getQueryString() {
+        return _query;
+    }
+
+    public boolean getIgnoreChanges() {
+        assertOpen();
+        return _ignoreChanges;
+    }
+
+    public void setIgnoreChanges(boolean flag) {
+        lock();
+        try {
+            assertOpen();
+            // allowed modification: no read-only check
+            _ignoreChanges = flag;
+        } finally {
+            unlock();
+        }
+    }
+
+    public boolean isReadOnly() {
+        assertOpen();
+        return _readOnly;
+    }
+
+    public void setReadOnly(boolean flag) {
+        lock();
+        try {
+            assertOpen();
+            _readOnly = flag;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void addFilterListener(FilterListener listener) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            if (_filtListeners == null)
+                _filtListeners = new HashMap(5);
+            _filtListeners.put(listener.getTag(), listener);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void removeFilterListener(FilterListener listener) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            if (_filtListeners != null)
+                _filtListeners.remove(listener.getTag());
+        } finally {
+            unlock();
+        }
+    }
+
+    public Collection getFilterListeners() {
+        return (_filtListeners == null) ? Collections.EMPTY_LIST
+            : _filtListeners.values();
+    }
+
+    public FilterListener getFilterListener(String tag) {
+        // first check listeners for this query
+        if (_filtListeners != null) {
+            FilterListener listen = (FilterListener) _filtListeners.get(tag);
+            if (listen != null)
+                return listen;
+        }
+
+        // check user-defined listeners from configuration
+        FilterListener[] confListeners = _broker.getConfiguration().
+            getFilterListenerInstances();
+        for (int i = 0; i < confListeners.length; i++)
+            if (confListeners[i].getTag().equals(tag))
+                return confListeners[i];
+
+        // check store listeners
+        return _storeQuery.getFilterListener(tag);
+    }
+
+    public void addAggregateListener(AggregateListener listener) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            if (_aggListeners == null)
+                _aggListeners = new HashMap(5);
+            _aggListeners.put(listener.getTag(), listener);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void removeAggregateListener(AggregateListener listener) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            if (_aggListeners != null)
+                _aggListeners.remove(listener.getTag());
+        } finally {
+            unlock();
+        }
+    }
+
+    public Collection getAggregateListeners() {
+        return (_aggListeners == null) ? Collections.EMPTY_LIST
+            : _aggListeners.values();
+    }
+
+    public AggregateListener getAggregateListener(String tag) {
+        // first check listeners for this query
+        if (_aggListeners != null) {
+            AggregateListener listen = (AggregateListener) _aggListeners.
+                get(tag);
+            if (listen != null)
+                return listen;
+        }
+
+        // check user-defined listeners from configuration
+        AggregateListener[] confListeners = _broker.getConfiguration().
+            getAggregateListenerInstances();
+        for (int i = 0; i < confListeners.length; i++)
+            if (confListeners[i].getTag().equals(tag))
+                return confListeners[i];
+
+        // check store listeners
+        return _storeQuery.getAggregateListener(tag);
+    }
+
+    public Extent getCandidateExtent() {
+        // if just the class is set, fetch the corresponding extent; if the
+        // extent is already set but its ignore cache setting is wrong,
+        // get a new extent with the correct setting (don't modify orig extent
+        // in case the user has a reference to it and might use it)
+        lock();
+        try {
+            Class cls = getCandidateType();
+            if (_extent == null && _collection == null && _broker != null
+                && cls != null) {
+                _extent = _broker.newExtent(cls, _subclasses);
+                _extent.setIgnoreChanges(_ignoreChanges);
+            } else if (_extent != null
+                && _extent.getIgnoreChanges() != _ignoreChanges && cls != null){
+                _extent = _broker.newExtent(cls, _extent.hasSubclasses());
+                _extent.setIgnoreChanges(_ignoreChanges);
+            }
+            return _extent;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void setCandidateExtent(Extent candidateExtent) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+
+            if (candidateExtent == _extent)
+                return;
+            if (candidateExtent == null) {
+                _extent = null;
+                return;
+            }
+
+            // if extent then not collection
+            _extent = candidateExtent;
+            _collection = null;
+
+            boolean invalidate = false;
+            if (_extent.getElementType() != _class) {
+                _class = _extent.getElementType();
+                _loader = null;
+                invalidate = true;
+            }
+            if (_extent.hasSubclasses() != _subclasses) {
+                _subclasses = _extent.hasSubclasses();
+                invalidate = true;
+            }
+            if (invalidate)
+                invalidateCompilation();
+        } finally {
+            unlock();
+        }
+    }
+
+    public Collection getCandidateCollection() {
+        assertOpen();
+        return _collection;
+    }
+
+    public void setCandidateCollection(Collection candidateCollection) {
+        if (!_storeQuery.supportsInMemoryExecution())
+            throw new UnsupportedException(_loc.get("query-nosupport",
+                _language));
+
+        lock();
+        try {
+            assertOpen();
+
+            // if collection then not extent
+            _collection = candidateCollection;
+            if (_collection != null)
+                _extent = null;
+        } finally {
+            unlock();
+        }
+    }
+
+    public Class getCandidateType() {
+        lock();
+        try {
+            assertOpen();
+            if (_class != null || _compiled != null || _query == null
+                || _broker == null)
+                return _class;
+
+            // check again after compilation; maybe encoded in string
+            compileForCompilation();
+            return _class;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void setCandidateType(Class candidateClass, boolean subs) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            _class = candidateClass;
+            _subclasses = subs;
+            _loader = null;
+            invalidateCompilation();
+        } finally {
+            unlock();
+        }
+    }
+
+    public boolean hasSubclasses() {
+        return _subclasses;
+    }
+
+    public String getResultMappingName() {
+        assertOpen();
+        return _resultMappingName;
+    }
+
+    public Class getResultMappingScope() {
+        assertOpen();
+        return _resultMappingScope;
+    }
+
+    public void setResultMapping(Class scope, String name) {
+        lock();
+        try {
+            assertOpen();
+            _resultMappingScope = scope;
+            _resultMappingName = name;
+            _packer = null;
+        } finally {
+            unlock();
+        }
+    }
+
+    public boolean isUnique() {
+        lock();
+        try {
+            assertOpen();
+            if (_unique != null)
+                return _unique.booleanValue();
+            if (_query == null || _compiling || _broker == null)
+                return false;
+
+            // check again after compilation; maybe encoded in string
+            if (_compiled == null) {
+                compileForCompilation();
+                if (_unique != null)
+                    return _unique.booleanValue();
+            }
+
+            // no explicit setting; default
+            StoreQuery.Executor ex = compileForExecutor();
+            if (!ex.isAggregate(_storeQuery))
+                return false;
+            return !ex.hasGrouping(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void setUnique(boolean unique) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            _unique = (unique) ? Boolean.TRUE : Boolean.FALSE;
+        } finally {
+            unlock();
+        }
+    }
+
+    public Class getResultType() {
+        lock();
+        try {
+            assertOpen();
+            if (_resultClass != null || _compiled != null || _query == null
+                || _broker == null)
+                return _resultClass;
+
+            // check again after compilation; maybe encoded in string
+            compileForCompilation();
+            return _resultClass;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void setResultType(Class cls) {
+        lock();
+        try {
+            assertOpen();
+            // allowed modification: no read-only check
+            _resultClass = cls;
+            _packer = null;
+        } finally {
+            unlock();
+        }
+    }
+
+    public long getStartRange() {
+        assertOpen();
+        return _startIdx;
+    }
+
+    public long getEndRange() {
+        assertOpen();
+        return _endIdx;
+    }
+
+    public void setRange(long start, long end) {
+        if (start < 0 || end < 0)
+            throw new UserException(_loc.get("invalid-range",
+                String.valueOf(start), String.valueOf(end)));
+
+        if (end - start > Integer.MAX_VALUE && end != Long.MAX_VALUE)
+            throw new UserException(_loc.get("range-too-big",
+                String.valueOf(start), String.valueOf(end)));
+
+        lock();
+        try {
+            assertOpen();
+            // allowed modification: no read-only check
+            _startIdx = start;
+            _endIdx = end;
+            _rangeSet = true;
+        } finally {
+            unlock();
+        }
+    }
+
+    public String getParameterDeclaration() {
+        lock();
+        try {
+            assertOpen();
+            if (_params != null || _compiled != null || _compiling
+                || _broker == null)
+                return _params;
+
+            // check again after compilation; maybe encoded in string
+            compileForCompilation();
+            return _params;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void declareParameters(String params) {
+        if (!_storeQuery.supportsParameterDeclarations())
+            throw new UnsupportedException(_loc.get("query-nosupport",
+                _language));
+
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+            _params = StringUtils.trimToNull(params);
+            invalidateCompilation();
+        } finally {
+            unlock();
+        }
+    }
+
+    public void compile() {
+        lock();
+        try {
+            assertOpen();
+            StoreQuery.Executor ex = compileForExecutor();
+            getResultPacker(_storeQuery, ex);
+            ex.validate(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public Object getCompilation() {
+        lock();
+        try {
+            return compileForCompilation().storeData;
+        } finally {
+            unlock();
+        }
+    }
+
+    /**
+     * Compile query properties.
+     */
+    private Compilation compileForCompilation() {
+        if (_compiled != null || _compiling)
+            return _compiled;
+
+        assertNotSerialized();
+        assertOpen();
+
+        boolean readOnly = _readOnly;
+        _readOnly = false;
+        _compiling = true;
+        try {
+            _compiled = compilationFromCache();
+            return _compiled;
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            _compiling = false;
+            _readOnly = readOnly;
+        }
+    }
+
+    /**
+     * Find the cached compilation for the current query, creating one if it
+     * does not exist.
+     */
+    protected Compilation compilationFromCache() {
+        Map compCache =
+            _broker.getConfiguration().getQueryCompilationCacheInstance();
+        if (compCache == null) {
+            return newCompilation();
+        } else {
+            CompilationKey key = new CompilationKey();
+            key.queryType = _storeQuery.getClass();
+            key.candidateType = getCandidateType();
+            key.subclasses = hasSubclasses();
+            key.query = getQueryString();
+            key.language = getLanguage();
+            key.storeKey = _storeQuery.newCompilationKey();
+            Compilation comp = (Compilation) compCache.get(key);
+
+            // parse declarations if needed
+            boolean cache = false;
+            if (comp == null) {
+                comp = newCompilation();
+                // only cache those queries that can be compiled
+                cache = comp.storeData != null;
+            } else
+                _storeQuery.populateFromCompilation(comp.storeData);
+
+            // cache parsed state if needed
+            if (cache)
+                compCache.put(key, comp);
+            return comp;
+        }
+    }
+    
+    /**
+     * Create and populate a new compilation.
+     */
+    private Compilation newCompilation() {
+        Compilation comp = new Compilation();
+        comp.storeData = _storeQuery.newCompilation();
+        _storeQuery.populateFromCompilation(comp.storeData);
+        return comp;
+    }
+
+    /**
+     * Compile for execution, choosing between datastore and in-mem
+     * compilation based on what we support and our settings.
+     */
+    private StoreQuery.Executor compileForExecutor() {
+        Compilation comp = compileForCompilation();
+        if (_collection == null) {
+            if (comp.datastore != null)
+                return comp.datastore;
+            if (comp.memory != null)
+                return comp.memory;
+            if (_storeQuery.supportsDataStoreExecution())
+                return compileForDataStore(comp);
+            return compileForInMemory(comp);
+        }
+
+        if (comp.memory != null)
+            return comp.memory;
+        if (comp.datastore != null)
+            return comp.datastore;
+        if (_storeQuery.supportsInMemoryExecution())
+            return compileForInMemory(comp);
+        return compileForDataStore(comp);
+    }
+
+    /**
+     * Create an expression tree for datastore execution.
+     */
+    private StoreQuery.Executor compileForDataStore(Compilation comp) {
+        if (comp.datastore == null)
+            comp.datastore = createExecutor(false);
+        return comp.datastore;
+    }
+
+    /**
+     * Create an expression tree for in-memory execution.
+     */
+    private StoreQuery.Executor compileForInMemory(Compilation comp) {
+        if (comp.memory == null)
+            comp.memory = createExecutor(true);
+        return comp.memory;
+    }
+
+    /**
+     * Return a query executor of the proper type.
+     */
+    private StoreQuery.Executor createExecutor(boolean inMem) {
+        assertCandidateType();
+
+        MetaDataRepository repos = _broker.getConfiguration().
+            getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(_class,
+            _broker.getClassLoader(), false);
+
+        ClassMetaData[] metas;
+        if (_class == null || _storeQuery.supportsAbstractExecutors())
+            metas = new ClassMetaData[]{ meta };
+        else if (_subclasses && (meta == null || meta.isManagedInterface()))
+            metas = repos.getImplementorMetaDatas(_class,
+                _broker.getClassLoader(), true);
+        else if (meta != null && (_subclasses || meta.isMapped()))
+            metas = new ClassMetaData[]{ meta };
+        else
+            metas = StoreQuery.EMPTY_METAS;
+
+        if (metas.length == 0)
+            throw new UserException(_loc.get("no-impls", _class));
+        try {
+            if (metas.length == 1) {
+                if (inMem)
+                    return _storeQuery.newInMemoryExecutor(metas[0],
+                        _subclasses);
+                return _storeQuery.newDataStoreExecutor(metas[0], _subclasses);
+            }
+
+            // multiple implementors
+            StoreQuery.Executor[] es = new StoreQuery.Executor[metas.length];
+            for (int i = 0; i < es.length; i++) {
+                if (inMem)
+                    es[i] = _storeQuery.newInMemoryExecutor(metas[i], true);
+                else
+                    es[i] = _storeQuery.newDataStoreExecutor(metas[i], true);
+            }
+            return new MergedExecutor(es);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+    }
+
+    /**
+     * Clear any compilation, forcing this query to be recompiled
+     * next time it's executed. This should be invoked whenever any
+     * state changes that would cause the underlying query
+     * representation to change.
+     *
+     * @since 0.3.0
+     */
+    private boolean invalidateCompilation() {
+        if (_compiling)
+            return false;
+        _storeQuery.invalidateCompilation();
+        _compiled = null;
+        _packer = null;
+        return true;
+    }
+
+    public Object execute() {
+        return execute((Object[]) null);
+    }
+
+    public Object execute(Object[] params) {
+        return execute(OP_SELECT, params);
+    }
+
+    public Object execute(Map params) {
+        return execute(OP_SELECT, params);
+    }
+
+    private Object execute(int operation, Object[] params) {
+        if (params == null)
+            params = StoreQuery.EMPTY_OBJECTS;
+
+        lock();
+        try {
+            assertNotSerialized();
+            _broker.beginOperation(true);
+            try {
+                assertOpen();
+                _broker.assertNontransactionalRead();
+
+                // get executor
+                Compilation comp = compileForCompilation();
+                StoreQuery.Executor ex = (isInMemory(operation))
+                    ? compileForInMemory(comp) : compileForDataStore(comp);
+
+                assertParameters(_storeQuery, ex, params);
+                if (_log.isTraceEnabled())
+                    logExecution(operation, ex.getParameterTypes(_storeQuery),
+                        params);
+
+                if (operation == OP_SELECT)
+                    return execute(_storeQuery, ex, params);
+                if (operation == OP_DELETE)
+                    return delete(_storeQuery, ex, params);
+                if (operation == OP_UPDATE)
+                    return update(_storeQuery, ex, params);
+                throw new UnsupportedException();
+            } catch (OpenJPAException ke) {
+                throw ke;
+            } catch (Exception e) {
+                throw new UserException(e);
+            } finally {
+                _broker.endOperation();
+            }
+        }
+        finally {
+            unlock();
+        }
+    }
+
+    private Object execute(int operation, Map params) {
+        if (params == null)
+            params = Collections.EMPTY_MAP;
+
+        lock();
+        try {
+            _broker.beginOperation(true);
+            try {
+                assertNotSerialized();
+                assertOpen();
+                _broker.assertNontransactionalRead();
+
+                // get executor
+                Compilation comp = compileForCompilation();
+                StoreQuery.Executor ex = (isInMemory(operation))
+                    ? compileForInMemory(comp) : compileForDataStore(comp);
+
+                Object[] arr = (params.isEmpty()) ? StoreQuery.EMPTY_OBJECTS :
+                    toParameterArray(ex.getParameterTypes(_storeQuery), params);
+                assertParameters(_storeQuery, ex, arr);
+                if (_log.isTraceEnabled())
+                    logExecution(operation, params);
+
+                if (operation == OP_SELECT)
+                    return execute(_storeQuery, ex, arr);
+                if (operation == OP_DELETE)
+                    return delete(_storeQuery, ex, arr);
+                if (operation == OP_UPDATE)
+                    return update(_storeQuery, ex, arr);
+                throw new UnsupportedException();
+            } catch (OpenJPAException ke) {
+                throw ke;
+            } catch (Exception e) {
+                throw new UserException(e);
+            } finally {
+                _broker.endOperation();
+            }
+        }
+        finally {
+            unlock();
+        }
+    }
+
+    public long deleteAll() {
+        return deleteAll((Object[]) null);
+    }
+
+    public long deleteAll(Object[] params) {
+        return ((Number) execute(OP_DELETE, params)).longValue();
+    }
+
+    public long deleteAll(Map params) {
+        return ((Number) execute(OP_DELETE, params)).longValue();
+    }
+
+    public long updateAll() {
+        return updateAll((Object[]) null);
+    }
+
+    public long updateAll(Object[] params) {
+        return ((Number) execute(OP_UPDATE, params)).longValue();
+    }
+
+    public long updateAll(Map params) {
+        return ((Number) execute(OP_UPDATE, params)).longValue();
+    }
+
+    private Object[] toParameterArray(LinkedMap paramTypes, Map params) {
+        if (params == null || params.isEmpty())
+            return StoreQuery.EMPTY_OBJECTS;
+
+        Object[] arr = new Object[params.size()];
+        Map.Entry entry;
+        Object key;
+        int idx;
+        int base = -1;
+        for (Iterator itr = params.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            key = entry.getKey();
+            idx = (paramTypes == null) ? -1 : paramTypes.indexOf(key);
+
+            // allow positional parameters and natural order parameters
+            if (idx != -1)
+                arr[idx] = entry.getValue();
+            else if (key instanceof Number) {
+                if (base == -1)
+                    base = positionalParameterBase(params.keySet());
+                arr[((Number) key).intValue() - base] = entry.getValue();
+            } else
+                throw new UserException(_loc.get("bad-param-name", key));
+        }
+        return arr;
+    }
+
+    /**
+     * Return the base (generally 0 or 1) to use for positional parameters.
+     */
+    private static int positionalParameterBase(Collection params) {
+        int low = Integer.MAX_VALUE;
+        Object obj;
+        int val;
+        for (Iterator itr = params.iterator(); itr.hasNext();) {
+            obj = itr.next();
+            if (!(obj instanceof Number))
+                return 0; // use 0 base when params are mixed types
+
+            val = ((Number) obj).intValue();
+            if (val == 0)
+                return val;
+            if (val < low)
+                low = val;
+        }
+        return low;
+    }
+
+    /**
+     * Return whether we should execute this query in memory.
+     */
+    private boolean isInMemory(int operation) {
+        // if there are any dirty instances in the current trans that are
+        // involved in this query, we have to execute in memory or flush
+        boolean inMem = !_storeQuery.supportsDataStoreExecution()
+            || _collection != null;
+        if (!inMem && (!_ignoreChanges || operation != OP_SELECT)
+            && _broker.isActive() && isAccessPathDirty()) {
+            int flush = _fc.getFlushBeforeQueries();
+            if ((flush == FLUSH_TRUE
+                || (flush == FLUSH_WITH_CONNECTION && _broker.hasConnection())
+                || operation != OP_SELECT
+                || !_storeQuery.supportsInMemoryExecution())
+                && _broker.getConfiguration().supportedOptions().
+                contains(OpenJPAConfiguration.OPTION_INC_FLUSH)) {
+                _broker.flush();
+            } else {
+                if (_log.isInfoEnabled())
+                    _log.info(_loc.get("force-in-mem", _class));
+                inMem = true;
+            }
+        }
+
+        if (inMem && !_storeQuery.supportsInMemoryExecution())
+            throw new InvalidStateException(_loc.get("cant-exec-inmem",
+                _language));
+        return inMem;
+    }
+
+    /**
+     * Execute the query using the given compilation, executor, and parameter
+     * values. All other execute methods delegate to this one or to
+     * {@link #execute(StoreQuery.Executor,Map)} after validation and locking.
+     */
+    private Object execute(StoreQuery q, StoreQuery.Executor ex, 
+        Object[] params)
+        throws Exception {
+        // if this is an impossible result range, return null / empty list
+        StoreQuery.Range range = new StoreQuery.Range(_startIdx, _endIdx);
+        if (!_rangeSet)
+            ex.getRange(q, params, range);
+        if (range.start >= range.end)
+            return emptyResult(q, ex);
+
+        // execute; if we have a result class or we have only one result
+        // and so need to remove it from its array, wrap in a packing rop
+        range.lrs = isLRS(range.start, range.end);
+        ResultObjectProvider rop = ex.executeQuery(q, params, range);
+        try {
+            return toResult(q, ex, rop, range);
+        } catch (Exception e) {
+            if (rop != null)
+                try { rop.close(); } catch (Exception e2) {}
+            throw e;
+        }
+    }
+
+    /**
+     * Delete the query using the given executor, and parameter
+     * values. All other execute methods delegate to this one or to
+     * {@link #delete(StoreQuery.Executor,Map)} after validation and locking.
+     * The return value will be a Number indicating the number of
+     * instances deleted.
+     */
+    private Number delete(StoreQuery q, StoreQuery.Executor ex, Object[] params)
+        throws Exception {
+        assertBulkModify(q, ex, params);
+        return ex.executeDelete(q, params);
+    }
+
+    public Number deleteInMemory(StoreQuery q, StoreQuery.Executor executor,
+        Object[] params) {
+        try {
+            Object o = execute(q, executor, params);
+            if (!(o instanceof Collection))
+                o = Collections.singleton(o);
+
+            int size = 0;
+            for (Iterator i = ((Collection) o).iterator(); i.hasNext(); size++)
+                _broker.delete(i.next(), null);
+            return Numbers.valueOf(size);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new UserException(e);
+        }
+    }
+
+    /**
+     * Update the query using the given compilation, executor, and parameter
+     * values. All other execute methods delegate to this one or to
+     * {@link #update(StoreQuery.Executor,Map)} after validation and locking.
+     * The return value will be a Number indicating the number of
+     * instances updated.
+     */
+    private Number update(StoreQuery q, StoreQuery.Executor ex, Object[] params)
+        throws Exception {
+        assertBulkModify(q, ex, params);
+        return ex.executeUpdate(q, params);
+    }
+
+    public Number updateInMemory(StoreQuery q, StoreQuery.Executor executor,
+        Object[] params) {
+        try {
+            Object o = execute(q, executor, params);
+            if (!(o instanceof Collection))
+                o = Collections.singleton(o);
+
+            int size = 0;
+            for (Iterator i = ((Collection) o).iterator(); i.hasNext(); size++)
+                updateInMemory(i.next(), params, q);
+            return Numbers.valueOf(size);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new UserException(e);
+        }
+    }
+
+    /**
+     * Set the values for the updates in memory.
+     *
+     * @param ob the persistent instance to change
+     * @param params the parameters passed to the query
+     */
+    private void updateInMemory(Object ob, Object[] params, StoreQuery q) {
+        for (Iterator it = getUpdates().entrySet().iterator();
+            it.hasNext();) {
+            Map.Entry e = (Map.Entry) it.next();
+            Path path = (Path) e.getKey();
+            FieldMetaData fmd = (FieldMetaData) path.last();
+            OpenJPAStateManager sm = _broker.getStateManager(ob);
+
+            Object val;
+            Object value = e.getValue();
+            if (value instanceof Val) {
+                val = ((Val) value).
+                    evaluate(ob, null, getStoreContext(), params);
+            } else if (value instanceof Literal) {
+                val = ((Literal) value).getValue();
+            } else if (value instanceof Constant) {
+                val = ((Constant) value).getValue(params);
+            } else {
+                try {
+                    val = q.evaluate(value, ob, params, sm);
+                } catch (UnsupportedException e1) {
+                    throw new UserException(_loc.get("fail-to-get-update-value"));
+                }
+            }
+
+            int i = fmd.getIndex();
+            PersistenceCapable into = ImplHelper.toPersistenceCapable(ob,
+                _broker.getConfiguration());
+
+            // set the actual field in the instance
+            int set = OpenJPAStateManager.SET_USER;
+            switch (fmd.getDeclaredTypeCode()) {
+                case JavaTypes.BOOLEAN:
+                    sm.settingBooleanField(into, i, sm.fetchBooleanField(i),
+                        val == null ? false : ((Boolean) val).booleanValue(),
+                        set);
+                    break;
+                case JavaTypes.BYTE:
+                    sm.settingByteField(into, i, sm.fetchByteField(i),
+                        val == null ? 0 : ((Number) val).byteValue(), set);
+                    break;
+                case JavaTypes.CHAR:
+                    sm.settingCharField(into, i, sm.fetchCharField(i),
+                        val == null ? 0 : val.toString().charAt(0), set);
+                    break;
+                case JavaTypes.DOUBLE:
+                    sm.settingDoubleField(into, i, sm.fetchDoubleField(i),
+                        val == null ? 0 : ((Number) val).doubleValue(), set);
+                    break;
+                case JavaTypes.FLOAT:
+                    sm.settingFloatField(into, i, sm.fetchFloatField(i),
+                        val == null ? 0 : ((Number) val).floatValue(), set);
+                    break;
+                case JavaTypes.INT:
+                    sm.settingIntField(into, i, sm.fetchIntField(i),
+                        val == null ? 0 : ((Number) val).intValue(), set);
+                    break;
+                case JavaTypes.LONG:
+                    sm.settingLongField(into, i, sm.fetchLongField(i),
+                        val == null ? 0 : ((Number) val).longValue(), set);
+                    break;
+                case JavaTypes.SHORT:
+                    sm.settingShortField(into, i, sm.fetchShortField(i),
+                        val == null ? 0 : ((Number) val).shortValue(), set);
+                    break;
+                case JavaTypes.STRING:
+                    sm.settingStringField(into, i, sm.fetchStringField(i),
+                        val == null ? null : val.toString(), set);
+                    break;
+                case JavaTypes.DATE:
+                case JavaTypes.NUMBER:
+                case JavaTypes.BOOLEAN_OBJ:
+                case JavaTypes.BYTE_OBJ:
+                case JavaTypes.CHAR_OBJ:
+                case JavaTypes.DOUBLE_OBJ:
+                case JavaTypes.FLOAT_OBJ:
+                case JavaTypes.INT_OBJ:
+                case JavaTypes.LONG_OBJ:
+                case JavaTypes.SHORT_OBJ:
+                case JavaTypes.BIGDECIMAL:
+                case JavaTypes.BIGINTEGER:
+                case JavaTypes.LOCALE:
+                case JavaTypes.OBJECT:
+                case JavaTypes.OID:
+                    sm.settingObjectField(into, i, sm.fetchObjectField(i), val,
+                        set);
+                    break;
+                default:
+                    throw new UserException(_loc.get("only-update-primitives"));
+            }
+        }
+    }
+
+    /**
+     * Trace log that the query is executing.
+     */
+    private void logExecution(int op, LinkedMap types, Object[] params) {
+        Map pmap = Collections.EMPTY_MAP;
+        if (params.length > 0) {
+            pmap = new HashMap((int) (params.length * 1.33 + 1));
+            if (types != null && types.size() == params.length) {
+                int i = 0;
+                for (Iterator itr = types.keySet().iterator(); itr.hasNext();)
+                    pmap.put(itr.next(), params[i++]);
+            } else {
+                for (int i = 0; i < params.length; i++)
+                    pmap.put(String.valueOf(i), params[i]);
+            }
+        }
+        logExecution(op, pmap);
+    }
+
+    /**
+     * Trace log that the query is executing.
+     */
+    private void logExecution(int op, Map params) {
+        String s = _query;
+        if (StringUtils.isEmpty(s))
+            s = toString();
+
+        String msg = "executing-query";
+        if (!params.isEmpty())
+            msg += "-with-params";
+
+        _log.trace(_loc.get(msg, s, params));
+    }
+
+    /**
+     * Return whether this should be treated as a potential large result set.
+     */
+    private boolean isLRS(long start, long end) {
+        long range = end - start;
+        return _fc.getFetchBatchSize() >= 0
+            && !(range <= _fc.getFetchBatchSize()
+            || (_fc.getFetchBatchSize() == 0 && range <= 50));
+    }
+
+    /**
+     * Return the query result for the given result object provider.
+     */
+    protected Object toResult(StoreQuery q, StoreQuery.Executor ex, 
+        ResultObjectProvider rop, StoreQuery.Range range)
+        throws Exception {
+        // pack projections if necessary
+        String[] aliases = ex.getProjectionAliases(q);
+        if (!ex.isPacking(q)) {
+            ResultPacker packer = getResultPacker(q, ex);
+            if (packer != null || aliases.length == 1)
+                rop = new PackingResultObjectProvider(rop, packer,
+                    aliases.length);
+        }
+
+        // if single result, extract it
+        if (_unique == Boolean.TRUE || (aliases.length > 0
+            && !ex.hasGrouping(q) && ex.isAggregate(q)))
+            return singleResult(rop, range);
+
+        // now that we've executed the query, we can call isAggregate and
+        // hasGrouping efficiently
+        boolean detach = (_broker.getAutoDetach() &
+            AutoDetach.DETACH_NONTXREAD) > 0 && !_broker.isActive();
+        boolean lrs = range.lrs && !ex.isAggregate(q) && !ex.hasGrouping(q);
+        ResultList res = (!detach && lrs) ? _fc.newResultList(rop)
+            : new EagerResultList(rop);
+
+        _resultLists.add(decorateResultList(res));
+        return res;
+    }
+
+    /**
+     * Optionally decorate the native result.
+     */
+    protected ResultList decorateResultList(ResultList res) {
+        return new RemoveOnCloseResultList(res);
+    }
+
+    /**
+     * Return a result packer for this projection, or null.
+     */
+    private ResultPacker getResultPacker(StoreQuery q, StoreQuery.Executor ex) {
+        if (_packer != null)
+            return _packer;
+
+        Class resultClass = (_resultClass != null) ? _resultClass
+            : ex.getResultClass(q);
+        if (resultClass == null)
+            return null;
+
+        String[] aliases = ex.getProjectionAliases(q);
+        if (aliases.length == 0) {
+            // result class but no result; means candidate is being set
+            // into some result class
+            _packer = new ResultPacker(_class, getAlias(), resultClass);
+        } else if (resultClass != null) {
+            // projection
+            Class[] types = ex.getProjectionTypes(q);
+            _packer = new ResultPacker(types, aliases, resultClass);
+        }
+        return _packer;
+    }
+
+    /**
+     * Create an empty result for this query.
+     */
+    private Object emptyResult(StoreQuery q, StoreQuery.Executor ex) {
+        if (_unique == Boolean.TRUE || (_unique == null
+            && !ex.hasGrouping(q) && ex.isAggregate(q)))
+            return null;
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Extract an expected single result from the given provider. Used when
+     * the result is an ungrouped aggregate or the unique flag is set to true.
+     */
+    private Object singleResult(ResultObjectProvider rop, 
+        StoreQuery.Range range)
+        throws Exception {
+        rop.open();
+        try {
+            // move to expected result
+            boolean next = rop.next();
+
+            // extract single result; throw an exception if multiple results
+            // match and not constrainted by range, or if a unique query with
+            // no results
+            Object single = null;
+            if (next) {
+                single = rop.getResultObject();
+                if (range.end != range.start + 1 && rop.next())
+                    throw new NonUniqueResultException(_loc.get("not-unique",
+                        _class, _query));
+            } else if (_unique == Boolean.TRUE)
+                throw new NoResultException(_loc.get("no-result", 
+                    _class, _query));
+
+            // if unique set to false, use collection
+            if (_unique == Boolean.FALSE) {
+                if (!next)
+                    return Collections.EMPTY_LIST;
+                // Collections.singletonList is JDK 1.3, so...
+                return Arrays.asList(new Object[]{ single });
+            }
+            
+            // return single result
+            return single;
+        } finally {
+            rop.close();
+        }
+    }
+
+    /**
+     * Calculates whether the access path of this query intersects with
+     * any dirty objects in the transaction.
+     */
+    private boolean isAccessPathDirty() {
+        return isAccessPathDirty(_broker, getAccessPathMetaDatas());
+    }
+
+    public static boolean isAccessPathDirty(Broker broker,
+        ClassMetaData[] accessMetas) {
+        Collection persisted = broker.getPersistedTypes();
+        Collection updated = broker.getUpdatedTypes();
+        Collection deleted = broker.getDeletedTypes();
+        if (persisted.isEmpty() && updated.isEmpty() && deleted.isEmpty())
+            return false;
+
+        // if no access metas, assume every dirty object affects path just
+        // to be safe
+        if (accessMetas.length == 0)
+            return true;
+
+        // compare dirty classes to the access path classes
+        Class accClass;
+        for (int i = 0; i < accessMetas.length; i++) {
+            // shortcut if actual class is dirty
+            accClass = accessMetas[i].getDescribedType();
+            if (persisted.contains(accClass) || updated.contains(accClass)
+                || deleted.contains(accClass))
+                return true;
+
+            // check for dirty subclass
+            for (Iterator dirty = persisted.iterator(); dirty.hasNext();)
+                if (accClass.isAssignableFrom((Class) dirty.next()))
+                    return true;
+            for (Iterator dirty = updated.iterator(); dirty.hasNext();)
+                if (accClass.isAssignableFrom((Class) dirty.next()))
+                    return true;
+            for (Iterator dirty = deleted.iterator(); dirty.hasNext();)
+                if (accClass.isAssignableFrom((Class) dirty.next()))
+                    return true;
+        }
+
+        // no intersection
+        return false;
+    }
+
+    public void closeAll() {
+        closeResults(true);
+    }
+
+    public void closeResources() {
+        closeResults(false);
+    }
+
+    /**
+     * Close open results.
+     */
+    private void closeResults(boolean force) {
+        lock();
+        try {
+            assertOpen();
+
+            RemoveOnCloseResultList res;
+            for (Iterator itr = _resultLists.iterator(); itr.hasNext();) {
+                res = (RemoveOnCloseResultList) itr.next();
+                if (force || res.isProviderOpen())
+                    res.close(false);
+            }
+            _resultLists.clear();
+        } finally {
+            unlock();
+        }
+    }
+
+    public String[] getDataStoreActions(Map params) {
+        if (params == null)
+            params = Collections.EMPTY_MAP;
+
+        lock();
+        try {
+            assertNotSerialized();
+            assertOpen();
+
+            StoreQuery.Executor ex = compileForExecutor();
+            Object[] arr = toParameterArray(ex.getParameterTypes(_storeQuery),
+                params);
+            assertParameters(_storeQuery, ex, arr);
+            StoreQuery.Range range = new StoreQuery.Range(_startIdx, _endIdx);
+            if (!_rangeSet)
+                ex.getRange(_storeQuery, arr, range);
+            return ex.getDataStoreActions(_storeQuery, arr, range);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (Exception e) {
+            throw new UserException(e);
+        } finally {
+            unlock();
+        }
+    }
+
+    public boolean setQuery(Object query) {
+        lock();
+        try {
+            assertOpen();
+            assertNotReadOnly();
+
+            if (query == null || query instanceof String) {
+                invalidateCompilation();
+                _query = (String) query;
+                if (_query != null)
+                    _query = _query.trim();
+                return true;
+            }
+            if (!(query instanceof QueryImpl))
+                return _storeQuery.setQuery(query);
+
+            // copy all non-transient state from the given query
+            invalidateCompilation();
+            QueryImpl q = (QueryImpl) query;
+            _class = q._class;
+            _subclasses = q._subclasses;
+            _query = q._query;
+            _ignoreChanges = q._ignoreChanges;
+            _unique = q._unique;
+            _resultClass = q._resultClass;
+            _params = q._params;
+            _resultMappingScope = q._resultMappingScope;
+            _resultMappingName = q._resultMappingName;
+            _readOnly = q._readOnly;
+
+            // don't share mutable objects
+            _fc.copy(q._fc);
+            if (q._filtListeners != null)
+                _filtListeners = new HashMap(q._filtListeners);
+            if (q._aggListeners != null)
+                _aggListeners = new HashMap(q._aggListeners);
+            return true;
+        } finally {
+            unlock();
+        }
+    }
+
+    public String getAlias() {
+        lock();
+        try {
+            String alias = compileForExecutor().getAlias(_storeQuery);
+            if (alias == null)
+                alias = Strings.getClassName(_class);
+            return alias;
+        } finally {
+            unlock();
+        }
+    }
+
+    public String[] getProjectionAliases() {
+        lock();
+        try {
+            return compileForExecutor().getProjectionAliases(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public Class[] getProjectionTypes() {
+        lock();
+        try {
+            return compileForExecutor().getProjectionTypes(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public int getOperation() {
+        lock();
+        try {
+            return compileForExecutor().getOperation(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public boolean isAggregate() {
+        lock();
+        try {
+            return compileForExecutor().isAggregate(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public boolean hasGrouping() {
+        lock();
+        try {
+            return compileForExecutor().hasGrouping(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public ClassMetaData[] getAccessPathMetaDatas() {
+        lock();
+        try {
+            ClassMetaData[] metas = compileForExecutor().
+                getAccessPathMetaDatas(_storeQuery);
+            return (metas == null) ? StoreQuery.EMPTY_METAS : metas;
+        } finally {
+            unlock();
+        }
+    }
+
+    public LinkedMap getParameterTypes() {
+        lock();
+        try {
+            return compileForExecutor().getParameterTypes(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public Map getUpdates() {
+        lock();
+        try {
+            return compileForExecutor().getUpdates(_storeQuery);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    public void unlock() {
+        if (_lock != null && _lock.isLocked())
+            _lock.unlock();
+    }
+
+    /////////
+    // Utils
+    /////////
+
+    public Class classForName(String name, String[] imports) {
+        // full class name or primitive type?
+        Class type = toClass(name);
+        if (type != null)
+            return type;
+
+        // first check the aliases map in the MetaDataRepository
+        ClassLoader loader = (_class == null) ? _loader
+            : (ClassLoader) AccessController.doPrivileged(
+                J2DoPrivHelper.getClassLoaderAction(_class)); 
+        ClassMetaData meta = _broker.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(name, loader, false);
+        if (meta != null)
+            return meta.getDescribedType();
+
+        // try the name in the package of the candidate class
+        if (_class != null) {
+            String fullName = _class.getName().substring
+                (0, _class.getName().lastIndexOf('.') + 1) + name;
+            type = toClass(fullName);
+            if (type != null)
+                return type;
+        }
+
+        // try java.lang
+        type = toClass("java.lang." + name);
+        if (type != null)
+            return type;
+
+        // try each import
+        if (imports != null && imports.length > 0) {
+            String dotName = "." + name;
+            String importName;
+            for (int i = 0; i < imports.length; i++) {
+                importName = imports[i];
+
+                // full class name import
+                if (importName.endsWith(dotName))
+                    type = toClass(importName);
+                    // wildcard; strip to package
+                else if (importName.endsWith(".*")) {
+                    importName = importName.substring
+                        (0, importName.length() - 1);
+                    type = toClass(importName + name);
+                }
+                if (type != null)
+                    return type;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return the {@link Class} for the given name, or null if name not valid.
+     */
+    private Class toClass(String name) {
+        if (_loader == null)
+            _loader = _broker.getConfiguration().getClassResolverInstance().
+                getClassLoader(_class, _broker.getClassLoader());
+        try {
+            return Strings.toClass(name, _loader);
+        } catch (RuntimeException re) {
+        } catch (NoClassDefFoundError ncdfe) {
+        }
+        return null;
+    }
+
+    public void assertOpen() {
+        if (_broker != null)
+            _broker.assertOpen();
+    }
+
+    public void assertNotReadOnly() {
+        if (_readOnly)
+            throw new InvalidStateException(_loc.get("read-only"));
+    }
+
+    public void assertNotSerialized() {
+        if (_broker == null)
+            throw new InvalidStateException(_loc.get("serialized"));
+    }
+
+    /**
+     * Check that a candidate class has been set for the query.
+     */
+    private void assertCandidateType() {
+        if (_class == null && _storeQuery.requiresCandidateType())
+            throw new InvalidStateException(_loc.get("no-class"));
+    }
+
+    /**
+     * Check that we are in a state to be able to perform a bulk operation;
+     * also flush the current modfications if any elements are currently dirty.
+     */
+    private void assertBulkModify(StoreQuery q, StoreQuery.Executor ex, 
+        Object[] params) {
+        _broker.assertActiveTransaction();
+        if (_startIdx != 0 || _endIdx != Long.MAX_VALUE)
+            throw new UserException(_loc.get("no-modify-range"));
+        if (_resultClass != null)
+            throw new UserException(_loc.get("no-modify-resultclass"));
+        StoreQuery.Range range = new StoreQuery.Range();
+        ex.getRange(q, params, range);
+        if (range.start != 0 || range.end != Long.MAX_VALUE)
+            throw new UserException(_loc.get("no-modify-range"));
+    }
+
+    /**
+     * Checks that the passed parameters match the declarations.
+     */
+    protected void assertParameters(StoreQuery q, StoreQuery.Executor ex, 
+        Object[] params) {
+        if (!q.requiresParameterDeclarations())
+            return;
+
+        LinkedMap paramTypes = ex.getParameterTypes(q);
+        int typeCount = paramTypes.size();
+        if (typeCount > params.length)
+            throw new UserException(_loc.get("unbound-params",
+                paramTypes.keySet()));
+
+        Iterator itr = paramTypes.entrySet().iterator();
+        Map.Entry entry;
+        for (int i = 0; itr.hasNext(); i++) {
+            entry = (Map.Entry) itr.next();
+            if (((Class) entry.getValue()).isPrimitive() && params[i] == null)
+                throw new UserException(_loc.get("null-primitive-param",
+                    entry.getKey()));
+        }
+    }
+
+    public String toString() {
+        StringBuffer buf = new StringBuffer(64);
+        buf.append("Query: ").append(super.toString());
+        buf.append("; candidate class: ").append(_class);
+        buf.append("; query: ").append(_query);
+        return buf.toString();
+    }
+
+    /**
+     * Struct of compiled query properties.
+     */
+    protected static class Compilation
+        implements Serializable {
+
+        public StoreQuery.Executor memory = null;
+        public StoreQuery.Executor datastore = null;
+        public Object storeData = null;
+    }
+
+    /**
+     * Struct to hold the unparsed properties associated with a query.
+     */
+    private static class CompilationKey
+        implements Serializable {
+
+        public Class queryType = null;
+        public Class candidateType = null;
+        public boolean subclasses = true;
+        public String query = null;
+        public String language = null;
+        public Object storeKey = null;
+
+        public int hashCode() {
+            int rs = 17;
+            rs = 37 * rs + ((queryType == null) ? 0 : queryType.hashCode());
+            rs = 37 * rs + ((query == null) ? 0 : query.hashCode());
+            rs = 37 * rs + ((language == null) ? 0 : language.hashCode());
+            rs = 37 * rs + ((storeKey == null) ? 0 : storeKey.hashCode());
+            if (subclasses)
+              rs++;
+            return rs;
+        }
+
+        public boolean equals(Object other) {
+            if (other == this)
+                return true;
+            if (other == null || other.getClass() != getClass())
+                return false;
+
+            CompilationKey key = (CompilationKey) other;
+            if (key.queryType != queryType
+                || !StringUtils.equals(key.query, query)
+                || !StringUtils.equals(key.language, language))
+                return false;
+            if (key.subclasses != subclasses)
+                return false;
+            if (!ObjectUtils.equals(key.storeKey, storeKey))
+                return false;
+
+            // allow either candidate type to be null because it might be
+            // encoded in the query string, but if both are set then they
+            // must be equal
+            return key.candidateType == null || candidateType == null
+                || key.candidateType == candidateType;
+        }
+    }
+
+    /**
+     * A merged executor executes multiple Queries and returns
+     * a merged result list with the appropriate ordering (if more than
+     * one query needs to be executed). This executor has the following
+     * limitations:
+     * <ul>
+     * <li>It cannot combine aggregates.
+     * <li>It cannot collate the result lists if ordering is specified and
+     * a result string is given, but does not include the ordering
+     * criteria.</li>
+     * <li>It cannot filter duplicate results from different result lists if
+     * the result is marked distinct. This would require tracking all
+     * previous results, which would interfere with large result set
+     * handling.</li>
+     * </ul>
+     *
+     * @author Marc Prud'hommeaux
+     * @nojavadoc
+     */
+    private static class MergedExecutor
+        implements StoreQuery.Executor {
+
+        private final StoreQuery.Executor[] _executors;
+
+        public MergedExecutor(StoreQuery.Executor[] executors) {
+            _executors = executors;
+        }
+
+        public ResultObjectProvider executeQuery(StoreQuery q,
+            Object[] params, StoreQuery.Range range) {
+            if (_executors.length == 1)
+                return _executors[0].executeQuery(q, params, range);
+
+            // use lrs settings if we couldn't take advantage of the start index
+            // so that hopefully the skip to the start will be efficient
+            StoreQuery.Range ropRange = new StoreQuery.Range(0, range.end);
+            ropRange.lrs = range.lrs || (range.start > 0 && q.getContext().
+                getFetchConfiguration().getFetchBatchSize() >= 0);
+
+            // execute the query; we cannot use the lower bound of the result
+            // range, but we can take advantage of the upper bound
+            ResultObjectProvider[] rops =
+                new ResultObjectProvider[_executors.length];
+            for (int i = 0; i < _executors.length; i++)
+                rops[i] = _executors[i].executeQuery(q, params, ropRange);
+
+            boolean[] asc = _executors[0].getAscending(q);
+            ResultObjectProvider rop;
+            if (asc.length == 0)
+                rop = new MergedResultObjectProvider(rops);
+            else
+                rop = new OrderingMergedResultObjectProvider(rops, asc,
+                    _executors, q, params);
+
+            // if there is a lower bound, wrap in range rop
+            if (range.start != 0)
+                rop = new RangeResultObjectProvider(rop, range.start, 
+                    range.end);
+            return rop;
+        }
+
+        public Number executeDelete(StoreQuery q, Object[] params) {
+            long num = 0;
+            for (int i = 0; i < _executors.length; i++)
+                num += _executors[i].executeDelete(q, params).longValue();
+            return Numbers.valueOf(num);
+        }
+
+        public Number executeUpdate(StoreQuery q, Object[] params) {
+            long num = 0;
+            for (int i = 0; i < _executors.length; i++)
+                num += _executors[i].executeUpdate(q, params).longValue();
+            return Numbers.valueOf(num);
+        }
+
+        public String[] getDataStoreActions(StoreQuery q, Object[] params,
+            StoreQuery.Range range) {
+            if (_executors.length == 1)
+                return _executors[0].getDataStoreActions(q, params, range);
+
+            List results = new ArrayList(_executors.length);
+            StoreQuery.Range ropRange = new StoreQuery.Range(0L, range.end);
+            String[] actions;
+            for (int i = 0; i < _executors.length; i++) {
+                actions = _executors[i].getDataStoreActions(q, params,ropRange);
+                if (actions != null && actions.length > 0)
+                    results.addAll(Arrays.asList(actions));
+            }
+            return (String[]) results.toArray(new String[results.size()]);
+        }
+
+        public void validate(StoreQuery q) {
+            _executors[0].validate(q);
+        }
+
+        public void getRange(StoreQuery q, Object[] params, 
+            StoreQuery.Range range) {
+            _executors[0].getRange(q, params, range);
+        }
+
+        public Object getOrderingValue(StoreQuery q, Object[] params,
+            Object resultObject, int idx) {
+            // unfortunately, at this point (must be a merged rop containing
+            // other merged rops) we have no idea which executor to extract
+            // the value from
+            return _executors[0].getOrderingValue(q, params, resultObject, idx);
+        }
+
+        public boolean[] getAscending(StoreQuery q) {
+            return _executors[0].getAscending(q);
+        }
+
+        public String getAlias(StoreQuery q) {
+            return _executors[0].getAlias(q);
+        }
+
+        public String[] getProjectionAliases(StoreQuery q) {
+            return _executors[0].getProjectionAliases(q);
+        }
+
+        public Class getResultClass(StoreQuery q) {
+            return _executors[0].getResultClass(q);
+        }
+
+        public Class[] getProjectionTypes(StoreQuery q) {
+            return _executors[0].getProjectionTypes(q);
+        }
+
+        public boolean isPacking(StoreQuery q) {
+            return _executors[0].isPacking(q);
+        }
+
+        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q) {
+            if (_executors.length == 1)
+                return _executors[0].getAccessPathMetaDatas(q);
+
+            // create set of base class metadatas in access path
+            List metas = null;
+            for (int i = 0; i < _executors.length; i++)
+                metas = Filters.addAccessPathMetaDatas(metas, _executors[i].
+                    getAccessPathMetaDatas(q));
+            if (metas == null)
+                return StoreQuery.EMPTY_METAS;
+            return (ClassMetaData[]) metas.toArray
+                (new ClassMetaData[metas.size()]);
+        }
+
+        public boolean isAggregate(StoreQuery q) {
+            if (!_executors[0].isAggregate(q))
+                return false;
+
+            // we can't merge aggregates
+            throw new UnsupportedException(_loc.get("merged-aggregate",
+                q.getContext().getCandidateType(),
+                q.getContext().getQueryString()));
+        }
+
+        public int getOperation(StoreQuery q) {
+            return _executors[0].getOperation(q);
+        }
+
+        public boolean hasGrouping(StoreQuery q) {
+            return _executors[0].hasGrouping(q);
+        }
+
+        public LinkedMap getParameterTypes(StoreQuery q) {
+            return _executors[0].getParameterTypes(q);
+        }
+
+        public Map getUpdates(StoreQuery q) {
+            return _executors[0].getUpdates(q);
+        }
+    }
+
+    /**
+     * Result object provider that packs results before returning them.
+     */
+    private static class PackingResultObjectProvider
+        implements ResultObjectProvider {
+
+        private final ResultObjectProvider _delegate;
+        private final ResultPacker _packer;
+        private final int _len;
+
+        public PackingResultObjectProvider(ResultObjectProvider delegate,
+            ResultPacker packer, int resultLength) {
+            _delegate = delegate;
+            _packer = packer;
+            _len = resultLength;
+        }
+
+        public boolean supportsRandomAccess() {
+            return _delegate.supportsRandomAccess();
+        }
+
+        public void open()
+            throws Exception {
+            _delegate.open();
+        }
+
+        public Object getResultObject()
+            throws Exception {
+            Object ob = _delegate.getResultObject();
+            if (_packer == null && _len == 1)
+                return ((Object[]) ob)[0];
+            if (_packer == null)
+                return ob;
+            if (_len == 0)
+                return _packer.pack(ob);
+            return _packer.pack((Object[]) ob);
+        }
+
+        public boolean next()
+            throws Exception {
+            return _delegate.next();
+        }
+
+        public boolean absolute(int pos)
+            throws Exception {
+            return _delegate.absolute(pos);
+        }
+
+        public int size()
+            throws Exception {
+            return _delegate.size();
+        }
+
+        public void reset()
+            throws Exception {
+            _delegate.reset();
+        }
+
+        public void close()
+            throws Exception {
+            _delegate.close();
+        }
+
+        public void handleCheckedException(Exception e) {
+            _delegate.handleCheckedException(e);
+        }
+    }
+
+    /**
+     * Result list that removes itself from the query's open result list
+     * when it is closed. Public for testing.
+     */
+    public class RemoveOnCloseResultList
+        implements ResultList {
+
+        private final ResultList _res;
+
+        public RemoveOnCloseResultList(ResultList res) {
+            _res = res;
+        }
+
+        public ResultList getDelegate() {
+            return _res;
+        }
+
+        public boolean isProviderOpen() {
+            return _res.isProviderOpen();
+        }
+
+        public boolean isClosed() {
+            return _res.isClosed();
+        }
+
+        public void close() {
+            close(true);
+        }
+
+        public void close(boolean remove) {
+            if (isClosed())
+                return;
+
+            _res.close();
+            if (!remove)
+                return;
+
+            lock();
+            try {
+                // don't use standard _resultLists.remove method b/c relies on
+                // collection equality, which relies on element equality, which
+                // means we end up traversing entire result lists!
+                for (Iterator itr = _resultLists.iterator(); itr.hasNext();) {
+                    if (itr.next() == this) {
+                        itr.remove();
+                        break;
+                    }
+                }
+            } finally {
+                unlock();
+            }
+        }
+
+        public int size() {
+            return _res.size();
+        }
+
+        public boolean isEmpty() {
+            return _res.isEmpty();
+        }
+
+        public boolean contains(Object o) {
+            return _res.contains(o);
+        }
+
+        public Iterator iterator() {
+            return _res.iterator();
+        }
+
+        public Object[] toArray() {
+            return _res.toArray();
+        }
+
+        public Object[] toArray(Object[] a) {
+            return _res.toArray(a);
+        }
+
+        public boolean add(Object o) {
+            return _res.add(o);
+        }
+
+        public boolean remove(Object o) {
+            return _res.remove(o);
+        }
+
+        public boolean containsAll(Collection c) {
+            return _res.containsAll(c);
+        }
+
+        public boolean addAll(Collection c) {
+            return _res.addAll(c);
+        }
+
+        public boolean addAll(int idx, Collection c) {
+            return _res.addAll(idx, c);
+        }
+
+        public boolean removeAll(Collection c) {
+            return _res.removeAll(c);
+        }
+
+        public boolean retainAll(Collection c) {
+            return _res.retainAll(c);
+        }
+
+        public void clear() {
+            _res.clear();
+        }
+
+        public Object get(int idx) {
+            return _res.get(idx);
+        }
+
+        public Object set(int idx, Object o) {
+            return _res.set(idx, o);
+        }
+
+        public void add(int idx, Object o) {
+            _res.add(idx, o);
+        }
+
+        public Object remove(int idx) {
+            return _res.remove(idx);
+        }
+
+        public int indexOf(Object o) {
+            return _res.indexOf(o);
+        }
+
+        public int lastIndexOf(Object o) {
+            return _res.lastIndexOf(o);
+        }
+
+        public ListIterator listIterator() {
+            return _res.listIterator();
+        }
+
+        public ListIterator listIterator(int idx) {
+            return _res.listIterator(idx);
+        }
+
+        public List subList(int start, int end) {
+            return _res.subList(start, end);
+        }
+
+        public boolean equals(Object o) {
+            return _res.equals(o);
+        }
+
+        public int hashCode() {
+            return _res.hashCode();
+        }
+
+        public String toString ()
+		{
+			return _res.toString ();
+		}
+
+		public Object writeReplace ()
+		{
+			return _res;
+		}
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java
index 5a690e8..ccd1c21 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreQuery.java
@@ -1,325 +1,325 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.commons.collections.map.LinkedMap;
-import org.apache.openjpa.kernel.exps.AggregateListener;
-import org.apache.openjpa.kernel.exps.Constant;
-import org.apache.openjpa.kernel.exps.FilterListener;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-
-/**
- * Component that executes queries against the datastore. For
- * expression-based queries, consider subclassing
- * {@link ExpressionStoreManagerQuery}.
- *
- * @author Abe White
- * @since 0.4.0
- */
-public interface StoreQuery
-    extends QueryOperations, Serializable {
-
-    // linkedmap doesn't allow a size of 0, so use 1
-    public static final LinkedMap EMPTY_PARAMS = new LinkedMap(1, 1F);
-    public static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
-    public static final String[] EMPTY_STRINGS = new String[0];
-    public static final Object[] EMPTY_OBJECTS = new Object[0];
-    public static final Class[] EMPTY_CLASSES = new Class[0];
-    public static final boolean[] EMPTY_BOOLEANS = new boolean[0];
-
-    /**
-     * Return the query context that has been set.
-     */
-    public QueryContext getContext();
-
-    /**
-     * Set the current query context. This will be called before use.
-     */
-    public void setContext(QueryContext ctx);
-
-    /**
-     * This is invoked when the user or a facade creates a new query with
-     * an object that the system does not recognize. Return true if
-     * the object is recognized by the store, false otherwise.
-     */
-    public boolean setQuery(Object query);
-
-    /**
-     * Return the standard filter listener for the given tag, or null.
-     */
-    public FilterListener getFilterListener(String tag);
-
-    /**
-     * Return the standard filter listener for the given tag, or null.
-     */
-    public AggregateListener getAggregateListener(String tag);
-
-    /**
-     * Create a new key for caching compiled query information. May be null.
-     */
-    public Object newCompilationKey();
-
-    /**
-     * Create a new compilation for this query. May be null.
-     */
-    public Object newCompilation();
-
-    /**
-     * Populate internal data from compilation.
-     */
-    public void populateFromCompilation(Object comp);
-
-    /**
-     * Invalidate any internal compilation state.
-     */
-    public void invalidateCompilation();
-
-    /**
-     * True if this query supports datastore execution, false if it
-     * can only run in memory.
-     */
-    public boolean supportsDataStoreExecution();
-
-    /**
-     * True if this query supports in-memory execution, false if it
-     * can only run against the datastore.
-     */
-    public boolean supportsInMemoryExecution();
-
-    /**
-     * Return an executor for in-memory execution of this query.
-     * Executors must be cachable and thread safe. If this class returns
-     * true from {@link #supportsAbstractExecutors}, the given metadata
-     * will always be for the candidate class of this query, or possibly
-     * null if the candidate class is not itself persistence capable (like
-     * an interface or abstract base class). Otherwise, the given type will
-     * be a mapped class.
-     *
-     * @param subs whether to include dependent mapped subclasses in the
-     * results; independent subclasses should never be included
-     */
-    public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs);
-
-    /**
-     * Return an executor for datastore execution of this query.
-     * Executors must be cachable and thread safe. If this class returns
-     * true from {@link #supportsAbstractExecutors}, the given metadata
-     * will always be for the candidate class of this query, or possibly
-     * null if the candidate class is not itself persistence capable (like
-     * an interface or abstract base class). Otherwise, the given type will
-     * be a mapped class.
-     *
-     * @param subs whether to include dependent mapped subclasses in the
-     * results; independent subclasses should never be included
-     */
-    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs);
-
-    /**
-     * Return true if this query supports execution against abstract or
-     * interface types. Returns false by default, meaning we will only
-     * request executors for persistent classes. In this case, we will
-     * automatically combine the results of the executors for all
-     * implementing classes if we execute a query for an interface for
-     * abstract type.
-     */
-    public boolean supportsAbstractExecutors();
-
-    /**
-     * Whether this query requires a candidate class.
-     */
-    public boolean requiresCandidateType();
-
-    /**
-     * Whether this query requires parameters to be declared.
-     */
-    public boolean requiresParameterDeclarations();
-
-    /**
-     * Whether this query supports declared parameters.
-     */
-    public boolean supportsParameterDeclarations();
-
-    public Object evaluate(Object value, Object ob, Object[] params, 
-        OpenJPAStateManager sm);
-
-    /**
-     * A query result range.
-     */
-    public static class Range {
-        public long start = 0L;
-        public long end = Long.MAX_VALUE;
-        public boolean lrs = false;
-
-        public Range() {
-        }
-
-        public Range(long start, long end) {
-            this.start = start;
-            this.end = end;
-        }
-    }
-
-    /**
-     * An executor provides a uniform interface to the mechanism for executing
-     * either an in-memory or datastore query. In the common case, the
-     * {@link #executeQuery} method will be called before other methods,
-     * though this is not guaranteed.
-     *
-     * @author Marc Prud'hommeaux
-     */
-    public static interface Executor {
-
-        /**
-         * Return the result of executing this query with the given parameter
-         * values. If this query is a projection and this executor does not
-         * pack results itself, each element of the returned result object
-         * provider should be an object array containing the projection values.
-         *
-         * @param lrs true if the query result should be treated as a
-         * large result set, assuming the query is not an
-         * aggregate and does not have grouping
-         * @see #isPacking
-         */
-        public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
-            Range range);
-
-        /**
-         * Deleted the objects that result from the execution of the
-         * query, retuning the number of objects that were deleted.
-         */
-        public Number executeDelete(StoreQuery q, Object[] params);
-
-        /**
-         * Updates the objects that result from the execution of the
-         * query, retuning the number of objects that were updated.
-         */
-        public Number executeUpdate(StoreQuery q, Object[] params);
-
-        /**
-         * Return a description of the commands that will be sent to
-         * the datastore in order to execute the query.
-         */
-        public String[] getDataStoreActions(StoreQuery q, Object[] params,
-            Range range);
-
-        /**
-         * Validate components of query.
-         */
-        public void validate(StoreQuery q);
-
-        /**
-         * Mutate the given range to set any range information stored in 
-         * the query string and/or parameters.
-         */
-        public void getRange(StoreQuery q, Object[] params, Range range);
-
-        /**
-         * Extract the value of the <code>orderIndex</code>th ordering
-         * expression in {@link Query#getOrderingClauses} from the
-         * given result object. The result object will be an object from
-         * the result object provider returned from {@link #executeQuery}.
-         * This method is used when several result lists have to be merged
-         * in memory. If this exeuctor's parent query supports executors on
-         * abstract or interface classes, this method will not be used.
-         *
-         * @see StoreQuery#supportsAbstractExecutors
-         */
-        public Object getOrderingValue(StoreQuery q, Object[] params,
-            Object resultObject, int orderIndex);
-
-        /**
-         * Return the ordering direction for all ordering clauses, or empty
-         * array if none.
-         */
-        public boolean[] getAscending(StoreQuery q);
-
-        /**
-         * Return true if this executor packs projections into the result
-         * class itself. Executors for query languages that allow projections
-         * without result clauses must return true and perform the result
-         * packing themselves.
-         */
-        public boolean isPacking(StoreQuery q);
-
-        /**
-         * If this is not a projection but the candidate results are placed
-         * into a result class with an alias, return that alias.
-         */
-        public String getAlias(StoreQuery q);
-
-        /**
-         * Return the alias for each projection element, or empty array
-         * if not a projection.
-         */
-        public String[] getProjectionAliases(StoreQuery q);
-
-        /**
-         * Return the expected types of the projections used by this query,
-         * or an empty array if not a projection.
-         */
-        public Class[] getProjectionTypes(StoreQuery q);
-
-        /**
-         * Return an array of all persistent classes used in this query, or
-         * empty array if unknown.
-         */
-        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q);
-
-        /**
-         * Returns the operation this executor is meant to execute.
-         *
-         * @see QueryOperations
-         */
-        public int getOperation(StoreQuery q);
-
-        /**
-         * Return true if the compiled query is an aggregate.
-         */
-        public boolean isAggregate(StoreQuery q);
-
-        /**
-         * Whether the compiled query has grouping.
-         */
-        public boolean hasGrouping(StoreQuery q);
-
-        /**
-         * Return a map of parameter names to types. The returned
-         * {@link Map#entrySet}'s {@link Iterator} must return values in the
-         * order in which they were declared or used.
-         */
-        public LinkedMap getParameterTypes(StoreQuery q);
-
-        /**
-         * Returns the result class, if any.
-         */
-        public Class getResultClass(StoreQuery q);
-
-        /**
-         * Return a map of {@link FieldMetaData} to update
-		 * {@link Constant}s, in cases where this query is for a bulk update.
-	 	 */
-		public Map getUpdates (StoreQuery q);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.openjpa.kernel.exps.AggregateListener;
+import org.apache.openjpa.kernel.exps.Constant;
+import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+
+/**
+ * Component that executes queries against the datastore. For
+ * expression-based queries, consider subclassing
+ * {@link ExpressionStoreManagerQuery}.
+ *
+ * @author Abe White
+ * @since 0.4.0
+ */
+public interface StoreQuery
+    extends QueryOperations, Serializable {
+
+    // linkedmap doesn't allow a size of 0, so use 1
+    public static final LinkedMap EMPTY_PARAMS = new LinkedMap(1, 1F);
+    public static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
+    public static final String[] EMPTY_STRINGS = new String[0];
+    public static final Object[] EMPTY_OBJECTS = new Object[0];
+    public static final Class[] EMPTY_CLASSES = new Class[0];
+    public static final boolean[] EMPTY_BOOLEANS = new boolean[0];
+
+    /**
+     * Return the query context that has been set.
+     */
+    public QueryContext getContext();
+
+    /**
+     * Set the current query context. This will be called before use.
+     */
+    public void setContext(QueryContext ctx);
+
+    /**
+     * This is invoked when the user or a facade creates a new query with
+     * an object that the system does not recognize. Return true if
+     * the object is recognized by the store, false otherwise.
+     */
+    public boolean setQuery(Object query);
+
+    /**
+     * Return the standard filter listener for the given tag, or null.
+     */
+    public FilterListener getFilterListener(String tag);
+
+    /**
+     * Return the standard filter listener for the given tag, or null.
+     */
+    public AggregateListener getAggregateListener(String tag);
+
+    /**
+     * Create a new key for caching compiled query information. May be null.
+     */
+    public Object newCompilationKey();
+
+    /**
+     * Create a new compilation for this query. May be null.
+     */
+    public Object newCompilation();
+
+    /**
+     * Populate internal data from compilation.
+     */
+    public void populateFromCompilation(Object comp);
+
+    /**
+     * Invalidate any internal compilation state.
+     */
+    public void invalidateCompilation();
+
+    /**
+     * True if this query supports datastore execution, false if it
+     * can only run in memory.
+     */
+    public boolean supportsDataStoreExecution();
+
+    /**
+     * True if this query supports in-memory execution, false if it
+     * can only run against the datastore.
+     */
+    public boolean supportsInMemoryExecution();
+
+    /**
+     * Return an executor for in-memory execution of this query.
+     * Executors must be cachable and thread safe. If this class returns
+     * true from {@link #supportsAbstractExecutors}, the given metadata
+     * will always be for the candidate class of this query, or possibly
+     * null if the candidate class is not itself persistence capable (like
+     * an interface or abstract base class). Otherwise, the given type will
+     * be a mapped class.
+     *
+     * @param subs whether to include dependent mapped subclasses in the
+     * results; independent subclasses should never be included
+     */
+    public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs);
+
+    /**
+     * Return an executor for datastore execution of this query.
+     * Executors must be cachable and thread safe. If this class returns
+     * true from {@link #supportsAbstractExecutors}, the given metadata
+     * will always be for the candidate class of this query, or possibly
+     * null if the candidate class is not itself persistence capable (like
+     * an interface or abstract base class). Otherwise, the given type will
+     * be a mapped class.
+     *
+     * @param subs whether to include dependent mapped subclasses in the
+     * results; independent subclasses should never be included
+     */
+    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs);
+
+    /**
+     * Return true if this query supports execution against abstract or
+     * interface types. Returns false by default, meaning we will only
+     * request executors for persistent classes. In this case, we will
+     * automatically combine the results of the executors for all
+     * implementing classes if we execute a query for an interface for
+     * abstract type.
+     */
+    public boolean supportsAbstractExecutors();
+
+    /**
+     * Whether this query requires a candidate class.
+     */
+    public boolean requiresCandidateType();
+
+    /**
+     * Whether this query requires parameters to be declared.
+     */
+    public boolean requiresParameterDeclarations();
+
+    /**
+     * Whether this query supports declared parameters.
+     */
+    public boolean supportsParameterDeclarations();
+
+    public Object evaluate(Object value, Object ob, Object[] params, 
+        OpenJPAStateManager sm);
+
+    /**
+     * A query result range.
+     */
+    public static class Range {
+        public long start = 0L;
+        public long end = Long.MAX_VALUE;
+        public boolean lrs = false;
+
+        public Range() {
+        }
+
+        public Range(long start, long end) {
+            this.start = start;
+            this.end = end;
+        }
+    }
+
+    /**
+     * An executor provides a uniform interface to the mechanism for executing
+     * either an in-memory or datastore query. In the common case, the
+     * {@link #executeQuery} method will be called before other methods,
+     * though this is not guaranteed.
+     *
+     * @author Marc Prud'hommeaux
+     */
+    public static interface Executor {
+
+        /**
+         * Return the result of executing this query with the given parameter
+         * values. If this query is a projection and this executor does not
+         * pack results itself, each element of the returned result object
+         * provider should be an object array containing the projection values.
+         *
+         * @param lrs true if the query result should be treated as a
+         * large result set, assuming the query is not an
+         * aggregate and does not have grouping
+         * @see #isPacking
+         */
+        public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
+            Range range);
+
+        /**
+         * Deleted the objects that result from the execution of the
+         * query, retuning the number of objects that were deleted.
+         */
+        public Number executeDelete(StoreQuery q, Object[] params);
+
+        /**
+         * Updates the objects that result from the execution of the
+         * query, retuning the number of objects that were updated.
+         */
+        public Number executeUpdate(StoreQuery q, Object[] params);
+
+        /**
+         * Return a description of the commands that will be sent to
+         * the datastore in order to execute the query.
+         */
+        public String[] getDataStoreActions(StoreQuery q, Object[] params,
+            Range range);
+
+        /**
+         * Validate components of query.
+         */
+        public void validate(StoreQuery q);
+
+        /**
+         * Mutate the given range to set any range information stored in 
+         * the query string and/or parameters.
+         */
+        public void getRange(StoreQuery q, Object[] params, Range range);
+
+        /**
+         * Extract the value of the <code>orderIndex</code>th ordering
+         * expression in {@link Query#getOrderingClauses} from the
+         * given result object. The result object will be an object from
+         * the result object provider returned from {@link #executeQuery}.
+         * This method is used when several result lists have to be merged
+         * in memory. If this exeuctor's parent query supports executors on
+         * abstract or interface classes, this method will not be used.
+         *
+         * @see StoreQuery#supportsAbstractExecutors
+         */
+        public Object getOrderingValue(StoreQuery q, Object[] params,
+            Object resultObject, int orderIndex);
+
+        /**
+         * Return the ordering direction for all ordering clauses, or empty
+         * array if none.
+         */
+        public boolean[] getAscending(StoreQuery q);
+
+        /**
+         * Return true if this executor packs projections into the result
+         * class itself. Executors for query languages that allow projections
+         * without result clauses must return true and perform the result
+         * packing themselves.
+         */
+        public boolean isPacking(StoreQuery q);
+
+        /**
+         * If this is not a projection but the candidate results are placed
+         * into a result class with an alias, return that alias.
+         */
+        public String getAlias(StoreQuery q);
+
+        /**
+         * Return the alias for each projection element, or empty array
+         * if not a projection.
+         */
+        public String[] getProjectionAliases(StoreQuery q);
+
+        /**
+         * Return the expected types of the projections used by this query,
+         * or an empty array if not a projection.
+         */
+        public Class[] getProjectionTypes(StoreQuery q);
+
+        /**
+         * Return an array of all persistent classes used in this query, or
+         * empty array if unknown.
+         */
+        public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q);
+
+        /**
+         * Returns the operation this executor is meant to execute.
+         *
+         * @see QueryOperations
+         */
+        public int getOperation(StoreQuery q);
+
+        /**
+         * Return true if the compiled query is an aggregate.
+         */
+        public boolean isAggregate(StoreQuery q);
+
+        /**
+         * Whether the compiled query has grouping.
+         */
+        public boolean hasGrouping(StoreQuery q);
+
+        /**
+         * Return a map of parameter names to types. The returned
+         * {@link Map#entrySet}'s {@link Iterator} must return values in the
+         * order in which they were declared or used.
+         */
+        public LinkedMap getParameterTypes(StoreQuery q);
+
+        /**
+         * Returns the result class, if any.
+         */
+        public Class getResultClass(StoreQuery q);
+
+        /**
+         * Return a map of {@link FieldMetaData} to update
+		 * {@link Constant}s, in cases where this query is for a bulk update.
+	 	 */
+		public Map getUpdates (StoreQuery q);
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
index f3a4150..94c5226 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
@@ -37,16 +37,19 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.datacache.AbstractDataCache;
 import org.apache.openjpa.datacache.DataCache;
 import org.apache.openjpa.enhance.PCRegistry;
 import org.apache.openjpa.enhance.Reflection;
 import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.lib.conf.Configurations;
 import org.apache.openjpa.lib.conf.Value;
 import org.apache.openjpa.lib.conf.ValueListener;
 import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.meta.SourceTracker;
 import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.lib.xml.Commentable;
 import org.apache.openjpa.util.BigDecimalId;
 import org.apache.openjpa.util.BigIntegerId;
@@ -192,6 +195,10 @@
     private FetchGroup[] _fgs = null;
     private FetchGroup[] _customFGs = null;
     private boolean _intercepting = false;
+    private boolean _abstract = false;
+    private Boolean _hasAbstractPKField = null;
+    private Boolean _hasPKFieldsFromAbstractClass = null;
+    private Boolean _isCacheable = null;
 
     /**
      * Constructor. Supply described type and repository.
@@ -1340,14 +1347,23 @@
     }
 
     /**
-     * The name of the datacache to use for this class, or null if none.
+     * The name of the datacache to use for this class. If this class is not
+     * eligible for caching based its annotation or the cache configuration
+     * null will be returned.
+     * 
+     * @return The cache name, or null if this type should not be cached.
      */
     public String getDataCacheName() {
         if (DEFAULT_STRING.equals(_cacheName)) {
-            if (_super != null)
+            if (_super != null) {
                 _cacheName = getPCSuperclassMetaData().getDataCacheName();
-            else
+            }
+            else {
                 _cacheName = DataCache.NAME_DEFAULT;
+            }
+            if(!isCacheable()) { 
+               _cacheName = null; 
+            }
         }
         return _cacheName;
     }
@@ -1877,11 +1893,15 @@
         if (_super != null) {
             // concrete superclass oids must match or be parent of ours
             ClassMetaData sup = getPCSuperclassMetaData();
-            if (!sup.getObjectIdType().isAssignableFrom(_objectId))
+
+            Class objectIdType = sup.getObjectIdType();
+            if (objectIdType != null &&
+                    !objectIdType.isAssignableFrom(_objectId)) {
                 throw new MetaDataException(_loc.get("id-classes",
                     new Object[]{ _type, _objectId, _super,
                         sup.getObjectIdType() }));
-
+            }
+            
             // validate that no other pks are declared if we have a
             // concrete PC superclass
             if (hasConcretePCSuperclass())
@@ -2393,4 +2413,196 @@
     		_cacheTimeout = Integer.MIN_VALUE;
     	}
     }
+    
+    /**
+     * Determine whether this Type should be included in the DataCache (if one
+     * is provided) based on the DataCache's configuration.
+     * 
+     * @return true if the DataCache will accept this type, otherwise false.
+     */
+    private boolean isCacheable() {
+    	if (_isCacheable != null) {
+    		return _isCacheable.booleanValue();
+    	}
+    	    	
+    	setIsCacheable(true, false);
+    	return _isCacheable.booleanValue();
+    }
+
+    /**
+     * <p>
+     * Set whether or not the class represented by this ClassMetaData object should be included in the datacache. The
+     * arguments provided are *hints* as to whether the class should be included in the datacache, and can be overridden
+     * by the configuration set in openjpa.Datacache.
+     * </p>
+     * 
+     * <p>
+     * Rules for this determination are:
+     * </p>
+     * <ol>
+     * <li>If the class shows up in the list of excluded types, it does not get cached, period.</li>
+     * <li>If the class does not show up in the excluded types, but the included types field is set (ie, has at least
+     * one class), then:
+     * <ol>
+     * <li>If the class is listed in the include list, then it gets cached</li>
+     * <li>If the class is set as cacheable by the @Datacache annotation, it gets cached</li>
+     * <li>If neither a or b are true, then the class does not get cached</li>
+     * </ol>
+     * </li>
+     * <li>If neither the include or exclude lists are defined, then go along with the value passed into the argument,
+     * which is either the default value (true) or whatever was set with the @Datacache annotation</li>
+     * </ol>
+     * 
+     * @param isCacheable
+     *            Hint whether this class should be included in the datacache. Default behavior is yes, though the
+     *            @Datacache annotation can specify if it should not be cached.
+     * @param annotationOverride
+     *            Whether this hint originated from the @Datacache annotation or whether this is the default "yes" hint.
+     *            The origination of the hint influences the decision making process in rule #2b.
+     * 
+     */
+    public void setIsCacheable(boolean isCacheable, boolean annotationOverride) {
+    	Options dataCacheOptions = getDataCacheOptions();
+    	Set excludedTypes = extractDataCacheClassListing(dataCacheOptions.getProperty("ExcludedTypes", null));
+    	Set types = extractDataCacheClassListing(dataCacheOptions.getProperty("Types", null));
+    	
+    	String className = getDescribedType().getName();
+    	if (excludedTypes != null && excludedTypes.contains(className)) {
+    		// Rule #1
+    		_isCacheable = Boolean.FALSE;
+    	} else if (types != null) {
+    		// Rule #2
+    		if ((annotationOverride && isCacheable) || (types.contains(className))) {
+    			_isCacheable = Boolean.TRUE;
+    		} else {
+    			_isCacheable = Boolean.FALSE;
+    		}
+    	} else {
+    		// Rule #3
+    		_isCacheable = isCacheable ? Boolean.TRUE : Boolean.FALSE;
+    	}
+    }
+    
+    /**
+     * Extract all of the DataCache plugin options from the configuration
+     * 
+     */
+    private Options getDataCacheOptions() {
+    	String dataCacheConfig = getRepository().getConfiguration().getDataCache();
+    	Options dataCacheOptions = 
+    		Configurations.parseProperties(Configurations.getProperties(dataCacheConfig));
+    	return dataCacheOptions;    
+    }
+    
+    /**
+     * Tool to extract classes defined in the datacache include and exclude list into
+     * individual entries in a Set.
+     * 
+     */
+    private final Set extractDataCacheClassListing(String classList) {
+    	if (classList == null || classList.length() == 0)
+    		return null;
+    	
+    	HashSet returnSet = new HashSet();
+    	String[] entries = classList.split(";");
+    	for (int index = 0; index < entries.length; index++) {
+    		returnSet.add(entries[index]);
+    	}
+    	
+    	return returnSet;
+    }
+    
+    /**
+     * Returns true if the pcType modeled by this ClassMetaData
+     * object is abstract (ie, a MappedSuperclass in JPA terms.)
+     *
+     * @return
+     */
+    public boolean isAbstract() {
+        return _abstract;
+    }
+
+    /**
+     * Sets the value determining if the pcType modeled by this
+     * ClassMetaData object is abstract (ie, a MappedSuperclass in JPA terms.)
+     *
+     * @return
+     */
+    public void setAbstract(boolean flag) {
+        _abstract = flag;
+        _hasAbstractPKField = null;
+    }
+
+    /**
+     * Convenience method to determine if the pcType modeled by
+     * this ClassMetaData object is both abstract and declares PKFields. This
+     * method is used by the PCEnhancer to determine if special handling is
+     * required.
+     *
+     * @return
+     */
+    public boolean hasAbstractPKField() {
+        if (_hasAbstractPKField != null) {
+            return _hasAbstractPKField.booleanValue();
+        }
+
+        // Default to false, set to true only if this type is abstract and
+        // declares a PKField.
+        _hasAbstractPKField = Boolean.FALSE;
+
+        if (isAbstract() == true) {
+            FieldMetaData[] declaredFields = getDeclaredFields();
+            if (declaredFields != null && declaredFields.length != 0) {
+                for (FieldMetaData fmd : declaredFields) {
+                    if (fmd.isPrimaryKey()) {
+                        _hasAbstractPKField = Boolean.TRUE;
+                        break;
+                    }
+                }
+            }
+        }
+
+        return _hasAbstractPKField.booleanValue();
+    }
+
+    /**
+     * Convenience method to determine if this type is a direct
+     * decendent of an abstract type declaring PKFields. Returns true if there
+     * are no pcTypes mapped to a table between this type and an abstract pcType
+     * declaring PKFields. Returns false if there no such abstract pcTypes in
+     * the inheritance hierarchy or if there are any pcTypes mapped to tables in
+     * between the type represented by this ClassMetaData object and the
+     * abstract pcType declaring PKFields.
+     *
+     * @return
+     */
+    public boolean hasPKFieldsFromAbstractClass() {
+        if (_hasPKFieldsFromAbstractClass != null) {
+            return _hasPKFieldsFromAbstractClass.booleanValue();
+        }
+
+        // Default to FALSE, until proven true.
+        _hasPKFieldsFromAbstractClass = Boolean.FALSE;
+
+        FieldMetaData[] pkFields = getPrimaryKeyFields();
+        for (FieldMetaData fmd : pkFields) {
+            ClassMetaData fmdDMDA = fmd.getDeclaringMetaData();
+            if (fmdDMDA.isAbstract()) {
+                ClassMetaData cmd = getPCSuperclassMetaData();
+                while (cmd != fmdDMDA) {
+                    if (fmdDMDA.isAbstract()) {
+                        cmd = cmd.getPCSuperclassMetaData();
+                    } else {
+                        break;
+                    }
+                }
+                if (cmd == fmdDMDA) {
+                    _hasPKFieldsFromAbstractClass = Boolean.TRUE;
+                    break;
+                }
+            }
+        }
+
+        return _hasPKFieldsFromAbstractClass.booleanValue();
+    }
 }
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
index 5809bec..22cc0c7 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
@@ -1,388 +1,388 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.meta;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.MetaDataException;
-import serp.util.Numbers;
-
-/**
- * Captures fetch group metadata.
- */
-public class FetchGroup 
-    implements Serializable {
-
-    /**
-     * Name of the default fetch group.
-     */
-    public static final String NAME_DEFAULT = "default";
-
-    /**
-     * Name of the "all" fetch group.
-     */
-    public static final String NAME_ALL = "all";
-
-    /**
-     * Default field recursion depth.
-     */
-    public static final int RECURSION_DEPTH_DEFAULT = 1;
-
-    /**
-     * Infinite depth.
-     */
-	public static final int DEPTH_INFINITE = -1;
-
-    /**
-     *  Standard default fetch group.
-     */
-    static final FetchGroup DEFAULT = new FetchGroup(NAME_DEFAULT, true);
-
-    /**
-     *  Standard "all" fetch group.
-     */
-    static final FetchGroup ALL = new FetchGroup(NAME_ALL, false);
-
-    private static final Localizer _loc = Localizer.forPackage
-        (FetchGroup.class);
-
-    private final String _name;
-    private final ClassMetaData _meta;
-    private final boolean _readOnly;
-    private List _includes;
-    private Set  _containedBy;
-    private Map _depths;
-    private Boolean _postLoad;
-
-    /**
-     * Constructor; supply immutable name.
-     *
-     * @param name must not by null or empty.
-     */
-    FetchGroup(ClassMetaData cm, String name) {
-        _meta = cm;
-        _name = name;
-        _readOnly = false;
-    }
-
-    /**
-     * Internal constructor for builtin fetch groups.
-     */
-    private FetchGroup(String name, boolean postLoad) {
-        _meta = null;
-        _name = name;
-        _postLoad = (postLoad) ? Boolean.TRUE : Boolean.FALSE;
-        _readOnly = true;
-    }
-
-    /**
-     * Copy state from the given fetch group.
-     */
-    void copy(FetchGroup fg) {
-        if (fg._includes != null)
-            for (Iterator itr = fg._includes.iterator(); itr.hasNext();)
-                addDeclaredInclude((String) itr.next());
-        if (fg._containedBy != null) 
-        	this._containedBy = new HashSet(fg._containedBy);
-        
-        if (fg._depths != null) {
-            Map.Entry entry;
-            for (Iterator itr = fg._depths.entrySet().iterator(); 
-                itr.hasNext();) {
-                entry = (Map.Entry) itr.next();
-                setRecursionDepth((FieldMetaData) entry.getKey(), ((Number) 
-                    entry.getValue()).intValue());
-            }
-        }
-        if (fg._postLoad != null)
-            _postLoad = fg._postLoad;
-    }
-
-    /**
-     * Fetch group name.
-     */
-    public String getName() {
-        return _name;
-    }
-
-    /**
-     * Includes given fetch group within this receiver.
-     */
-    public void addDeclaredInclude(String fgName) {
-        if (_readOnly)
-            throw new UnsupportedOperationException();
-        if (StringUtils.isEmpty(fgName))
-            throw new MetaDataException(_loc.get("null-include-fg", this));
-        if (_includes == null)
-            _includes = new ArrayList();
-        if (!_includes.contains(fgName))
-            _includes.add(fgName);
-    }
-
-    /**
-     * Affirms if given fetch group is included by this receiver.  Includes
-     * superclass definition of fetch group and optionally other included 
-     * groups.
-     *
-     * @param recurse if true then recursively checks within the included
-     * fecth groups
-     */
-    public boolean includes(String fgName, boolean recurse) {
-        // check our includes
-        if (_includes != null) {
-            if (_includes.contains(fgName))
-                return true;
-            if (recurse && _meta!=null) {
-                FetchGroup fg;
-                for (Iterator i = _includes.iterator(); i.hasNext();) {
-                    fg = _meta.getFetchGroup((String) i.next());
-                    if (fg != null && fg.includes(fgName, true))
-                        return true;
-                }
-            }
-        }
-        if (_meta != null) {
-            // check superclass includes
-            ClassMetaData sup = _meta.getPCSuperclassMetaData();
-            if (sup != null) {
-                FetchGroup supFG = sup.getFetchGroup(_name);
-                if (supFG != null)
-                    return supFG.includes(fgName, recurse);
-            }
-        }
-        return false;
-    }
-    
-    /**
-     * Adds this receiver as one of the included fetch groups of the given
-     * parent. 
-     * The parent fecth group will include this receiver as a side-effect of
-     * this call.
-     * 
-     * @see #includes(String, boolean)
-     * @see #addDeclaredInclude(String) 
-     * 
-     * @return true if given parent is a new addition. false othrwise.
-     * @since 1.1.0
-     */
-    public boolean addContainedBy(FetchGroup parent) {
-    	parent.addDeclaredInclude(this.getName());
-    	if (_containedBy==null)
-    		_containedBy = new HashSet();
-    	return _containedBy.add(parent.getName());
-    }
-    
-    /**
-     * Gets the name of the fetch groups in which this receiver has been
-     * included.
-     * 
-     * @see #addContainedBy(FetchGroup)
-     * @since 1.1.0
-     */
-    public Set getContainedBy() {
-    	return (_containedBy == null) ? Collections.EMPTY_SET :
-            Collections.unmodifiableSet(_containedBy);
-    }
-
-    /**
-     * Return the fetch group names declared included by this group.
-     */
-    public String[] getDeclaredIncludes() {
-        // only used during serialization; no need to cache
-        return (_includes == null) ? new String[0]
-            : (String[]) _includes.toArray(new String[_includes.size()]);
-    }
-
-    /**
-     * Recursion depth for the given field.  This is the depth of relations of
-     * the same class as this one we can fetch through the given field.
-     */
-    public void setRecursionDepth(FieldMetaData fm, int depth) {
-        if (_readOnly)
-            throw new UnsupportedOperationException();
-        if (depth < -1)
-            throw new MetaDataException(_loc.get("invalid-fg-depth", _name, fm, 
-                Numbers.valueOf(depth)));
-        if (_depths == null)
-            _depths = new HashMap();
-        _depths.put(fm, Numbers.valueOf(depth));
-    }
-
-    /**
-     * Recursion depth for the given field.  This is the depth of relations of
-     * the same class as this one we can fetch through the given field.
-     */
-    public int getRecursionDepth(FieldMetaData fm) {
-        Number depth = findRecursionDepth(fm);
-        return (depth == null) ? RECURSION_DEPTH_DEFAULT : depth.intValue();
-    }
-
-    /**
-     * Return the recursion depth declared for the given field, or 
-     * 0 if none.
-     */
-    public int getDeclaredRecursionDepth(FieldMetaData fm) {
-        Number depth = (_depths == null) ? null : (Number) _depths.get(fm);
-        return (depth == null) ? 0 : depth.intValue();
-    }
-
-    /**
-     * Helper to find recursion depth recursively in our includes.
-     */
-    private Number findRecursionDepth(FieldMetaData fm) { 
-        Number depth = (_depths == null) ? null : (Number) _depths.get(fm);
-        if (depth != null)
-            return depth;
-
-        // check for superclass declaration of depth
-        Number max = null;
-        if (_meta != null && fm.getDeclaringMetaData() != _meta) {
-            ClassMetaData sup = _meta.getPCSuperclassMetaData();
-            if (sup != null) {
-                FetchGroup supFG = sup.getFetchGroup(_name);
-                if (supFG != null)
-                    max = supFG.findRecursionDepth(fm);
-            }
-        }
-        if (_includes == null)
-            return max;
-
-        // find largest included depth
-        FetchGroup fg;
-        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
-            fg = _meta.getFetchGroup((String) itr.next());
-            depth = (fg == null) ? null : fg.findRecursionDepth(fm);
-            if (depth != null && (max == null 
-                || depth.intValue() > max.intValue()))
-                max = depth;
-        }
-        return max;
-    }
-
-    /**
-     * Return the fields with declared recursion depths in this group.
-     */
-    public FieldMetaData[] getDeclaredRecursionDepthFields() {
-        // used in serialization only; no need to cache
-        if (_depths == null)
-            return new FieldMetaData[0];
-         return (FieldMetaData[]) _depths.keySet().toArray
-            (new FieldMetaData[_depths.size()]);
-    } 
-
-    /**
-     * Whether loading this fetch group causes a post-load callback on the
-     * loaded instance.
-     */
-    public void setPostLoad (boolean flag) {
-        if (_readOnly && flag != isPostLoad())
-            throw new UnsupportedOperationException();
-    	_postLoad = (flag) ? Boolean.TRUE : Boolean.FALSE;
-    }
-
-    /**
-     * Whether loading this fetch group causes a post-load callback on the
-     * loaded instance.
-     */
-    public boolean isPostLoad () {
-    	if (_postLoad != null)
-            return _postLoad.booleanValue();
-
-        if (_meta != null) {
-            ClassMetaData sup = _meta.getPCSuperclassMetaData();
-            if (sup != null) {
-                FetchGroup supFG = sup.getFetchGroup(_name);
-                if (supFG != null && supFG.isPostLoad())
-                    return true;
-            }
-        }
-
-        if (_includes == null)
-            return false;
-        FetchGroup fg;
-        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
-            fg = _meta.getFetchGroup((String) itr.next());
-            if (fg != null && fg.isPostLoad())
-                return true;
-        }
-        return false;
-    }
-
-    /**
-     * Whether the post-load value is declared for this group.  
-     */
-    public boolean isPostLoadExplicit() {
-        return _postLoad != null;
-    }
-
-    /**
-     * Resolve and validate fetch group metadata.
-     */
-    public void resolve() {
-        if (_includes == null)
-            return;
-
-        // validate includes
-        String name;
-        FetchGroup fg;
-        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
-            name = (String) itr.next();
-            if (name.equals(_name))
-                throw new MetaDataException(_loc.get("cyclic-fg", this, name));
-            fg = _meta.getFetchGroup(name);
-            if (fg == null)
-                throw new MetaDataException(_loc.get("bad-fg-include", this,
-                    name));
-            if (fg.includes(_name, true))
-                throw new MetaDataException(_loc.get("cyclic-fg", this, name));
-        }
-    }
-    
-    /**
-     * Affirms equality if the other has the same name and declaring type.
-     */
-    public boolean equals(Object other) {
-        if (other == this)
-            return true;
-        if (!(other instanceof FetchGroup))
-            return false;
-        FetchGroup that = (FetchGroup) other;
-        return _name.equals(that._name)
-            && ObjectUtils.equals(_meta, that._meta);
-    }
-
-    public int hashCode() {
-        return _name.hashCode() + ((_meta == null) ? 0 : _meta.hashCode());
-    }
-
-    public String toString() {
-        return ((_meta == null) ? "Builtin" : _meta.toString ()) + "." + _name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.meta;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+import serp.util.Numbers;
+
+/**
+ * Captures fetch group metadata.
+ */
+public class FetchGroup 
+    implements Serializable {
+
+    /**
+     * Name of the default fetch group.
+     */
+    public static final String NAME_DEFAULT = "default";
+
+    /**
+     * Name of the "all" fetch group.
+     */
+    public static final String NAME_ALL = "all";
+
+    /**
+     * Default field recursion depth.
+     */
+    public static final int RECURSION_DEPTH_DEFAULT = 1;
+
+    /**
+     * Infinite depth.
+     */
+	public static final int DEPTH_INFINITE = -1;
+
+    /**
+     *  Standard default fetch group.
+     */
+    static final FetchGroup DEFAULT = new FetchGroup(NAME_DEFAULT, true);
+
+    /**
+     *  Standard "all" fetch group.
+     */
+    static final FetchGroup ALL = new FetchGroup(NAME_ALL, false);
+
+    private static final Localizer _loc = Localizer.forPackage
+        (FetchGroup.class);
+
+    private final String _name;
+    private final ClassMetaData _meta;
+    private final boolean _readOnly;
+    private List _includes;
+    private Set  _containedBy;
+    private Map _depths;
+    private Boolean _postLoad;
+
+    /**
+     * Constructor; supply immutable name.
+     *
+     * @param name must not by null or empty.
+     */
+    FetchGroup(ClassMetaData cm, String name) {
+        _meta = cm;
+        _name = name;
+        _readOnly = false;
+    }
+
+    /**
+     * Internal constructor for builtin fetch groups.
+     */
+    private FetchGroup(String name, boolean postLoad) {
+        _meta = null;
+        _name = name;
+        _postLoad = (postLoad) ? Boolean.TRUE : Boolean.FALSE;
+        _readOnly = true;
+    }
+
+    /**
+     * Copy state from the given fetch group.
+     */
+    void copy(FetchGroup fg) {
+        if (fg._includes != null)
+            for (Iterator itr = fg._includes.iterator(); itr.hasNext();)
+                addDeclaredInclude((String) itr.next());
+        if (fg._containedBy != null) 
+        	this._containedBy = new HashSet(fg._containedBy);
+        
+        if (fg._depths != null) {
+            Map.Entry entry;
+            for (Iterator itr = fg._depths.entrySet().iterator(); 
+                itr.hasNext();) {
+                entry = (Map.Entry) itr.next();
+                setRecursionDepth((FieldMetaData) entry.getKey(), ((Number) 
+                    entry.getValue()).intValue());
+            }
+        }
+        if (fg._postLoad != null)
+            _postLoad = fg._postLoad;
+    }
+
+    /**
+     * Fetch group name.
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Includes given fetch group within this receiver.
+     */
+    public void addDeclaredInclude(String fgName) {
+        if (_readOnly)
+            throw new UnsupportedOperationException();
+        if (StringUtils.isEmpty(fgName))
+            throw new MetaDataException(_loc.get("null-include-fg", this));
+        if (_includes == null)
+            _includes = new ArrayList();
+        if (!_includes.contains(fgName))
+            _includes.add(fgName);
+    }
+
+    /**
+     * Affirms if given fetch group is included by this receiver.  Includes
+     * superclass definition of fetch group and optionally other included 
+     * groups.
+     *
+     * @param recurse if true then recursively checks within the included
+     * fecth groups
+     */
+    public boolean includes(String fgName, boolean recurse) {
+        // check our includes
+        if (_includes != null) {
+            if (_includes.contains(fgName))
+                return true;
+            if (recurse && _meta!=null) {
+                FetchGroup fg;
+                for (Iterator i = _includes.iterator(); i.hasNext();) {
+                    fg = _meta.getFetchGroup((String) i.next());
+                    if (fg != null && fg.includes(fgName, true))
+                        return true;
+                }
+            }
+        }
+        if (_meta != null) {
+            // check superclass includes
+            ClassMetaData sup = _meta.getPCSuperclassMetaData();
+            if (sup != null) {
+                FetchGroup supFG = sup.getFetchGroup(_name);
+                if (supFG != null)
+                    return supFG.includes(fgName, recurse);
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Adds this receiver as one of the included fetch groups of the given
+     * parent. 
+     * The parent fecth group will include this receiver as a side-effect of
+     * this call.
+     * 
+     * @see #includes(String, boolean)
+     * @see #addDeclaredInclude(String) 
+     * 
+     * @return true if given parent is a new addition. false othrwise.
+     * @since 1.1.0
+     */
+    public boolean addContainedBy(FetchGroup parent) {
+    	parent.addDeclaredInclude(this.getName());
+    	if (_containedBy==null)
+    		_containedBy = new HashSet();
+    	return _containedBy.add(parent.getName());
+    }
+    
+    /**
+     * Gets the name of the fetch groups in which this receiver has been
+     * included.
+     * 
+     * @see #addContainedBy(FetchGroup)
+     * @since 1.1.0
+     */
+    public Set getContainedBy() {
+    	return (_containedBy == null) ? Collections.EMPTY_SET :
+            Collections.unmodifiableSet(_containedBy);
+    }
+
+    /**
+     * Return the fetch group names declared included by this group.
+     */
+    public String[] getDeclaredIncludes() {
+        // only used during serialization; no need to cache
+        return (_includes == null) ? new String[0]
+            : (String[]) _includes.toArray(new String[_includes.size()]);
+    }
+
+    /**
+     * Recursion depth for the given field.  This is the depth of relations of
+     * the same class as this one we can fetch through the given field.
+     */
+    public void setRecursionDepth(FieldMetaData fm, int depth) {
+        if (_readOnly)
+            throw new UnsupportedOperationException();
+        if (depth < -1)
+            throw new MetaDataException(_loc.get("invalid-fg-depth", _name, fm, 
+                Numbers.valueOf(depth)));
+        if (_depths == null)
+            _depths = new HashMap();
+        _depths.put(fm, Numbers.valueOf(depth));
+    }
+
+    /**
+     * Recursion depth for the given field.  This is the depth of relations of
+     * the same class as this one we can fetch through the given field.
+     */
+    public int getRecursionDepth(FieldMetaData fm) {
+        Number depth = findRecursionDepth(fm);
+        return (depth == null) ? RECURSION_DEPTH_DEFAULT : depth.intValue();
+    }
+
+    /**
+     * Return the recursion depth declared for the given field, or 
+     * 0 if none.
+     */
+    public int getDeclaredRecursionDepth(FieldMetaData fm) {
+        Number depth = (_depths == null) ? null : (Number) _depths.get(fm);
+        return (depth == null) ? 0 : depth.intValue();
+    }
+
+    /**
+     * Helper to find recursion depth recursively in our includes.
+     */
+    private Number findRecursionDepth(FieldMetaData fm) { 
+        Number depth = (_depths == null) ? null : (Number) _depths.get(fm);
+        if (depth != null)
+            return depth;
+
+        // check for superclass declaration of depth
+        Number max = null;
+        if (_meta != null && fm.getDeclaringMetaData() != _meta) {
+            ClassMetaData sup = _meta.getPCSuperclassMetaData();
+            if (sup != null) {
+                FetchGroup supFG = sup.getFetchGroup(_name);
+                if (supFG != null)
+                    max = supFG.findRecursionDepth(fm);
+            }
+        }
+        if (_includes == null)
+            return max;
+
+        // find largest included depth
+        FetchGroup fg;
+        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
+            fg = _meta.getFetchGroup((String) itr.next());
+            depth = (fg == null) ? null : fg.findRecursionDepth(fm);
+            if (depth != null && (max == null 
+                || depth.intValue() > max.intValue()))
+                max = depth;
+        }
+        return max;
+    }
+
+    /**
+     * Return the fields with declared recursion depths in this group.
+     */
+    public FieldMetaData[] getDeclaredRecursionDepthFields() {
+        // used in serialization only; no need to cache
+        if (_depths == null)
+            return new FieldMetaData[0];
+         return (FieldMetaData[]) _depths.keySet().toArray
+            (new FieldMetaData[_depths.size()]);
+    } 
+
+    /**
+     * Whether loading this fetch group causes a post-load callback on the
+     * loaded instance.
+     */
+    public void setPostLoad (boolean flag) {
+        if (_readOnly && flag != isPostLoad())
+            throw new UnsupportedOperationException();
+    	_postLoad = (flag) ? Boolean.TRUE : Boolean.FALSE;
+    }
+
+    /**
+     * Whether loading this fetch group causes a post-load callback on the
+     * loaded instance.
+     */
+    public boolean isPostLoad () {
+    	if (_postLoad != null)
+            return _postLoad.booleanValue();
+
+        if (_meta != null) {
+            ClassMetaData sup = _meta.getPCSuperclassMetaData();
+            if (sup != null) {
+                FetchGroup supFG = sup.getFetchGroup(_name);
+                if (supFG != null && supFG.isPostLoad())
+                    return true;
+            }
+        }
+
+        if (_includes == null)
+            return false;
+        FetchGroup fg;
+        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
+            fg = _meta.getFetchGroup((String) itr.next());
+            if (fg != null && fg.isPostLoad())
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Whether the post-load value is declared for this group.  
+     */
+    public boolean isPostLoadExplicit() {
+        return _postLoad != null;
+    }
+
+    /**
+     * Resolve and validate fetch group metadata.
+     */
+    public void resolve() {
+        if (_includes == null)
+            return;
+
+        // validate includes
+        String name;
+        FetchGroup fg;
+        for (Iterator itr = _includes.iterator(); itr.hasNext();) {
+            name = (String) itr.next();
+            if (name.equals(_name))
+                throw new MetaDataException(_loc.get("cyclic-fg", this, name));
+            fg = _meta.getFetchGroup(name);
+            if (fg == null)
+                throw new MetaDataException(_loc.get("bad-fg-include", this,
+                    name));
+            if (fg.includes(_name, true))
+                throw new MetaDataException(_loc.get("cyclic-fg", this, name));
+        }
+    }
+    
+    /**
+     * Affirms equality if the other has the same name and declaring type.
+     */
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (!(other instanceof FetchGroup))
+            return false;
+        FetchGroup that = (FetchGroup) other;
+        return _name.equals(that._name)
+            && ObjectUtils.equals(_meta, that._meta);
+    }
+
+    public int hashCode() {
+        return _name.hashCode() + ((_meta == null) ? 0 : _meta.hashCode());
+    }
+
+    public String toString() {
+        return ((_meta == null) ? "Builtin" : _meta.toString ()) + "." + _name;
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
index 1b58457..559b1ab 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
@@ -20,6 +20,7 @@
 
 import java.io.Serializable;
 import java.security.AccessController;
+import java.security.PrivilegedActionException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -37,8 +38,8 @@
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.enhance.DynamicPersistenceCapable;
 import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.PCRegistry.RegisterClassListener;
 import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.PCRegistry.RegisterClassListener;
 import org.apache.openjpa.event.LifecycleEventManager;
 import org.apache.openjpa.lib.conf.Configurable;
 import org.apache.openjpa.lib.conf.Configuration;
@@ -46,11 +47,14 @@
 import org.apache.openjpa.lib.util.Closeable;
 import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.MultiClassLoader;
+import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.lib.util.StringDistance;
 import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.MetaDataException;
 import org.apache.openjpa.util.OpenJPAId;
+
 import serp.util.Strings;
 
 /**
@@ -63,6 +67,8 @@
 public class MetaDataRepository
     implements PCRegistry.RegisterClassListener, Configurable, Closeable, 
     MetaDataModes, Serializable {
+    
+    protected boolean _locking = true;
 
     /**
      * Constant to not validate any metadata.
@@ -105,18 +111,18 @@
 
     // cache of parsed metadata, oid class to class, and interface class
     // to metadatas
-    private final Map _metas = new HashMap();
-    private final Map _oids = Collections.synchronizedMap(new HashMap());
-    private final Map _impls = Collections.synchronizedMap(new HashMap());
-    private final Map _ifaces = Collections.synchronizedMap(new HashMap());
-    private final Map _queries = new HashMap();
-    private final Map _seqs = new HashMap();
-    private final Map _aliases = Collections.synchronizedMap(new HashMap());
-    private final Map _pawares = Collections.synchronizedMap(new HashMap());
-    private final Map _nonMapped = Collections.synchronizedMap(new HashMap());
+	private Map _metas = new HashMap();
+	private Map _oids = Collections.synchronizedMap(new HashMap());
+	private Map _impls = Collections.synchronizedMap(new HashMap());
+	private Map _ifaces = Collections.synchronizedMap(new HashMap());
+	private Map _queries = new HashMap();
+	private Map _seqs = new HashMap();
+	private Map _aliases = Collections.synchronizedMap(new HashMap());
+	private Map _pawares = Collections.synchronizedMap(new HashMap());
+	private Map _nonMapped = Collections.synchronizedMap(new HashMap());
     
     // map of classes to lists of their subclasses
-    private final Map _subs = Collections.synchronizedMap(new HashMap());
+	private Map _subs = Collections.synchronizedMap(new HashMap());
 
     // xml mapping
     protected final XMLMetaData[] EMPTY_XMLMETAS;
@@ -146,6 +152,11 @@
     private LifecycleEventManager.ListenerList _listeners =
         new LifecycleEventManager.ListenerList(3);
 
+    private boolean _reorderMetaDataResolution = false;
+    protected boolean _preload = false;
+    protected boolean _preloadComplete = false;
+    private static final String PRELOAD_STR = "Preload";
+    
     /**
      * Default constructor.  Configure via {@link Configurable}.
      */
@@ -273,6 +284,70 @@
     }
 
     /**
+     * Sets whether this repository will load all MetaData for all known persistent classes at
+     * initialization and remove all locking. Defaults to false.
+     */
+    public void setPreload(boolean p) {
+        _preload = p;
+    }
+
+    /**
+     * Returns a boolean indicating whether this repository will load all MetaData for all known
+     * persistent classes at initialization.
+     */
+    public boolean getPreload() {
+        return _preload;
+    }   
+    
+     /**
+     * If the openjpa.MetaDataRepository plugin value Preload=true is set, this method will load all
+     * MetaData for all persistent classes and will remove locking from this class.
+     * <p>
+     * 
+     */
+    public synchronized void preload() {
+        if (_preload == false) {
+            return;
+        }
+        // If pooling EMFs, this method may be invoked more than once. Only perform this work once.
+        if (_preloadComplete == true) {
+            return;
+        }
+
+        MultiClassLoader multi = AccessController.doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
+        multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
+        multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper
+            .getClassLoaderAction(MetaDataRepository.class)));
+
+        Set<String> classes = getPersistentTypeNames(false, multi);
+        if (classes == null || classes.size() == 0) {
+            throw new MetaDataException(_loc.get("repos-initializeEager-none"));
+        }
+        if (_log.isTraceEnabled() == true) {
+            _log.trace(_loc.get("repos-initializeEager-found", classes));
+        }
+
+        List<Class> loaded = new ArrayList<Class>();
+        for (String c : classes) {
+            try {
+                Class<?> cls = AccessController.doPrivileged((J2DoPrivHelper.getForNameAction(c, true, multi)));
+                loaded.add(cls);
+                // This call may be unnecessary?
+                _factory.load(cls, MODE_ALL, multi);
+            } catch (PrivilegedActionException pae) {
+                throw new MetaDataException(_loc.get("repos-initializeEager-error"), pae);
+            }
+        }
+        resolveAll(multi);
+        
+        // Hook in this class as a listener and process registered classes list to populate _aliases list.
+        PCRegistry.addRegisterClassListener(this);
+        processRegisteredClasses(multi);
+        _locking = false;
+        _preloadComplete = true;
+    }
+    
+    /**
      * Return the metadata for the given class.
      *
      * @param cls the class to retrieve metadata for
@@ -280,7 +355,17 @@
      * @param mustExist if true, throws a {@link MetaDataException}
      * if no metadata is found
      */
-    public synchronized ClassMetaData getMetaData(Class cls,
+    public ClassMetaData getMetaData(Class cls, ClassLoader envLoader, boolean mustExist) {
+        if (_locking) {
+            return getMetaDataLocking(cls, envLoader, mustExist);
+        } else {
+            return getMetaDataInternal(cls, envLoader, mustExist);
+        }
+    }
+    private synchronized ClassMetaData getMetaDataLocking(Class cls, ClassLoader envLoader, boolean mustExist) {
+        return getMetaDataInternal(cls, envLoader, mustExist);
+    }
+    private ClassMetaData getMetaDataInternal(Class cls,
         ClassLoader envLoader, boolean mustExist) {
         if (cls != null &&
             DynamicPersistenceCapable.class.isAssignableFrom(cls))
@@ -401,14 +486,24 @@
      * @since 1.1.0
      */
     public Collection getAliasNames() {
-        Collection aliases = new HashSet();
+        if (_locking) {
+            return getAliasNamesLocking();
+        } else {
+            return getAliasNamesInternal();
+        }
+    }
+
+    private Collection getAliasNamesLocking() {
         synchronized (_aliases) {
-            for (Iterator iter = _aliases.entrySet().iterator();
-                iter.hasNext(); ) {
-                Map.Entry e = (Map.Entry) iter.next();
-                if (e.getValue() != null)
-                    aliases.add(e.getKey());
-            }
+            return getAliasNamesInternal();
+        }
+    }
+    private final Collection getAliasNamesInternal() {
+        Collection aliases = new HashSet();
+        for (Iterator iter = _aliases.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry e = (Map.Entry) iter.next();
+            if (e.getValue() != null)
+                aliases.add(e.getKey());
         }
         return aliases;
     }
@@ -735,13 +830,29 @@
                 buffer.clear();
             }
         }
+        
+        // Check if process buffer reordering for PCTypes that have relationships to other PCTypes in their identity 
+        // should be performed.
+        if (_reorderMetaDataResolution) {
+        	processed = resolveFKInPKDependenciesOrdering(processed);
+        }
         return processed;
     }
 
     /**
      * Return all the metadata instances currently in the repository.
      */
-    public synchronized ClassMetaData[] getMetaDatas() {
+    public ClassMetaData[] getMetaDatas() {
+        if (_locking) {
+            return getMetaDatasLocking();
+        } else {
+            return getMetaDatasInternal();
+        }
+    }
+    private synchronized ClassMetaData[] getMetaDatasLocking() {
+        return getMetaDatasInternal();
+    }
+    private ClassMetaData[] getMetaDatasInternal() {
         // prevent concurrent mod errors when resolving one metadata
         // introduces others
         ClassMetaData[] metas = (ClassMetaData[]) _metas.values().
@@ -795,13 +906,22 @@
 
         // synchronize on this rather than the map, because all other methods
         // that access _metas are synchronized on this
-        synchronized (this) {
-            if (_pawares.containsKey(cls))
-                throw new MetaDataException(_loc.get("pc-and-aware", cls));
-            _metas.put(cls, meta);
+        if (_locking) {
+            metasPutLocking(cls, meta);
+        } else {
+            metasPutInternal(cls, meta);
         }
+            
         return meta;
     }
+    private synchronized void metasPutLocking(Class cls, ClassMetaData meta){
+        metasPutInternal(cls, meta);
+    }
+    private void metasPutInternal(Class cls, ClassMetaData meta){
+        if (_pawares.containsKey(cls))
+            throw new MetaDataException(_loc.get("pc-and-aware", cls));
+        _metas.put(cls, meta);
+    }
     
     /**
      * Create a new class metadata instance.
@@ -919,7 +1039,17 @@
      *
      * @return true if removed, false if not in this repository
      */
-    public synchronized boolean removeMetaData(Class cls) {
+    public boolean removeMetaData(Class cls) {
+        if(_locking){
+            return removeMetaDataLocking(cls);
+        }else{
+            return removeMetaDataInternal(cls);
+        }
+    }
+    private synchronized boolean removeMetaDataLocking(Class cls) {
+        return removeMetaDataInternal(cls);
+    }
+    private boolean removeMetaDataInternal(Class cls) {
         if (cls == null)
             return false;
         if (_metas.remove(cls) != null) {
@@ -935,24 +1065,42 @@
      * Add the given metadata as declared interface implementation.
      */
     void addDeclaredInterfaceImpl(ClassMetaData meta, Class iface) {
-        synchronized (_impls) {
-            Collection vals = (Collection) _impls.get(iface);
-            
-            // check to see if the superclass already declares to avoid dups
-            if (vals != null) {
-                ClassMetaData sup = meta.getPCSuperclassMetaData();
-                for (; sup != null; sup = sup.getPCSuperclassMetaData())
-                    if (vals.contains(sup.getDescribedType()))
-                        return;
-            }
-            addToCollection(_impls, iface, meta.getDescribedType(), false);
+        if (_locking) {
+            addDeclaredInterfaceImplLocking(meta, iface);
+        } else {
+            addDeclaredInterfaceImplInternal(meta, iface);
         }
     }
-
+    void addDeclaredInterfaceImplLocking(ClassMetaData meta, Class iface) {
+        synchronized (_impls) {
+            addDeclaredInterfaceImplInternal(meta, iface);
+        }
+    }
+    private void addDeclaredInterfaceImplInternal(ClassMetaData meta, Class iface) {
+        Collection vals = (Collection) _impls.get(iface);
+        // check to see if the superclass already declares to avoid dups
+        if (vals != null) {
+            ClassMetaData sup = meta.getPCSuperclassMetaData();
+            for (; sup != null; sup = sup.getPCSuperclassMetaData())
+                if (vals.contains(sup.getDescribedType()))
+                    return;
+        }
+        addToCollection(_impls, iface, meta.getDescribedType(), false);
+    }
     /**
      * Set the implementation for the given managed interface.
      */
-    synchronized void setInterfaceImpl(ClassMetaData meta, Class impl) {
+    void setInterfaceImpl(ClassMetaData meta, Class impl) {
+        if(_locking){
+            setInterfaceImplLocking(meta, impl);
+        }else{
+            setInterfaceImplInternal(meta, impl);
+        }
+    }
+    private synchronized void setInterfaceImplLocking(ClassMetaData meta, Class impl) {
+        setInterfaceImplInternal(meta, impl);
+    }
+    private void setInterfaceImplInternal(ClassMetaData meta, Class impl) {
         if (!meta.isManagedInterface())
             throw new MetaDataException(_loc.get("not-managed-interface", 
                 meta, impl));
@@ -1088,19 +1236,12 @@
         // get impls of given interface / abstract class
         loadRegisteredClassMetaData(envLoader);
         Collection vals = (Collection) _impls.get(cls);
-        ClassMetaData meta;
         Collection mapped = null;
         if (vals != null) {
-            synchronized (vals) {
-                for (Iterator itr = vals.iterator(); itr.hasNext();) {
-                    meta = getMetaData((Class) itr.next(), envLoader, true);
-                    if (meta.isMapped()
-                        || meta.getMappedPCSubclassMetaDatas().length > 0) {
-                        if (mapped == null)
-                            mapped = new ArrayList(vals.size());
-                        mapped.add(meta);
-                    }
-                }
+            if (_locking) {
+                mapped = getImplementorMetaDatasLocking(vals, envLoader, mustExist);
+            } else {
+                mapped = getImplementorMetaDatasInternal(vals, envLoader, mustExist);
             }
         }
 
@@ -1111,6 +1252,22 @@
         return (ClassMetaData[]) mapped.toArray(newClassMetaDataArray
             (mapped.size()));
     }
+    private Collection getImplementorMetaDatasLocking(Collection<Class> classes, ClassLoader envLoader, boolean mustExist) {
+        synchronized (classes) {
+            return getImplementorMetaDatasInternal(classes, envLoader, mustExist);
+        }
+    }
+    private Collection getImplementorMetaDatasInternal(Collection<Class> classes, ClassLoader envLoader, boolean mustExist) {
+        Collection mapped = new ArrayList(classes.size());
+        ClassMetaData meta = null;
+        for (Iterator itr = classes.iterator(); itr.hasNext();) {
+            meta = getMetaData((Class) itr.next(), envLoader, true);
+            if (meta.isMapped() || meta.getMappedPCSubclassMetaDatas().length > 0) {
+                mapped.add(meta);
+            }
+        }
+        return mapped;
+    }
      
     /**
      * Gets the metadata corresponding to the given persistence-aware class. 
@@ -1127,12 +1284,21 @@
      * @return empty array if no class has been registered as pers-aware
      */
     public NonPersistentMetaData[] getPersistenceAwares() {
+        if (_locking) {
+            return getPersistenceAwaresLocking();
+        } else {
+            return getPersistenceAwaresInternal();
+        }
+    }
+    private NonPersistentMetaData[] getPersistenceAwaresLocking() {
         synchronized (_pawares) {
+            return getPersistenceAwaresInternal();
+        }
+    }
+    private NonPersistentMetaData[] getPersistenceAwaresInternal() {
             if (_pawares.isEmpty())
                 return EMPTY_NON_PERSISTENT;
-            return (NonPersistentMetaData[])_pawares.values().toArray
-                (new NonPersistentMetaData[_pawares.size()]);
-        }
+        return (NonPersistentMetaData[]) _pawares.values().toArray(new NonPersistentMetaData[_pawares.size()]);
     }
 
     /**
@@ -1143,17 +1309,26 @@
     public NonPersistentMetaData addPersistenceAware(Class cls) {
     	if (cls == null)
     		return null;
-        synchronized(this) {
+        if (_locking) {
+            return addPersistenceAwareLocking(cls);
+        } else {
+            return addPersistenceAwareInternal(cls);
+        }
+    }
+
+    private synchronized NonPersistentMetaData addPersistenceAwareLocking(Class cls) {
+        return addPersistenceAwareInternal(cls);
+    }
+
+    private NonPersistentMetaData addPersistenceAwareInternal(Class cls) {
             if (_pawares.containsKey(cls))
                 return (NonPersistentMetaData)_pawares.get(cls);
             if (getCachedMetaData(cls) != null)
                 throw new MetaDataException(_loc.get("pc-and-aware", cls));
-            NonPersistentMetaData meta = new NonPersistentMetaData(cls, this,
-                NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
+        NonPersistentMetaData meta = new NonPersistentMetaData(cls, this, NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
             _pawares.put(cls, meta);
             return meta;
     	}
-    }
 
     /**
      * Remove a persitence-aware class from the repository
@@ -1180,12 +1355,21 @@
      * @return empty array if no non-mapped interface has been registered.
      */
     public NonPersistentMetaData[] getNonMappedInterfaces() {
+        if(_locking){
+            return getNonMappedInterfacesLocking();   
+        }else{
+            return getNonMappedInterfacesInternal();
+        }
+    }
+    private NonPersistentMetaData[] getNonMappedInterfacesLocking() {
         synchronized (_nonMapped) {
+            return getNonMappedInterfacesInternal();
+        }
+    }
+    private NonPersistentMetaData[] getNonMappedInterfacesInternal() {
             if (_nonMapped.isEmpty())
                 return EMPTY_NON_PERSISTENT;
-            return (NonPersistentMetaData[])_nonMapped.values().toArray
-                (new NonPersistentMetaData[_nonMapped.size()]);
-        }
+        return (NonPersistentMetaData[]) _nonMapped.values().toArray(new NonPersistentMetaData[_nonMapped.size()]);
     }
 
     /**
@@ -1198,7 +1382,17 @@
     		return null;
         if (!iface.isInterface())
             throw new MetaDataException(_loc.get("not-non-mapped", iface));
-        synchronized(this) {
+        if(_locking){
+            return addNonMappedInterfaceLocking(iface);
+        }else{
+            return addNonMappedInterfaceInternal(iface); 
+        }
+    }
+    private synchronized NonPersistentMetaData addNonMappedInterfaceLocking(Class iface) {
+        return addNonMappedInterfaceInternal(iface);
+    }
+    
+    private NonPersistentMetaData addNonMappedInterfaceInternal(Class iface) {
             if (_nonMapped.containsKey(iface))
                 return (NonPersistentMetaData)_nonMapped.get(iface);
             if (getCachedMetaData(iface) != null)
@@ -1208,7 +1402,6 @@
             _nonMapped.put(iface, meta);
             return meta;
     	}
-    }
 
     /**
      * Remove a non-mapped interface from the repository
@@ -1223,10 +1416,21 @@
      * Clear the cache of parsed metadata. This method also clears the
      * internal {@link MetaDataFactory MetaDataFactory}'s cache.
      */
-    public synchronized void clear() {
+    public void clear() {
         if (_log.isTraceEnabled())
             _log.trace(_loc.get("clear-repos", this));
-
+        
+        if (_locking) {
+            clearLocking();
+        } else {
+            clearInternal();
+        }
+    }
+    private synchronized void clearLocking(){
+        clearInternal();
+    }
+    private void clearInternal(){
+        // Recreating these datastructures is probably faster than calling clear. Future change?
         _metas.clear();
         _oids.clear();
         _subs.clear();
@@ -1239,7 +1443,6 @@
         _pawares.clear();
         _nonMapped.clear();
     }
-
     /**
      * Return the set of configured persistent classes, or null if the user
      * did not configure any.
@@ -1248,8 +1451,18 @@
      * in the classpath if no classes are configured explicitly
      * @param envLoader the class loader to use, or null for default
      */
-    public synchronized Set getPersistentTypeNames(boolean devpath,
+    public Set getPersistentTypeNames(boolean devpath,
         ClassLoader envLoader) {
+        if (_locking) {
+            return getPersistentTypeNamesLocking(devpath, envLoader);
+        } else {
+            return getPersistentTypeNamesInternal(devpath, envLoader);
+        }
+    }
+    private synchronized Set getPersistentTypeNamesLocking(boolean devpath, ClassLoader envLoader) {
+        return getPersistentTypeNamesInternal(devpath, envLoader);
+    }
+    private Set getPersistentTypeNamesInternal(boolean devpath, ClassLoader envLoader) {
         return _factory.getPersistentTypeNames(devpath, envLoader);
     }
 
@@ -1265,15 +1478,26 @@
      * @param envLoader the class loader to use, or null for default
      * @return the loaded classes, or empty collection if none
      */
-    public synchronized Collection loadPersistentTypes(boolean devpath,
+    public Collection loadPersistentTypes(boolean devpath,
         ClassLoader envLoader) {
+        if (_locking) {
+            return loadPersistentTypesLocking(devpath, envLoader);
+        } else {
+            return loadPersistentTypesInternal(devpath, envLoader);
+        }
+    }
+
+    private synchronized Collection loadPersistentTypesLocking(boolean devpath, ClassLoader envLoader) {
+        return loadPersistentTypesInternal(devpath, envLoader);
+    }
+
+    private Collection loadPersistentTypesInternal(boolean devpath, ClassLoader envLoader) {
         Set names = getPersistentTypeNames(devpath, envLoader);
         if (names == null || names.isEmpty())
             return Collections.EMPTY_LIST;
 
         // attempt to load classes so that they get processed
-        ClassLoader clsLoader = _conf.getClassResolverInstance().
-            getClassLoader(getClass(), envLoader);
+        ClassLoader clsLoader = _conf.getClassResolverInstance().getClassLoader(getClass(), envLoader);
         List classes = new ArrayList(names.size());
         Class cls;
         for (Iterator itr = names.iterator(); itr.hasNext();) {
@@ -1341,7 +1565,11 @@
     public void register(Class cls) {
         // buffer registered classes until an oid metadata request is made,
         // at which point we'll parse everything in the buffer
+        if (_locking) {
         synchronized (_registered) {
+                _registered.add(cls);
+            }
+        } else {
             _registered.add(cls);
         }
     }
@@ -1371,7 +1599,12 @@
         // copy into new collection to avoid concurrent mod errors on reentrant
         // registrations
         Class[] reg;
-        synchronized (_registered) {
+        if (_locking) {
+            synchronized (_registered) {
+                reg = (Class[]) _registered.toArray(new Class[_registered.size()]);
+                _registered.clear();
+            }
+        } else {
             reg = (Class[]) _registered.toArray(new Class[_registered.size()]);
             _registered.clear();
         }
@@ -1400,7 +1633,11 @@
             }
         }
         if (failed != null) {
-            synchronized (_registered) {
+            if(_locking){
+                synchronized (_registered) {
+                    _registered.addAll(failed);
+                }
+            }else{
                 _registered.addAll(failed);
             }
         }
@@ -1420,16 +1657,10 @@
         // update subclass lists; synchronize on this because accessing _metas
         // requires it
         Class leastDerived = cls;
-        synchronized (this) {
-            ClassMetaData meta;
-            for (Class anc = cls;
-                (anc = PCRegistry.getPersistentSuperclass(anc)) != null;) {
-                addToCollection(_subs, anc, cls, true);
-                meta = (ClassMetaData) _metas.get(anc);
-                if (meta != null)
-                    meta.clearSubclassCache();
-                leastDerived = anc;
-            }
+        if (_locking) {
+        	leastDerived = calcualteLeastDerivedLocking(cls);
+        } else {
+            leastDerived = calcualteLeastDerivedInternal(cls);
         }
 
         // update oid mappings if this is a base concrete class
@@ -1459,25 +1690,67 @@
 
         // update mappings from interfaces and non-pc superclasses to
         // pc implementing types
-        synchronized (_impls) {
+        if (_locking) {
+            synchronized (_impls) {
+                updateImpls(cls, leastDerived, cls);
+            }
+        } else {
             updateImpls(cls, leastDerived, cls);
         }
 
         // set alias for class
         String alias = PCRegistry.getTypeAlias(cls);
         if (alias != null) {
-            synchronized (_aliases) {
-                List classList = (List) _aliases.get(alias);
-                if (classList == null) {
-                    classList = new ArrayList(3);
-                    _aliases.put(alias, classList);
-                }
-                if (!classList.contains(cls))
-                    classList.add(cls);
+            if(_locking){
+                setAliasForClassLocking(alias, cls);
+            }else{
+                setAliasForClassInternal(alias, cls);
             }
         }
     }
-
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private void setAliasForClassLocking(String alias, Class cls){
+        synchronized(_aliases){
+            setAliasForClassInternal(alias, cls);
+        }
+    }
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private void setAliasForClassInternal(String alias, Class cls){
+        List classList = (List) _aliases.get(alias);
+        if (classList == null) {
+            classList = new ArrayList(3);
+            _aliases.put(alias, classList);
+        }
+        if (!classList.contains(cls))
+            classList.add(cls);
+    }
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private synchronized Class calcualteLeastDerivedLocking(Class cls){
+        return calcualteLeastDerivedInternal(cls);
+    }
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private Class calcualteLeastDerivedInternal(Class cls){
+        Class leastDerived = cls;
+        ClassMetaData meta;
+        for (Class anc = cls; (anc = PCRegistry.getPersistentSuperclass(anc)) != null;) {
+            addToCollection(_subs, anc, cls, true);
+            meta = (ClassMetaData) _metas.get(anc);
+            if (meta != null)
+                meta.clearSubclassCache();
+            leastDerived = anc;
+        }
+        
+        return leastDerived;
+    }
+    
     /**
      * Update the list of implementations of base classes and interfaces.
      */
@@ -1527,7 +1800,18 @@
      */
     private void addToCollection(Map map, Class key, Class value,
         boolean inheritance) {
+        if(_locking){
+            addToCollectionLocking(map, key, value, inheritance);
+        }else{
+            addToCollectionInternal(map, key, value, inheritance);
+        }
+    }
+    private void addToCollectionLocking(Map map, Class key, Class value, boolean inheritance) {
         synchronized (map) {
+            addToCollectionInternal(map, key, value, inheritance);
+        }
+    }
+    private void addToCollectionInternal(Map map, Class key, Class value, boolean inheritance) {
             Collection coll = (Collection) map.get(key);
             if (coll == null) {
                 if (inheritance) {
@@ -1540,7 +1824,6 @@
             }
             coll.add(value);
         }
-    }
 
     ///////////////////////////////
     // Configurable implementation
@@ -1549,6 +1832,7 @@
     public void setConfiguration(Configuration conf) {
         _conf = (OpenJPAConfiguration) conf;
         _log = _conf.getLog(OpenJPAConfiguration.LOG_METADATA);
+        _reorderMetaDataResolution = _conf.getCompatibilityInstance().getReorderMetaDataResolution();
     }
 
     public void startConfiguration() {
@@ -1558,6 +1842,16 @@
         initializeMetaDataFactory();
         if (_implGen == null)
             _implGen = new InterfaceImplGenerator(this);
+        if (_preload == true) {
+            _oids = new HashMap();
+            _impls = new HashMap();
+            _ifaces = new HashMap();
+            _aliases = new HashMap();
+            _pawares = new HashMap();
+            _nonMapped = new HashMap();
+            _subs = new HashMap();
+            // Wait till we're done loading MetaData to remove lock.
+        }            
     }
 
     private void initializeMetaDataFactory() {
@@ -1576,8 +1870,20 @@
     /**
      * Return query metadata for the given class, name, and classloader.
      */
-    public synchronized QueryMetaData getQueryMetaData(Class cls, String name,
+    public QueryMetaData getQueryMetaData(Class cls, String name,
         ClassLoader envLoader, boolean mustExist) {
+        if(_locking){
+            return getQueryMetaDataLocking(cls, name, envLoader, mustExist);
+        }else{
+            return getQueryMetaDataInternal(cls, name, envLoader, mustExist);
+        }
+    }
+    private synchronized QueryMetaData getQueryMetaDataLocking(Class cls, String name, ClassLoader envLoader,
+        boolean mustExist) {
+        return getQueryMetaDataInternal(cls, name, envLoader, mustExist);
+    }
+
+    private QueryMetaData getQueryMetaDataInternal(Class cls, String name, ClassLoader envLoader, boolean mustExist) {
         QueryMetaData meta = getQueryMetaDataInternal(cls, name, envLoader);
         if (meta == null) {
             // load all the metadatas for all the known classes so that
@@ -1588,12 +1894,10 @@
 
         if (meta == null && mustExist) {
             if (cls == null) {
-                throw new MetaDataException(_loc.get
-                    ("no-named-query-null-class", 
-                        getPersistentTypeNames(false, envLoader), name));
+                throw new MetaDataException(_loc.get("no-named-query-null-class", getPersistentTypeNames(false,
+                    envLoader), name));
             } else {
-                throw new MetaDataException(_loc.get("no-named-query",
-                    cls, name));
+                throw new MetaDataException(_loc.get("no-named-query", cls, name));
             }
         }
 
@@ -1646,26 +1950,45 @@
     /**
      * Return the cached query metadata.
      */
-    public synchronized QueryMetaData[] getQueryMetaDatas() {
-        return (QueryMetaData[]) _queries.values().toArray
-            (new QueryMetaData[_queries.size()]);
+    public QueryMetaData[] getQueryMetaDatas() {
+        if (_locking) {
+            synchronized (this) {
+                return (QueryMetaData[]) _queries.values().toArray(new QueryMetaData[_queries.size()]);
+            }
+        } else {
+            return (QueryMetaData[]) _queries.values().toArray(new QueryMetaData[_queries.size()]);
+        }
     }
 
     /**
      * Return the cached query metadata for the given name.
      */
-    public synchronized QueryMetaData getCachedQueryMetaData(Class cls,
+    public QueryMetaData getCachedQueryMetaData(Class cls,
         String name) {
-        return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+        if (_locking) {
+            synchronized (this) {
+                return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+            }
+        } else {
+            return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+        }
     }
 
     /**
      * Add a new query metadata to the repository and return it.
      */
-    public synchronized QueryMetaData addQueryMetaData(Class cls, String name) {
-        QueryMetaData meta = newQueryMetaData(cls, name);
-        _queries.put(getQueryKey(meta), meta);
-        return meta;
+    public QueryMetaData addQueryMetaData(Class cls, String name) {
+        if (_locking) {
+            synchronized (this) {
+                QueryMetaData meta = newQueryMetaData(cls, name);
+                _queries.put(getQueryKey(meta), meta);
+                return meta;
+            }
+        }else{
+            QueryMetaData meta = newQueryMetaData(cls, name);
+            _queries.put(getQueryKey(meta), meta);
+            return meta;   
+        }
     }
 
     /**
@@ -1680,19 +2003,35 @@
     /**
      * Remove the given query metadata from the repository.
      */
-    public synchronized boolean removeQueryMetaData(QueryMetaData meta) {
-        if (meta == null)
-            return false;
-        return _queries.remove(getQueryKey(meta)) != null;
+    public  boolean removeQueryMetaData(QueryMetaData meta) {
+        if(_locking){
+            synchronized (this) {
+                if (meta == null)
+                    return false;
+                return _queries.remove(getQueryKey(meta)) != null;
+            }
+        }else{
+            if (meta == null)
+                return false;
+            return _queries.remove(getQueryKey(meta)) != null;
+        }
     }
 
     /**
      * Remove query metadata for the given class name if in the repository.
      */
-    public synchronized boolean removeQueryMetaData(Class cls, String name) {
-        if (name == null)
-            return false;
-        return _queries.remove(getQueryKey(cls, name)) != null;
+    public boolean removeQueryMetaData(Class cls, String name) {
+        if (_locking) {
+            synchronized (this) {
+                if (name == null)
+                    return false;
+                return _queries.remove(getQueryKey(cls, name)) != null;
+            }
+        } else {
+            if (name == null)
+                return false;
+            return _queries.remove(getQueryKey(cls, name)) != null;
+        }
     }
 
     /**
@@ -1724,7 +2063,19 @@
     /**
      * Return sequence metadata for the given name and classloader.
      */
-    public synchronized SequenceMetaData getSequenceMetaData(String name,
+    public SequenceMetaData getSequenceMetaData(String name,
+        ClassLoader envLoader, boolean mustExist) {
+        if(_locking){
+            return getSequenceMetaDataLocking(name, envLoader, mustExist);
+        }else{
+            return getSequenceMetaDataInternal(name, envLoader, mustExist);
+        }
+    }
+    private synchronized SequenceMetaData getSequenceMetaDataLocking(String name,
+        ClassLoader envLoader, boolean mustExist) {
+        return getSequenceMetaDataInternal(name, envLoader, mustExist);
+    }
+    private SequenceMetaData getSequenceMetaDataInternal(String name,
         ClassLoader envLoader, boolean mustExist) {
         SequenceMetaData meta = getSequenceMetaDataInternal(name, envLoader);
         if (meta == null && SequenceMetaData.NAME_SYSTEM.equals(name)) {
@@ -1797,26 +2148,44 @@
     /**
      * Return the cached sequence metadata.
      */
-    public synchronized SequenceMetaData[] getSequenceMetaDatas() {
-        return (SequenceMetaData[]) _seqs.values().toArray
-            (new SequenceMetaData[_seqs.size()]);
+    public SequenceMetaData[] getSequenceMetaDatas() {
+        if (_locking) {
+            synchronized (this) {
+                return (SequenceMetaData[]) _seqs.values().toArray(new SequenceMetaData[_seqs.size()]);
+            }
+        } else {
+            return (SequenceMetaData[]) _seqs.values().toArray(new SequenceMetaData[_seqs.size()]);
+        }
     }
 
     /**
      * Return the cached a sequence metadata for the given name.
      */
-    public synchronized SequenceMetaData getCachedSequenceMetaData(
-        String name) {
-        return (SequenceMetaData) _seqs.get(name);
+    public SequenceMetaData getCachedSequenceMetaData(String name) {
+        if (_locking) {
+            synchronized (this) {
+                return (SequenceMetaData) _seqs.get(name);
+            }
+        } else {
+            return (SequenceMetaData) _seqs.get(name);
+        }
     }
 
     /**
      * Add a new sequence metadata to the repository and return it.
      */
-    public synchronized SequenceMetaData addSequenceMetaData(String name) {
-        SequenceMetaData meta = newSequenceMetaData(name);
-        _seqs.put(name, meta);
-        return meta;
+    public SequenceMetaData addSequenceMetaData(String name) {
+        if (_locking) {
+            synchronized (this) {
+                SequenceMetaData meta = newSequenceMetaData(name);
+                _seqs.put(name, meta);
+                return meta;
+            }
+        } else {
+            SequenceMetaData meta = newSequenceMetaData(name);
+            _seqs.put(name, meta);
+            return meta;
+        }
     }
 
     /**
@@ -1829,44 +2198,76 @@
     /**
      * Remove the given sequence metadata from the repository.
      */
-    public synchronized boolean removeSequenceMetaData(SequenceMetaData meta) {
-        if (meta == null)
-            return false;
-        return _seqs.remove(meta.getName()) != null;
+    public boolean removeSequenceMetaData(SequenceMetaData meta) {
+        if (_locking) {
+            synchronized (this) {
+                if (meta == null)
+                    return false;
+                return _seqs.remove(meta.getName()) != null;
+            }
+        } else {
+            if (meta == null)
+                return false;
+            return _seqs.remove(meta.getName()) != null;
+        }
     }
 
     /**
      * Remove sequence metadata for the name if in the repository.
      */
-    public synchronized boolean removeSequenceMetaData(String name) {
-        if (name == null)
-            return false;
-        return _seqs.remove(name) != null;
+    public boolean removeSequenceMetaData(String name) {
+        if (_locking) {
+            synchronized (this) {
+                if (name == null)
+                    return false;
+                return _seqs.remove(name) != null;
+            }
+        }else{
+            if (name == null)
+                return false;
+            return _seqs.remove(name) != null;
+        }
     }
 
     /**
      * Add the given system lifecycle listener.
      */
-    public synchronized void addSystemListener(Object listener) {
-        // copy to avoid issues with ListenerList and avoid unncessary
-        // locking on the list during runtime
-        LifecycleEventManager.ListenerList listeners = new
-            LifecycleEventManager.ListenerList(_listeners);
-        listeners.add(listener);
-        _listeners = listeners;
+    public void addSystemListener(Object listener) {
+        if (_locking) {
+            synchronized (this) {
+                // copy to avoid issues with ListenerList and avoid unncessary
+                // locking on the list during runtime
+                LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
+                listeners.add(listener);
+                _listeners = listeners;
+            }
+        } else {
+            LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
+            listeners.add(listener);
+            _listeners = listeners;
+        }
     }
 
     /**
      * Remove the given system lifecycle listener.
      */
-    public synchronized boolean removeSystemListener(Object listener) {
+    public boolean removeSystemListener(Object listener) {
+        if (_locking) {
+            return removeSystemListenerLocking(listener);
+        } else {
+            return removeSystemListenerInternal(listener);
+        }
+    }
+    private synchronized boolean removeSystemListenerLocking(Object listener) {
+        return removeSystemListenerInternal(listener);
+    }
+    private boolean removeSystemListenerInternal(Object listener) {
         if (!_listeners.contains(listener))
             return false;
 
         // copy to avoid issues with ListenerList and avoid unncessary
         // locking on the list during runtime
-        LifecycleEventManager.ListenerList listeners = new
-            LifecycleEventManager.ListenerList(_listeners);
+        LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
         listeners.remove(listener);
         _listeners = listeners;
         return true;
@@ -1882,7 +2283,17 @@
     /**
      * Free the resources used by this repository. Closes all user sequences.
      */
-    public synchronized void close() {
+    public void close() {
+        if(_locking){
+            closeLocking();
+        }else{
+            closeInternal();
+        }
+    }
+    private synchronized void closeLocking() {
+        closeInternal();
+    }
+    private void closeInternal() {
         SequenceMetaData[] smds = getSequenceMetaDatas();
         for (int i = 0; i < smds.length; i++)
             smds[i].close();
@@ -1922,7 +2333,17 @@
      * @param fmd
      * @return XML metadata
      */
-    public synchronized XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+    public XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+        if(_locking){
+            return getXMLMetaDataLocking(fmd);
+        }else{
+            return getXMLMetaDataInternal(fmd);
+        }
+    }
+    private synchronized XMLMetaData getXMLMetaDataLocking(FieldMetaData fmd) {
+        return getXMLMetaDataInternal(fmd);
+    }
+    private XMLMetaData getXMLMetaDataInternal(FieldMetaData fmd) {
         Class cls = fmd.getDeclaredType();
         // check if cached before
         XMLMetaData xmlmeta = (XMLClassMetaData) _xmlmetas.get(cls);
@@ -1948,7 +2369,11 @@
         
         // synchronize on this rather than the map, because all other methods
         // that access _xmlmetas are synchronized on this
+        if(_locking){
         synchronized (this) {
+                    _xmlmetas.put(type, meta);
+                }
+        }else{
             _xmlmetas.put(type, meta);
         }
         return meta;
@@ -1983,4 +2408,204 @@
     public XMLFieldMetaData newXMLFieldMetaData(Class type, String name) {
         return new XMLFieldMetaData(type, name);
     }
+    
+    /**
+     * This helper method returns true if Options paramater has the property Preload
+     * set to true.
+     */
+    public static boolean needsPreload(Options o) {
+        if (o.getBooleanProperty(PRELOAD_STR) == true) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Analyzes the list of ClassMetaData in the supplied list for any which has foreign keys to other ClassMetaData 
+     * instances in its identity (in other words, PCTypes which have primary keys that are foreign keys to other
+     * tables), and returns a list arranged so that a ClassMetaData that depends on another ClassMetaData appears
+     * after it in the list.
+     *
+     * @param cmdList - List of ClassMetaData to examine
+     * @return - List of ClassMetaData, with ClassMetaData dependees moved after the last identified dependent 
+     *           ClassMetaData, if any move is necessary.
+     */
+    private List<ClassMetaData> resolveFKInPKDependenciesOrdering(List<ClassMetaData> cmdList) {
+        HashMap<ClassMetaData, CMDDependencyNode> nodeMap = new HashMap<ClassMetaData, CMDDependencyNode>();
+        HashSet<CMDDependencyNode> nodesWithDependenciesSet = new HashSet<CMDDependencyNode>();
+        ArrayList<CMDDependencyNode> nodeList = new ArrayList<CMDDependencyNode>(cmdList.size());
+        
+        // Initial analysis of ClassMetaData objects -- Populate the linked list with objects in the same order of 
+        // appearance in the original list. Identify CMDs whose identities have a FK to another CMD, and catalog that 
+        // dependency.
+        for (ClassMetaData cmd : cmdList) {
+            // Add this node to the list
+            CMDDependencyNode node = nodeMap.get(cmd);
+            if (node == null) {
+                node = new CMDDependencyNode(cmd);
+                nodeMap.put(cmd, node);
+            }
+            nodeList.add(node);
+            
+            // Examine its primary key fields, flag any references to another PCType that is defined in cmdList as a 
+            // dependency
+            FieldMetaData[] fmdArr = cmd.getPrimaryKeyFields();
+            for (FieldMetaData fmd : fmdArr) {
+                ValueMetaData vmd = fmd.getValue();
+                if (vmd.isTypePC()) {
+                    ClassMetaData targetCMD = vmd.getDeclaredTypeMetaData();
+
+                    // Only process entries which are in the cmdList, as we don't want to be adding anything new.
+                    if (!cmdList.contains(targetCMD)) {
+                        continue;
+                    }
+
+                    // Register the dependency
+                    CMDDependencyNode targetNode = null;
+                    if ((targetNode = nodeMap.get(targetCMD)) == null) {
+                        targetNode = new CMDDependencyNode(targetCMD);
+                        nodeMap.put(targetCMD, targetNode);
+                    }
+                    node.registerDependentNode(targetNode);
+                    nodesWithDependenciesSet.add(node);
+                }
+            }
+        }
+        
+        // Analysis is complete. For each CMD that has an identity foreign key dependency on another CMD, ensure that it
+        // appears later in the list then the CMD it is dependent on. If it appears earlier, move it immediately after 
+        // the CMD. If there are multiple CMDs the identity is dependent on, move it after the last dependency in
+        // the linked list.
+        for (CMDDependencyNode node : nodesWithDependenciesSet) {
+            // Check if there is a cycle (dependencies or subdependencies that create a cycle in the graph. If one is 
+            // detected, then this algorithm cannot be used to reorder the CMD list.  Emit a warning, and return the 
+            // original list.
+            if (node.checkForCycle()) {
+                if (_log.isWarnEnabled()) {
+                    _log.warn(_loc.get("cmd-discover-cycle", node.getCmd().getResourceName()));
+                }
+                return cmdList;
+            }
+ 
+            int nodeIndex = nodeList.indexOf(node);
+            Set<CMDDependencyNode> dependencies = node.getDependsOnSet();       
+            
+            // If the current node has a dependency that appears later in the list, then this node needs
+            // to be moved to the point immediately after that dependency.
+            CMDDependencyNode moveAfter = null;
+            int moveAfterIndex = -1;
+            for (CMDDependencyNode depNode : dependencies) {               
+                int dependencyIndex = nodeList.indexOf(depNode);
+                if ((nodeIndex < dependencyIndex) && (moveAfterIndex < dependencyIndex)) {
+                    moveAfter = depNode;
+                    moveAfterIndex = dependencyIndex;
+                }
+            }
+            if (moveAfter != null) {
+                nodeList.remove(nodeIndex);
+                nodeList.add(nodeList.indexOf(moveAfter) + 1, node);
+            }      
+        }
+        
+        // Sorting is complete, build the return list.  Clear the dependsOnSet for the GC.
+        ArrayList<ClassMetaData> returnList = new ArrayList<ClassMetaData>();
+        for (CMDDependencyNode current : nodeList) {
+            returnList.add(current.getCmd());
+            current.getDependsOnSet().clear();
+        }
+        
+        return returnList;
+    }
+
+    /**
+     * Linked list node class for managing any foreign keys in the identity of a ClassMetaData instance.
+     * 
+     */
+    private class CMDDependencyNode {
+        private ClassMetaData cmd;
+
+        // Marker for quick determination if this node has dependencies
+        private boolean hasDependencies = false;
+
+        // List of ClassMetaData objects this ClassMetaData depends on
+        private HashSet<CMDDependencyNode> dependsOnSet = new HashSet<CMDDependencyNode>();
+
+        /**
+         * Inner class constructor
+         */
+        CMDDependencyNode(ClassMetaData cmd) {
+            this.cmd = cmd;
+        }
+
+        /**
+         * Returns the ClassMetaData instance referenced by this node.
+         */
+        public ClassMetaData getCmd() {
+            return cmd;
+        }
+
+        /**
+         * 
+         * @return true if this node's ClassMetaData has a FK in its identity that refers to another ClassMetaData; 
+         *         false if it does not.
+         */
+        public boolean getHasDependencies() {
+            return hasDependencies;
+        }
+
+        /**
+         * Registers a ClassMetaData modelled by a CMDDependencyNode as a dependency of this ClassMetaData.
+         * 
+         */
+        public void registerDependentNode(CMDDependencyNode node) {
+            getDependsOnSet().add(node);
+            hasDependencies = true;
+        }
+
+        /**
+         * Returns a Set containing all of the CMDDependencyNode instances that this node has a FK in identity 
+         * dependency on.
+         * 
+         */
+        public Set<CMDDependencyNode> getDependsOnSet() {
+            return dependsOnSet;
+        }
+
+        /**
+         * Checks all dependencies, and sub-dependencies, for any cycles in the dependency graph.
+         * 
+         * @return true if a cycle was discovered, false if not.
+         */
+        public boolean checkForCycle() {
+            java.util.Stack<CMDDependencyNode> visitStack = new java.util.Stack<CMDDependencyNode>();
+            return internalCheckForCycle(visitStack);
+        }
+
+        /**
+         * Internal implementation of the cycle detection.
+         * 
+         * @param visitStack
+         * @return true if a cycle is detected, false if no cycle was detected.
+         */
+        private boolean internalCheckForCycle(java.util.Stack<CMDDependencyNode> visitStack) {
+            if (visitStack.contains(this)) {
+                return true;
+            }
+            visitStack.push(this);
+
+            try {
+                for (CMDDependencyNode node : dependsOnSet) {
+                    if (node.getHasDependencies()) {
+                        if (node.internalCheckForCycle(visitStack) == true) {
+                            return true;
+                        }
+                    }
+                }
+            } finally {
+                visitStack.pop();
+            }
+            
+            return false;
+        }
+    }
 }
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NonPersistentMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NonPersistentMetaData.java
index 81ff89e..2ac0349 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NonPersistentMetaData.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NonPersistentMetaData.java
@@ -1,149 +1,149 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.meta;
-
-import java.io.File;
-import java.io.Serializable;
-
-import org.apache.openjpa.lib.meta.SourceTracker;
-import org.apache.openjpa.lib.xml.Commentable;
-
-/**
- * Metadata about a persistence-aware type.
- *
- * @author Pinaki Poddar
- */
-public class NonPersistentMetaData 
-	implements Comparable, SourceTracker, Commentable, MetaDataContext,
-        Serializable {
-    public static final int TYPE_PERSISTENCE_AWARE = 1;
-    public static final int TYPE_NON_MAPPED_INTERFACE = 2;
-
-    private final MetaDataRepository _repos;
-	private final Class _class;
-    private final int _type;
-	
-    private File _srcFile = null;
-    private int _lineNum = 0;  
-    private int _colNum = 0;  
-    
-    private int _srcType = SRC_OTHER;
-    private String[] _comments = null;
-    private int _listIndex = -1;
-	
-	protected NonPersistentMetaData(Class cls, MetaDataRepository repos, 
-        int type) {
-		_repos = repos;
-		_class = cls;
-        _type = type;
-	}
-	
-    /**
-     * Owning repository.
-     */
-	public MetaDataRepository getRepository() {
-		return _repos;
-	}
-	
-    /**
-     * Persistence-aware type.
-     */
-	public Class getDescribedType() {
-		return _class;
-	}
-
-    /**
-     * The type of metadata.
-     */
-    public int getType() {
-        return _type;
-    }
-	
-    /**
-     * The index in which this class was listed in the metadata. Defaults to
-     * <code>-1</code> if this class was not listed in the metadata.
-     */
-    public int getListingIndex() {
-        return _listIndex;
-    }
-
-    /**
-     * The index in which this field was listed in the metadata. Defaults to
-     * <code>-1</code> if this class was not listed in the metadata.
-     */
-    public void setListingIndex(int index) {
-        _listIndex = index;
-    }
-
-    public File getSourceFile() {
-        return _srcFile;
-    }
-
-    public Object getSourceScope() {
-        return null;
-    }
-
-    public int getSourceType() {
-        return _srcType;
-    }
-
-    public void setSource(File file, int srcType) {
-        _srcFile = file;
-        _srcType = srcType;
-    }
-
-    public int getLineNumber() {
-        return _lineNum;
-    }
-
-    public void setLineNumber(int lineNum) {
-        _lineNum = lineNum;
-    }
-
-    public int getColNumber() {
-        return _colNum;
-    }
-
-    public void setColNumber(int colNum) {
-        _colNum = colNum;
-    }
-    
-    public String getResourceName() {
-        return _class.getName();
-    }
-
-    public String[] getComments() {
-        return (_comments == null) ? ClassMetaData.EMPTY_COMMENTS : _comments;
-    }
-
-    public void setComments(String[] comments) {
-        _comments = comments;
-    }
-    
-    public int compareTo(Object o) {
-        if (o == this)
-            return 0;
-        if (!(o instanceof NonPersistentMetaData))
-        	return 1;
-        NonPersistentMetaData other = (NonPersistentMetaData) o;
-        if (_type != other.getType())
-            return _type - other.getType();
-        return _class.getName().compareTo(other.getDescribedType().getName());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.meta;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.apache.openjpa.lib.meta.SourceTracker;
+import org.apache.openjpa.lib.xml.Commentable;
+
+/**
+ * Metadata about a persistence-aware type.
+ *
+ * @author Pinaki Poddar
+ */
+public class NonPersistentMetaData 
+	implements Comparable, SourceTracker, Commentable, MetaDataContext,
+        Serializable {
+    public static final int TYPE_PERSISTENCE_AWARE = 1;
+    public static final int TYPE_NON_MAPPED_INTERFACE = 2;
+
+    private final MetaDataRepository _repos;
+	private final Class _class;
+    private final int _type;
+	
+    private File _srcFile = null;
+    private int _lineNum = 0;  
+    private int _colNum = 0;  
+    
+    private int _srcType = SRC_OTHER;
+    private String[] _comments = null;
+    private int _listIndex = -1;
+	
+	protected NonPersistentMetaData(Class cls, MetaDataRepository repos, 
+        int type) {
+		_repos = repos;
+		_class = cls;
+        _type = type;
+	}
+	
+    /**
+     * Owning repository.
+     */
+	public MetaDataRepository getRepository() {
+		return _repos;
+	}
+	
+    /**
+     * Persistence-aware type.
+     */
+	public Class getDescribedType() {
+		return _class;
+	}
+
+    /**
+     * The type of metadata.
+     */
+    public int getType() {
+        return _type;
+    }
+	
+    /**
+     * The index in which this class was listed in the metadata. Defaults to
+     * <code>-1</code> if this class was not listed in the metadata.
+     */
+    public int getListingIndex() {
+        return _listIndex;
+    }
+
+    /**
+     * The index in which this field was listed in the metadata. Defaults to
+     * <code>-1</code> if this class was not listed in the metadata.
+     */
+    public void setListingIndex(int index) {
+        _listIndex = index;
+    }
+
+    public File getSourceFile() {
+        return _srcFile;
+    }
+
+    public Object getSourceScope() {
+        return null;
+    }
+
+    public int getSourceType() {
+        return _srcType;
+    }
+
+    public void setSource(File file, int srcType) {
+        _srcFile = file;
+        _srcType = srcType;
+    }
+
+    public int getLineNumber() {
+        return _lineNum;
+    }
+
+    public void setLineNumber(int lineNum) {
+        _lineNum = lineNum;
+    }
+
+    public int getColNumber() {
+        return _colNum;
+    }
+
+    public void setColNumber(int colNum) {
+        _colNum = colNum;
+    }
+    
+    public String getResourceName() {
+        return _class.getName();
+    }
+
+    public String[] getComments() {
+        return (_comments == null) ? ClassMetaData.EMPTY_COMMENTS : _comments;
+    }
+
+    public void setComments(String[] comments) {
+        _comments = comments;
+    }
+    
+    public int compareTo(Object o) {
+        if (o == this)
+            return 0;
+        if (!(o instanceof NonPersistentMetaData))
+        	return 1;
+        NonPersistentMetaData other = (NonPersistentMetaData) o;
+        if (_type != other.getType())
+            return _type - other.getType();
+        return _class.getName().compareTo(other.getDescribedType().getName());
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigDecimalId.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigDecimalId.java
index 529b9f0..b5aa972 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigDecimalId.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigDecimalId.java
@@ -1,74 +1,74 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.math.BigDecimal;
-
-/**
- * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
- * @since 1.1.0
- */
-public class BigDecimalId
-    extends OpenJPAId {
-
-    private final BigDecimal key;
-
-    public BigDecimalId(Class cls, String key) {
-        this(cls, (key == null) ? null : new BigDecimal(key));
-    }
-
-    public BigDecimalId(Class cls, BigDecimal key) {
-        super(cls);
-        this.key = key;
-    }
-
-    public BigDecimalId(Class cls, BigDecimal key, boolean subs) {
-        super(cls, subs);
-        this.key = key;
-    }
-
-    public BigDecimal getId() {
-        return key;
-    }
-
-    public Object getIdObject() {
-        return key;
-    }
-
-    public String toString() {
-        if (key == null)
-            return "NULL";
-
-        return key.toString();
-    }
-
-    protected int idHash() {
-        if (key != null)
-            return key.hashCode();
-
-        return 0;
-    }
-
-    protected boolean idEquals(OpenJPAId other) {
-        if(key == null)
-            return false;
-
-        return key.equals(other);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.math.BigDecimal;
+
+/**
+ * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
+ * @since 1.1.0
+ */
+public class BigDecimalId
+    extends OpenJPAId {
+
+    private final BigDecimal key;
+
+    public BigDecimalId(Class cls, String key) {
+        this(cls, (key == null) ? null : new BigDecimal(key));
+    }
+
+    public BigDecimalId(Class cls, BigDecimal key) {
+        super(cls);
+        this.key = key;
+    }
+
+    public BigDecimalId(Class cls, BigDecimal key, boolean subs) {
+        super(cls, subs);
+        this.key = key;
+    }
+
+    public BigDecimal getId() {
+        return key;
+    }
+
+    public Object getIdObject() {
+        return key;
+    }
+
+    public String toString() {
+        if (key == null)
+            return "NULL";
+
+        return key.toString();
+    }
+
+    protected int idHash() {
+        if (key != null)
+            return key.hashCode();
+
+        return 0;
+    }
+
+    protected boolean idEquals(OpenJPAId other) {
+        if(key == null)
+            return false;
+
+        return key.equals(other);
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigIntegerId.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigIntegerId.java
index 95e9053..55a5976 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigIntegerId.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/BigIntegerId.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.math.BigInteger;
-
-/**
- * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
- * @since 1.1.0
- */
-public class BigIntegerId
-    extends OpenJPAId {
-
-    private final BigInteger key;
-
-    public BigIntegerId(Class cls, String key) {
-        this(cls, (key == null) ? null : new BigInteger(key));
-    }
-
-    public BigIntegerId(Class cls, BigInteger key) {
-        super(cls);
-        this.key = key;
-    }
-
-    public BigIntegerId(Class cls, BigInteger key, boolean subs) {
-        super(cls, subs);
-        this.key = key;
-    }
-
-    public BigInteger getId() {
-        return key;
-    }
-
-    public Object getIdObject() {
-        return key;
-    }
-
-    public String toString() {
-        if (key == null)
-            return "NULL";
-
-        return key.toString();
-    }
-
-    protected int idHash() {
-        if (key != null)
-            return key.hashCode();
-
-        return 0;
-    }
-
-    protected boolean idEquals(OpenJPAId other) {
-        if (key == null)
-            return false;
-
-        return key.equals(other);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.math.BigInteger;
+
+/**
+ * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
+ * @since 1.1.0
+ */
+public class BigIntegerId
+    extends OpenJPAId {
+
+    private final BigInteger key;
+
+    public BigIntegerId(Class cls, String key) {
+        this(cls, (key == null) ? null : new BigInteger(key));
+    }
+
+    public BigIntegerId(Class cls, BigInteger key) {
+        super(cls);
+        this.key = key;
+    }
+
+    public BigIntegerId(Class cls, BigInteger key, boolean subs) {
+        super(cls, subs);
+        this.key = key;
+    }
+
+    public BigInteger getId() {
+        return key;
+    }
+
+    public Object getIdObject() {
+        return key;
+    }
+
+    public String toString() {
+        if (key == null)
+            return "NULL";
+
+        return key.toString();
+    }
+
+    protected int idHash() {
+        if (key != null)
+            return key.hashCode();
+
+        return 0;
+    }
+
+    protected boolean idEquals(OpenJPAId other) {
+        if (key == null)
+            return false;
+
+        return key.equals(other);
+    }
+
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/CacheMap.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/CacheMap.java
index 123e96a..d885a5d 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/CacheMap.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/CacheMap.java
@@ -1,642 +1,642 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.util.AbstractCollection;
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.iterators.FilterIterator;
-import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.openjpa.lib.util.LRUMap;
-import org.apache.openjpa.lib.util.ReferenceMap;
-import org.apache.openjpa.lib.util.SizedMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Fixed-size map that has ability to pin/unpin entries and move overflow to
- * a backing soft map.
- *
- * @author Patrick Linskey
- * @author Abe White
- */
-public class CacheMap
-    implements Map {
-
-    /**
-     * The map for non-expired and non-pinned references.
-     */
-    protected final SizedMap cacheMap;
-
-    /**
-     * The map for expired references.
-     */
-    protected final SizedMap softMap;
-
-    /**
-     * The set of objects pinned into the cache.
-     */
-    protected final Map pinnedMap;
-
-    // number of pinned values (not including keys not mapped to values)
-    private int _pinnedSize = 0;
-
-    private final ReentrantLock _writeLock = new ReentrantLock();
-    private final ReentrantLock _readLock;
-
-    /**
-     * Create a non-LRU (and therefore highly concurrent) cache map with a
-     * size of 1000.
-     */
-    public CacheMap() {
-        this(false, 1000);
-    }
-
-    /**
-     * Create a cache map with the given properties.
-     */
-    public CacheMap(boolean lru, int max) {
-        this(lru, max, max / 2, .75F);
-    }
-
-    /**
-     * @deprecated use {@link CacheMap#CacheMap(boolean, int, int, float, int)}
-     * instead.
-     */
-    public CacheMap(boolean lru, int max, int size, float load) {
-        this(lru, max, size, load, 16);
-    }
-
-    /**
-     * Create a cache map with the given properties.
-     *
-     * @since 1.1.0
-     */
-    public CacheMap(boolean lru, int max, int size, float load,
-        int concurrencyLevel) {
-        if (size < 0)
-            size = 500;
-
-        softMap = new ConcurrentReferenceHashMap(ReferenceMap.HARD,
-            ReferenceMap.SOFT, size, load) {
-            public void overflowRemoved(Object key, Object value) {
-                softMapOverflowRemoved(key, value);
-            }
-
-            public void valueExpired(Object key) {
-                softMapValueExpired(key);
-            }
-        };
-        pinnedMap = new ConcurrentHashMap();
-
-        if (!lru) {
-            cacheMap = new ConcurrentHashMap(size, load) {
-                public void overflowRemoved(Object key, Object value) {
-                    cacheMapOverflowRemoved(key, value);
-                }
-            };
-            _readLock = null;
-        } else {
-            cacheMap = new LRUMap(size, load) {
-                public void overflowRemoved(Object key, Object value) {
-                    cacheMapOverflowRemoved(key, value);
-                }
-            };
-            _readLock = _writeLock;
-        }
-        if (max < 0)
-            max = Integer.MAX_VALUE;
-        cacheMap.setMaxSize(max);
-    }
-
-    /**
-     * Called from {@link SizedMap#overflowRemoved} in the cache map.
-     */
-    protected void cacheMapOverflowRemoved(Object key, Object value) {
-        if (softMap.size() < softMap.getMaxSize())
-            put(softMap, key, value);
-        else
-            entryRemoved(key, value, true);
-    }
-
-    /**
-     * Called from {@link SizedMap#overflowRemoved} in the soft map.
-     */
-    protected void softMapOverflowRemoved(Object key, Object value) {
-        entryRemoved(key, value, true);
-    }
-
-    /**
-     * Called when a value expires from the soft map.
-     */
-    protected void softMapValueExpired(Object key) {
-        entryRemoved(key, null, true);
-    }
-
-    /**
-     * Put the given entry into the given map. Allows subclasses to
-     * take additional actions.
-     */
-    protected Object put(Map map, Object key, Object value) {
-        return map.put(key, value);
-    }
-
-    /**
-     * Remove the given key from the given map. Allows subclasses to
-     * take additional actions.
-     */
-    protected Object remove(Map map, Object key) {
-        return map.remove(key);
-    }
-
-    /**
-     * Acquire read lock.
-     */
-    public void readLock() {
-        if (_readLock != null)
-            _readLock.lock();
-    }
-
-    /**
-     * Release read lock.
-     */
-    public void readUnlock() {
-        if (_readLock != null)
-            _readLock.unlock();
-    }
-
-    /**
-     * Acquire write lock.
-     */
-    public void writeLock() {
-        _writeLock.lock();
-    }
-
-    /**
-     * Release write lock.
-     */
-    public void writeUnlock() {
-        _writeLock.unlock();
-    }
-
-    /**
-     * Whether this cache map uses LRU eviction.
-     */
-    public boolean isLRU() {
-        return _readLock != null;
-    }
-
-    /**
-     * The maximum number of hard references to maintain, or -1 for no limit.
-     */
-    public void setCacheSize(int size) {
-        writeLock();
-        try {
-            cacheMap.setMaxSize((size < 0) ? Integer.MAX_VALUE : size);
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    /**
-     * The maximum number of hard references to maintain, or -1 for no limit.
-     */
-    public int getCacheSize() {
-        int max = cacheMap.getMaxSize();
-        return (max == Integer.MAX_VALUE) ? -1 : max;
-    }
-
-    /**
-     * The maximum number of soft references to maintain, or -1 for no limit.
-     */
-    public void setSoftReferenceSize(int size) {
-        writeLock();
-        try {
-            softMap.setMaxSize((size < 0) ? Integer.MAX_VALUE : size);
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    /**
-     * The maximum number of soft references to maintain, or -1 for no limit.
-     */
-    public int getSoftReferenceSize() {
-        int max = softMap.getMaxSize();
-        return (max == Integer.MAX_VALUE) ? -1 : max;
-    }
-
-    /**
-     * The keys pinned into the map.
-     */
-    public Set getPinnedKeys() {
-        readLock();
-        try {
-            return Collections.unmodifiableSet(pinnedMap.keySet());
-        } finally {
-            readUnlock();
-        }
-    }
-
-    /**
-     * Locks the given key and its value into the map. Objects pinned into
-     * the map are not counted towards the maximum cache size, and are never
-     * evicted implicitly. You may pin keys for which no value is in the map.
-     *
-     * @return true if the givne key's value was pinned; false if no value
-     * for the given key is cached
-     */
-    public boolean pin(Object key) {
-        writeLock();
-        try {
-            // if we don't have a pinned map we need to create one; else if the
-            // pinned map already contains the key, nothing to do
-            if (pinnedMap.containsKey(key))
-                return pinnedMap.get(key) != null;
-
-            // check other maps for key
-            Object val = remove(cacheMap, key);
-            if (val == null)
-                val = remove(softMap, key);
-
-            // pin key
-            put(pinnedMap, key, val);
-            if (val != null) {
-                _pinnedSize++;
-                return true;
-            }
-            return false;
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    /**
-     * Undo a pinning.
-     */
-    public boolean unpin(Object key) {
-        writeLock();
-        try {
-            Object val = remove(pinnedMap, key);
-            if (val != null) {
-                // put back into unpinned cache
-                put(key, val);
-                _pinnedSize--;
-                return true;
-            }
-            return false;
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    /**
-     * Invoked when a key-value pair is evicted from this data
-     * structure. This is invoked with <code>expired</code> set to
-     * <code>true</code> when an object is dropped because of space
-     * requirements or through garbage collection of soft references.
-     * It is invoked with <code>expired</code> set to <code>false</code>
-     * when an object is explicitly removed via the {@link #remove} or
-     * {@link #clear} methods. This may be invoked more than once for a
-     * given entry.
-     *
-     * @param value may be null if the value was a soft reference that has
-     * been GCd
-     * @since 0.2.5.0
-     */
-    protected void entryRemoved(Object key, Object value, boolean expired) {
-    }
-
-    /**
-     * Invoked when an entry is added to the cache. This may be invoked
-     * more than once for an entry.
-     */
-    protected void entryAdded(Object key, Object value) {
-    }
-
-    public Object get(Object key) {
-        readLock();
-        try {
-            Object val = pinnedMap.get(key);
-            if (val != null)
-                return val;
-
-            val = cacheMap.get(key);
-            if (val == null) {
-                // if we find the key in the soft map, move it back into
-                // the primary map
-                val = softMap.get(key);
-                if (val != null)
-                    put(key, val);
-            }
-            return val;
-        } finally {
-            readUnlock();
-        }
-    }
-
-    public Object put(Object key, Object value) {
-        writeLock();
-        try {
-            // if the key is pinned, just interact directly with the pinned map
-            Object val;
-            if (pinnedMap.containsKey(key)) {
-                val = put(pinnedMap, key, value);
-                if (val == null) {
-                    _pinnedSize++;
-                    entryAdded(key, value);
-                } else {
-                    entryRemoved(key, val, false);
-                    entryAdded(key, value);
-                }
-                return val;
-            }
-
-            // if no hard refs, don't put anything
-            if (cacheMap.getMaxSize() == 0)
-                return null;
-
-            // otherwise, put the value into the map and clear it from the
-            // soft map
-            val = put(cacheMap, key, value);
-            if (val == null) {
-                val = remove(softMap, key);
-                if (val == null)
-                    entryAdded(key, value);
-                else {
-                    entryRemoved(key, val, false);
-                    entryAdded(key, value);
-                }
-            } else {
-                entryRemoved(key, val, false);
-                entryAdded(key, value);
-            }
-            return val;
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    public void putAll(Map map) {
-        Map.Entry entry;
-        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            put(entry.getKey(), entry.getValue());
-        }
-    }
-
-    /**
-     * If <code>key</code> is pinned into the cache, the pin is
-     * cleared and the object is removed.
-     */
-    public Object remove(Object key) {
-        writeLock();
-        try {
-            // if the key is pinned, just interact directly with the
-            // pinned map
-            Object val;
-            if (pinnedMap.containsKey(key)) {
-                // re-put with null value; we still want key pinned
-                val = put(pinnedMap, key, null);
-                if (val != null) {
-                    _pinnedSize--;
-                    entryRemoved(key, val, false);
-                }
-                return val;
-            }
-
-            val = remove(cacheMap, key);
-            if (val == null)
-                val = softMap.remove(key);
-            if (val != null)
-                entryRemoved(key, val, false);
-
-            return val;
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    /**
-     * Removes pinned objects as well as unpinned ones.
-     */
-    public void clear() {
-        writeLock();
-        try {
-            notifyEntryRemovals(pinnedMap.entrySet());
-            pinnedMap.clear();
-            _pinnedSize = 0;
-
-            notifyEntryRemovals(cacheMap.entrySet());
-            cacheMap.clear();
-
-            notifyEntryRemovals(softMap.entrySet());
-            softMap.clear();
-        } finally {
-            writeUnlock();
-        }
-    }
-
-    private void notifyEntryRemovals(Set set) {
-        Map.Entry entry;
-        for (Iterator itr = set.iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            if (entry.getValue() != null)
-                entryRemoved(entry.getKey(), entry.getValue(), false);
-        }
-    }
-
-    public int size() {
-        readLock();
-        try {
-            return _pinnedSize + cacheMap.size() + softMap.size();
-        } finally {
-            readUnlock();
-        }
-    }
-
-    public boolean isEmpty() {
-        return size() == 0;
-    }
-
-    public boolean containsKey(Object key) {
-        readLock();
-        try {
-            return pinnedMap.get(key) != null
-                || cacheMap.containsKey(key)
-                || softMap.containsKey(key);
-        } finally {
-            readUnlock();
-        }
-    }
-
-    public boolean containsValue(Object val) {
-        readLock();
-        try {
-            return pinnedMap.containsValue(val)
-                || cacheMap.containsValue(val)
-                || softMap.containsValue(val);
-        } finally {
-            readUnlock();
-        }
-    }
-
-    public Set keySet() {
-        return new KeySet();
-    }
-
-    public Collection values() {
-        return new ValueCollection();
-    }
-
-    public Set entrySet() {
-        return new EntrySet();
-    }
-
-    public String toString() {
-        readLock();
-        try {
-            return "CacheMap:" + cacheMap.toString() + "::"
-                + softMap.toString();
-        } finally {
-            readUnlock();
-        }
-    }
-
-    /**
-     * View of the entry set.
-     */
-    private class EntrySet
-        extends AbstractSet {
-
-        public int size() {
-            return CacheMap.this.size();
-        }
-
-        public boolean add(Object o) {
-            Map.Entry entry = (Map.Entry) o;
-            put(entry.getKey(), entry.getValue());
-            return true;
-        }
-
-        public Iterator iterator() {
-            return new EntryIterator(EntryIterator.ENTRY);
-        }
-    }
-
-    /**
-     * View of the key set.
-     */
-    private class KeySet
-        extends AbstractSet {
-
-        public int size() {
-            return CacheMap.this.size();
-        }
-
-        public Iterator iterator() {
-            return new EntryIterator(EntryIterator.KEY);
-        }
-    }
-
-    /**
-     * View of the value collection.
-     */
-    private class ValueCollection
-        extends AbstractCollection {
-
-        public int size() {
-            return CacheMap.this.size();
-        }
-
-        public Iterator iterator() {
-            return new EntryIterator(EntryIterator.VALUE);
-        }
-    }
-
-    /**
-     * Iterator over all entries.
-     */
-    private class EntryIterator
-        implements Iterator, Predicate {
-
-        public static final int ENTRY = 0;
-        public static final int KEY = 1;
-        public static final int VALUE = 2;
-
-        private final IteratorChain _itr = new IteratorChain();
-        private final int _type;
-
-        public EntryIterator(int type) {
-            _type = type;
-            _itr.addIterator(new FilterIterator(getView(pinnedMap), this));
-            _itr.addIterator(getView(cacheMap));
-            _itr.addIterator(getView(softMap));
-        }
-
-        /**
-         * Return an iterator over the appropriate view of the given map.
-         */
-        private Iterator getView(Map m) {
-            if (m == null)
-                return null;
-
-            switch (_type) {
-                case KEY:
-                    return m.keySet().iterator();
-                case VALUE:
-                    return m.values().iterator();
-                default:
-                    return m.entrySet().iterator();
-            }
-        }
-
-        public boolean hasNext() {
-            return _itr.hasNext();
-        }
-
-        public Object next() {
-            return _itr.next();
-        }
-
-        public void remove() {
-            _itr.remove();
-        }
-
-        public boolean evaluate(Object obj) {
-            switch (_type) {
-                case ENTRY:
-                    return ((Map.Entry) obj).getValue() != null;
-			case VALUE:
-				return obj != null;
-			default:
-				return true;
-			}
-		}
-	}
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.iterators.FilterIterator;
+import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.openjpa.lib.util.LRUMap;
+import org.apache.openjpa.lib.util.ReferenceMap;
+import org.apache.openjpa.lib.util.SizedMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Fixed-size map that has ability to pin/unpin entries and move overflow to
+ * a backing soft map.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ */
+public class CacheMap
+    implements Map {
+
+    /**
+     * The map for non-expired and non-pinned references.
+     */
+    protected final SizedMap cacheMap;
+
+    /**
+     * The map for expired references.
+     */
+    protected final SizedMap softMap;
+
+    /**
+     * The set of objects pinned into the cache.
+     */
+    protected final Map pinnedMap;
+
+    // number of pinned values (not including keys not mapped to values)
+    private int _pinnedSize = 0;
+
+    private final ReentrantLock _writeLock = new ReentrantLock();
+    private final ReentrantLock _readLock;
+
+    /**
+     * Create a non-LRU (and therefore highly concurrent) cache map with a
+     * size of 1000.
+     */
+    public CacheMap() {
+        this(false, 1000);
+    }
+
+    /**
+     * Create a cache map with the given properties.
+     */
+    public CacheMap(boolean lru, int max) {
+        this(lru, max, max / 2, .75F);
+    }
+
+    /**
+     * @deprecated use {@link CacheMap#CacheMap(boolean, int, int, float, int)}
+     * instead.
+     */
+    public CacheMap(boolean lru, int max, int size, float load) {
+        this(lru, max, size, load, 16);
+    }
+
+    /**
+     * Create a cache map with the given properties.
+     *
+     * @since 1.1.0
+     */
+    public CacheMap(boolean lru, int max, int size, float load,
+        int concurrencyLevel) {
+        if (size < 0)
+            size = 500;
+
+        softMap = new ConcurrentReferenceHashMap(ReferenceMap.HARD,
+            ReferenceMap.SOFT, size, load) {
+            public void overflowRemoved(Object key, Object value) {
+                softMapOverflowRemoved(key, value);
+            }
+
+            public void valueExpired(Object key) {
+                softMapValueExpired(key);
+            }
+        };
+        pinnedMap = new ConcurrentHashMap();
+
+        if (!lru) {
+            cacheMap = new ConcurrentHashMap(size, load) {
+                public void overflowRemoved(Object key, Object value) {
+                    cacheMapOverflowRemoved(key, value);
+                }
+            };
+            _readLock = null;
+        } else {
+            cacheMap = new LRUMap(size, load) {
+                public void overflowRemoved(Object key, Object value) {
+                    cacheMapOverflowRemoved(key, value);
+                }
+            };
+            _readLock = _writeLock;
+        }
+        if (max < 0)
+            max = Integer.MAX_VALUE;
+        cacheMap.setMaxSize(max);
+    }
+
+    /**
+     * Called from {@link SizedMap#overflowRemoved} in the cache map.
+     */
+    protected void cacheMapOverflowRemoved(Object key, Object value) {
+        if (softMap.size() < softMap.getMaxSize())
+            put(softMap, key, value);
+        else
+            entryRemoved(key, value, true);
+    }
+
+    /**
+     * Called from {@link SizedMap#overflowRemoved} in the soft map.
+     */
+    protected void softMapOverflowRemoved(Object key, Object value) {
+        entryRemoved(key, value, true);
+    }
+
+    /**
+     * Called when a value expires from the soft map.
+     */
+    protected void softMapValueExpired(Object key) {
+        entryRemoved(key, null, true);
+    }
+
+    /**
+     * Put the given entry into the given map. Allows subclasses to
+     * take additional actions.
+     */
+    protected Object put(Map map, Object key, Object value) {
+        return map.put(key, value);
+    }
+
+    /**
+     * Remove the given key from the given map. Allows subclasses to
+     * take additional actions.
+     */
+    protected Object remove(Map map, Object key) {
+        return map.remove(key);
+    }
+
+    /**
+     * Acquire read lock.
+     */
+    public void readLock() {
+        if (_readLock != null)
+            _readLock.lock();
+    }
+
+    /**
+     * Release read lock.
+     */
+    public void readUnlock() {
+        if (_readLock != null)
+            _readLock.unlock();
+    }
+
+    /**
+     * Acquire write lock.
+     */
+    public void writeLock() {
+        _writeLock.lock();
+    }
+
+    /**
+     * Release write lock.
+     */
+    public void writeUnlock() {
+        _writeLock.unlock();
+    }
+
+    /**
+     * Whether this cache map uses LRU eviction.
+     */
+    public boolean isLRU() {
+        return _readLock != null;
+    }
+
+    /**
+     * The maximum number of hard references to maintain, or -1 for no limit.
+     */
+    public void setCacheSize(int size) {
+        writeLock();
+        try {
+            cacheMap.setMaxSize((size < 0) ? Integer.MAX_VALUE : size);
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    /**
+     * The maximum number of hard references to maintain, or -1 for no limit.
+     */
+    public int getCacheSize() {
+        int max = cacheMap.getMaxSize();
+        return (max == Integer.MAX_VALUE) ? -1 : max;
+    }
+
+    /**
+     * The maximum number of soft references to maintain, or -1 for no limit.
+     */
+    public void setSoftReferenceSize(int size) {
+        writeLock();
+        try {
+            softMap.setMaxSize((size < 0) ? Integer.MAX_VALUE : size);
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    /**
+     * The maximum number of soft references to maintain, or -1 for no limit.
+     */
+    public int getSoftReferenceSize() {
+        int max = softMap.getMaxSize();
+        return (max == Integer.MAX_VALUE) ? -1 : max;
+    }
+
+    /**
+     * The keys pinned into the map.
+     */
+    public Set getPinnedKeys() {
+        readLock();
+        try {
+            return Collections.unmodifiableSet(pinnedMap.keySet());
+        } finally {
+            readUnlock();
+        }
+    }
+
+    /**
+     * Locks the given key and its value into the map. Objects pinned into
+     * the map are not counted towards the maximum cache size, and are never
+     * evicted implicitly. You may pin keys for which no value is in the map.
+     *
+     * @return true if the givne key's value was pinned; false if no value
+     * for the given key is cached
+     */
+    public boolean pin(Object key) {
+        writeLock();
+        try {
+            // if we don't have a pinned map we need to create one; else if the
+            // pinned map already contains the key, nothing to do
+            if (pinnedMap.containsKey(key))
+                return pinnedMap.get(key) != null;
+
+            // check other maps for key
+            Object val = remove(cacheMap, key);
+            if (val == null)
+                val = remove(softMap, key);
+
+            // pin key
+            put(pinnedMap, key, val);
+            if (val != null) {
+                _pinnedSize++;
+                return true;
+            }
+            return false;
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    /**
+     * Undo a pinning.
+     */
+    public boolean unpin(Object key) {
+        writeLock();
+        try {
+            Object val = remove(pinnedMap, key);
+            if (val != null) {
+                // put back into unpinned cache
+                put(key, val);
+                _pinnedSize--;
+                return true;
+            }
+            return false;
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    /**
+     * Invoked when a key-value pair is evicted from this data
+     * structure. This is invoked with <code>expired</code> set to
+     * <code>true</code> when an object is dropped because of space
+     * requirements or through garbage collection of soft references.
+     * It is invoked with <code>expired</code> set to <code>false</code>
+     * when an object is explicitly removed via the {@link #remove} or
+     * {@link #clear} methods. This may be invoked more than once for a
+     * given entry.
+     *
+     * @param value may be null if the value was a soft reference that has
+     * been GCd
+     * @since 0.2.5.0
+     */
+    protected void entryRemoved(Object key, Object value, boolean expired) {
+    }
+
+    /**
+     * Invoked when an entry is added to the cache. This may be invoked
+     * more than once for an entry.
+     */
+    protected void entryAdded(Object key, Object value) {
+    }
+
+    public Object get(Object key) {
+        readLock();
+        try {
+            Object val = pinnedMap.get(key);
+            if (val != null)
+                return val;
+
+            val = cacheMap.get(key);
+            if (val == null) {
+                // if we find the key in the soft map, move it back into
+                // the primary map
+                val = softMap.get(key);
+                if (val != null)
+                    put(key, val);
+            }
+            return val;
+        } finally {
+            readUnlock();
+        }
+    }
+
+    public Object put(Object key, Object value) {
+        writeLock();
+        try {
+            // if the key is pinned, just interact directly with the pinned map
+            Object val;
+            if (pinnedMap.containsKey(key)) {
+                val = put(pinnedMap, key, value);
+                if (val == null) {
+                    _pinnedSize++;
+                    entryAdded(key, value);
+                } else {
+                    entryRemoved(key, val, false);
+                    entryAdded(key, value);
+                }
+                return val;
+            }
+
+            // if no hard refs, don't put anything
+            if (cacheMap.getMaxSize() == 0)
+                return null;
+
+            // otherwise, put the value into the map and clear it from the
+            // soft map
+            val = put(cacheMap, key, value);
+            if (val == null) {
+                val = remove(softMap, key);
+                if (val == null)
+                    entryAdded(key, value);
+                else {
+                    entryRemoved(key, val, false);
+                    entryAdded(key, value);
+                }
+            } else {
+                entryRemoved(key, val, false);
+                entryAdded(key, value);
+            }
+            return val;
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    public void putAll(Map map) {
+        Map.Entry entry;
+        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * If <code>key</code> is pinned into the cache, the pin is
+     * cleared and the object is removed.
+     */
+    public Object remove(Object key) {
+        writeLock();
+        try {
+            // if the key is pinned, just interact directly with the
+            // pinned map
+            Object val;
+            if (pinnedMap.containsKey(key)) {
+                // re-put with null value; we still want key pinned
+                val = put(pinnedMap, key, null);
+                if (val != null) {
+                    _pinnedSize--;
+                    entryRemoved(key, val, false);
+                }
+                return val;
+            }
+
+            val = remove(cacheMap, key);
+            if (val == null)
+                val = softMap.remove(key);
+            if (val != null)
+                entryRemoved(key, val, false);
+
+            return val;
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    /**
+     * Removes pinned objects as well as unpinned ones.
+     */
+    public void clear() {
+        writeLock();
+        try {
+            notifyEntryRemovals(pinnedMap.entrySet());
+            pinnedMap.clear();
+            _pinnedSize = 0;
+
+            notifyEntryRemovals(cacheMap.entrySet());
+            cacheMap.clear();
+
+            notifyEntryRemovals(softMap.entrySet());
+            softMap.clear();
+        } finally {
+            writeUnlock();
+        }
+    }
+
+    private void notifyEntryRemovals(Set set) {
+        Map.Entry entry;
+        for (Iterator itr = set.iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            if (entry.getValue() != null)
+                entryRemoved(entry.getKey(), entry.getValue(), false);
+        }
+    }
+
+    public int size() {
+        readLock();
+        try {
+            return _pinnedSize + cacheMap.size() + softMap.size();
+        } finally {
+            readUnlock();
+        }
+    }
+
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    public boolean containsKey(Object key) {
+        readLock();
+        try {
+            return pinnedMap.get(key) != null
+                || cacheMap.containsKey(key)
+                || softMap.containsKey(key);
+        } finally {
+            readUnlock();
+        }
+    }
+
+    public boolean containsValue(Object val) {
+        readLock();
+        try {
+            return pinnedMap.containsValue(val)
+                || cacheMap.containsValue(val)
+                || softMap.containsValue(val);
+        } finally {
+            readUnlock();
+        }
+    }
+
+    public Set keySet() {
+        return new KeySet();
+    }
+
+    public Collection values() {
+        return new ValueCollection();
+    }
+
+    public Set entrySet() {
+        return new EntrySet();
+    }
+
+    public String toString() {
+        readLock();
+        try {
+            return "CacheMap:" + cacheMap.toString() + "::"
+                + softMap.toString();
+        } finally {
+            readUnlock();
+        }
+    }
+
+    /**
+     * View of the entry set.
+     */
+    private class EntrySet
+        extends AbstractSet {
+
+        public int size() {
+            return CacheMap.this.size();
+        }
+
+        public boolean add(Object o) {
+            Map.Entry entry = (Map.Entry) o;
+            put(entry.getKey(), entry.getValue());
+            return true;
+        }
+
+        public Iterator iterator() {
+            return new EntryIterator(EntryIterator.ENTRY);
+        }
+    }
+
+    /**
+     * View of the key set.
+     */
+    private class KeySet
+        extends AbstractSet {
+
+        public int size() {
+            return CacheMap.this.size();
+        }
+
+        public Iterator iterator() {
+            return new EntryIterator(EntryIterator.KEY);
+        }
+    }
+
+    /**
+     * View of the value collection.
+     */
+    private class ValueCollection
+        extends AbstractCollection {
+
+        public int size() {
+            return CacheMap.this.size();
+        }
+
+        public Iterator iterator() {
+            return new EntryIterator(EntryIterator.VALUE);
+        }
+    }
+
+    /**
+     * Iterator over all entries.
+     */
+    private class EntryIterator
+        implements Iterator, Predicate {
+
+        public static final int ENTRY = 0;
+        public static final int KEY = 1;
+        public static final int VALUE = 2;
+
+        private final IteratorChain _itr = new IteratorChain();
+        private final int _type;
+
+        public EntryIterator(int type) {
+            _type = type;
+            _itr.addIterator(new FilterIterator(getView(pinnedMap), this));
+            _itr.addIterator(getView(cacheMap));
+            _itr.addIterator(getView(softMap));
+        }
+
+        /**
+         * Return an iterator over the appropriate view of the given map.
+         */
+        private Iterator getView(Map m) {
+            if (m == null)
+                return null;
+
+            switch (_type) {
+                case KEY:
+                    return m.keySet().iterator();
+                case VALUE:
+                    return m.values().iterator();
+                default:
+                    return m.entrySet().iterator();
+            }
+        }
+
+        public boolean hasNext() {
+            return _itr.hasNext();
+        }
+
+        public Object next() {
+            return _itr.next();
+        }
+
+        public void remove() {
+            _itr.remove();
+        }
+
+        public boolean evaluate(Object obj) {
+            switch (_type) {
+                case ENTRY:
+                    return ((Map.Entry) obj).getValue() != null;
+			case VALUE:
+				return obj != null;
+			default:
+				return true;
+			}
+		}
+	}
+}
+
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/GeneratedClasses.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/GeneratedClasses.java
index 4dd235a..1616894 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/GeneratedClasses.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/GeneratedClasses.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.util;
-
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.lang.reflect.Constructor;
-
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import serp.bytecode.BCClass;
-import serp.bytecode.BCClassLoader;
-
-/**
- * Utility methods when generating classes, including at runtime.
- *
- * @since 1.0.0
- */
-public class GeneratedClasses {
-
-    /**
-     * Return the more derived loader of the class laoders for the given 
-     * classes.
-     */
-    public static ClassLoader getMostDerivedLoader(Class c1, Class c2) {
-        ClassLoader l1 = (ClassLoader) AccessController.doPrivileged(
-            J2DoPrivHelper.getClassLoaderAction(c1));
-        ClassLoader l2 = (ClassLoader) AccessController.doPrivileged(
-            J2DoPrivHelper.getClassLoaderAction(c2));
-        if (l1 == l2)
-            return l1;
-        if (l1 == null)
-            return l2;
-        if (l2 == null)
-            return l1;
-
-        if(canLoad(l1, c2)) {
-            return l1;
-        }
-        return l2;
-    }
-
-    /**
-     * Load the class represented by the given bytecode.
-     */
-    public static Class loadBCClass(BCClass bc, ClassLoader loader) {
-        BCClassLoader bcloader = (BCClassLoader) AccessController
-                .doPrivileged(J2DoPrivHelper.newBCClassLoaderAction(bc
-                        .getProject(), loader));
-        try {
-            Class c = Class.forName(bc.getName(), true, bcloader);
-            bc.getProject().clear();
-            return c;
-        } catch (Throwable t) {
-            throw new GeneralException(bc.getName()).setCause(t);
-        }
-    }
-    
-    /**
-     * Return true if the given loader will load the same version of a given 
-     * class.  
-     * 
-     * @param loader Classloader to use.
-     * @param clazz  Expected class. 
-     * @return true if loader.load(clazz.getName()) == clazz. Otherwise false.
-     */
-    private static boolean canLoad(ClassLoader loader, Class clazz) {
-        Class loaded = null;
-        try {
-            loaded = loader.loadClass(clazz.getName());
-        } catch (ClassNotFoundException e) {
-            // Rely on caller to handle return value = false.
-        }
-        return clazz == loaded;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.util;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.lang.reflect.Constructor;
+
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import serp.bytecode.BCClass;
+import serp.bytecode.BCClassLoader;
+
+/**
+ * Utility methods when generating classes, including at runtime.
+ *
+ * @since 1.0.0
+ */
+public class GeneratedClasses {
+
+    /**
+     * Return the more derived loader of the class laoders for the given 
+     * classes.
+     */
+    public static ClassLoader getMostDerivedLoader(Class c1, Class c2) {
+        ClassLoader l1 = (ClassLoader) AccessController.doPrivileged(
+            J2DoPrivHelper.getClassLoaderAction(c1));
+        ClassLoader l2 = (ClassLoader) AccessController.doPrivileged(
+            J2DoPrivHelper.getClassLoaderAction(c2));
+        if (l1 == l2)
+            return l1;
+        if (l1 == null)
+            return l2;
+        if (l2 == null)
+            return l1;
+
+        if(canLoad(l1, c2)) {
+            return l1;
+        }
+        return l2;
+    }
+
+    /**
+     * Load the class represented by the given bytecode.
+     */
+    public static Class loadBCClass(BCClass bc, ClassLoader loader) {
+        BCClassLoader bcloader = (BCClassLoader) AccessController
+                .doPrivileged(J2DoPrivHelper.newBCClassLoaderAction(bc
+                        .getProject(), loader));
+        try {
+            Class c = Class.forName(bc.getName(), true, bcloader);
+            bc.getProject().clear();
+            return c;
+        } catch (Throwable t) {
+            throw new GeneralException(bc.getName()).setCause(t);
+        }
+    }
+    
+    /**
+     * Return true if the given loader will load the same version of a given 
+     * class.  
+     * 
+     * @param loader Classloader to use.
+     * @param clazz  Expected class. 
+     * @return true if loader.load(clazz.getName()) == clazz. Otherwise false.
+     */
+    private static boolean canLoad(ClassLoader loader, Class clazz) {
+        Class loaded = null;
+        try {
+            loaded = loader.loadClass(clazz.getName());
+        } catch (ClassNotFoundException e) {
+            // Rely on caller to handle return value = false.
+        }
+        return clazz == loaded;
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
index 7f6b2f2..a305b59 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
@@ -1,326 +1,326 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.StateManager;
-import org.apache.openjpa.enhance.ManagedInstanceProvider;
-import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
-import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.LockManager;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.kernel.StoreManager;
-import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.lib.util.ReferenceMap;
-import org.apache.openjpa.lib.util.UUIDGenerator;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.SequenceMetaData;
-import org.apache.openjpa.meta.ValueStrategies;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-
-/**
- * Helper for OpenJPA back-ends.
- *
- * @since 0.3.0
- * @author Abe White
- * @nojavadoc
- */
-public class ImplHelper {
-
-    // Cache for from/to type assignments
-    private static final Map _assignableTypes =
-        new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
-
-    // map of all new unenhanced instances active in this classloader
-    public static final Map _unenhancedInstanceMap =
-        new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD) {
-
-            protected boolean eq(Object x, Object y) {
-                // the Entries in ConcurrentReferenceHashMap delegate back to
-                // eq() in their equals() impls
-                if (x instanceof Map.Entry)
-                    return super.eq(x, y);
-                else
-                    return x == y;
-            }
-
-            protected int hc(Object o) {
-                // the Entries in ConcurrentReferenceHashMap delegate back to
-                // hc() in their hashCode() impls
-                if (o instanceof Map.Entry)
-                    return super.hc(o);
-                else
-                    return System.identityHashCode(o);
-            }
-        };
-
-    /**
-     * Helper for store manager implementations. This method simply delegates
-     * to the proper singular method for each state manager.
-     *
-     * @see StoreManager#loadAll
-     * @since 0.4.0
-     */
-    public static Collection loadAll(Collection sms, StoreManager store,
-        PCState state, int load, FetchConfiguration fetch, Object context) {
-        Collection failed = null;
-        OpenJPAStateManager sm;
-        LockManager lm;
-        for (Iterator itr = sms.iterator(); itr.hasNext();) {
-            sm = (OpenJPAStateManager) itr.next();
-            if (sm.getManagedInstance() == null) {
-                if (!store.initialize(sm, state, fetch, context))
-                    failed = addFailedId(sm, failed);
-            } else if (load != StoreManager.FORCE_LOAD_NONE
-                || sm.getPCState() == PCState.HOLLOW) {
-                lm = sm.getContext().getLockManager();
-                if (!store.load(sm, sm.getUnloaded(fetch), fetch, 
-                    lm.getLockLevel(sm), context))
-                    failed = addFailedId(sm, failed);
-            } else if (!store.exists(sm, context))
-                failed = addFailedId(sm, failed);
-        }
-        return (failed == null) ? Collections.EMPTY_LIST : failed;
-    }
-
-    /**
-     * Add identity of given instance to collection.
-     */
-    private static Collection addFailedId(OpenJPAStateManager sm,
-        Collection failed) {
-        if (failed == null)
-            failed = new ArrayList();
-        failed.add(sm.getId());
-        return failed;
-    }
-
-    /**
-     * Generate a value for the given metadata, or return null. Generates
-     * values for hte following strategies: {@link ValueStrategies#SEQUENCE},
-     * {@link ValueStrategies#UUID_STRING}, {@link ValueStrategies#UUID_HEX}
-     */
-    public static Object generateIdentityValue(StoreContext ctx,
-        ClassMetaData meta, int typeCode) {
-        return generateValue(ctx, meta, null, typeCode);
-    }
-
-    /**
-     * Generate a value for the given metadata, or return null. Generates
-     * values for hte following strategies: {@link ValueStrategies#SEQUENCE},
-     * {@link ValueStrategies#UUID_STRING}, {@link ValueStrategies#UUID_HEX}
-     */
-    public static Object generateFieldValue(StoreContext ctx,
-        FieldMetaData fmd) {
-        return generateValue(ctx, fmd.getDefiningMetaData(), fmd, 
-            fmd.getDeclaredTypeCode());
-    }
-
-    /**
-     * Generate a value for the given metadaa.
-     */
-    private static Object generateValue(StoreContext ctx,
-        ClassMetaData meta, FieldMetaData fmd, int typeCode) {
-        int strategy = (fmd == null) ? meta.getIdentityStrategy()
-            : fmd.getValueStrategy();
-        switch (strategy) {
-            case ValueStrategies.SEQUENCE:
-                SequenceMetaData smd = (fmd == null)
-                    ? meta.getIdentitySequenceMetaData()
-                    : fmd.getValueSequenceMetaData();
-                return JavaTypes.convert(smd.getInstance(ctx.getClassLoader()).
-                    next(ctx, meta), typeCode);
-            case ValueStrategies.UUID_STRING:
-                return UUIDGenerator.nextString(UUIDGenerator.TYPE1);
-            case ValueStrategies.UUID_HEX:
-                return UUIDGenerator.nextHex(UUIDGenerator.TYPE1);
-            case ValueStrategies.UUID_TYPE4_STRING:
-                return UUIDGenerator.nextString(UUIDGenerator.TYPE4);
-            case ValueStrategies.UUID_TYPE4_HEX:
-                return UUIDGenerator.nextHex(UUIDGenerator.TYPE4);
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Returns the fields of the state that require an update.
-     *
-     * @param  sm  the state to check
-     * @return the BitSet of fields that need update, or null if none
-     */
-    public static BitSet getUpdateFields(OpenJPAStateManager sm) {
-        if ((sm.getPCState() == PCState.PDIRTY
-            && (!sm.isFlushed() || sm.isFlushedDirty()))
-            || (sm.getPCState() == PCState.PNEW && sm.isFlushedDirty())) {
-            BitSet dirty = sm.getDirty();
-            if (sm.isFlushed()) {
-                dirty = (BitSet) dirty.clone();
-                dirty.andNot(sm.getFlushed());
-            }
-            if (dirty.length() > 0)
-                return dirty;
-        }
-        return null;
-    }
-
-    /**
-     * Close the given resource. The resource can be an extent iterator,
-     * query result, large result set relation, or any closeable OpenJPA
-     * component.
-     */
-    public static void close(Object o) {
-        try {
-            if (o instanceof Closeable)
-                ((Closeable) o).close();
-        } catch (RuntimeException re) {
-            throw re;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        }
-    }
-
-    /**
-     * Returns true if the specified class is a type that can be managed by
-     * OpenJPA.
-     *
-     * @param type the class to test
-     * @return true if the class is manageable.
-     *
-     * @since 1.0.0
-     */
-    public static boolean isManagedType(OpenJPAConfiguration conf, Class type) {
-        return (PersistenceCapable.class.isAssignableFrom(type)
-            || (type != null
-                && (conf == null || conf.getRuntimeUnenhancedClassesConstant()
-                    == RuntimeUnenhancedClasssesModes.SUPPORTED)
-                && PCRegistry.isRegistered(type)));
-    }
-
-    /**
-     * Returns true if the specified instance is manageable.
-     *
-     * @param instance the object to check
-     * @return true if the instance is a persistent type, false otherwise
-     */
-    public static boolean isManageable(Object instance) {
-        return instance instanceof PersistenceCapable
-            || instance != null && PCRegistry.isRegistered(instance.getClass());
-    }
-
-    /**
-     * Returns true if the referenced "to" class is assignable to the "from"
-     * class.  This helper method utilizes a cache to help avoid the overhead
-     * of the Class.isAssignableFrom() method.
-     *
-     * @param from target class instance to be checked for assignability
-     * @param to second class instance to be checked for assignability
-     * @return true if the "to" class is assignable to the "from" class
-     */
-    public static boolean isAssignable(Class from, Class to) {
-        if (from == null || to == null)
-            return false;
-
-        Boolean isAssignable = null;
-        Map assignableTo = (Map) _assignableTypes.get(from);
-        if (assignableTo == null) { // "to" cache doesn't exist, so create it...
-            assignableTo = new ConcurrentReferenceHashMap(ReferenceMap.WEAK,
-                    ReferenceMap.HARD);
-            _assignableTypes.put(from, assignableTo);
-        } else { // "to" cache exists...
-            isAssignable = (Boolean) assignableTo.get(to);
-        }
-
-        if (isAssignable == null) {// we don't have a record of this pair...
-            isAssignable = Boolean.valueOf(from.isAssignableFrom(to));
-            assignableTo.put(to, isAssignable);
-        }
-
-        return isAssignable.booleanValue();
-    }
-
-    /**
-     * @return the persistence-capable instance responsible for managing
-     * <code>o</code>, or <code>null</code> if <code>o</code> is not manageable.
-     * @since 1.0.0
-     */
-    public static PersistenceCapable toPersistenceCapable(Object o, Object ctx){
-        if (o instanceof PersistenceCapable)
-            return (PersistenceCapable) o;
-
-        OpenJPAConfiguration conf = null;
-        if (ctx instanceof OpenJPAConfiguration)
-            conf = (OpenJPAConfiguration) ctx;
-        else if (ctx instanceof StateManager
-            && ((StateManager) ctx).getGenericContext() instanceof StoreContext)
-            conf = ((StoreContext) ((StateManager) ctx).getGenericContext())
-                .getConfiguration();
-
-        if (!isManageable(o))
-            return null;
-
-        // if we had a putIfAbsent() method, we wouldn't need to sync here
-        synchronized (o) {
-            PersistenceCapable pc = (PersistenceCapable)
-                _unenhancedInstanceMap.get(o);
-
-            if (pc != null)
-                return pc;
-
-            // if we don't have a conf passed in, then we can't create a new
-            // ReflectingPC; this will only be the case when invoked from a
-            // context outside of OpenJPA.
-            if (conf == null)
-                return null;
-
-            pc = new ReflectingPersistenceCapable(o, conf);
-            _unenhancedInstanceMap.put(o, pc);
-            return pc;
-        }
-    }
-
-    public static void registerPersistenceCapable(
-        ReflectingPersistenceCapable pc) {
-        _unenhancedInstanceMap.put(pc.getManagedInstance(), pc);
-    }
-
-    /**
-     * @return the user-visible representation of <code>o</code>.
-     * @since 1.0.0
-     */
-    public static Object getManagedInstance(Object o) {
-        if (o instanceof ManagedInstanceProvider)
-            return ((ManagedInstanceProvider) o).getManagedInstance();
-        else
-            return o;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.PCRegistry;
+import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.enhance.ManagedInstanceProvider;
+import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
+import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.LockManager;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.ReferenceMap;
+import org.apache.openjpa.lib.util.UUIDGenerator;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.SequenceMetaData;
+import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * Helper for OpenJPA back-ends.
+ *
+ * @since 0.3.0
+ * @author Abe White
+ * @nojavadoc
+ */
+public class ImplHelper {
+
+    // Cache for from/to type assignments
+    private static final Map _assignableTypes =
+        new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
+
+    // map of all new unenhanced instances active in this classloader
+    public static final Map _unenhancedInstanceMap =
+        new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD) {
+
+            protected boolean eq(Object x, Object y) {
+                // the Entries in ConcurrentReferenceHashMap delegate back to
+                // eq() in their equals() impls
+                if (x instanceof Map.Entry)
+                    return super.eq(x, y);
+                else
+                    return x == y;
+            }
+
+            protected int hc(Object o) {
+                // the Entries in ConcurrentReferenceHashMap delegate back to
+                // hc() in their hashCode() impls
+                if (o instanceof Map.Entry)
+                    return super.hc(o);
+                else
+                    return System.identityHashCode(o);
+            }
+        };
+
+    /**
+     * Helper for store manager implementations. This method simply delegates
+     * to the proper singular method for each state manager.
+     *
+     * @see StoreManager#loadAll
+     * @since 0.4.0
+     */
+    public static Collection loadAll(Collection sms, StoreManager store,
+        PCState state, int load, FetchConfiguration fetch, Object context) {
+        Collection failed = null;
+        OpenJPAStateManager sm;
+        LockManager lm;
+        for (Iterator itr = sms.iterator(); itr.hasNext();) {
+            sm = (OpenJPAStateManager) itr.next();
+            if (sm.getManagedInstance() == null) {
+                if (!store.initialize(sm, state, fetch, context))
+                    failed = addFailedId(sm, failed);
+            } else if (load != StoreManager.FORCE_LOAD_NONE
+                || sm.getPCState() == PCState.HOLLOW) {
+                lm = sm.getContext().getLockManager();
+                if (!store.load(sm, sm.getUnloaded(fetch), fetch, 
+                    lm.getLockLevel(sm), context))
+                    failed = addFailedId(sm, failed);
+            } else if (!store.exists(sm, context))
+                failed = addFailedId(sm, failed);
+        }
+        return (failed == null) ? Collections.EMPTY_LIST : failed;
+    }
+
+    /**
+     * Add identity of given instance to collection.
+     */
+    private static Collection addFailedId(OpenJPAStateManager sm,
+        Collection failed) {
+        if (failed == null)
+            failed = new ArrayList();
+        failed.add(sm.getId());
+        return failed;
+    }
+
+    /**
+     * Generate a value for the given metadata, or return null. Generates
+     * values for hte following strategies: {@link ValueStrategies#SEQUENCE},
+     * {@link ValueStrategies#UUID_STRING}, {@link ValueStrategies#UUID_HEX}
+     */
+    public static Object generateIdentityValue(StoreContext ctx,
+        ClassMetaData meta, int typeCode) {
+        return generateValue(ctx, meta, null, typeCode);
+    }
+
+    /**
+     * Generate a value for the given metadata, or return null. Generates
+     * values for hte following strategies: {@link ValueStrategies#SEQUENCE},
+     * {@link ValueStrategies#UUID_STRING}, {@link ValueStrategies#UUID_HEX}
+     */
+    public static Object generateFieldValue(StoreContext ctx,
+        FieldMetaData fmd) {
+        return generateValue(ctx, fmd.getDefiningMetaData(), fmd, 
+            fmd.getDeclaredTypeCode());
+    }
+
+    /**
+     * Generate a value for the given metadaa.
+     */
+    private static Object generateValue(StoreContext ctx,
+        ClassMetaData meta, FieldMetaData fmd, int typeCode) {
+        int strategy = (fmd == null) ? meta.getIdentityStrategy()
+            : fmd.getValueStrategy();
+        switch (strategy) {
+            case ValueStrategies.SEQUENCE:
+                SequenceMetaData smd = (fmd == null)
+                    ? meta.getIdentitySequenceMetaData()
+                    : fmd.getValueSequenceMetaData();
+                return JavaTypes.convert(smd.getInstance(ctx.getClassLoader()).
+                    next(ctx, meta), typeCode);
+            case ValueStrategies.UUID_STRING:
+                return UUIDGenerator.nextString(UUIDGenerator.TYPE1);
+            case ValueStrategies.UUID_HEX:
+                return UUIDGenerator.nextHex(UUIDGenerator.TYPE1);
+            case ValueStrategies.UUID_TYPE4_STRING:
+                return UUIDGenerator.nextString(UUIDGenerator.TYPE4);
+            case ValueStrategies.UUID_TYPE4_HEX:
+                return UUIDGenerator.nextHex(UUIDGenerator.TYPE4);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Returns the fields of the state that require an update.
+     *
+     * @param  sm  the state to check
+     * @return the BitSet of fields that need update, or null if none
+     */
+    public static BitSet getUpdateFields(OpenJPAStateManager sm) {
+        if ((sm.getPCState() == PCState.PDIRTY
+            && (!sm.isFlushed() || sm.isFlushedDirty()))
+            || (sm.getPCState() == PCState.PNEW && sm.isFlushedDirty())) {
+            BitSet dirty = sm.getDirty();
+            if (sm.isFlushed()) {
+                dirty = (BitSet) dirty.clone();
+                dirty.andNot(sm.getFlushed());
+            }
+            if (dirty.length() > 0)
+                return dirty;
+        }
+        return null;
+    }
+
+    /**
+     * Close the given resource. The resource can be an extent iterator,
+     * query result, large result set relation, or any closeable OpenJPA
+     * component.
+     */
+    public static void close(Object o) {
+        try {
+            if (o instanceof Closeable)
+                ((Closeable) o).close();
+        } catch (RuntimeException re) {
+            throw re;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        }
+    }
+
+    /**
+     * Returns true if the specified class is a type that can be managed by
+     * OpenJPA.
+     *
+     * @param type the class to test
+     * @return true if the class is manageable.
+     *
+     * @since 1.0.0
+     */
+    public static boolean isManagedType(OpenJPAConfiguration conf, Class type) {
+        return (PersistenceCapable.class.isAssignableFrom(type)
+            || (type != null
+                && (conf == null || conf.getRuntimeUnenhancedClassesConstant()
+                    == RuntimeUnenhancedClasssesModes.SUPPORTED)
+                && PCRegistry.isRegistered(type)));
+    }
+
+    /**
+     * Returns true if the specified instance is manageable.
+     *
+     * @param instance the object to check
+     * @return true if the instance is a persistent type, false otherwise
+     */
+    public static boolean isManageable(Object instance) {
+        return instance instanceof PersistenceCapable
+            || instance != null && PCRegistry.isRegistered(instance.getClass());
+    }
+
+    /**
+     * Returns true if the referenced "to" class is assignable to the "from"
+     * class.  This helper method utilizes a cache to help avoid the overhead
+     * of the Class.isAssignableFrom() method.
+     *
+     * @param from target class instance to be checked for assignability
+     * @param to second class instance to be checked for assignability
+     * @return true if the "to" class is assignable to the "from" class
+     */
+    public static boolean isAssignable(Class from, Class to) {
+        if (from == null || to == null)
+            return false;
+
+        Boolean isAssignable = null;
+        Map assignableTo = (Map) _assignableTypes.get(from);
+        if (assignableTo == null) { // "to" cache doesn't exist, so create it...
+            assignableTo = new ConcurrentReferenceHashMap(ReferenceMap.WEAK,
+                    ReferenceMap.HARD);
+            _assignableTypes.put(from, assignableTo);
+        } else { // "to" cache exists...
+            isAssignable = (Boolean) assignableTo.get(to);
+        }
+
+        if (isAssignable == null) {// we don't have a record of this pair...
+            isAssignable = Boolean.valueOf(from.isAssignableFrom(to));
+            assignableTo.put(to, isAssignable);
+        }
+
+        return isAssignable.booleanValue();
+    }
+
+    /**
+     * @return the persistence-capable instance responsible for managing
+     * <code>o</code>, or <code>null</code> if <code>o</code> is not manageable.
+     * @since 1.0.0
+     */
+    public static PersistenceCapable toPersistenceCapable(Object o, Object ctx){
+        if (o instanceof PersistenceCapable)
+            return (PersistenceCapable) o;
+
+        OpenJPAConfiguration conf = null;
+        if (ctx instanceof OpenJPAConfiguration)
+            conf = (OpenJPAConfiguration) ctx;
+        else if (ctx instanceof StateManager
+            && ((StateManager) ctx).getGenericContext() instanceof StoreContext)
+            conf = ((StoreContext) ((StateManager) ctx).getGenericContext())
+                .getConfiguration();
+
+        if (!isManageable(o))
+            return null;
+
+        // if we had a putIfAbsent() method, we wouldn't need to sync here
+        synchronized (o) {
+            PersistenceCapable pc = (PersistenceCapable)
+                _unenhancedInstanceMap.get(o);
+
+            if (pc != null)
+                return pc;
+
+            // if we don't have a conf passed in, then we can't create a new
+            // ReflectingPC; this will only be the case when invoked from a
+            // context outside of OpenJPA.
+            if (conf == null)
+                return null;
+
+            pc = new ReflectingPersistenceCapable(o, conf);
+            _unenhancedInstanceMap.put(o, pc);
+            return pc;
+        }
+    }
+
+    public static void registerPersistenceCapable(
+        ReflectingPersistenceCapable pc) {
+        _unenhancedInstanceMap.put(pc.getManagedInstance(), pc);
+    }
+
+    /**
+     * @return the user-visible representation of <code>o</code>.
+     * @since 1.0.0
+     */
+    public static Object getManagedInstance(Object o) {
+        if (o instanceof ManagedInstanceProvider)
+            return ((ManagedInstanceProvider) o).getManagedInstance();
+        else
+            return o;
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java
index 8879de0..5f29919 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java
@@ -1,148 +1,148 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.io.Serializable;
-
-import org.apache.openjpa.lib.util.ReferenceMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-
-/**
- * Identity class extended by builtin OpenJPA identity objects.
- *
- * @author Steve Kim
- */
-public abstract class OpenJPAId
-    implements Comparable, Serializable {
-
-    // cache the types' generated hashcodes
-    private static ConcurrentReferenceHashMap _typeCache =
-        new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
-
-    protected Class type;
-    protected boolean subs = true;
-
-    // type has his based on the least-derived non-object class so that
-    // user-given ids with non-exact types match ids with exact types
-    private transient int _typeHash = 0;
-
-    protected OpenJPAId() {
-    }
-
-    protected OpenJPAId(Class type) {
-        this.type = type;
-    }
-
-    protected OpenJPAId(Class type, boolean subs) {
-        this.type = type;
-        this.subs = subs;
-    }
-
-    /**
-     * Return the persistent class which this id instance represents.
-     */
-    public Class getType() {
-        return type;
-    }
-
-    /**
-     * Whether this oid might be for a subclass of the given type.
-     * Defaults to true.
-     */
-    public boolean hasSubclasses() {
-        return subs;
-    }
-
-    /**
-     * Set the exact type of the described instance once it is known.
-     */
-    public void setManagedInstanceType(Class type) {
-        setManagedInstanceType(type, false);
-    }
-
-    /**
-     * Set the exact type of the described instance once it is known.
-     */
-    public void setManagedInstanceType(Class type, boolean subs) {
-        this.type = type;
-        this.subs = subs;
-    }
-
-    /**
-     * Return the identity value as an object.
-     */
-    public abstract Object getIdObject();
-
-    /**
-     * Return the id's hash code.
-     */
-    protected abstract int idHash();
-
-    /**
-     * Compare the id to the id of the given instance.
-     */
-    protected abstract boolean idEquals(OpenJPAId other);
-
-    /**
-     * Generate the hashcode for this Id.  Cache the type's generated hashcode
-     * so that it doesn't have to be generated each time.
-     */
-    public int hashCode() {
-        if (_typeHash == 0) {
-            Integer typeHashInt = (Integer) _typeCache.get(type);
-            if (typeHashInt == null) {
-                Class base = type;
-                Class superclass = base.getSuperclass();
-                while (superclass != null && superclass != Object.class) {
-                    base = base.getSuperclass();
-                    superclass = base.getSuperclass();
-                }
-                _typeHash = base.hashCode();
-                _typeCache.put(type, new Integer(_typeHash));
-            } else {
-                _typeHash = typeHashInt.intValue();
-            }
-        }
-        return _typeHash ^ idHash();
-    }
-
-    public boolean equals(Object o) {
-        if (o == this)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        OpenJPAId id = (OpenJPAId) o;
-        return idEquals(id) && (id.type.isAssignableFrom(type)
-            || (subs && type.isAssignableFrom(id.type)));
-    }
-
-    public String toString() {
-        return type.getName() + "-" + getIdObject();
-    }
-
-    public int compareTo(Object other) {
-        if (other == this)
-            return 0;
-        if (other == null)
-            return 1;
-        return ((Comparable) getIdObject()).compareTo(((OpenJPAId) other).
-            getIdObject ());
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.io.Serializable;
+
+import org.apache.openjpa.lib.util.ReferenceMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+
+/**
+ * Identity class extended by builtin OpenJPA identity objects.
+ *
+ * @author Steve Kim
+ */
+public abstract class OpenJPAId
+    implements Comparable, Serializable {
+
+    // cache the types' generated hashcodes
+    private static ConcurrentReferenceHashMap _typeCache =
+        new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
+
+    protected Class type;
+    protected boolean subs = true;
+
+    // type has his based on the least-derived non-object class so that
+    // user-given ids with non-exact types match ids with exact types
+    private transient int _typeHash = 0;
+
+    protected OpenJPAId() {
+    }
+
+    protected OpenJPAId(Class type) {
+        this.type = type;
+    }
+
+    protected OpenJPAId(Class type, boolean subs) {
+        this.type = type;
+        this.subs = subs;
+    }
+
+    /**
+     * Return the persistent class which this id instance represents.
+     */
+    public Class getType() {
+        return type;
+    }
+
+    /**
+     * Whether this oid might be for a subclass of the given type.
+     * Defaults to true.
+     */
+    public boolean hasSubclasses() {
+        return subs;
+    }
+
+    /**
+     * Set the exact type of the described instance once it is known.
+     */
+    public void setManagedInstanceType(Class type) {
+        setManagedInstanceType(type, false);
+    }
+
+    /**
+     * Set the exact type of the described instance once it is known.
+     */
+    public void setManagedInstanceType(Class type, boolean subs) {
+        this.type = type;
+        this.subs = subs;
+    }
+
+    /**
+     * Return the identity value as an object.
+     */
+    public abstract Object getIdObject();
+
+    /**
+     * Return the id's hash code.
+     */
+    protected abstract int idHash();
+
+    /**
+     * Compare the id to the id of the given instance.
+     */
+    protected abstract boolean idEquals(OpenJPAId other);
+
+    /**
+     * Generate the hashcode for this Id.  Cache the type's generated hashcode
+     * so that it doesn't have to be generated each time.
+     */
+    public int hashCode() {
+        if (_typeHash == 0) {
+            Integer typeHashInt = (Integer) _typeCache.get(type);
+            if (typeHashInt == null) {
+                Class base = type;
+                Class superclass = base.getSuperclass();
+                while (superclass != null && superclass != Object.class) {
+                    base = base.getSuperclass();
+                    superclass = base.getSuperclass();
+                }
+                _typeHash = base.hashCode();
+                _typeCache.put(type, new Integer(_typeHash));
+            } else {
+                _typeHash = typeHashInt.intValue();
+            }
+        }
+        return _typeHash ^ idHash();
+    }
+
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        OpenJPAId id = (OpenJPAId) o;
+        return idEquals(id) && (id.type.isAssignableFrom(type)
+            || (subs && type.isAssignableFrom(id.type)));
+    }
+
+    public String toString() {
+        return type.getName() + "-" + getIdObject();
+    }
+
+    public int compareTo(Object other) {
+        if (other == this)
+            return 0;
+        if (other == null)
+            return 1;
+        return ((Comparable) getIdObject()).compareTo(((OpenJPAId) other).
+            getIdObject ());
+	}
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java
index 9048d21..3f9e071 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java
@@ -1,1662 +1,1662 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.ObjectStreamException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TimeZone;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.Queue;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.util.Files;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.JavaVersions;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.lib.util.concurrent.NullSafeConcurrentHashMap;
-
-import java.util.concurrent.ConcurrentHashMap;
-import serp.bytecode.BCClass;
-import serp.bytecode.BCField;
-import serp.bytecode.BCMethod;
-import serp.bytecode.Code;
-import serp.bytecode.JumpInstruction;
-import serp.bytecode.Project;
-import serp.util.Strings;
-
-/**
- * Default implementation of the {@link ProxyManager} interface.
- *
- * @author Abe White
- */
-public class ProxyManagerImpl
-    implements ProxyManager {
-
-    private static final String PROXY_SUFFIX = "$proxy";
-
-    private static final Localizer _loc = Localizer.forPackage
-        (ProxyManagerImpl.class);
-
-    private static long _proxyId = 0L;
-    private static final Map _stdCollections = new HashMap();
-    private static final Map _stdMaps = new HashMap();
-    static {
-        _stdCollections.put(Collection.class, ArrayList.class);
-        _stdCollections.put(Set.class, HashSet.class);
-        _stdCollections.put(SortedSet.class, TreeSet.class);
-        _stdCollections.put(List.class, ArrayList.class);
-        _stdCollections.put(Queue.class, LinkedList.class);
-        _stdMaps.put(Map.class, HashMap.class);
-        _stdMaps.put(SortedMap.class, TreeMap.class);
-    }
-
-    private final Set _unproxyable = new HashSet();
-    private final Map _proxies = new NullSafeConcurrentHashMap();
-    private boolean _trackChanges = true;
-    private boolean _assertType = false;
-
-    public ProxyManagerImpl() {
-        _unproxyable.add(TimeZone.class.getName());
-    }
-
-    /**
-     * Whether proxies produced by this factory will use {@link ChangeTracker}s
-     * to try to cut down on data store operations at the cost of some extra
-     * bookkeeping overhead. Defaults to true.
-     */
-    public boolean getTrackChanges() {
-        return _trackChanges;
-    }
-
-    /**
-     * Whether proxies produced by this factory will use {@link ChangeTracker}s
-     * to try to cut down on data store operations at the cost of some extra
-     * bookkeeping overhead. Defaults to true.
-     */
-    public void setTrackChanges(boolean track) {
-        _trackChanges = track;
-    }
-
-    /**
-     * Whether to perform runtime checks to ensure that all elements
-     * added to collection and map proxies are the proper element/key/value
-     * type as defined by the metadata. Defaults to false.
-     */
-    public boolean getAssertAllowedType() {
-        return _assertType;
-    }
-
-    /**
-     * Whether to perform runtime checks to ensure that all elements
-     * added to collection and map proxies are the proper element/key/value
-     * type as defined by the metadata. Defaults to false.
-     */
-    public void setAssertAllowedType(boolean assertType) {
-        _assertType = assertType;
-    }
-
-    /**
-     * Return a mutable view of class names we know cannot be proxied  
-     * correctly by this manager.
-     */
-    public Collection getUnproxyable() {
-        return _unproxyable;
-    }
-
-    /**
-     * Provided for auto-configuration.  Add the given semicolon-separated
-     * class names to the set of class names we know cannot be proxied correctly
-     * by this manager.
-     */
-    public void setUnproxyable(String clsNames) {
-        if (clsNames != null)
-            _unproxyable.addAll(Arrays.asList(Strings.split(clsNames, ";", 0)));
-    }
-
-    public Object copyArray(Object orig) {
-        if (orig == null)
-            return null;
-
-        try {
-            int length = Array.getLength(orig);
-            Object array = Array.newInstance(orig.getClass().
-                getComponentType(), length);
-
-            System.arraycopy(orig, 0, array, 0, length);
-            return array;
-        } catch (Exception e) {
-            throw new UnsupportedException(_loc.get("bad-array",
-                e.getMessage()), e);
-        }
-    }
-
-    public Collection copyCollection(Collection orig) {
-        if (orig == null)
-            return null;
-        if (orig instanceof Proxy)
-            return (Collection) ((Proxy) orig).copy(orig);
-
-        ProxyCollection proxy = getFactoryProxyCollection(orig.getClass());
-        return (Collection) proxy.copy(orig);
-    }
-
-    public Proxy newCollectionProxy(Class type, Class elementType,
-        Comparator compare) {
-        type = toProxyableCollectionType(type);
-        ProxyCollection proxy = getFactoryProxyCollection(type);
-        return proxy.newInstance((_assertType) ? elementType : null, compare,
-            _trackChanges);
-    }
-
-    public Map copyMap(Map orig) {
-        if (orig == null)
-            return null;
-        if (orig instanceof Proxy)
-            return (Map) ((Proxy) orig).copy(orig);
-
-        ProxyMap proxy = getFactoryProxyMap(orig.getClass());
-        return (Map) proxy.copy(orig);
-    }
-
-    public Proxy newMapProxy(Class type, Class keyType, 
-        Class elementType, Comparator compare) {
-        type = toProxyableMapType(type);
-        ProxyMap proxy = getFactoryProxyMap(type);
-        return proxy.newInstance((_assertType) ? keyType : null, 
-            (_assertType) ? elementType : null, compare, _trackChanges);
-    }
-
-    public Date copyDate(Date orig) {
-        if (orig == null)
-            return null;
-        if (orig instanceof Proxy)
-            return (Date) ((Proxy) orig).copy(orig);
-
-        ProxyDate proxy = getFactoryProxyDate(orig.getClass());
-        return (Date) proxy.copy(orig);
-    }
-
-    public Proxy newDateProxy(Class type) {
-        ProxyDate proxy = getFactoryProxyDate(type);
-        return proxy.newInstance();
-    }
-
-    public Calendar copyCalendar(Calendar orig) {
-        if (orig == null)
-            return null;
-        if (orig instanceof Proxy)
-            return (Calendar) ((Proxy) orig).copy(orig);
-
-        ProxyCalendar proxy = getFactoryProxyCalendar(orig.getClass());
-        return (Calendar) proxy.copy(orig);
-    }
-
-    public Proxy newCalendarProxy(Class type, TimeZone zone) {
-        if (type == Calendar.class)
-            type = GregorianCalendar.class;
-        ProxyCalendar proxy = getFactoryProxyCalendar(type);
-        ProxyCalendar cal = proxy.newInstance();
-        if (zone != null)
-            ((Calendar) cal).setTimeZone(zone);
-        return cal;
-    }
-
-    public Object copyCustom(Object orig) {
-        if (orig == null)
-            return null;
-        if (orig instanceof Proxy)
-            return ((Proxy) orig).copy(orig);
-        if (ImplHelper.isManageable(orig))
-            return null;
-        if (orig instanceof Collection)
-            return copyCollection((Collection) orig);
-        if (orig instanceof Map)
-            return copyMap((Map) orig);
-        if (orig instanceof Date)
-            return copyDate((Date) orig);
-        if (orig instanceof Calendar)
-            return copyCalendar((Calendar) orig);
-        ProxyBean proxy = getFactoryProxyBean(orig);
-        return (proxy == null) ? null : proxy.copy(orig); 
-    }
-
-    public Proxy newCustomProxy(Object orig) {
-        if (orig == null)
-            return null;
-        if (orig instanceof Proxy)
-            return (Proxy) orig;
-        if (ImplHelper.isManageable(orig))
-            return null;
-        if (orig instanceof Collection) {
-            Comparator comp = (orig instanceof SortedSet) 
-                ? ((SortedSet) orig).comparator() : null;
-            Collection c = (Collection) newCollectionProxy(orig.getClass(), 
-                null, comp); 
-            c.addAll((Collection) orig);
-            return (Proxy) c;
-        }
-        if (orig instanceof Map) {
-            Comparator comp = (orig instanceof SortedMap) 
-                ? ((SortedMap) orig).comparator() : null;
-            Map m = (Map) newMapProxy(orig.getClass(), null, null, comp);
-            m.putAll((Map) orig);
-            return (Proxy) m;
-        }
-        if (orig instanceof Date) {
-            Date d = (Date) newDateProxy(orig.getClass());
-            d.setTime(((Date) orig).getTime());
-            if (orig instanceof Timestamp)
-                ((Timestamp) d).setNanos(((Timestamp) orig).getNanos());
-            return (Proxy) d;
-        }
-        if (orig instanceof Calendar) {
-            Calendar c = (Calendar) newCalendarProxy(orig.getClass(),
-                ((Calendar) orig).getTimeZone());
-            c.setTimeInMillis(((Calendar) orig).getTimeInMillis());
-            return (Proxy) c;
-        }
-
-        ProxyBean proxy = getFactoryProxyBean(orig);
-        return (proxy == null) ? null : proxy.newInstance(orig);
-    }
-
-    /**
-     * Return the concrete type for proxying.
-     */
-    protected Class toProxyableCollectionType(Class type) {
-        if (type.getName().endsWith(PROXY_SUFFIX))
-            type = type.getSuperclass();
-        else if (type.isInterface()) {
-            type = toConcreteType(type, _stdCollections);
-            if (type == null)
-                throw new UnsupportedException(_loc.get("no-proxy-intf", type));
-        } else if (Modifier.isAbstract(type.getModifiers()))
-            throw new UnsupportedException(_loc.get("no-proxy-abstract", type));
-        return type;
-    }
-
-    /**
-     * Return the concrete type for proxying.
-     */
-    protected Class toProxyableMapType(Class type) {
-        if (type.getName().endsWith(PROXY_SUFFIX))
-            type = type.getSuperclass();
-        else if (type.isInterface()) {
-            type = toConcreteType(type, _stdMaps);
-            if (type == null)
-                throw new UnsupportedException(_loc.get("no-proxy-intf", type));
-        } else if (Modifier.isAbstract(type.getModifiers()))
-            throw new UnsupportedException(_loc.get("no-proxy-abstract", type));
-        return type;
-    }
-
-    /**
-     * Locate a concrete type to proxy for the given collection interface.
-     */
-    private static Class toConcreteType(Class intf, Map concretes) {
-        Class concrete = (Class) concretes.get(intf);
-        if (concrete != null)
-            return concrete;
-        Class[] intfs = intf.getInterfaces();         
-        for (int i = 0; i < intfs.length; i++) {
-            concrete = toConcreteType(intfs[i], concretes);
-            if (concrete != null)
-                return concrete;
-        }
-        return null; 
-    }
-
-    /**
-     * Return the cached factory proxy for the given collection type.
-     */
-    private ProxyCollection getFactoryProxyCollection(Class type) {
-        // we don't lock here; ok if two proxies get generated for same type
-        ProxyCollection proxy = (ProxyCollection) _proxies.get(type);
-        if (proxy == null) {
-            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
-                ProxyCollection.class);
-            Class pcls = loadBuildTimeProxy(type, l);
-            if (pcls == null)
-                pcls = GeneratedClasses.loadBCClass(
-                    generateProxyCollectionBytecode(type, true), l);
-            proxy = (ProxyCollection) instantiateProxy(pcls, null, null);
-            _proxies.put(type, proxy);
-        }
-        return proxy;
-    }
-
-    /**
-     * Return the cached factory proxy for the given map type.
-     */
-    private ProxyMap getFactoryProxyMap(Class type) {
-        // we don't lock here; ok if two proxies get generated for same type
-        ProxyMap proxy = (ProxyMap) _proxies.get(type);
-        if (proxy == null) {
-            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
-                ProxyMap.class);
-            Class pcls = loadBuildTimeProxy(type, l);
-            if (pcls == null)
-                pcls = GeneratedClasses.loadBCClass(
-                    generateProxyMapBytecode(type, true), l);
-            proxy = (ProxyMap) instantiateProxy(pcls, null, null);
-            _proxies.put(type, proxy);
-        }
-        return proxy;
-    }
-
-    /**
-     * Return the cached factory proxy for the given date type.
-     */
-    private ProxyDate getFactoryProxyDate(Class type) {
-        // we don't lock here; ok if two proxies get generated for same type
-        ProxyDate proxy = (ProxyDate) _proxies.get(type);
-        if (proxy == null) {
-            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
-                ProxyDate.class);
-            Class pcls = loadBuildTimeProxy(type, l);
-            if (pcls == null)
-                pcls = GeneratedClasses.loadBCClass(
-                    generateProxyDateBytecode(type, true), l);
-            proxy = (ProxyDate) instantiateProxy(pcls, null, null);
-            _proxies.put(type, proxy);
-        }
-        return proxy;
-    }
-
-    /**
-     * Return the cached factory proxy for the given calendar type.
-     */
-    private ProxyCalendar getFactoryProxyCalendar(Class type) {
-        // we don't lock here; ok if two proxies get generated for same type
-        ProxyCalendar proxy = (ProxyCalendar) _proxies.get(type);
-        if (proxy == null) {
-            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
-                ProxyCalendar.class);
-            Class pcls = loadBuildTimeProxy(type, l);
-            if (pcls == null)
-                pcls = GeneratedClasses.loadBCClass(
-                    generateProxyCalendarBytecode(type, true), l);
-            proxy = (ProxyCalendar) instantiateProxy(pcls, null, null);
-            _proxies.put(type, proxy);
-        }
-        return proxy;
-    }
-
-    /**
-     * Return the cached factory proxy for the given bean type.
-     */
-    private ProxyBean getFactoryProxyBean(Object orig) {
-        final Class type = orig.getClass();
-        if (isUnproxyable(type))
-            return null;
-
-        // we don't lock here; ok if two proxies get generated for same type
-        ProxyBean proxy = (ProxyBean) _proxies.get(type);
-        if (proxy == null && !_proxies.containsKey(type)) {
-            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
-                ProxyBean.class);
-            Class pcls = loadBuildTimeProxy(type, l);
-            if (pcls == null) {
-                BCClass bc = (BCClass) AccessController
-                    .doPrivileged(new PrivilegedAction() {
-                        public Object run() {
-                            return generateProxyBeanBytecode(type, true);
-                        }
-                    });
-                if (bc != null)
-                    pcls = GeneratedClasses.loadBCClass(bc, l);
-            }
-            if (pcls != null)
-                proxy = (ProxyBean) instantiateProxy(pcls,
-                    findCopyConstructor(type), new Object[] {orig});
-            _proxies.put(type, proxy);
-        }
-        return proxy;
-    }
-
-    /**
-     * Return whether the given type is known to be unproxyable.
-     */
-    protected boolean isUnproxyable(Class type) {
-        for (; type != null && type != Object.class; 
-            type = type.getSuperclass()) {
-            if (_unproxyable.contains(type.getName()))
-                return true;
-        }
-        return false;
-    }
-
-    /**
-     * Load the proxy class generated at build time for the given type,
-     * returning null if none exists.
-     */
-    protected Class loadBuildTimeProxy(Class type, ClassLoader loader) {
-        try {
-            return Class.forName(getProxyClassName(type, false), true, loader);
-        } catch (Throwable t) {
-            return null;
-        }
-    }
-
-    /**
-     * Instantiate the given proxy class.
-     */
-    private Proxy instantiateProxy(Class cls, Constructor cons, Object[] args) {
-        try {
-            if (cons != null)
-                return (Proxy) cls.getConstructor(cons.getParameterTypes()).
-                    newInstance(args);
-            return (Proxy) AccessController.doPrivileged(
-                J2DoPrivHelper.newInstanceAction(cls));
-        } catch (InstantiationException ie) {
-            throw new UnsupportedException(_loc.get("cant-newinstance",
-                cls.getSuperclass().getName()));
-        } catch (PrivilegedActionException pae) {
-            Exception e = pae.getException();
-            if (e instanceof InstantiationException)
-                throw new UnsupportedException(_loc.get("cant-newinstance",
-                    cls.getSuperclass().getName()));
-            else
-                throw new GeneralException(cls.getName()).setCause(e);
-        } catch (Throwable t) {
-            throw new GeneralException(cls.getName()).setCause(t);
-        }
-    }
-
-    /**
-     * Generate the bytecode for a collection proxy for the given type.
-     */
-    protected BCClass generateProxyCollectionBytecode(Class type, 
-        boolean runtime) {
-        assertNotFinal(type);
-        Project project = new Project(); 
-        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
-            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
-        bc.setSuperclass(type);
-        bc.declareInterface(ProxyCollection.class);
- 
-        delegateConstructors(bc, type);
-        addProxyMethods(bc, false);
-        addProxyCollectionMethods(bc, type);
-        proxyRecognizedMethods(bc, type, ProxyCollections.class, 
-            ProxyCollection.class);
-        proxySetters(bc, type);
-        addWriteReplaceMethod(bc, runtime);
-        return bc;
-    }
-
-    /**
-     * Return the name of the proxy class to generate for the given type.   
-     */
-    private static String getProxyClassName(Class type, boolean runtime) {
-        String id = (runtime) ? "$" + nextProxyId() : "";
-        return Strings.getPackageName(ProxyManagerImpl.class) + "." 
-            + type.getName().replace('.', '$') + id + PROXY_SUFFIX;
-    }
-
-    /**
-     * Throw appropriate exception if the given type is final.
-     */
-    private static void assertNotFinal(Class type) {
-        if (Modifier.isFinal(type.getModifiers()))
-            throw new UnsupportedException(_loc.get("no-proxy-final", type));
-    }
-
-    /**
-     * Generate the bytecode for a map proxy for the given type.
-     */
-    protected BCClass generateProxyMapBytecode(Class type, boolean runtime) {
-        assertNotFinal(type);
-        Project project = new Project(); 
-        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
-            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
-        bc.setSuperclass(type);
-        bc.declareInterface(ProxyMap.class);
- 
-        delegateConstructors(bc, type);
-        addProxyMethods(bc, false);
-        addProxyMapMethods(bc, type);
-        proxyRecognizedMethods(bc, type, ProxyMaps.class, ProxyMap.class);
-        proxySetters(bc, type);
-        addWriteReplaceMethod(bc, runtime);
-        return bc;
-    }
-
-    /**
-     * Generate the bytecode for a date proxy for the given type.
-     */
-    protected BCClass generateProxyDateBytecode(Class type, boolean runtime) {
-        assertNotFinal(type);
-        Project project = new Project(); 
-        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
-            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
-        bc.setSuperclass(type);
-        bc.declareInterface(ProxyDate.class);
- 
-        delegateConstructors(bc, type);
-        addProxyMethods(bc, true);
-        addProxyDateMethods(bc, type);
-        proxySetters(bc, type);
-        addWriteReplaceMethod(bc, runtime);
-        return bc;
-    }
-
-    /**
-     * Generate the bytecode for a calendar proxy for the given type.
-     */
-    protected BCClass generateProxyCalendarBytecode(Class type, 
-        boolean runtime) {
-        assertNotFinal(type);
-        Project project = new Project(); 
-        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
-            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
-        bc.setSuperclass(type);
-        bc.declareInterface(ProxyCalendar.class);
- 
-        delegateConstructors(bc, type);
-        addProxyMethods(bc, true);
-        addProxyCalendarMethods(bc, type);
-        proxySetters(bc, type);
-        addWriteReplaceMethod(bc, runtime);
-        return bc;
-    }
-
-    /**
-     * Generate the bytecode for a bean proxy for the given type.
-     */
-    protected BCClass generateProxyBeanBytecode(Class type, boolean runtime) {
-        if (Modifier.isFinal(type.getModifiers()))
-            return null;
-        if (ImplHelper.isManagedType(null, type))
-            return null;
-
-        // we can only generate a valid proxy if there is a copy constructor
-        // or a default constructor
-        Constructor cons = findCopyConstructor(type);
-        if (cons == null) {
-            Constructor[] cs = type.getConstructors();
-            for (int i = 0; cons == null && i < cs.length; i++)
-               if (cs[i].getParameterTypes().length == 0)
-                    cons = cs[i]; 
-            if (cons == null)
-                return null;
-        }
-
-        Project project = new Project(); 
-        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
-            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
-        bc.setSuperclass(type);
-        bc.declareInterface(ProxyBean.class);
- 
-        delegateConstructors(bc, type);
-        addProxyMethods(bc, true);
-        addProxyBeanMethods(bc, type, cons);
-        if (!proxySetters(bc, type))
-            return null;
-        addWriteReplaceMethod(bc, runtime);
-        return bc;
-    }
-
-    /**
-     * Create pass-through constructors to base type.
-     */
-    private void delegateConstructors(BCClass bc, Class type) {
-        Constructor[] cons = type.getConstructors();
-        Class[] params;
-        BCMethod m;
-        Code code;
-        for (int i = 0; i < cons.length; i++) {
-            params = cons[i].getParameterTypes();
-            m = bc.declareMethod("<init>", void.class, params); 
-            m.makePublic();
-
-            code = m.getCode(true);
-            code.aload().setThis();
-            for (int j = 0; j < params.length; j++)
-                code.xload().setParam(j).setType(params[j]);
-            code.invokespecial().setMethod(cons[i]);
-            code.vreturn();
-            code.calculateMaxStack();
-            code.calculateMaxLocals();
-        }
-    }
-
-    /**
-     * Implement the methods in the {@link Proxy} interface, with the exception
-     * of {@link Proxy#copy}.
-     *
-     * @param changeTracker whether to implement a null change tracker; if false
-     * the change tracker method is left unimplemented
-     */
-    private void addProxyMethods(BCClass bc, boolean changeTracker) {
-        BCField sm = bc.declareField("sm", OpenJPAStateManager.class);
-        sm.setTransient(true);
-        BCField field = bc.declareField("field", int.class);
-        field.setTransient(true);
-
-        BCMethod m = bc.declareMethod("setOwner", void.class, new Class[] {
-            OpenJPAStateManager.class, int.class });
-        m.makePublic();
-        Code code = m.getCode(true);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.putfield().setField(sm);
-        code.aload().setThis();
-        code.iload().setParam(1);
-        code.putfield().setField(field);
-        code.vreturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        m = bc.declareMethod("getOwner", OpenJPAStateManager.class, null);
-        m.makePublic();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(sm);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        m = bc.declareMethod("getOwnerField", int.class, null);
-        m.makePublic();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(field);
-        code.ireturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        /* 
-         * clone (return detached proxy object)
-         * Note:  This method is only being provided to satisfy a quirk with
-         * the IBM JDK -- while comparing Calendar objects, the clone() method
-         * was invoked.  So, we are now overriding the clone() method so as to
-         * provide a detached proxy object (null out the StateManager).
-         */
-        m = bc.declareMethod("clone", Object.class, null);
-        m.makePublic();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.invokespecial().setMethod(bc.getSuperclassType(), "clone",
-                Object.class, null);  
-        code.checkcast().setType(Proxy.class);  
-        int other = code.getNextLocalsIndex();
-        code.astore().setLocal(other);
-        code.aload().setLocal(other);
-        code.constant().setNull();
-        code.constant().setValue(0);
-        code.invokeinterface().setMethod(Proxy.class, "setOwner", void.class,
-                new Class[] { OpenJPAStateManager.class, int.class });
-        code.aload().setLocal(other);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-        
-        if (changeTracker) {
-            m = bc.declareMethod("getChangeTracker", ChangeTracker.class, null);
-            m.makePublic();
-            code = m.getCode(true);
-            code.constant().setNull();
-            code.areturn();
-            code.calculateMaxStack();
-            code.calculateMaxLocals();
-        }
-    }
-
-    /**
-     * Implement the methods in the {@link ProxyCollection} interface.
-     */
-    private void addProxyCollectionMethods(BCClass bc, Class type) {
-        // change tracker
-        BCField changeTracker = bc.declareField("changeTracker", 
-            CollectionChangeTracker.class);
-        changeTracker.setTransient(true);
-        BCMethod m = bc.declareMethod("getChangeTracker", ChangeTracker.class, 
-            null);
-        m.makePublic();
-        Code code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(changeTracker);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // collection copy
-        Constructor cons = findCopyConstructor(type);
-        if (cons == null && SortedSet.class.isAssignableFrom(type))
-            cons = findComparatorConstructor(type);
-        Class[] params = (cons == null) ? new Class[0] 
-            : cons.getParameterTypes();
-
-        m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
-        m.makePublic();
-        code = m.getCode(true);
-
-        code.anew().setType(type);
-        code.dup();
-        if (params.length == 1) {
-            code.aload().setParam(0);
-            if (params[0] == Comparator.class) {
-                code.checkcast().setType(SortedSet.class);
-                code.invokeinterface().setMethod(SortedSet.class, "comparator", 
-                    Comparator.class, null);
-            } else
-                code.checkcast().setType(params[0]);
-        }
-        code.invokespecial().setMethod(type, "<init>", void.class, params);
-        if (params.length == 0 || params[0] == Comparator.class) {
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Collection.class);
-            code.invokevirtual().setMethod(type, "addAll", boolean.class, 
-                new Class[] { Collection.class });
-            code.pop();
-        }
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // element type
-        BCField elementType = bc.declareField("elementType", Class.class);
-        elementType.setTransient(true);
-        m = bc.declareMethod("getElementType", Class.class, null);
-        m.makePublic();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(elementType);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // new instance factory
-        m = bc.declareMethod("newInstance", ProxyCollection.class, 
-            new Class[] { Class.class, Comparator.class, boolean.class });
-        m.makePublic();
-        code = m.getCode(true);
-
-        code.anew().setType(bc); 
-        code.dup();
-        cons = findComparatorConstructor(type);
-        params = (cons == null) ? new Class[0] : cons.getParameterTypes();
-        if (params.length == 1)
-            code.aload().setParam(1);
-        code.invokespecial().setMethod("<init>", void.class, params);
-        int ret = code.getNextLocalsIndex();
-        code.astore().setLocal(ret);
-
-        // set element type
-        code.aload().setLocal(ret);
-        code.aload().setParam(0);
-        code.putfield().setField(elementType);
-
-        // create change tracker and set it
-        code.iload().setParam(2);
-        JumpInstruction ifins = code.ifeq();
-        code.aload().setLocal(ret);
-        code.anew().setType(CollectionChangeTrackerImpl.class);
-        code.dup();
-        code.aload().setLocal(ret);
-        code.constant().setValue(allowsDuplicates(type));
-        code.constant().setValue(isOrdered(type));
-        code.invokespecial().setMethod(CollectionChangeTrackerImpl.class, 
-            "<init>", void.class, new Class[] { Collection.class, 
-            boolean.class, boolean.class });
-        code.putfield().setField(changeTracker);
-
-        ifins.setTarget(code.aload().setLocal(ret));
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Return whether the given collection type allows duplicates.
-     */
-    protected boolean allowsDuplicates(Class type) {
-        return !Set.class.isAssignableFrom(type);
-    }
-
-    /**
-     * Return whether the given collection type maintains an artificial 
-     * ordering.
-     */
-    protected boolean isOrdered(Class type) {
-        return List.class.isAssignableFrom(type)
-            || "java.util.LinkedHashSet".equals(type.getName());
-    }
-
-    /**
-     * Implement the methods in the {@link ProxyMap} interface.
-     */
-    private void addProxyMapMethods(BCClass bc, Class type) {
-        // change tracker
-        BCField changeTracker = bc.declareField("changeTracker", 
-            MapChangeTracker.class);
-        changeTracker.setTransient(true);
-        BCMethod m = bc.declareMethod("getChangeTracker", ChangeTracker.class, 
-            null);
-        m.makePublic();
-        Code code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(changeTracker);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // map copy
-        Constructor cons = findCopyConstructor(type);
-        if (cons == null && SortedMap.class.isAssignableFrom(type))
-            cons = findComparatorConstructor(type);
-        Class[] params = (cons == null) ? new Class[0] 
-            : cons.getParameterTypes();
-
-        m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
-        m.makePublic();
-        code = m.getCode(true);
-
-        code.anew().setType(type);
-        code.dup();
-        if (params.length == 1) {
-            code.aload().setParam(0);
-            if (params[0] == Comparator.class) {
-                code.checkcast().setType(SortedMap.class);
-                code.invokeinterface().setMethod(SortedMap.class, "comparator", 
-                    Comparator.class, null);
-            } else 
-                code.checkcast().setType(params[0]);
-        }
-        code.invokespecial().setMethod(type, "<init>", void.class, params);
-        if (params.length == 0 || params[0] == Comparator.class) {
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Map.class);
-            code.invokevirtual().setMethod(type, "putAll", void.class, 
-                new Class[] { Map.class });
-        }
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // key type
-        BCField keyType = bc.declareField("keyType", Class.class);
-        keyType.setTransient(true);
-        m = bc.declareMethod("getKeyType", Class.class, null);
-        m.makePublic();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(keyType);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // value type
-        BCField valueType = bc.declareField("valueType", Class.class);
-        valueType.setTransient(true);
-        m = bc.declareMethod("getValueType", Class.class, null);
-        m.makePublic();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(valueType);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // new instance factory
-        m = bc.declareMethod("newInstance", ProxyMap.class, 
-            new Class[] { Class.class, Class.class, Comparator.class, 
-            boolean.class });
-        m.makePublic();
-        code = m.getCode(true);
-
-        code.anew().setType(bc); 
-        code.dup();
-        cons = findComparatorConstructor(type);
-        params = (cons == null) ? new Class[0] : cons.getParameterTypes();
-        if (params.length == 1)
-            code.aload().setParam(2);
-        code.invokespecial().setMethod("<init>", void.class, params);
-        int ret = code.getNextLocalsIndex();
-        code.astore().setLocal(ret);
-
-        // set key and value types
-        code.aload().setLocal(ret);
-        code.aload().setParam(0);
-        code.putfield().setField(keyType);
-        code.aload().setLocal(ret);
-        code.aload().setParam(1);
-        code.putfield().setField(valueType);
-
-        // create change tracker and set it
-        code.iload().setParam(3);
-        JumpInstruction ifins = code.ifeq();
-        code.aload().setLocal(ret);
-        code.anew().setType(MapChangeTrackerImpl.class);
-        code.dup();
-        code.aload().setLocal(ret);
-        code.invokespecial().setMethod(MapChangeTrackerImpl.class, 
-            "<init>", void.class, new Class[] { Map.class });
-        code.putfield().setField(changeTracker);
-
-        ifins.setTarget(code.aload().setLocal(ret));
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Implement the methods in the {@link ProxyDate} interface.
-     */
-    private void addProxyDateMethods(BCClass bc, Class type) {
-        boolean hasDefaultCons = bc.getDeclaredMethod("<init>", 
-            (Class[]) null) != null;
-        boolean hasMillisCons = bc.getDeclaredMethod("<init>", 
-            new Class[] { long.class }) != null;
-        if (!hasDefaultCons && !hasMillisCons)
-            throw new UnsupportedException(_loc.get("no-date-cons", type));
-
-        // add a default constructor that delegates to the millis constructor
-        BCMethod m;
-        Code code;
-        if (!hasDefaultCons) {
-            m = bc.declareMethod("<init>", void.class, null);
-            m.makePublic();
-            code = m.getCode(true);
-            code.aload().setThis();
-            code.invokestatic().setMethod(System.class, "currentTimeMillis",
-                long.class, null);
-            code.invokespecial().setMethod(type, "<init>", void.class,
-                new Class[] { long.class });
-            code.vreturn();
-            code.calculateMaxStack();           
-            code.calculateMaxLocals();
-        }
-
-        // date copy
-        Constructor cons = findCopyConstructor(type);
-        Class[] params;
-        if (cons != null)
-            params = cons.getParameterTypes();
-        else if (hasMillisCons)
-            params = new Class[] { long.class };
-        else
-            params = new Class[0];
-
-        m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
-        m.makePublic();
-        code = m.getCode(true);
-
-        code.anew().setType(type);
-        code.dup();
-        if (params.length == 1) {
-            if (params[0] == long.class) {
-                code.aload().setParam(0);
-                code.checkcast().setType(Date.class);
-                code.invokevirtual().setMethod(Date.class, "getTime", 
-                    long.class, null);
-            } else {
-                code.aload().setParam(0);
-                code.checkcast().setType(params[0]);
-            }
-        }
-        code.invokespecial().setMethod(type, "<init>", void.class, params);
-        if (params.length == 0) {
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Date.class);
-            code.invokevirtual().setMethod(Date.class, "getTime", long.class, 
-                null);
-            code.invokevirtual().setMethod(type, "setTime", void.class,
-                new Class[] { long.class });
-        }
-        if ((params.length == 0 || params[0] == long.class) 
-            && Timestamp.class.isAssignableFrom(type)) {
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Timestamp.class);
-            code.invokevirtual().setMethod(Timestamp.class, "getNanos", 
-                int.class, null);
-            code.invokevirtual().setMethod(type, "setNanos", void.class,
-                new Class[] { int.class });
-        }
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // new instance factory
-        m = bc.declareMethod("newInstance", ProxyDate.class, null); 
-        m.makePublic();
-        code = m.getCode(true);
-        code.anew().setType(bc); 
-        code.dup();
-        code.invokespecial().setMethod("<init>", void.class, null);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Implement the methods in the {@link ProxyCalendar} interface.
-     */
-    private void addProxyCalendarMethods(BCClass bc, Class type) {
-        // calendar copy
-        Constructor cons = findCopyConstructor(type);
-        Class[] params = (cons == null) ? new Class[0] 
-            : cons.getParameterTypes();
-
-        BCMethod m = bc.declareMethod("copy", Object.class, 
-            new Class[] {Object.class});
-        m.makePublic();
-        Code code = m.getCode(true);
-
-        code.anew().setType(type);
-        code.dup();
-        if (params.length == 1) {
-            code.aload().setParam(0);
-            code.checkcast().setType(params[0]);
-        }
-        code.invokespecial().setMethod(type, "<init>", void.class, params);
-        if (params.length == 0) {
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Calendar.class);
-            code.invokevirtual().setMethod(Calendar.class, "getTimeInMillis", 
-                long.class, null);
-            code.invokevirtual().setMethod(type, "setTimeInMillis", void.class,
-                new Class[] { long.class });
-
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Calendar.class);
-            code.invokevirtual().setMethod(Calendar.class, "isLenient", 
-                boolean.class, null);
-            code.invokevirtual().setMethod(type, "setLenient", void.class,
-                new Class[] { boolean.class });
-
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Calendar.class);
-            code.invokevirtual().setMethod(Calendar.class, "getFirstDayOfWeek", 
-                int.class, null);
-            code.invokevirtual().setMethod(type, "setFirstDayOfWeek", 
-                void.class, new Class[] { int.class });
-
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Calendar.class);
-            code.invokevirtual().setMethod(Calendar.class, 
-                "getMinimalDaysInFirstWeek", int.class, null);
-            code.invokevirtual().setMethod(type, "setMinimalDaysInFirstWeek", 
-                void.class, new Class[] { int.class });
-
-            code.dup();
-            code.aload().setParam(0);
-            code.checkcast().setType(Calendar.class);
-            code.invokevirtual().setMethod(Calendar.class, "getTimeZone", 
-                TimeZone.class, null);
-            code.invokevirtual().setMethod(type, "setTimeZone", void.class,
-                new Class[] { TimeZone.class });
-        }
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // new instance factory
-        m = bc.declareMethod("newInstance", ProxyCalendar.class, null); 
-        m.makePublic();
-        code = m.getCode(true);
-        code.anew().setType(bc); 
-        code.dup();
-        code.invokespecial().setMethod("<init>", void.class, null);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // proxy the protected computeFields method b/c it is called on
-        // mutate, and some setters are final and therefore not proxyable
-        m = bc.declareMethod("computeFields", void.class, null);
-        m.makeProtected();
-        code = m.getCode(true);
-        code.aload().setThis();
-        code.constant().setValue(true);
-        code.invokestatic().setMethod(Proxies.class, "dirty", void.class,
-            new Class[] { Proxy.class, boolean.class });
-        code.aload().setThis();
-        code.invokespecial().setMethod(type, "computeFields", void.class, null);
-        code.vreturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Implement the methods in the {@link ProxyBean} interface.
-     */
-    private void addProxyBeanMethods(BCClass bc, Class type, Constructor cons) {
-        // bean copy
-        BCMethod m = bc.declareMethod("copy", Object.class, 
-            new Class[] { Object.class });
-        m.makePublic();
-        Code code = m.getCode(true);
-
-        code.anew().setType(type);
-        code.dup();
-        Class[] params = cons.getParameterTypes();
-        if (params.length == 1) {
-            code.aload().setParam(0);
-            code.checkcast().setType(params[0]);
-        }
-        code.invokespecial().setMethod(cons);
-        if (params.length == 0)
-            copyProperties(type, code);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-
-        // new instance factory
-        m = bc.declareMethod("newInstance", ProxyBean.class, 
-            new Class[] { Object.class }); 
-        m.makePublic();
-        code = m.getCode(true);
-        code.anew().setType(bc); 
-        code.dup();
-        if (params.length == 1) {
-            code.aload().setParam(0);
-            code.checkcast().setType(params[0]);
-        }
-        code.invokespecial().setMethod("<init>", void.class, params);
-        if (params.length == 0)
-            copyProperties(type, code);
-        code.areturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Copy bean properties.  Called with the copy object on the stack.  Must
-     * return with the copy object on the stack.
-     */
-    private void copyProperties(Class type, Code code) {
-        int copy = code.getNextLocalsIndex();
-        code.astore().setLocal(copy);
-        
-        Method[] meths = type.getMethods();
-        Method getter;
-        int mods;
-        for (int i = 0; i < meths.length; i++) {
-            mods = meths[i].getModifiers(); 
-            if (!Modifier.isPublic(mods) || Modifier.isStatic(mods))
-                continue;
-            if (!startsWith(meths[i].getName(), "set")
-                || meths[i].getParameterTypes().length != 1)
-                continue;
-            getter = findGetter(type, meths[i]);
-            if (getter == null)
-                continue;
-
-            // copy.setXXX(orig.getXXX());
-            code.aload().setLocal(copy);
-            code.aload().setParam(0);
-            code.checkcast().setType(type);
-            code.invokevirtual().setMethod(getter);
-            code.invokevirtual().setMethod(meths[i]);
-        }
-        code.aload().setLocal(copy);
-    }
-
-    /**
-     * Proxy recognized methods to invoke helpers in given helper class.
-     */
-    private void proxyRecognizedMethods(BCClass bc, Class type, Class helper,
-        Class proxyType) {
-        Method[] meths = type.getMethods();
-        Class[] params;
-        Class[] afterParams;
-        Method match;
-        Method after;
-        for (int i = 0; i < meths.length; i++) {
-            params = toHelperParameters(meths[i].getParameterTypes(), 
-                proxyType);
-
-            // first check for overriding method 
-            try {
-                match = helper.getMethod(meths[i].getName(), params); 
-                proxyOverrideMethod(bc, meths[i], match, params);
-                continue;
-            } catch (NoSuchMethodException nsme) {
-            } catch (Exception e) {
-                throw new GeneralException(e);
-            }
-
-            // check for before and after methods, either of which may not
-            // exist
-            match = null;
-            try {
-                match = helper.getMethod("before" 
-                    + StringUtils.capitalize(meths[i].getName()), params);
-            } catch (NoSuchMethodException nsme) {
-            } catch (Exception e) {
-                throw new GeneralException(e);
-            }
-            after = null;
-            afterParams = null;
-            try {
-                afterParams = toHelperAfterParameters(params, 
-                    meths[i].getReturnType(), (match == null) 
-                    ? void.class : match.getReturnType());
-                after = helper.getMethod("after" 
-                    + StringUtils.capitalize(meths[i].getName()), afterParams);
-            } catch (NoSuchMethodException nsme) {
-            } catch (Exception e) {
-                throw new GeneralException(e);
-            }
-            if (match != null || after != null)
-                proxyBeforeAfterMethod(bc, type, meths[i], match, params, after,
-                    afterParams);
-        }
-    }
-
-    /**
-     * Return the parameter types to the corresponding helper class method.
-     */ 
-    private static Class[] toHelperParameters(Class[] cls, Class helper) {
-        Class[] params = new Class[cls.length + 1];
-        params[0] = helper;
-        System.arraycopy(cls, 0, params, 1, cls.length); 
-        return params;
-    }
-
-    /**
-     * Return the parameter types to the corresponding helper class "after"     
-     * method.
-     */
-    private static Class[] toHelperAfterParameters(Class[] cls, Class ret,
-        Class beforeRet) {
-        if (ret == void.class && beforeRet == void.class)
-            return cls;
-        int len = cls.length;
-        if (ret != void.class)
-            len++;
-        if (beforeRet != void.class)
-            len++;
-        Class[] params = new Class[len];
-        System.arraycopy(cls, 0, params, 0, cls.length);
-        int pos = cls.length;
-        if (ret != void.class)
-            params[pos++] = ret;
-        if (beforeRet != void.class)
-            params[pos++] = beforeRet;
-        return params;
-    }
-
-    /**
-     * Proxy setter methods of the given type.
-     * 
-     * @return true if we find any setters, false otherwise
-     */
-    private boolean proxySetters(BCClass bc, Class type) {
-        Method[] meths = type.getMethods();
-        int setters = 0;
-        for (int i = 0; i < meths.length; i++) {
-            if (isSetter(meths[i]) && !Modifier.isFinal(meths[i].getModifiers())
-                && bc.getDeclaredMethod(meths[i].getName(),
-                meths[i].getParameterTypes()) == null) {
-                setters++;
-                proxySetter(bc, type, meths[i]);
-            }
-        } 
-        return setters > 0;
-    }
-
-    /**
-     * Proxy the given method with one that overrides it by calling into the
-     * given helper.
-     */
-    private void proxyOverrideMethod(BCClass bc, Method meth, 
-        Method helper, Class[] params) {
-        BCMethod m = bc.declareMethod(meth.getName(), meth.getReturnType(),
-            meth.getParameterTypes());
-        m.makePublic();
-        Code code = m.getCode(true);
-
-        code.aload().setThis();
-        for (int i = 1; i < params.length; i++)
-            code.xload().setParam(i - 1).setType(params[i]);
-        code.invokestatic().setMethod(helper);
-        code.xreturn().setType(meth.getReturnType());
-
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Proxy the given method with one that overrides it by calling into the
-     * given helper.
-     */
-    private void proxyBeforeAfterMethod(BCClass bc, Class type, Method meth, 
-        Method before, Class[] params, Method after, Class[] afterParams) {
-        BCMethod m = bc.declareMethod(meth.getName(), meth.getReturnType(),
-            meth.getParameterTypes());
-        m.makePublic();
-        Code code = m.getCode(true);
-
-        // invoke before
-        int beforeRet = -1;
-        if (before != null) {
-            code.aload().setThis();
-            for (int i = 1; i < params.length; i++)
-                code.xload().setParam(i - 1).setType(params[i]);
-            code.invokestatic().setMethod(before);
-            if (after != null && before.getReturnType() != void.class) {
-                beforeRet = code.getNextLocalsIndex();
-                code.xstore().setLocal(beforeRet).
-                    setType(before.getReturnType());
-            }
-        }
-
-        // invoke super
-        code.aload().setThis();
-        for (int i = 1; i < params.length; i++)
-            code.xload().setParam(i - 1).setType(params[i]);
-        code.invokespecial().setMethod(type, meth.getName(), 
-            meth.getReturnType(), meth.getParameterTypes());
-
-        // invoke after 
-        if (after != null) {
-            int ret = -1;
-            if (meth.getReturnType() != void.class) {
-                ret = code.getNextLocalsIndex();
-                code.xstore().setLocal(ret).setType(meth.getReturnType());
-            }
-            code.aload().setThis();
-            for (int i = 1; i < params.length; i++)
-                code.xload().setParam(i - 1).setType(params[i]);
-            if (ret != -1)
-                code.xload().setLocal(ret).setType(meth.getReturnType());
-            if (beforeRet != -1)
-                code.xload().setLocal(beforeRet).
-                    setType(before.getReturnType());
-            code.invokestatic().setMethod(after);
-        }
-        code.xreturn().setType(meth.getReturnType());
-
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Return whether the given method is a setter.
-     */
-    protected boolean isSetter(Method meth) {
-        return startsWith(meth.getName(), "set")
-            || startsWith(meth.getName(), "add")
-            || startsWith(meth.getName(), "remove")
-            || startsWith(meth.getName(), "insert")
-            || startsWith(meth.getName(), "clear")
-            || startsWith(meth.getName(), "roll"); // used by Calendar
-    }
-
-    /**
-     * Return the getter corresponding to the given setter, or null.
-     */
-    protected Method findGetter(Class type, Method setter) {
-        String name = setter.getName().substring(3);
-        Class param = setter.getParameterTypes()[0];
-        Method getter;
-        try {
-            getter = type.getMethod("get" + name, (Class[]) null);   
-            if (getter.getReturnType().isAssignableFrom(param)
-                || param.isAssignableFrom(getter.getReturnType()))
-                return getter;
-        } catch (NoSuchMethodException nsme) {
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        }
-
-        if (param == boolean.class || param == Boolean.class) {
-            try {
-                getter = type.getMethod("is" + name, (Class[]) null);   
-                if (getter.getReturnType().isAssignableFrom(param)
-                    || param.isAssignableFrom(getter.getReturnType()))
-                    return getter;
-            } catch (NoSuchMethodException nsme) {
-            } catch (Exception e) {
-                throw new GeneralException(e);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return whether the target string stars with the given token.
-     */
-    private static boolean startsWith(String str, String token) {
-        return str.startsWith(token)
-            && (str.length() == token.length() 
-            || Character.isUpperCase(str.charAt(token.length())));
-    }
-
-    /**
-     * Proxy the given setter method to dirty the proxy owner.
-     */
-    private void proxySetter(BCClass bc, Class type, Method meth) {
-        Class[] params = meth.getParameterTypes();
-        Class ret = meth.getReturnType();
-        BCMethod m = bc.declareMethod(meth.getName(), ret, params);
-        m.makePublic();
-        Code code = m.getCode(true);
-        code.aload().setThis();
-        code.constant().setValue(true);
-        code.invokestatic().setMethod(Proxies.class, "dirty", void.class,
-            new Class[] { Proxy.class, boolean.class });
-        code.aload().setThis();
-        for (int i = 0; i < params.length; i++)
-            code.xload().setParam(i).setType(params[i]);
-        code.invokespecial().setMethod(type, meth.getName(), ret, params);
-        code.xreturn().setType(ret);
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-    }
-
-    /**
-     * Add a writeReplace implementation that serializes to a non-proxy type
-     * unless detached and this is a build-time generated class.
-     */
-    private void addWriteReplaceMethod(BCClass bc, boolean runtime) {
-        BCMethod m = bc.declareMethod("writeReplace", Object.class, null);
-        m.makeProtected();
-        m.getExceptions(true).addException(ObjectStreamException.class);
-        Code code = m.getCode(true);
-        code.aload().setThis();
-        code.constant().setValue(!runtime);
-        code.invokestatic().setMethod(Proxies.class, "writeReplace", 
-            Object.class, new Class[] { Proxy.class, boolean.class });
-        code.areturn();
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
-    }
-
-    /**
-     * Create a unique id to avoid proxy class name conflicts.
-     */
-    private static synchronized long nextProxyId() {
-        return _proxyId++;
-    }
-
-    /**
-     * Find an appropriate copy constructor for the given type, or return null
-     * if none.
-     */
-    protected Constructor findCopyConstructor(Class cls) {
-        Constructor[] cons = cls.getConstructors();
-        Constructor match = null;
-        Class matchParam = null;
-        Class[] params;
-        for (int i = 0; i < cons.length; i++) {
-            params = cons[i].getParameterTypes();
-            if (params.length != 1)
-                continue;
-
-            // quit immediately on exact match
-            if (params[0] == cls)
-                return cons[i];
-
-            if (params[0].isAssignableFrom(cls) && (matchParam == null
-                || matchParam.isAssignableFrom(params[0]))) {
-                 // track most derived collection constructor
-                match = cons[i];
-                matchParam = params[0];
-            }
-        }
-        return match; 
-    }
-
-    /**
-     * Return the constructor that takes a comparator for the given type, or
-     * null if none.
-     */
-    private static Constructor findComparatorConstructor(Class cls) {
-        try {
-            return cls.getConstructor(new Class[] { Comparator.class });
-        } catch (NoSuchMethodException nsme) {
-            return null;
-        } catch (Exception e) {
-            throw new GeneralException(e);
-        }
-    }
-
-    /**
-     * Usage: java org.apache.openjpa.util.proxy.ProxyManagerImpl [option]*
-     * &lt;class name&gt;+<br />
-     * Where the following options are recognized:
-     * <ul> 
-     * <li><i>-utils/-u &lt;number&gt;</i>: Generate proxies for the standard
-     * java.util collection, map, date, and calendar classes of the given Java
-     * version.  Use 4 for Java 1.4, 5 for Java 5, etc.</li>
-     * </ul>
-     *
-     * The main method generates .class files for the proxies to the classes    
-     * given on the command line.  It writes the generated classes to beside the
-     * ProxyManagerImpl.class file if possible; otherwise it writes to the 
-     * current directory.  The proxy manager looks for these classes 
-     * before generating its own proxies at runtime.
-     */
-    public static void main(String[] args) 
-        throws ClassNotFoundException, IOException {
-        File dir = Files.getClassFile(ProxyManagerImpl.class);
-        dir = (dir == null) ? new File((String) AccessController.doPrivileged(
-            J2DoPrivHelper.getPropertyAction("user.dir")))
-            : dir.getParentFile();
-
-        Options opts = new Options();
-        args = opts.setFromCmdLine(args);
-
-        List types = new ArrayList();
-        types.addAll(Arrays.asList(args));
-        int utils = opts.removeIntProperty("utils", "u", 0);
-        if (utils >= 4) {
-            types.addAll(Arrays.asList(new String[] {
-                java.sql.Date.class.getName(),
-                java.sql.Time.class.getName(),
-                java.sql.Timestamp.class.getName(),
-                java.util.ArrayList.class.getName(),
-                java.util.Date.class.getName(),
-                java.util.GregorianCalendar.class.getName(),
-                java.util.HashMap.class.getName(),
-                java.util.HashSet.class.getName(),
-                java.util.Hashtable.class.getName(),
-                java.util.LinkedList.class.getName(),
-                java.util.Properties.class.getName(),
-                java.util.TreeMap.class.getName(),
-                java.util.TreeSet.class.getName(),
-                java.util.Vector.class.getName(),
-            })); 
-        }
-        if (utils >= 5) {
-            types.addAll(Arrays.asList(new String[] {
-                "java.util.EnumMap",
-                "java.util.IdentityHashMap",
-                "java.util.LinkedHashMap",
-                "java.util.LinkedHashSet",
-                "java.util.PriorityQueue",
-            })); 
-        }
-
-        final ProxyManagerImpl mgr = new ProxyManagerImpl();
-        Class cls;
-        BCClass bc;
-        for (int i = 0; i < types.size(); i++) {
-            cls = Class.forName((String) types.get(i));
-            try {
-                if (Class.forName(getProxyClassName(cls, false), true,
-                    GeneratedClasses.getMostDerivedLoader(cls, Proxy.class))
-                    != null)
-                    continue;
-            } catch (Throwable t) {
-                // expected if the class hasn't been generated
-            }
-
-            if (Collection.class.isAssignableFrom(cls))
-                bc = mgr.generateProxyCollectionBytecode(cls, false);         
-            else if (Map.class.isAssignableFrom(cls))
-                bc = mgr.generateProxyMapBytecode(cls, false);         
-            else if (Date.class.isAssignableFrom(cls))
-                bc = mgr.generateProxyDateBytecode(cls, false);
-            else if (Calendar.class.isAssignableFrom(cls))
-                bc = mgr.generateProxyCalendarBytecode(cls, false);
-            else {
-                final Class fCls = cls;
-                bc = (BCClass) AccessController
-                    .doPrivileged(new PrivilegedAction() {
-                        public Object run() {
-                            return mgr.generateProxyBeanBytecode(fCls, false);
-                        }
-                    });
-            }
-
-            System.out.println(bc.getName());
-            bc.write(new File(dir, bc.getClassName() + ".class"));
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Queue;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Files;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.JavaVersions;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.lib.util.concurrent.NullSafeConcurrentHashMap;
+
+import java.util.concurrent.ConcurrentHashMap;
+import serp.bytecode.BCClass;
+import serp.bytecode.BCField;
+import serp.bytecode.BCMethod;
+import serp.bytecode.Code;
+import serp.bytecode.JumpInstruction;
+import serp.bytecode.Project;
+import serp.util.Strings;
+
+/**
+ * Default implementation of the {@link ProxyManager} interface.
+ *
+ * @author Abe White
+ */
+public class ProxyManagerImpl
+    implements ProxyManager {
+
+    private static final String PROXY_SUFFIX = "$proxy";
+
+    private static final Localizer _loc = Localizer.forPackage
+        (ProxyManagerImpl.class);
+
+    private static long _proxyId = 0L;
+    private static final Map _stdCollections = new HashMap();
+    private static final Map _stdMaps = new HashMap();
+    static {
+        _stdCollections.put(Collection.class, ArrayList.class);
+        _stdCollections.put(Set.class, HashSet.class);
+        _stdCollections.put(SortedSet.class, TreeSet.class);
+        _stdCollections.put(List.class, ArrayList.class);
+        _stdCollections.put(Queue.class, LinkedList.class);
+        _stdMaps.put(Map.class, HashMap.class);
+        _stdMaps.put(SortedMap.class, TreeMap.class);
+    }
+
+    private final Set _unproxyable = new HashSet();
+    private final Map _proxies = new NullSafeConcurrentHashMap();
+    private boolean _trackChanges = true;
+    private boolean _assertType = false;
+
+    public ProxyManagerImpl() {
+        _unproxyable.add(TimeZone.class.getName());
+    }
+
+    /**
+     * Whether proxies produced by this factory will use {@link ChangeTracker}s
+     * to try to cut down on data store operations at the cost of some extra
+     * bookkeeping overhead. Defaults to true.
+     */
+    public boolean getTrackChanges() {
+        return _trackChanges;
+    }
+
+    /**
+     * Whether proxies produced by this factory will use {@link ChangeTracker}s
+     * to try to cut down on data store operations at the cost of some extra
+     * bookkeeping overhead. Defaults to true.
+     */
+    public void setTrackChanges(boolean track) {
+        _trackChanges = track;
+    }
+
+    /**
+     * Whether to perform runtime checks to ensure that all elements
+     * added to collection and map proxies are the proper element/key/value
+     * type as defined by the metadata. Defaults to false.
+     */
+    public boolean getAssertAllowedType() {
+        return _assertType;
+    }
+
+    /**
+     * Whether to perform runtime checks to ensure that all elements
+     * added to collection and map proxies are the proper element/key/value
+     * type as defined by the metadata. Defaults to false.
+     */
+    public void setAssertAllowedType(boolean assertType) {
+        _assertType = assertType;
+    }
+
+    /**
+     * Return a mutable view of class names we know cannot be proxied  
+     * correctly by this manager.
+     */
+    public Collection getUnproxyable() {
+        return _unproxyable;
+    }
+
+    /**
+     * Provided for auto-configuration.  Add the given semicolon-separated
+     * class names to the set of class names we know cannot be proxied correctly
+     * by this manager.
+     */
+    public void setUnproxyable(String clsNames) {
+        if (clsNames != null)
+            _unproxyable.addAll(Arrays.asList(Strings.split(clsNames, ";", 0)));
+    }
+
+    public Object copyArray(Object orig) {
+        if (orig == null)
+            return null;
+
+        try {
+            int length = Array.getLength(orig);
+            Object array = Array.newInstance(orig.getClass().
+                getComponentType(), length);
+
+            System.arraycopy(orig, 0, array, 0, length);
+            return array;
+        } catch (Exception e) {
+            throw new UnsupportedException(_loc.get("bad-array",
+                e.getMessage()), e);
+        }
+    }
+
+    public Collection copyCollection(Collection orig) {
+        if (orig == null)
+            return null;
+        if (orig instanceof Proxy)
+            return (Collection) ((Proxy) orig).copy(orig);
+
+        ProxyCollection proxy = getFactoryProxyCollection(orig.getClass());
+        return (Collection) proxy.copy(orig);
+    }
+
+    public Proxy newCollectionProxy(Class type, Class elementType,
+        Comparator compare) {
+        type = toProxyableCollectionType(type);
+        ProxyCollection proxy = getFactoryProxyCollection(type);
+        return proxy.newInstance((_assertType) ? elementType : null, compare,
+            _trackChanges);
+    }
+
+    public Map copyMap(Map orig) {
+        if (orig == null)
+            return null;
+        if (orig instanceof Proxy)
+            return (Map) ((Proxy) orig).copy(orig);
+
+        ProxyMap proxy = getFactoryProxyMap(orig.getClass());
+        return (Map) proxy.copy(orig);
+    }
+
+    public Proxy newMapProxy(Class type, Class keyType, 
+        Class elementType, Comparator compare) {
+        type = toProxyableMapType(type);
+        ProxyMap proxy = getFactoryProxyMap(type);
+        return proxy.newInstance((_assertType) ? keyType : null, 
+            (_assertType) ? elementType : null, compare, _trackChanges);
+    }
+
+    public Date copyDate(Date orig) {
+        if (orig == null)
+            return null;
+        if (orig instanceof Proxy)
+            return (Date) ((Proxy) orig).copy(orig);
+
+        ProxyDate proxy = getFactoryProxyDate(orig.getClass());
+        return (Date) proxy.copy(orig);
+    }
+
+    public Proxy newDateProxy(Class type) {
+        ProxyDate proxy = getFactoryProxyDate(type);
+        return proxy.newInstance();
+    }
+
+    public Calendar copyCalendar(Calendar orig) {
+        if (orig == null)
+            return null;
+        if (orig instanceof Proxy)
+            return (Calendar) ((Proxy) orig).copy(orig);
+
+        ProxyCalendar proxy = getFactoryProxyCalendar(orig.getClass());
+        return (Calendar) proxy.copy(orig);
+    }
+
+    public Proxy newCalendarProxy(Class type, TimeZone zone) {
+        if (type == Calendar.class)
+            type = GregorianCalendar.class;
+        ProxyCalendar proxy = getFactoryProxyCalendar(type);
+        ProxyCalendar cal = proxy.newInstance();
+        if (zone != null)
+            ((Calendar) cal).setTimeZone(zone);
+        return cal;
+    }
+
+    public Object copyCustom(Object orig) {
+        if (orig == null)
+            return null;
+        if (orig instanceof Proxy)
+            return ((Proxy) orig).copy(orig);
+        if (ImplHelper.isManageable(orig))
+            return null;
+        if (orig instanceof Collection)
+            return copyCollection((Collection) orig);
+        if (orig instanceof Map)
+            return copyMap((Map) orig);
+        if (orig instanceof Date)
+            return copyDate((Date) orig);
+        if (orig instanceof Calendar)
+            return copyCalendar((Calendar) orig);
+        ProxyBean proxy = getFactoryProxyBean(orig);
+        return (proxy == null) ? null : proxy.copy(orig); 
+    }
+
+    public Proxy newCustomProxy(Object orig) {
+        if (orig == null)
+            return null;
+        if (orig instanceof Proxy)
+            return (Proxy) orig;
+        if (ImplHelper.isManageable(orig))
+            return null;
+        if (orig instanceof Collection) {
+            Comparator comp = (orig instanceof SortedSet) 
+                ? ((SortedSet) orig).comparator() : null;
+            Collection c = (Collection) newCollectionProxy(orig.getClass(), 
+                null, comp); 
+            c.addAll((Collection) orig);
+            return (Proxy) c;
+        }
+        if (orig instanceof Map) {
+            Comparator comp = (orig instanceof SortedMap) 
+                ? ((SortedMap) orig).comparator() : null;
+            Map m = (Map) newMapProxy(orig.getClass(), null, null, comp);
+            m.putAll((Map) orig);
+            return (Proxy) m;
+        }
+        if (orig instanceof Date) {
+            Date d = (Date) newDateProxy(orig.getClass());
+            d.setTime(((Date) orig).getTime());
+            if (orig instanceof Timestamp)
+                ((Timestamp) d).setNanos(((Timestamp) orig).getNanos());
+            return (Proxy) d;
+        }
+        if (orig instanceof Calendar) {
+            Calendar c = (Calendar) newCalendarProxy(orig.getClass(),
+                ((Calendar) orig).getTimeZone());
+            c.setTimeInMillis(((Calendar) orig).getTimeInMillis());
+            return (Proxy) c;
+        }
+
+        ProxyBean proxy = getFactoryProxyBean(orig);
+        return (proxy == null) ? null : proxy.newInstance(orig);
+    }
+
+    /**
+     * Return the concrete type for proxying.
+     */
+    protected Class toProxyableCollectionType(Class type) {
+        if (type.getName().endsWith(PROXY_SUFFIX))
+            type = type.getSuperclass();
+        else if (type.isInterface()) {
+            type = toConcreteType(type, _stdCollections);
+            if (type == null)
+                throw new UnsupportedException(_loc.get("no-proxy-intf", type));
+        } else if (Modifier.isAbstract(type.getModifiers()))
+            throw new UnsupportedException(_loc.get("no-proxy-abstract", type));
+        return type;
+    }
+
+    /**
+     * Return the concrete type for proxying.
+     */
+    protected Class toProxyableMapType(Class type) {
+        if (type.getName().endsWith(PROXY_SUFFIX))
+            type = type.getSuperclass();
+        else if (type.isInterface()) {
+            type = toConcreteType(type, _stdMaps);
+            if (type == null)
+                throw new UnsupportedException(_loc.get("no-proxy-intf", type));
+        } else if (Modifier.isAbstract(type.getModifiers()))
+            throw new UnsupportedException(_loc.get("no-proxy-abstract", type));
+        return type;
+    }
+
+    /**
+     * Locate a concrete type to proxy for the given collection interface.
+     */
+    private static Class toConcreteType(Class intf, Map concretes) {
+        Class concrete = (Class) concretes.get(intf);
+        if (concrete != null)
+            return concrete;
+        Class[] intfs = intf.getInterfaces();         
+        for (int i = 0; i < intfs.length; i++) {
+            concrete = toConcreteType(intfs[i], concretes);
+            if (concrete != null)
+                return concrete;
+        }
+        return null; 
+    }
+
+    /**
+     * Return the cached factory proxy for the given collection type.
+     */
+    private ProxyCollection getFactoryProxyCollection(Class type) {
+        // we don't lock here; ok if two proxies get generated for same type
+        ProxyCollection proxy = (ProxyCollection) _proxies.get(type);
+        if (proxy == null) {
+            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
+                ProxyCollection.class);
+            Class pcls = loadBuildTimeProxy(type, l);
+            if (pcls == null)
+                pcls = GeneratedClasses.loadBCClass(
+                    generateProxyCollectionBytecode(type, true), l);
+            proxy = (ProxyCollection) instantiateProxy(pcls, null, null);
+            _proxies.put(type, proxy);
+        }
+        return proxy;
+    }
+
+    /**
+     * Return the cached factory proxy for the given map type.
+     */
+    private ProxyMap getFactoryProxyMap(Class type) {
+        // we don't lock here; ok if two proxies get generated for same type
+        ProxyMap proxy = (ProxyMap) _proxies.get(type);
+        if (proxy == null) {
+            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
+                ProxyMap.class);
+            Class pcls = loadBuildTimeProxy(type, l);
+            if (pcls == null)
+                pcls = GeneratedClasses.loadBCClass(
+                    generateProxyMapBytecode(type, true), l);
+            proxy = (ProxyMap) instantiateProxy(pcls, null, null);
+            _proxies.put(type, proxy);
+        }
+        return proxy;
+    }
+
+    /**
+     * Return the cached factory proxy for the given date type.
+     */
+    private ProxyDate getFactoryProxyDate(Class type) {
+        // we don't lock here; ok if two proxies get generated for same type
+        ProxyDate proxy = (ProxyDate) _proxies.get(type);
+        if (proxy == null) {
+            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
+                ProxyDate.class);
+            Class pcls = loadBuildTimeProxy(type, l);
+            if (pcls == null)
+                pcls = GeneratedClasses.loadBCClass(
+                    generateProxyDateBytecode(type, true), l);
+            proxy = (ProxyDate) instantiateProxy(pcls, null, null);
+            _proxies.put(type, proxy);
+        }
+        return proxy;
+    }
+
+    /**
+     * Return the cached factory proxy for the given calendar type.
+     */
+    private ProxyCalendar getFactoryProxyCalendar(Class type) {
+        // we don't lock here; ok if two proxies get generated for same type
+        ProxyCalendar proxy = (ProxyCalendar) _proxies.get(type);
+        if (proxy == null) {
+            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
+                ProxyCalendar.class);
+            Class pcls = loadBuildTimeProxy(type, l);
+            if (pcls == null)
+                pcls = GeneratedClasses.loadBCClass(
+                    generateProxyCalendarBytecode(type, true), l);
+            proxy = (ProxyCalendar) instantiateProxy(pcls, null, null);
+            _proxies.put(type, proxy);
+        }
+        return proxy;
+    }
+
+    /**
+     * Return the cached factory proxy for the given bean type.
+     */
+    private ProxyBean getFactoryProxyBean(Object orig) {
+        final Class type = orig.getClass();
+        if (isUnproxyable(type))
+            return null;
+
+        // we don't lock here; ok if two proxies get generated for same type
+        ProxyBean proxy = (ProxyBean) _proxies.get(type);
+        if (proxy == null && !_proxies.containsKey(type)) {
+            ClassLoader l = GeneratedClasses.getMostDerivedLoader(type,
+                ProxyBean.class);
+            Class pcls = loadBuildTimeProxy(type, l);
+            if (pcls == null) {
+                BCClass bc = (BCClass) AccessController
+                    .doPrivileged(new PrivilegedAction() {
+                        public Object run() {
+                            return generateProxyBeanBytecode(type, true);
+                        }
+                    });
+                if (bc != null)
+                    pcls = GeneratedClasses.loadBCClass(bc, l);
+            }
+            if (pcls != null)
+                proxy = (ProxyBean) instantiateProxy(pcls,
+                    findCopyConstructor(type), new Object[] {orig});
+            _proxies.put(type, proxy);
+        }
+        return proxy;
+    }
+
+    /**
+     * Return whether the given type is known to be unproxyable.
+     */
+    protected boolean isUnproxyable(Class type) {
+        for (; type != null && type != Object.class; 
+            type = type.getSuperclass()) {
+            if (_unproxyable.contains(type.getName()))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Load the proxy class generated at build time for the given type,
+     * returning null if none exists.
+     */
+    protected Class loadBuildTimeProxy(Class type, ClassLoader loader) {
+        try {
+            return Class.forName(getProxyClassName(type, false), true, loader);
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+
+    /**
+     * Instantiate the given proxy class.
+     */
+    private Proxy instantiateProxy(Class cls, Constructor cons, Object[] args) {
+        try {
+            if (cons != null)
+                return (Proxy) cls.getConstructor(cons.getParameterTypes()).
+                    newInstance(args);
+            return (Proxy) AccessController.doPrivileged(
+                J2DoPrivHelper.newInstanceAction(cls));
+        } catch (InstantiationException ie) {
+            throw new UnsupportedException(_loc.get("cant-newinstance",
+                cls.getSuperclass().getName()));
+        } catch (PrivilegedActionException pae) {
+            Exception e = pae.getException();
+            if (e instanceof InstantiationException)
+                throw new UnsupportedException(_loc.get("cant-newinstance",
+                    cls.getSuperclass().getName()));
+            else
+                throw new GeneralException(cls.getName()).setCause(e);
+        } catch (Throwable t) {
+            throw new GeneralException(cls.getName()).setCause(t);
+        }
+    }
+
+    /**
+     * Generate the bytecode for a collection proxy for the given type.
+     */
+    protected BCClass generateProxyCollectionBytecode(Class type, 
+        boolean runtime) {
+        assertNotFinal(type);
+        Project project = new Project(); 
+        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
+            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
+        bc.setSuperclass(type);
+        bc.declareInterface(ProxyCollection.class);
+ 
+        delegateConstructors(bc, type);
+        addProxyMethods(bc, false);
+        addProxyCollectionMethods(bc, type);
+        proxyRecognizedMethods(bc, type, ProxyCollections.class, 
+            ProxyCollection.class);
+        proxySetters(bc, type);
+        addWriteReplaceMethod(bc, runtime);
+        return bc;
+    }
+
+    /**
+     * Return the name of the proxy class to generate for the given type.   
+     */
+    private static String getProxyClassName(Class type, boolean runtime) {
+        String id = (runtime) ? "$" + nextProxyId() : "";
+        return Strings.getPackageName(ProxyManagerImpl.class) + "." 
+            + type.getName().replace('.', '$') + id + PROXY_SUFFIX;
+    }
+
+    /**
+     * Throw appropriate exception if the given type is final.
+     */
+    private static void assertNotFinal(Class type) {
+        if (Modifier.isFinal(type.getModifiers()))
+            throw new UnsupportedException(_loc.get("no-proxy-final", type));
+    }
+
+    /**
+     * Generate the bytecode for a map proxy for the given type.
+     */
+    protected BCClass generateProxyMapBytecode(Class type, boolean runtime) {
+        assertNotFinal(type);
+        Project project = new Project(); 
+        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
+            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
+        bc.setSuperclass(type);
+        bc.declareInterface(ProxyMap.class);
+ 
+        delegateConstructors(bc, type);
+        addProxyMethods(bc, false);
+        addProxyMapMethods(bc, type);
+        proxyRecognizedMethods(bc, type, ProxyMaps.class, ProxyMap.class);
+        proxySetters(bc, type);
+        addWriteReplaceMethod(bc, runtime);
+        return bc;
+    }
+
+    /**
+     * Generate the bytecode for a date proxy for the given type.
+     */
+    protected BCClass generateProxyDateBytecode(Class type, boolean runtime) {
+        assertNotFinal(type);
+        Project project = new Project(); 
+        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
+            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
+        bc.setSuperclass(type);
+        bc.declareInterface(ProxyDate.class);
+ 
+        delegateConstructors(bc, type);
+        addProxyMethods(bc, true);
+        addProxyDateMethods(bc, type);
+        proxySetters(bc, type);
+        addWriteReplaceMethod(bc, runtime);
+        return bc;
+    }
+
+    /**
+     * Generate the bytecode for a calendar proxy for the given type.
+     */
+    protected BCClass generateProxyCalendarBytecode(Class type, 
+        boolean runtime) {
+        assertNotFinal(type);
+        Project project = new Project(); 
+        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
+            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
+        bc.setSuperclass(type);
+        bc.declareInterface(ProxyCalendar.class);
+ 
+        delegateConstructors(bc, type);
+        addProxyMethods(bc, true);
+        addProxyCalendarMethods(bc, type);
+        proxySetters(bc, type);
+        addWriteReplaceMethod(bc, runtime);
+        return bc;
+    }
+
+    /**
+     * Generate the bytecode for a bean proxy for the given type.
+     */
+    protected BCClass generateProxyBeanBytecode(Class type, boolean runtime) {
+        if (Modifier.isFinal(type.getModifiers()))
+            return null;
+        if (ImplHelper.isManagedType(null, type))
+            return null;
+
+        // we can only generate a valid proxy if there is a copy constructor
+        // or a default constructor
+        Constructor cons = findCopyConstructor(type);
+        if (cons == null) {
+            Constructor[] cs = type.getConstructors();
+            for (int i = 0; cons == null && i < cs.length; i++)
+               if (cs[i].getParameterTypes().length == 0)
+                    cons = cs[i]; 
+            if (cons == null)
+                return null;
+        }
+
+        Project project = new Project(); 
+        BCClass bc = (BCClass) AccessController.doPrivileged(J2DoPrivHelper
+            .loadProjectClassAction(project, getProxyClassName(type, runtime))); 
+        bc.setSuperclass(type);
+        bc.declareInterface(ProxyBean.class);
+ 
+        delegateConstructors(bc, type);
+        addProxyMethods(bc, true);
+        addProxyBeanMethods(bc, type, cons);
+        if (!proxySetters(bc, type))
+            return null;
+        addWriteReplaceMethod(bc, runtime);
+        return bc;
+    }
+
+    /**
+     * Create pass-through constructors to base type.
+     */
+    private void delegateConstructors(BCClass bc, Class type) {
+        Constructor[] cons = type.getConstructors();
+        Class[] params;
+        BCMethod m;
+        Code code;
+        for (int i = 0; i < cons.length; i++) {
+            params = cons[i].getParameterTypes();
+            m = bc.declareMethod("<init>", void.class, params); 
+            m.makePublic();
+
+            code = m.getCode(true);
+            code.aload().setThis();
+            for (int j = 0; j < params.length; j++)
+                code.xload().setParam(j).setType(params[j]);
+            code.invokespecial().setMethod(cons[i]);
+            code.vreturn();
+            code.calculateMaxStack();
+            code.calculateMaxLocals();
+        }
+    }
+
+    /**
+     * Implement the methods in the {@link Proxy} interface, with the exception
+     * of {@link Proxy#copy}.
+     *
+     * @param changeTracker whether to implement a null change tracker; if false
+     * the change tracker method is left unimplemented
+     */
+    private void addProxyMethods(BCClass bc, boolean changeTracker) {
+        BCField sm = bc.declareField("sm", OpenJPAStateManager.class);
+        sm.setTransient(true);
+        BCField field = bc.declareField("field", int.class);
+        field.setTransient(true);
+
+        BCMethod m = bc.declareMethod("setOwner", void.class, new Class[] {
+            OpenJPAStateManager.class, int.class });
+        m.makePublic();
+        Code code = m.getCode(true);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.putfield().setField(sm);
+        code.aload().setThis();
+        code.iload().setParam(1);
+        code.putfield().setField(field);
+        code.vreturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        m = bc.declareMethod("getOwner", OpenJPAStateManager.class, null);
+        m.makePublic();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(sm);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        m = bc.declareMethod("getOwnerField", int.class, null);
+        m.makePublic();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(field);
+        code.ireturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        /* 
+         * clone (return detached proxy object)
+         * Note:  This method is only being provided to satisfy a quirk with
+         * the IBM JDK -- while comparing Calendar objects, the clone() method
+         * was invoked.  So, we are now overriding the clone() method so as to
+         * provide a detached proxy object (null out the StateManager).
+         */
+        m = bc.declareMethod("clone", Object.class, null);
+        m.makePublic();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.invokespecial().setMethod(bc.getSuperclassType(), "clone",
+                Object.class, null);  
+        code.checkcast().setType(Proxy.class);  
+        int other = code.getNextLocalsIndex();
+        code.astore().setLocal(other);
+        code.aload().setLocal(other);
+        code.constant().setNull();
+        code.constant().setValue(0);
+        code.invokeinterface().setMethod(Proxy.class, "setOwner", void.class,
+                new Class[] { OpenJPAStateManager.class, int.class });
+        code.aload().setLocal(other);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+        
+        if (changeTracker) {
+            m = bc.declareMethod("getChangeTracker", ChangeTracker.class, null);
+            m.makePublic();
+            code = m.getCode(true);
+            code.constant().setNull();
+            code.areturn();
+            code.calculateMaxStack();
+            code.calculateMaxLocals();
+        }
+    }
+
+    /**
+     * Implement the methods in the {@link ProxyCollection} interface.
+     */
+    private void addProxyCollectionMethods(BCClass bc, Class type) {
+        // change tracker
+        BCField changeTracker = bc.declareField("changeTracker", 
+            CollectionChangeTracker.class);
+        changeTracker.setTransient(true);
+        BCMethod m = bc.declareMethod("getChangeTracker", ChangeTracker.class, 
+            null);
+        m.makePublic();
+        Code code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(changeTracker);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // collection copy
+        Constructor cons = findCopyConstructor(type);
+        if (cons == null && SortedSet.class.isAssignableFrom(type))
+            cons = findComparatorConstructor(type);
+        Class[] params = (cons == null) ? new Class[0] 
+            : cons.getParameterTypes();
+
+        m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
+        m.makePublic();
+        code = m.getCode(true);
+
+        code.anew().setType(type);
+        code.dup();
+        if (params.length == 1) {
+            code.aload().setParam(0);
+            if (params[0] == Comparator.class) {
+                code.checkcast().setType(SortedSet.class);
+                code.invokeinterface().setMethod(SortedSet.class, "comparator", 
+                    Comparator.class, null);
+            } else
+                code.checkcast().setType(params[0]);
+        }
+        code.invokespecial().setMethod(type, "<init>", void.class, params);
+        if (params.length == 0 || params[0] == Comparator.class) {
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Collection.class);
+            code.invokevirtual().setMethod(type, "addAll", boolean.class, 
+                new Class[] { Collection.class });
+            code.pop();
+        }
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // element type
+        BCField elementType = bc.declareField("elementType", Class.class);
+        elementType.setTransient(true);
+        m = bc.declareMethod("getElementType", Class.class, null);
+        m.makePublic();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(elementType);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // new instance factory
+        m = bc.declareMethod("newInstance", ProxyCollection.class, 
+            new Class[] { Class.class, Comparator.class, boolean.class });
+        m.makePublic();
+        code = m.getCode(true);
+
+        code.anew().setType(bc); 
+        code.dup();
+        cons = findComparatorConstructor(type);
+        params = (cons == null) ? new Class[0] : cons.getParameterTypes();
+        if (params.length == 1)
+            code.aload().setParam(1);
+        code.invokespecial().setMethod("<init>", void.class, params);
+        int ret = code.getNextLocalsIndex();
+        code.astore().setLocal(ret);
+
+        // set element type
+        code.aload().setLocal(ret);
+        code.aload().setParam(0);
+        code.putfield().setField(elementType);
+
+        // create change tracker and set it
+        code.iload().setParam(2);
+        JumpInstruction ifins = code.ifeq();
+        code.aload().setLocal(ret);
+        code.anew().setType(CollectionChangeTrackerImpl.class);
+        code.dup();
+        code.aload().setLocal(ret);
+        code.constant().setValue(allowsDuplicates(type));
+        code.constant().setValue(isOrdered(type));
+        code.invokespecial().setMethod(CollectionChangeTrackerImpl.class, 
+            "<init>", void.class, new Class[] { Collection.class, 
+            boolean.class, boolean.class });
+        code.putfield().setField(changeTracker);
+
+        ifins.setTarget(code.aload().setLocal(ret));
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Return whether the given collection type allows duplicates.
+     */
+    protected boolean allowsDuplicates(Class type) {
+        return !Set.class.isAssignableFrom(type);
+    }
+
+    /**
+     * Return whether the given collection type maintains an artificial 
+     * ordering.
+     */
+    protected boolean isOrdered(Class type) {
+        return List.class.isAssignableFrom(type)
+            || "java.util.LinkedHashSet".equals(type.getName());
+    }
+
+    /**
+     * Implement the methods in the {@link ProxyMap} interface.
+     */
+    private void addProxyMapMethods(BCClass bc, Class type) {
+        // change tracker
+        BCField changeTracker = bc.declareField("changeTracker", 
+            MapChangeTracker.class);
+        changeTracker.setTransient(true);
+        BCMethod m = bc.declareMethod("getChangeTracker", ChangeTracker.class, 
+            null);
+        m.makePublic();
+        Code code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(changeTracker);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // map copy
+        Constructor cons = findCopyConstructor(type);
+        if (cons == null && SortedMap.class.isAssignableFrom(type))
+            cons = findComparatorConstructor(type);
+        Class[] params = (cons == null) ? new Class[0] 
+            : cons.getParameterTypes();
+
+        m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
+        m.makePublic();
+        code = m.getCode(true);
+
+        code.anew().setType(type);
+        code.dup();
+        if (params.length == 1) {
+            code.aload().setParam(0);
+            if (params[0] == Comparator.class) {
+                code.checkcast().setType(SortedMap.class);
+                code.invokeinterface().setMethod(SortedMap.class, "comparator", 
+                    Comparator.class, null);
+            } else 
+                code.checkcast().setType(params[0]);
+        }
+        code.invokespecial().setMethod(type, "<init>", void.class, params);
+        if (params.length == 0 || params[0] == Comparator.class) {
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Map.class);
+            code.invokevirtual().setMethod(type, "putAll", void.class, 
+                new Class[] { Map.class });
+        }
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // key type
+        BCField keyType = bc.declareField("keyType", Class.class);
+        keyType.setTransient(true);
+        m = bc.declareMethod("getKeyType", Class.class, null);
+        m.makePublic();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(keyType);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // value type
+        BCField valueType = bc.declareField("valueType", Class.class);
+        valueType.setTransient(true);
+        m = bc.declareMethod("getValueType", Class.class, null);
+        m.makePublic();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.getfield().setField(valueType);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // new instance factory
+        m = bc.declareMethod("newInstance", ProxyMap.class, 
+            new Class[] { Class.class, Class.class, Comparator.class, 
+            boolean.class });
+        m.makePublic();
+        code = m.getCode(true);
+
+        code.anew().setType(bc); 
+        code.dup();
+        cons = findComparatorConstructor(type);
+        params = (cons == null) ? new Class[0] : cons.getParameterTypes();
+        if (params.length == 1)
+            code.aload().setParam(2);
+        code.invokespecial().setMethod("<init>", void.class, params);
+        int ret = code.getNextLocalsIndex();
+        code.astore().setLocal(ret);
+
+        // set key and value types
+        code.aload().setLocal(ret);
+        code.aload().setParam(0);
+        code.putfield().setField(keyType);
+        code.aload().setLocal(ret);
+        code.aload().setParam(1);
+        code.putfield().setField(valueType);
+
+        // create change tracker and set it
+        code.iload().setParam(3);
+        JumpInstruction ifins = code.ifeq();
+        code.aload().setLocal(ret);
+        code.anew().setType(MapChangeTrackerImpl.class);
+        code.dup();
+        code.aload().setLocal(ret);
+        code.invokespecial().setMethod(MapChangeTrackerImpl.class, 
+            "<init>", void.class, new Class[] { Map.class });
+        code.putfield().setField(changeTracker);
+
+        ifins.setTarget(code.aload().setLocal(ret));
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Implement the methods in the {@link ProxyDate} interface.
+     */
+    private void addProxyDateMethods(BCClass bc, Class type) {
+        boolean hasDefaultCons = bc.getDeclaredMethod("<init>", 
+            (Class[]) null) != null;
+        boolean hasMillisCons = bc.getDeclaredMethod("<init>", 
+            new Class[] { long.class }) != null;
+        if (!hasDefaultCons && !hasMillisCons)
+            throw new UnsupportedException(_loc.get("no-date-cons", type));
+
+        // add a default constructor that delegates to the millis constructor
+        BCMethod m;
+        Code code;
+        if (!hasDefaultCons) {
+            m = bc.declareMethod("<init>", void.class, null);
+            m.makePublic();
+            code = m.getCode(true);
+            code.aload().setThis();
+            code.invokestatic().setMethod(System.class, "currentTimeMillis",
+                long.class, null);
+            code.invokespecial().setMethod(type, "<init>", void.class,
+                new Class[] { long.class });
+            code.vreturn();
+            code.calculateMaxStack();           
+            code.calculateMaxLocals();
+        }
+
+        // date copy
+        Constructor cons = findCopyConstructor(type);
+        Class[] params;
+        if (cons != null)
+            params = cons.getParameterTypes();
+        else if (hasMillisCons)
+            params = new Class[] { long.class };
+        else
+            params = new Class[0];
+
+        m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
+        m.makePublic();
+        code = m.getCode(true);
+
+        code.anew().setType(type);
+        code.dup();
+        if (params.length == 1) {
+            if (params[0] == long.class) {
+                code.aload().setParam(0);
+                code.checkcast().setType(Date.class);
+                code.invokevirtual().setMethod(Date.class, "getTime", 
+                    long.class, null);
+            } else {
+                code.aload().setParam(0);
+                code.checkcast().setType(params[0]);
+            }
+        }
+        code.invokespecial().setMethod(type, "<init>", void.class, params);
+        if (params.length == 0) {
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Date.class);
+            code.invokevirtual().setMethod(Date.class, "getTime", long.class, 
+                null);
+            code.invokevirtual().setMethod(type, "setTime", void.class,
+                new Class[] { long.class });
+        }
+        if ((params.length == 0 || params[0] == long.class) 
+            && Timestamp.class.isAssignableFrom(type)) {
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Timestamp.class);
+            code.invokevirtual().setMethod(Timestamp.class, "getNanos", 
+                int.class, null);
+            code.invokevirtual().setMethod(type, "setNanos", void.class,
+                new Class[] { int.class });
+        }
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // new instance factory
+        m = bc.declareMethod("newInstance", ProxyDate.class, null); 
+        m.makePublic();
+        code = m.getCode(true);
+        code.anew().setType(bc); 
+        code.dup();
+        code.invokespecial().setMethod("<init>", void.class, null);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Implement the methods in the {@link ProxyCalendar} interface.
+     */
+    private void addProxyCalendarMethods(BCClass bc, Class type) {
+        // calendar copy
+        Constructor cons = findCopyConstructor(type);
+        Class[] params = (cons == null) ? new Class[0] 
+            : cons.getParameterTypes();
+
+        BCMethod m = bc.declareMethod("copy", Object.class, 
+            new Class[] {Object.class});
+        m.makePublic();
+        Code code = m.getCode(true);
+
+        code.anew().setType(type);
+        code.dup();
+        if (params.length == 1) {
+            code.aload().setParam(0);
+            code.checkcast().setType(params[0]);
+        }
+        code.invokespecial().setMethod(type, "<init>", void.class, params);
+        if (params.length == 0) {
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Calendar.class);
+            code.invokevirtual().setMethod(Calendar.class, "getTimeInMillis", 
+                long.class, null);
+            code.invokevirtual().setMethod(type, "setTimeInMillis", void.class,
+                new Class[] { long.class });
+
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Calendar.class);
+            code.invokevirtual().setMethod(Calendar.class, "isLenient", 
+                boolean.class, null);
+            code.invokevirtual().setMethod(type, "setLenient", void.class,
+                new Class[] { boolean.class });
+
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Calendar.class);
+            code.invokevirtual().setMethod(Calendar.class, "getFirstDayOfWeek", 
+                int.class, null);
+            code.invokevirtual().setMethod(type, "setFirstDayOfWeek", 
+                void.class, new Class[] { int.class });
+
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Calendar.class);
+            code.invokevirtual().setMethod(Calendar.class, 
+                "getMinimalDaysInFirstWeek", int.class, null);
+            code.invokevirtual().setMethod(type, "setMinimalDaysInFirstWeek", 
+                void.class, new Class[] { int.class });
+
+            code.dup();
+            code.aload().setParam(0);
+            code.checkcast().setType(Calendar.class);
+            code.invokevirtual().setMethod(Calendar.class, "getTimeZone", 
+                TimeZone.class, null);
+            code.invokevirtual().setMethod(type, "setTimeZone", void.class,
+                new Class[] { TimeZone.class });
+        }
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // new instance factory
+        m = bc.declareMethod("newInstance", ProxyCalendar.class, null); 
+        m.makePublic();
+        code = m.getCode(true);
+        code.anew().setType(bc); 
+        code.dup();
+        code.invokespecial().setMethod("<init>", void.class, null);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // proxy the protected computeFields method b/c it is called on
+        // mutate, and some setters are final and therefore not proxyable
+        m = bc.declareMethod("computeFields", void.class, null);
+        m.makeProtected();
+        code = m.getCode(true);
+        code.aload().setThis();
+        code.constant().setValue(true);
+        code.invokestatic().setMethod(Proxies.class, "dirty", void.class,
+            new Class[] { Proxy.class, boolean.class });
+        code.aload().setThis();
+        code.invokespecial().setMethod(type, "computeFields", void.class, null);
+        code.vreturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Implement the methods in the {@link ProxyBean} interface.
+     */
+    private void addProxyBeanMethods(BCClass bc, Class type, Constructor cons) {
+        // bean copy
+        BCMethod m = bc.declareMethod("copy", Object.class, 
+            new Class[] { Object.class });
+        m.makePublic();
+        Code code = m.getCode(true);
+
+        code.anew().setType(type);
+        code.dup();
+        Class[] params = cons.getParameterTypes();
+        if (params.length == 1) {
+            code.aload().setParam(0);
+            code.checkcast().setType(params[0]);
+        }
+        code.invokespecial().setMethod(cons);
+        if (params.length == 0)
+            copyProperties(type, code);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+
+        // new instance factory
+        m = bc.declareMethod("newInstance", ProxyBean.class, 
+            new Class[] { Object.class }); 
+        m.makePublic();
+        code = m.getCode(true);
+        code.anew().setType(bc); 
+        code.dup();
+        if (params.length == 1) {
+            code.aload().setParam(0);
+            code.checkcast().setType(params[0]);
+        }
+        code.invokespecial().setMethod("<init>", void.class, params);
+        if (params.length == 0)
+            copyProperties(type, code);
+        code.areturn();
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Copy bean properties.  Called with the copy object on the stack.  Must
+     * return with the copy object on the stack.
+     */
+    private void copyProperties(Class type, Code code) {
+        int copy = code.getNextLocalsIndex();
+        code.astore().setLocal(copy);
+        
+        Method[] meths = type.getMethods();
+        Method getter;
+        int mods;
+        for (int i = 0; i < meths.length; i++) {
+            mods = meths[i].getModifiers(); 
+            if (!Modifier.isPublic(mods) || Modifier.isStatic(mods))
+                continue;
+            if (!startsWith(meths[i].getName(), "set")
+                || meths[i].getParameterTypes().length != 1)
+                continue;
+            getter = findGetter(type, meths[i]);
+            if (getter == null)
+                continue;
+
+            // copy.setXXX(orig.getXXX());
+            code.aload().setLocal(copy);
+            code.aload().setParam(0);
+            code.checkcast().setType(type);
+            code.invokevirtual().setMethod(getter);
+            code.invokevirtual().setMethod(meths[i]);
+        }
+        code.aload().setLocal(copy);
+    }
+
+    /**
+     * Proxy recognized methods to invoke helpers in given helper class.
+     */
+    private void proxyRecognizedMethods(BCClass bc, Class type, Class helper,
+        Class proxyType) {
+        Method[] meths = type.getMethods();
+        Class[] params;
+        Class[] afterParams;
+        Method match;
+        Method after;
+        for (int i = 0; i < meths.length; i++) {
+            params = toHelperParameters(meths[i].getParameterTypes(), 
+                proxyType);
+
+            // first check for overriding method 
+            try {
+                match = helper.getMethod(meths[i].getName(), params); 
+                proxyOverrideMethod(bc, meths[i], match, params);
+                continue;
+            } catch (NoSuchMethodException nsme) {
+            } catch (Exception e) {
+                throw new GeneralException(e);
+            }
+
+            // check for before and after methods, either of which may not
+            // exist
+            match = null;
+            try {
+                match = helper.getMethod("before" 
+                    + StringUtils.capitalize(meths[i].getName()), params);
+            } catch (NoSuchMethodException nsme) {
+            } catch (Exception e) {
+                throw new GeneralException(e);
+            }
+            after = null;
+            afterParams = null;
+            try {
+                afterParams = toHelperAfterParameters(params, 
+                    meths[i].getReturnType(), (match == null) 
+                    ? void.class : match.getReturnType());
+                after = helper.getMethod("after" 
+                    + StringUtils.capitalize(meths[i].getName()), afterParams);
+            } catch (NoSuchMethodException nsme) {
+            } catch (Exception e) {
+                throw new GeneralException(e);
+            }
+            if (match != null || after != null)
+                proxyBeforeAfterMethod(bc, type, meths[i], match, params, after,
+                    afterParams);
+        }
+    }
+
+    /**
+     * Return the parameter types to the corresponding helper class method.
+     */ 
+    private static Class[] toHelperParameters(Class[] cls, Class helper) {
+        Class[] params = new Class[cls.length + 1];
+        params[0] = helper;
+        System.arraycopy(cls, 0, params, 1, cls.length); 
+        return params;
+    }
+
+    /**
+     * Return the parameter types to the corresponding helper class "after"     
+     * method.
+     */
+    private static Class[] toHelperAfterParameters(Class[] cls, Class ret,
+        Class beforeRet) {
+        if (ret == void.class && beforeRet == void.class)
+            return cls;
+        int len = cls.length;
+        if (ret != void.class)
+            len++;
+        if (beforeRet != void.class)
+            len++;
+        Class[] params = new Class[len];
+        System.arraycopy(cls, 0, params, 0, cls.length);
+        int pos = cls.length;
+        if (ret != void.class)
+            params[pos++] = ret;
+        if (beforeRet != void.class)
+            params[pos++] = beforeRet;
+        return params;
+    }
+
+    /**
+     * Proxy setter methods of the given type.
+     * 
+     * @return true if we find any setters, false otherwise
+     */
+    private boolean proxySetters(BCClass bc, Class type) {
+        Method[] meths = type.getMethods();
+        int setters = 0;
+        for (int i = 0; i < meths.length; i++) {
+            if (isSetter(meths[i]) && !Modifier.isFinal(meths[i].getModifiers())
+                && bc.getDeclaredMethod(meths[i].getName(),
+                meths[i].getParameterTypes()) == null) {
+                setters++;
+                proxySetter(bc, type, meths[i]);
+            }
+        } 
+        return setters > 0;
+    }
+
+    /**
+     * Proxy the given method with one that overrides it by calling into the
+     * given helper.
+     */
+    private void proxyOverrideMethod(BCClass bc, Method meth, 
+        Method helper, Class[] params) {
+        BCMethod m = bc.declareMethod(meth.getName(), meth.getReturnType(),
+            meth.getParameterTypes());
+        m.makePublic();
+        Code code = m.getCode(true);
+
+        code.aload().setThis();
+        for (int i = 1; i < params.length; i++)
+            code.xload().setParam(i - 1).setType(params[i]);
+        code.invokestatic().setMethod(helper);
+        code.xreturn().setType(meth.getReturnType());
+
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Proxy the given method with one that overrides it by calling into the
+     * given helper.
+     */
+    private void proxyBeforeAfterMethod(BCClass bc, Class type, Method meth, 
+        Method before, Class[] params, Method after, Class[] afterParams) {
+        BCMethod m = bc.declareMethod(meth.getName(), meth.getReturnType(),
+            meth.getParameterTypes());
+        m.makePublic();
+        Code code = m.getCode(true);
+
+        // invoke before
+        int beforeRet = -1;
+        if (before != null) {
+            code.aload().setThis();
+            for (int i = 1; i < params.length; i++)
+                code.xload().setParam(i - 1).setType(params[i]);
+            code.invokestatic().setMethod(before);
+            if (after != null && before.getReturnType() != void.class) {
+                beforeRet = code.getNextLocalsIndex();
+                code.xstore().setLocal(beforeRet).
+                    setType(before.getReturnType());
+            }
+        }
+
+        // invoke super
+        code.aload().setThis();
+        for (int i = 1; i < params.length; i++)
+            code.xload().setParam(i - 1).setType(params[i]);
+        code.invokespecial().setMethod(type, meth.getName(), 
+            meth.getReturnType(), meth.getParameterTypes());
+
+        // invoke after 
+        if (after != null) {
+            int ret = -1;
+            if (meth.getReturnType() != void.class) {
+                ret = code.getNextLocalsIndex();
+                code.xstore().setLocal(ret).setType(meth.getReturnType());
+            }
+            code.aload().setThis();
+            for (int i = 1; i < params.length; i++)
+                code.xload().setParam(i - 1).setType(params[i]);
+            if (ret != -1)
+                code.xload().setLocal(ret).setType(meth.getReturnType());
+            if (beforeRet != -1)
+                code.xload().setLocal(beforeRet).
+                    setType(before.getReturnType());
+            code.invokestatic().setMethod(after);
+        }
+        code.xreturn().setType(meth.getReturnType());
+
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Return whether the given method is a setter.
+     */
+    protected boolean isSetter(Method meth) {
+        return startsWith(meth.getName(), "set")
+            || startsWith(meth.getName(), "add")
+            || startsWith(meth.getName(), "remove")
+            || startsWith(meth.getName(), "insert")
+            || startsWith(meth.getName(), "clear")
+            || startsWith(meth.getName(), "roll"); // used by Calendar
+    }
+
+    /**
+     * Return the getter corresponding to the given setter, or null.
+     */
+    protected Method findGetter(Class type, Method setter) {
+        String name = setter.getName().substring(3);
+        Class param = setter.getParameterTypes()[0];
+        Method getter;
+        try {
+            getter = type.getMethod("get" + name, (Class[]) null);   
+            if (getter.getReturnType().isAssignableFrom(param)
+                || param.isAssignableFrom(getter.getReturnType()))
+                return getter;
+        } catch (NoSuchMethodException nsme) {
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        }
+
+        if (param == boolean.class || param == Boolean.class) {
+            try {
+                getter = type.getMethod("is" + name, (Class[]) null);   
+                if (getter.getReturnType().isAssignableFrom(param)
+                    || param.isAssignableFrom(getter.getReturnType()))
+                    return getter;
+            } catch (NoSuchMethodException nsme) {
+            } catch (Exception e) {
+                throw new GeneralException(e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return whether the target string stars with the given token.
+     */
+    private static boolean startsWith(String str, String token) {
+        return str.startsWith(token)
+            && (str.length() == token.length() 
+            || Character.isUpperCase(str.charAt(token.length())));
+    }
+
+    /**
+     * Proxy the given setter method to dirty the proxy owner.
+     */
+    private void proxySetter(BCClass bc, Class type, Method meth) {
+        Class[] params = meth.getParameterTypes();
+        Class ret = meth.getReturnType();
+        BCMethod m = bc.declareMethod(meth.getName(), ret, params);
+        m.makePublic();
+        Code code = m.getCode(true);
+        code.aload().setThis();
+        code.constant().setValue(true);
+        code.invokestatic().setMethod(Proxies.class, "dirty", void.class,
+            new Class[] { Proxy.class, boolean.class });
+        code.aload().setThis();
+        for (int i = 0; i < params.length; i++)
+            code.xload().setParam(i).setType(params[i]);
+        code.invokespecial().setMethod(type, meth.getName(), ret, params);
+        code.xreturn().setType(ret);
+        code.calculateMaxStack();
+        code.calculateMaxLocals();
+    }
+
+    /**
+     * Add a writeReplace implementation that serializes to a non-proxy type
+     * unless detached and this is a build-time generated class.
+     */
+    private void addWriteReplaceMethod(BCClass bc, boolean runtime) {
+        BCMethod m = bc.declareMethod("writeReplace", Object.class, null);
+        m.makeProtected();
+        m.getExceptions(true).addException(ObjectStreamException.class);
+        Code code = m.getCode(true);
+        code.aload().setThis();
+        code.constant().setValue(!runtime);
+        code.invokestatic().setMethod(Proxies.class, "writeReplace", 
+            Object.class, new Class[] { Proxy.class, boolean.class });
+        code.areturn();
+        code.calculateMaxLocals();
+        code.calculateMaxStack();
+    }
+
+    /**
+     * Create a unique id to avoid proxy class name conflicts.
+     */
+    private static synchronized long nextProxyId() {
+        return _proxyId++;
+    }
+
+    /**
+     * Find an appropriate copy constructor for the given type, or return null
+     * if none.
+     */
+    protected Constructor findCopyConstructor(Class cls) {
+        Constructor[] cons = cls.getConstructors();
+        Constructor match = null;
+        Class matchParam = null;
+        Class[] params;
+        for (int i = 0; i < cons.length; i++) {
+            params = cons[i].getParameterTypes();
+            if (params.length != 1)
+                continue;
+
+            // quit immediately on exact match
+            if (params[0] == cls)
+                return cons[i];
+
+            if (params[0].isAssignableFrom(cls) && (matchParam == null
+                || matchParam.isAssignableFrom(params[0]))) {
+                 // track most derived collection constructor
+                match = cons[i];
+                matchParam = params[0];
+            }
+        }
+        return match; 
+    }
+
+    /**
+     * Return the constructor that takes a comparator for the given type, or
+     * null if none.
+     */
+    private static Constructor findComparatorConstructor(Class cls) {
+        try {
+            return cls.getConstructor(new Class[] { Comparator.class });
+        } catch (NoSuchMethodException nsme) {
+            return null;
+        } catch (Exception e) {
+            throw new GeneralException(e);
+        }
+    }
+
+    /**
+     * Usage: java org.apache.openjpa.util.proxy.ProxyManagerImpl [option]*
+     * &lt;class name&gt;+<br />
+     * Where the following options are recognized:
+     * <ul> 
+     * <li><i>-utils/-u &lt;number&gt;</i>: Generate proxies for the standard
+     * java.util collection, map, date, and calendar classes of the given Java
+     * version.  Use 4 for Java 1.4, 5 for Java 5, etc.</li>
+     * </ul>
+     *
+     * The main method generates .class files for the proxies to the classes    
+     * given on the command line.  It writes the generated classes to beside the
+     * ProxyManagerImpl.class file if possible; otherwise it writes to the 
+     * current directory.  The proxy manager looks for these classes 
+     * before generating its own proxies at runtime.
+     */
+    public static void main(String[] args) 
+        throws ClassNotFoundException, IOException {
+        File dir = Files.getClassFile(ProxyManagerImpl.class);
+        dir = (dir == null) ? new File((String) AccessController.doPrivileged(
+            J2DoPrivHelper.getPropertyAction("user.dir")))
+            : dir.getParentFile();
+
+        Options opts = new Options();
+        args = opts.setFromCmdLine(args);
+
+        List types = new ArrayList();
+        types.addAll(Arrays.asList(args));
+        int utils = opts.removeIntProperty("utils", "u", 0);
+        if (utils >= 4) {
+            types.addAll(Arrays.asList(new String[] {
+                java.sql.Date.class.getName(),
+                java.sql.Time.class.getName(),
+                java.sql.Timestamp.class.getName(),
+                java.util.ArrayList.class.getName(),
+                java.util.Date.class.getName(),
+                java.util.GregorianCalendar.class.getName(),
+                java.util.HashMap.class.getName(),
+                java.util.HashSet.class.getName(),
+                java.util.Hashtable.class.getName(),
+                java.util.LinkedList.class.getName(),
+                java.util.Properties.class.getName(),
+                java.util.TreeMap.class.getName(),
+                java.util.TreeSet.class.getName(),
+                java.util.Vector.class.getName(),
+            })); 
+        }
+        if (utils >= 5) {
+            types.addAll(Arrays.asList(new String[] {
+                "java.util.EnumMap",
+                "java.util.IdentityHashMap",
+                "java.util.LinkedHashMap",
+                "java.util.LinkedHashSet",
+                "java.util.PriorityQueue",
+            })); 
+        }
+
+        final ProxyManagerImpl mgr = new ProxyManagerImpl();
+        Class cls;
+        BCClass bc;
+        for (int i = 0; i < types.size(); i++) {
+            cls = Class.forName((String) types.get(i));
+            try {
+                if (Class.forName(getProxyClassName(cls, false), true,
+                    GeneratedClasses.getMostDerivedLoader(cls, Proxy.class))
+                    != null)
+                    continue;
+            } catch (Throwable t) {
+                // expected if the class hasn't been generated
+            }
+
+            if (Collection.class.isAssignableFrom(cls))
+                bc = mgr.generateProxyCollectionBytecode(cls, false);         
+            else if (Map.class.isAssignableFrom(cls))
+                bc = mgr.generateProxyMapBytecode(cls, false);         
+            else if (Date.class.isAssignableFrom(cls))
+                bc = mgr.generateProxyDateBytecode(cls, false);
+            else if (Calendar.class.isAssignableFrom(cls))
+                bc = mgr.generateProxyCalendarBytecode(cls, false);
+            else {
+                final Class fCls = cls;
+                bc = (BCClass) AccessController
+                    .doPrivileged(new PrivilegedAction() {
+                        public Object run() {
+                            return mgr.generateProxyBeanBytecode(fCls, false);
+                        }
+                    });
+            }
+
+            System.out.println(bc.getName());
+            bc.write(new File(dir, bc.getClassName() + ".class"));
+        }
+    }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java
index 8d4bcd4..2cd2965 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.util;
-
-import java.util.Map;
-
-import org.apache.openjpa.kernel.StoreManager;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Repository of store-specific facade classes. This is used by facade 
- * implementations to wrap store-specific components without knowing 
- * about all possible back-ends.
- */
-public class StoreFacadeTypeRegistry {
-
-    private Map _impls = new ConcurrentHashMap();
-
-    /**
-     * Register a facade implementation.
-     *
-     * @param facadeType the facade interface
-     * @param storeType the store's 
-     * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
-     * @param implType the class implementing the facade
-     */
-    public void registerImplementation(Class facadeType, Class storeType, 
-        Class implType) {
-        Object key = (storeType == null) ? (Object) facadeType 
-            : new Key(facadeType, storeType);
-        _impls.put(key, implType);
-    }
-    
-    /**
-     * Return the implementation for the given facade and store.
-     *
-     * @param facadeType the facade interface
-     * @param storeType the store's 
-     * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
-     * @param implType the registered implementor
-     */
-    public Class getImplementation(Class facadeType, Class storeType) {
-        // traverse store type hierarchy to store manager to find most specific
-        // store avaialble
-        Class impl;
-        for (; storeType != null && storeType != StoreManager.class; 
-            storeType = storeType.getSuperclass()) {
-            impl = (Class) _impls.get(new Key(facadeType, storeType));
-            if (impl != null)
-                return impl; 
-        }    
-        return (Class) _impls.get(facadeType);
-    }
-    
-    /**
-     * Return the implementation for the given facade and store. If no 
-     * registered implementation is found then returns the given default type
-     * provided it the facade type is assignable from the deafult type.
-     *
-     * @param facadeType the facade interface
-     * @param storeType the store's 
-     * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
-     * @param implType the registered implementor
-     * @param defaultType class if no registered implementation is available.
-     */
-    public Class getImplementation(Class facadeType, Class storeType, 
-    	Class defaultType) {
-    	Class result = getImplementation(facadeType, storeType);
-    	if (result == null)
-    		result = defaultType;
-    	if (facadeType == null || !facadeType.isAssignableFrom(result))
-    		throw new InternalException();
-    	return result;
-    }
-
-    /**
-     * Lookup key for facade+store hash.
-     */
-    private static class Key {
-        public final Class _facadeType;
-        public final Class _storeType;
-
-        public Key(Class facadeType, Class storeType) {
-            _facadeType = facadeType;
-            _storeType = storeType;
-        }
-
-        public int hashCode() {
-            return _facadeType.hashCode() ^ _storeType.hashCode();
-        }
-
-        public boolean equals(Object other) {
-            if (other == this)
-                return true;
-            Key k = (Key) other;
-            return _facadeType == k._facadeType && _storeType == k._storeType;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.util.Map;
+
+import org.apache.openjpa.kernel.StoreManager;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Repository of store-specific facade classes. This is used by facade 
+ * implementations to wrap store-specific components without knowing 
+ * about all possible back-ends.
+ */
+public class StoreFacadeTypeRegistry {
+
+    private Map _impls = new ConcurrentHashMap();
+
+    /**
+     * Register a facade implementation.
+     *
+     * @param facadeType the facade interface
+     * @param storeType the store's 
+     * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
+     * @param implType the class implementing the facade
+     */
+    public void registerImplementation(Class facadeType, Class storeType, 
+        Class implType) {
+        Object key = (storeType == null) ? (Object) facadeType 
+            : new Key(facadeType, storeType);
+        _impls.put(key, implType);
+    }
+    
+    /**
+     * Return the implementation for the given facade and store.
+     *
+     * @param facadeType the facade interface
+     * @param storeType the store's 
+     * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
+     * @param implType the registered implementor
+     */
+    public Class getImplementation(Class facadeType, Class storeType) {
+        // traverse store type hierarchy to store manager to find most specific
+        // store avaialble
+        Class impl;
+        for (; storeType != null && storeType != StoreManager.class; 
+            storeType = storeType.getSuperclass()) {
+            impl = (Class) _impls.get(new Key(facadeType, storeType));
+            if (impl != null)
+                return impl; 
+        }    
+        return (Class) _impls.get(facadeType);
+    }
+    
+    /**
+     * Return the implementation for the given facade and store. If no 
+     * registered implementation is found then returns the given default type
+     * provided it the facade type is assignable from the deafult type.
+     *
+     * @param facadeType the facade interface
+     * @param storeType the store's 
+     * {@link org.apache.openjpa.kernel.StoreManager} type, or null for generic
+     * @param implType the registered implementor
+     * @param defaultType class if no registered implementation is available.
+     */
+    public Class getImplementation(Class facadeType, Class storeType, 
+    	Class defaultType) {
+    	Class result = getImplementation(facadeType, storeType);
+    	if (result == null)
+    		result = defaultType;
+    	if (facadeType == null || !facadeType.isAssignableFrom(result))
+    		throw new InternalException();
+    	return result;
+    }
+
+    /**
+     * Lookup key for facade+store hash.
+     */
+    private static class Key {
+        public final Class _facadeType;
+        public final Class _storeType;
+
+        public Key(Class facadeType, Class storeType) {
+            _facadeType = facadeType;
+            _storeType = storeType;
+        }
+
+        public int hashCode() {
+            return _facadeType.hashCode() ^ _storeType.hashCode();
+        }
+
+        public boolean equals(Object other) {
+            if (other == this)
+                return true;
+            Key k = (Key) other;
+            return _facadeType == k._facadeType && _storeType == k._storeType;
+        }
+    }
+}
diff --git a/openjpa-kernel/src/main/resources/org/apache/openjpa/ee/localizer.properties b/openjpa-kernel/src/main/resources/org/apache/openjpa/ee/localizer.properties
index 014e0ac..d4ac3bd 100644
--- a/openjpa-kernel/src/main/resources/org/apache/openjpa/ee/localizer.properties
+++ b/openjpa-kernel/src/main/resources/org/apache/openjpa/ee/localizer.properties
@@ -1,44 +1,44 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.  
-
-tm-not-found: Could not perform automatic lookup of EJB container''s \
-	javax.transaction.TransactionManager implementation. Please ensure that \
-	you are running the application from within an EJB 1.1 compliant EJB \
-	container, and then set the org.apache.openjpa.ManagedRuntime property to \ 
-	the	appropriate value to obtain the TransactionManager.
-expected-reference: Expected object to be of type Reference, but instead was \
-	"{0}".
-not-supported: This operation is not supported.
-was-unsupported-op: Unable to execute {0} on a WebSphere managed transaction. \
-	WebSphere does not support direct manipulation of managed transactions.
-was-transaction-id-exception: Unable to determine identity of the current \ 
-	WebSphere managed transaction. Please ensure that your are running the \
-	application from within WebSphere Application Server (version 5.0.2 or \ 
-	newer).
-was-reflection-exception: An error occurred reflecting WebSphere proprietary \
-	interfaces. Please ensure that you are running the application from within \
-	WebSphere Application Server (version 5.0.2 or newer).
-was-lookup-error: An error occurred looking up the WebSphere extended JTA \
-	service. Please ensure that you are running the application from within \ 
-	WebSphere Application Server (version 5.0.2 or newer).
-tm-unavailable: Unable to obtain a TransactionManager using {0}. 
-tsr-cannot-suspend: The Transaction Synchronization Registry can not suspend \
-	the current transaction. 
-exc-suspend-tran: A {0} exception occurred when trying to suspend the current \
-	transaction. 
-exc-resume-tran: A {0} exception occurred when trying to resume the current \
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.  
+
+tm-not-found: Could not perform automatic lookup of EJB container''s \
+	javax.transaction.TransactionManager implementation. Please ensure that \
+	you are running the application from within an EJB 1.1 compliant EJB \
+	container, and then set the org.apache.openjpa.ManagedRuntime property to \ 
+	the	appropriate value to obtain the TransactionManager.
+expected-reference: Expected object to be of type Reference, but instead was \
+	"{0}".
+not-supported: This operation is not supported.
+was-unsupported-op: Unable to execute {0} on a WebSphere managed transaction. \
+	WebSphere does not support direct manipulation of managed transactions.
+was-transaction-id-exception: Unable to determine identity of the current \ 
+	WebSphere managed transaction. Please ensure that your are running the \
+	application from within WebSphere Application Server (version 5.0.2 or \ 
+	newer).
+was-reflection-exception: An error occurred reflecting WebSphere proprietary \
+	interfaces. Please ensure that you are running the application from within \
+	WebSphere Application Server (version 5.0.2 or newer).
+was-lookup-error: An error occurred looking up the WebSphere extended JTA \
+	service. Please ensure that you are running the application from within \ 
+	WebSphere Application Server (version 5.0.2 or newer).
+tm-unavailable: Unable to obtain a TransactionManager using {0}. 
+tsr-cannot-suspend: The Transaction Synchronization Registry can not suspend \
+	the current transaction. 
+exc-suspend-tran: A {0} exception occurred when trying to suspend the current \
+	transaction. 
+exc-resume-tran: A {0} exception occurred when trying to resume the current \
 	transaction. The transaction will be marked rollback only.
\ No newline at end of file
diff --git a/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties b/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
index 985d7de..a4d439c 100644
--- a/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
+++ b/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
@@ -1,402 +1,403 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.  
-
-cant-convert-result: There is no conversion between query projection type \
-	"{0}" and result type "{1}".
-unloaded-detached: Attempt to access an unloaded field of detached instance \
-	"{0}".
-meta-unknownid: Cannot manipulate identity of type "{0}": it''s identity type \
-	is unknown.
-new-abstract: Cannot create an instance of "{0}": abstract classes are not \
-    yet supported.
-bad-new-query: Attempt to construct a query from an extent or class.  You must \
-	pass a (possibly null) query string or template to the query factory \
-	method when creating the query. 
-update-restrict: Detected attempt to modify field "{0}" with value strategy \
-	"restrict".
-reentrant-flush: Detected reentrant flush.  Make sure your flush-time instance \
-	callback methods or event listeners do not invoke any operations that \
-	require the in-progress flush to complete.
-rolled-back: The transaction has been rolled back.  See the nested exceptions \
-	for details on the errors that occurred.
-bad-lock-level: This lock manager does not recognize lock level "{0}".
-pessimistic-mutate: You are attempting to directly mutate a persistent second \
-	class object (such as a collection or map field) that you obtained before \
-	the transaction began.  After beginning a datastore transaction, you \
-	must re-obtain any references to mutable second class objects from the \
-	owning persistent object.  Detected attempt to mutate value of field "{0}" \
-	in instance "{1}".  This instance may not be locked correctly.
-not-derefed: Encountered unknown dependent instance "{0}".  This error is \
-	often caused by either removing a dependent instance from one dependent \
-	field, but not other dependent fields that reference it, or by removing a \
-	dependent instance from its owning field, flushing \
-	(causing the unreferenced dependent instance to be deleted), and then \
-	trying to assign the deleted instance to another field before commit.  \
-	The instance cannot be un-deleted, resulting in an error.  Make sure not \
-	to leave dangling dependent references to objects, and to reassign \
-	dependent objects before flush so that OpenJPA does not think they are \
-	unreferenced and therefore safe to delete.
-init-null-pc: Attempt to initialize a state manager with a null \
-	persistence-capable instance for type "{0}".  This is often caused by \
-	attempting to load an instance of an abstract class, or \
-	neglecting to use a class indicator when the base persistence-capable \
-	class in an inheritance tree is abstract.
-init-sm-pc: Attempt to initialize a state manager with an instance that is \
-	already managed ("{0}").  You might be trying to persist this instance \
-	in two threads at the same time.
-bad-ds-oid: The type "{0}" declares datastore identity but the value \
-	passed to lookup of type "{1}" is not a OpenJPA id instance.
-null-oids: Some of the object ids passed to getObjectsById were null.
-marked-rollback: The transaction cannot be committed, because it was already \
-	marked for rollback only.  The transaction will be rolled back instead. \
-    The cause of the rollback-only status is reported in the embedded stack.
-refresh-flushed: You cannot refresh an instance that has been flushed to the \
-	data store.
-pc-loader-different: Attempt to cast instance "{0}" to PersistenceCapable failed. \
-    The object implemented org.apache.openjpa.enhance.PersistenceCapable, \
-    but the instance of that interface was loaded by two different ClassLoaders: \
-    "{1}" and "{2}".
-pc-cast: Attempt to cast instance "{0}" to PersistenceCapable failed.  Ensure \
-	that it has been enhanced.
-del-instance: The instance of type "{0}" with oid "{1}" no longer exists in \
-	the data store.  This may mean that you deleted the instance in a separate \
-	transaction, but this context still has a cached version.
-no-broker-class: The specified type "{0}" could not be loaded. Please ensure \
-	that the class exists in the project class path.
-bad-embed: Attempt to set an embedded value for unembeddable field "{0}". \
-	Please report this error to OpenJPA support.
-embed-ref: You are attempting to access an embedded object reference \
-	that was obtained before the last transaction status change. After \
-	transactions begin and end, all references to embedded objects become \
-	invalid; you have to re-acquire the reference from the owning persistent \
-	object.
-deleted: Operation attempted on a deleted instance.
-dirty: Illegal operation attempted on a dirty instance: dirty objects cannot \
-	be evicted or made transient or non-transactional.
-nested-exceps: This operation failed for some instances.  See the nested \
-	exceptions array for details.
-new: Illegal operation attempted on a newly persisted instance: new objects \
-	cannot be evicted or made transient or non-transactional.
-transient: Illegal operation attempted on a transient instance.
-not-active: Can only perform operation while a transaction is active.
-trans-active: The "{0}" transaction property cannot be set during an \
-	active transaction.
-active: This operation cannot be performed while a Transaction is active.
-closed: The context has been closed.  The stack trace at which the \
-	context was closed is held in the embedded exception.
-closed-notrace: The context has been closed.  The stack trace at which the \
-	context was closed is available if Runtime=TRACE logging is enabled.
-closed-factory: The factory has been closed.  The stack trace at \
-	which the factory was closed is held in the embedded exception.
-closed-factory-notrace: The factory has been closed.  The stack trace at \
-	which the factory was closed is available if Runtime=TRACE logging is \
-	enabled.
-non-trans-read: To perform reads on persistent data outside of a transaction, \
-	the "NontransactionalRead" property must be set on the Transaction.
-non-trans-write: To perform writes on persistent data outside of a \
-	transaction, the "NontransactionalWrite" property must be set to true.
-write-operation: To perform this operation, it must be written within a transaction, \
-	or your settings must allow nontransactional writes and must not detach \
-	all nontransactional reads.
-not-managed: The given instance "{0}" is not managed by this context.
-trans-not-managed: This broker is not configured to use managed transactions.
-bad-detached-op: You cannot perform operation {0} on detached object "{1}". \
-	This operation only applies to managed objects.
-persist-detached: Attempt to persist detached object "{0}".  If this is a new \
-  instance, make sure any version and/or auto-generated primary key fields are \
-  null/default when persisting.
-null-value: The field "{0}" of instance "{1}" contained a null value; \
-	the metadata for this field specifies that nulls are illegal.
-change-identity: Attempt to change a primary key field of an instance that \
-	already has a final object id.  Only new, unflushed instances whose id you \
-	have not retrieved can have their primary keys changed.
-managed-oid: You cannot assign managed object "{0}" to the primary key field \
-	of "{1}".  Embedded primary key values must be transient objects.
-changed-oid: You have modified the object id field of "{2}".  Its old value \
-	was "{0}", and its new value is "{1}".  Object id fields are immutable \
-	once the object id of the instance has been assigned. 
-cache-exists: An object of type "{0}" with oid "{1}" already exists in this \
-	context; another cannot be persisted.
-null-trans: Attempt to commit a null javax.transaction.Transaction.  Some \
-	application servers set the transaction to null if a rollback occurs.
-end-trans-error: An exception occurred while ending the transaction.  This \
-	exception will be re-thrown.
-not-bound: The file named "{0}" could not be found.
-naming-exception: A NamingException was thrown while obtaining the \
-	factory at "{0}" from JNDI.
-attach-deleted: The object "{0}" with id "{1}" has been deleted and \
-	cannot be attached.
-not-detachable: The class "{0}" does not declare the "detachable" metadata \
-	extension, so cannot be detached.
-not-copyable: Attempt to copy field "{0}" failed.  The field is \
-	not copyable.  This can occur with custom SCO types. Only standard or \
-    immutable SCO types can be attached and detached.
-no-detach-object-id: Cannot access the detached object id of class "{0}". \
-	Ensure that the class has the "detachable" metadata extension, and \
-	the the class has been re-enhanced.
-attach-version-del: Attempted to attach deleted instance type "{0}" with oid \
-	"{1}".  If the instance is new, the version field should be left to its \
-	default value.
-attach-wrongclass: Attempted to attach instance "{0}" of type "{1}", but this \
-	instance is already in the datastore as type "{2}".
-sjvm-acquired-lock: Acquired an exclusive lock "{0}" on oid "{1}".
-sjvm-released-lock: Released lock "{0}".
-conn-not-supported: This data store cannot return connections.
-incremental-flush-not-supported: This data store does not support incremental \
-	flushing.  If you got this error while performing a query, make sure that \
-	you have not set the FlushBeforeQueries option to true, either by \
-	setting that option in your configuration file, or by programmatically \
-	setting the current FetchConfiguration''s FlushBeforeQueries property \
-	to QueryFlushModes.FLUSH_TRUE.
-nontrans-read-not-supported: This data store does not support nontransactional \
-	reads.  Set the NontransactionalRead property to false.
-optimistic-not-supported: This datastore does not support optimistic \
-	transactions.  Set the Optimistic property to false.
-restore-unset: The RestoreValues option is off, so initial values are \
-	not available. Turn on RestoreValues to be able to obtain initial \
-	values.
-mutable-restore-unset: The RestoreValues option is not set to "all", \
-	initial values of mutable fields are not available. Set RestoreValues to \
-	"all" in your properties to be able to obtain initial mutable values.
-initial-unloaded: OpenJPA cannot provide the initial value for field "{0}" \
-	because the field was never loaded before being changed.
-dup-oid-assign: Attempt to assign id "{0}" to new instance "{1}" failed; \
-	there is already an object in the L1 cache with this id. \
-	You must delete this object (in a previous transaction or the current one) \
-	before reusing its id.  This error can also occur when a horizontally \
-	or vertically mapped classes uses auto-increment application identity and \
-	does not use a hierarchy of application identity classes.
-dup-load: Cannot load object with id "{0}".  Instance "{1}" with the same id \
-	already exists in the L1 cache.  This can occur when you \
-	assign an existing id to a new instance, and before flushing attempt to \
-	load the existing instance for that id.
-bad-id-value: The given value "{0}" cannot be converted into an identity \
-	for "{2}".  The value is the wrong type ({1}).
-factory-init: Starting OpenJPA {0}
-factory-properties: Properties: {0}
-inverse-consistency: An inverse inconsistency in the object model was \
-	detected while flushing the field "{0}" of the instance with id "{1}" \
-	in context "{2}".
-no-brokerfactory: You did not name the factory class with the required \
-	property openjpa.BrokerFactory.  Normally this property defaults \
-    appropriately; have you forgotten to include all the OpenJPA jars in your \
-    classpath?
-brokerfactory-excep: There was an error when invoking the static \
-	getInstance method on the named factory class "{0}".  See the \
-	nested exception for details.
-new-brokerfactory-excep: There was an error when invoking the static \
-	newInstance method on the named factory class "{0}".  See the \
-	nested exception for details.
-bad-brokerfactory: Could not invoke the static getInstance method on the \
-	named factory class "{0}".
-bad-new-brokerfactory: Could not invoke the static newInstance method on the \
-	named factory class "{0}".
-bad-brokerfactory-class: The named BrokerFactory "{0}" is not valid.
-instantiate-abstract: Cannot instantiate abstract class of type "{0}" with \
-	object id "{1}"; this may indicate that the inheritance discriminator \
-	for the class is not configured correctly.
-nontrans-proxied: You cannot make a property access object created with "new" \
-	nontransactional.
-no-field: Field "{0}" is not declared in "{1}", or is not managed.
-no-field-index: "{0}" is not the index of any managed field in "{1}".
-cant-cascade-persist: Encountered unmanaged object in persistent field \
-	"{0}" during flush.  However, this field does not \
-	allow cascade persist. Set the cascade attribute for this field to \
-    CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or \
-    "persist" or "all" (JPA orm.xml), or enable cascade-persist globally, \
-    or manually persist the related field value prior to flushing. \
-	You cannot flush unmanaged objects or graphs that have persistent \
-    associations to unmanaged objects.
-cant-cascade-attach: Encountered new object in persistent field \
-	"{0}" during attach.  However, this field does not \
-	allow cascade attach. Set the cascade attribute for this field to \
-    CascadeType.MERGE or CascadeType.ALL (JPA annotations) or \
-    "merge" or "all" (JPA orm.xml). \
-    You cannot attach a reference to a new object without cascading.
-ref-to-deleted: Encountered deleted object "{0}" in persistent field \
-	"{1}" of managed object "{2}" during flush.
-no-version-field: Encountered object "{0}" without a version field during \
-	attach.  In order to attach an object, it must either be enhanced or must \
-	have a version field.
-inmem-agg-proj-var: Queries with aggregates or projections using variables \
-	currently cannot be executed in-memory.  Either set IgnoreCache to true, \
-	set the openjpa.FlushBeforeQueries property to true, or execute the query \
-	before changing any instances in the transaction.  The offending query was \
-	on type "{0}" with filter "{1}".
-merged-order-with-result: This query on candidate type "{0}" with filter "{1}" \
-	involves combining the results of multiple queries in memory. \
-	You have chosen to order the results on "{2}", but you have not selected \
-	this data in your setResult() clause.  Please include this ordering data \
-	in setResult() so that OpenJPA can extract it for in-memory ordering.
-bad-grouping: Your query on type "{0}" with filter "{1}" is invalid.  Your \
-    select and having clauses must only include aggregates or values that also \
-    appear in your grouping clause.
-query-nosupport: The "{0}" query type does not support this operation.
-query-unmapped: You cannot query unmapped type "{0}".
-range-too-big: The range of the query is too big. Start index: "{0}", end \
-	index: "{1}". The range must be less than Integer.MAX_VALUE.
-invalid-range: The query range from {0} to {1} is not valid.
-no-impls: Unable to execute a query on type "{0}".  This class or interface \
-	is not mapped, and does not have any mapped implementors.
-bad-param-name: The parameter name or position "{0}" passed to \
-	execute() is not valid.  All map keys must be a declared parameter \
-	name or a number matching the parameter position. Native queries only \
-	allow the use of positional parameters.
-force-in-mem: This query on type "{0}" must load the entire candidate class \
-	extent and evaluate the query in-memory.  This may be very slow.  The \
-	query must be executed in memory because OpenJPA is configured with \
-	IgnoreCache=false and FlushBeforeQueries=false and \
-	there are dirty instances that may affect the query''s outcome in the \
-	cache.
-cant-exec-inmem: Queries of this type ("{0}") cannot be executed in-memory. \
-	Either set IgnoreCache to true, set the openjpa.FlushBeforeQueries \
-	property to true, or execute the query before changing any instances in \
-	the transaction.
-executing-query: Executing query: {0}
-executing-query-with-params: Executing query: [{0}] with parameters: {1}
-not-unique: The query on candidate type "{0}" with filter "{1}" was \
-	configured to have a unique result, but more than one instance matched \
-	the query.
-no-result: The query on candidate type "{0}" with filter "{1}" was \
-	configured to have a unique result, but no instance matched \
-	the query.
-serialized: Queries that have been serialized do not support this operation.
-read-only: Attempt to modify a read-only query object.
-no-class: A candidate Class must be specified before executing a query.
-no-modify-resultclass: A query that declares a result class cannot be used \
-	to perform bulk updates.
-no-modify-unique: A query that declares unique results cannot be used \
-	to perform bulk updates.
-no-modify-range: A query that declares a result range cannot be used \
-	to perform bulk updates.
-unbound-param: Cannot execute query; the declared parameter "{0}" was \
-	not given a value.
-unbound-params: Cannot execute query; some declared parameters were not given \
-	values.  You must supply a value for each of the following parameters, \
-	in the given order: {0}
-extra-params: More parameters were passed to execute() than were declared: \
-	{1} parameters were specified for query execution, but only {0} \
-	parameters were declared in the query.
-null-primitive-param: Parameter "{0}" was declared with a primitive type, but \
-	has been given a null value.
-merged-aggregate: This query on candidate type "{0}" with filter "{1}" \
-	involves combining the results of multiple sub-queries.  However, because \
-	this query is for aggregate data, OpenJPA cannot combine the sub-query \
-	aggregates into correct final values.
-bad-dec: The {1} declaration "{0}" is \
-	not valid. Variables and imports must be delimited with ";".  Parameters \
-	and orderings must be delimited with ",".  Imports require the "import" \
-	keyword, and orderings require the "ascending" or "descending" keyword.
-mod-bigdecimal: You cannot use the modulo operator (%) on numbers of type \
-	BigDecimal.
-cant-convert: Cannot convert object "{0}" of type "{1}" into an instance of \
-	"{2}".
-bad-method-class: You set the method name of this openjpa.MethodQL query to \
-	"{1}", but class "{0}" is not a valid class name.  Make sure to fully \
-	qualify the class name or to import its package into this query if the \
-	class is not in the query candidate class'' package. 
-method-not-static: Method "{0}" named in the MethodQL query must be static.
-method-return-type-invalid: Method "{0}" named in the MethodQL query must \
-    have a return type that is assignable from ResultObjectProvider. Return \
-    type is: {1}.
-no-method: You must set the query filter to the name of the method to execute \
-	for this MethodQL query instance.
-method-error: There was an error invoking method "{0}" with arguments "{1}".
-bad-param-type: The type "{0}" as used in the parameter declarations \
-	could not be found in the imports.
-cant-set: Result type "{0}" does not have any public fields or setter methods \
-	for the projection or aggregate result element "{1}", nor does it have a \
-	generic put(Object,Object) method that can be used, nor does it have a \
-	public constructor that takes the types {2}.
-pack-err: There was an error packing the projection and/or aggregate results \
-	of the query into result type "{0}".  See the nested Throwable exception \
-	for details.
-pack-instantiation-err: There was an error creating an instance of type "{0}" \
-	when packing the projection and/or aggregate results of the query. Ensure \
-	that you have defined a public no-args constructor in "{0}".
-bad-inmem-method: Method "{0}(StoreContext, ClassMetaData, boolean, Object, \
-	Map, FetchConfiguration)" is not declared in type "{1}". \
-	Check the method name supplied in your MethodQL query filter.  \
-	OpenJPA is attempting to execute this query in-memory; if you implemented \
-    the datastore method instead (a method with the same signature but without \
-    the Object argument) and want this query to execute in the datastore, \
-    either create the query before modifying objects in the current transaction, \
-	set IgnoreCache to true, or set the openjpa.FlushBeforeQueries property to \
-	true.
-bad-datastore-method: Method "{0}(StoreContext, ClassMetaData, boolean, Map, \
-	FetchConfiguration)" is not declared in type "{1}".  Check \
-	the method name supplied in your MethodQL query filter.  OpenJPA is \
-	attempting to execute this query against the datastore; if you implemented \
-	the in-memory method instead (a method with the same signature but with an \
-	Object argument) and want this query to execute in-memory, supply a \
-	Collection of candidates to filter.
-only-update-constants: Bulk update queries when executed in memory \
-	may only update to constant values.
-only-range-constants: Range values must be numeric constants.  Illegal query: \
-    {0}
-no-savepoint-copy: Unable to copy field "{0}" for savepoint.
-savepoint-exists: A savepoint with the name "{0}" already exists.  \
-	Each savepoint name must be unique.
-no-lastsavepoint: Cannot rollback/release last savepoint as no savepoint \
-	has been set.
-no-savepoint: You have not set a savepoint with the name "{0}"
-savepoint-init: This savepoint has already been initialized.
-savepoint-flush-not-supported: The configured SavepointManager does not \
-	support incremental flushing when a savepoint has been set.  You must \
-	release your savepoints before flushing.
-callback-err: Errors occurred processing listener callbacks.  See the nested \
-    exceptions for details.
-bad-agg-listener-hint: Query hint value "{0}" ({1}) cannot be converted into \
-	an aggregate listener.
-bad-filter-listener-hint: Query hint value "{0}" ({1}) cannot be converted \
-	into a filter listener.
-bad-setter-hint-arg: In query hint "{0}", cannot convert hint value "{1}" to \
-    type "{2}".
-detach-val-mismatch: The instance "{0}" is managed by another context and \
-	cannot be inspected for field values.
-detach-val-badsm: The instance "{0}" has an unknown state manager which \
-	prevents field inspection.
-null-oid: Cannot perform find using null object id.
-illegal-op-in-prestore: This operation is illegal when called during \
-	transaction completion.
-no-expressions: The query cannot be executed because it has no \
-	valid expressions.
-null-fg: Attempt to add null/empty fetch group name to fetch configuration.
-null-field: Attempt to add null/empty field name to fetch configuration.
-container-projection: Query projections cannot include array, collection, or \
-    map fields.  Invalid query: "{0}"
-existing-value-override-excep: The generated value processing detected an \
-existing value assigned to this field: {0}.  This existing value was either \
-provided via an initializer or by calling the setter method.  You either need \
-to remove the @GeneratedValue annotation or modify the code to remove the \
-initializer processing.
-invalid-tran-status: The transaction was not in a valid state ({0}) to \
-accept the "{1}" method invocation.  Processing will continue.
-multi-threaded-access: Multiple concurrent threads attempted to access a \
-    single broker. By default brokers are not thread safe; if you require \
-    and/or intend a broker to be accessed by more than one thread, set the \
-    openjpa.Multithreaded property to true to override the default behavior.
-no-saved-fields: No state snapshot is available for instance of type "{0}", \
-    but this instance uses state-comparison for dirty detection.
-cant-serialize-flushed-broker: Serialization not allowed once a broker has \
-    been flushed.
-cant-serialize-pessimistic-broker: Serialization not allowed for brokers with \
-    an active datastore (pessimistic) transaction.
-cant-serialize-connected-broker: Serialization not allowed for brokers with \
-    an active connection to the database.
-no-interface-metadata: No metadata was found for managed interface {0}.
-fetch-configuration-stack-empty: Fetch configuration stack is empty.
\ No newline at end of file
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.  
+
+cant-convert-result: There is no conversion between query projection type \
+	"{0}" and result type "{1}".
+unloaded-detached: Attempt to access an unloaded field of detached instance \
+	"{0}".
+meta-unknownid: Cannot manipulate identity of type "{0}": it''s identity type \
+	is unknown.
+new-abstract: Cannot create an instance of "{0}": abstract classes are not \
+    yet supported.
+bad-new-query: Attempt to construct a query from an extent or class.  You must \
+	pass a (possibly null) query string or template to the query factory \
+	method when creating the query. 
+update-restrict: Detected attempt to modify field "{0}" with value strategy \
+	"restrict".
+reentrant-flush: Detected reentrant flush.  Make sure your flush-time instance \
+	callback methods or event listeners do not invoke any operations that \
+	require the in-progress flush to complete.
+rolled-back: The transaction has been rolled back.  See the nested exceptions \
+	for details on the errors that occurred.
+bad-lock-level: This lock manager does not recognize lock level "{0}".
+pessimistic-mutate: You are attempting to directly mutate a persistent second \
+	class object (such as a collection or map field) that you obtained before \
+	the transaction began.  After beginning a datastore transaction, you \
+	must re-obtain any references to mutable second class objects from the \
+	owning persistent object.  Detected attempt to mutate value of field "{0}" \
+	in instance "{1}".  This instance may not be locked correctly.
+not-derefed: Encountered unknown dependent instance "{0}".  This error is \
+	often caused by either removing a dependent instance from one dependent \
+	field, but not other dependent fields that reference it, or by removing a \
+	dependent instance from its owning field, flushing \
+	(causing the unreferenced dependent instance to be deleted), and then \
+	trying to assign the deleted instance to another field before commit.  \
+	The instance cannot be un-deleted, resulting in an error.  Make sure not \
+	to leave dangling dependent references to objects, and to reassign \
+	dependent objects before flush so that OpenJPA does not think they are \
+	unreferenced and therefore safe to delete.
+init-null-pc: Attempt to initialize a state manager with a null \
+	persistence-capable instance for type "{0}".  This is often caused by \
+	attempting to load an instance of an abstract class, or \
+	neglecting to use a class indicator when the base persistence-capable \
+	class in an inheritance tree is abstract.
+init-sm-pc: Attempt to initialize a state manager with an instance that is \
+	already managed ("{0}").  You might be trying to persist this instance \
+	in two threads at the same time.
+bad-ds-oid: The type "{0}" declares datastore identity but the value \
+	passed to lookup of type "{1}" is not a OpenJPA id instance.
+null-oids: Some of the object ids passed to getObjectsById were null.
+marked-rollback: The transaction cannot be committed, because it was already \
+	marked for rollback only.  The transaction will be rolled back instead. \
+    The cause of the rollback-only status is reported in the embedded stack.
+refresh-flushed: You cannot refresh an instance that has been flushed to the \
+	data store.
+pc-loader-different: Attempt to cast instance "{0}" to PersistenceCapable failed. \
+    The object implemented org.apache.openjpa.enhance.PersistenceCapable, \
+    but the instance of that interface was loaded by two different ClassLoaders: \
+    "{1}" and "{2}".
+pc-cast: Attempt to cast instance "{0}" to PersistenceCapable failed.  Ensure \
+	that it has been enhanced.
+del-instance: The instance of type "{0}" with oid "{1}" no longer exists in \
+	the data store.  This may mean that you deleted the instance in a separate \
+	transaction, but this context still has a cached version.
+no-broker-class: The specified type "{0}" could not be loaded. Please ensure \
+	that the class exists in the project class path.
+bad-embed: Attempt to set an embedded value for unembeddable field "{0}". \
+	Please report this error to OpenJPA support.
+embed-ref: You are attempting to access an embedded object reference \
+	that was obtained before the last transaction status change. After \
+	transactions begin and end, all references to embedded objects become \
+	invalid; you have to re-acquire the reference from the owning persistent \
+	object.
+deleted: Operation attempted on a deleted instance.
+dirty: Illegal operation attempted on a dirty instance: dirty objects cannot \
+	be evicted or made transient or non-transactional.
+nested-exceps: This operation failed for some instances.  See the nested \
+	exceptions array for details.
+new: Illegal operation attempted on a newly persisted instance: new objects \
+	cannot be evicted or made transient or non-transactional.
+transient: Illegal operation attempted on a transient instance.
+not-active: Can only perform operation while a transaction is active.
+trans-active: The "{0}" transaction property cannot be set during an \
+	active transaction.
+active: This operation cannot be performed while a Transaction is active.
+closed: The context has been closed.  The stack trace at which the \
+	context was closed is held in the embedded exception.
+closed-notrace: The context has been closed.  The stack trace at which the \
+	context was closed is available if Runtime=TRACE logging is enabled.
+closed-factory: The factory has been closed.  The stack trace at \
+	which the factory was closed is held in the embedded exception.
+closed-factory-notrace: The factory has been closed.  The stack trace at \
+	which the factory was closed is available if Runtime=TRACE logging is \
+	enabled.
+non-trans-read: To perform reads on persistent data outside of a transaction, \
+	the "NontransactionalRead" property must be set on the Transaction.
+non-trans-write: To perform writes on persistent data outside of a \
+	transaction, the "NontransactionalWrite" property must be set to true.
+write-operation: To perform this operation, it must be written within a transaction, \
+	or your settings must allow nontransactional writes and must not detach \
+	all nontransactional reads.
+not-managed: The given instance "{0}" is not managed by this context.
+trans-not-managed: This broker is not configured to use managed transactions.
+bad-detached-op: You cannot perform operation {0} on detached object "{1}". \
+	This operation only applies to managed objects.
+persist-detached: Attempt to persist detached object "{0}".  If this is a new \
+  instance, make sure any version and/or auto-generated primary key fields are \
+  null/default when persisting.
+null-value: The field "{0}" of instance "{1}" contained a null value; \
+	the metadata for this field specifies that nulls are illegal.
+change-identity: Attempt to change a primary key field of an instance that \
+	already has a final object id.  Only new, unflushed instances whose id you \
+	have not retrieved can have their primary keys changed.
+managed-oid: You cannot assign managed object "{0}" to the primary key field \
+	of "{1}".  Embedded primary key values must be transient objects.
+changed-oid: You have modified the object id field of "{2}".  Its old value \
+	was "{0}", and its new value is "{1}".  Object id fields are immutable \
+	once the object id of the instance has been assigned. 
+cache-exists: An object of type "{0}" with oid "{1}" already exists in this \
+	context; another cannot be persisted.
+null-trans: Attempt to commit a null javax.transaction.Transaction.  Some \
+	application servers set the transaction to null if a rollback occurs.
+end-trans-error: An exception occurred while ending the transaction.  This \
+	exception will be re-thrown.
+not-bound: The file named "{0}" could not be found.
+naming-exception: A NamingException was thrown while obtaining the \
+	factory at "{0}" from JNDI.
+attach-deleted: The object "{0}" with id "{1}" has been deleted and \
+	cannot be attached.
+not-detachable: The class "{0}" does not declare the "detachable" metadata \
+	extension, so cannot be detached.
+not-copyable: Attempt to copy field "{0}" failed.  The field is \
+	not copyable.  This can occur with custom SCO types. Only standard or \
+    immutable SCO types can be attached and detached.
+no-detach-object-id: Cannot access the detached object id of class "{0}". \
+	Ensure that the class has the "detachable" metadata extension, and \
+	the the class has been re-enhanced.
+attach-version-del: Attempted to attach deleted instance type "{0}" with oid \
+	"{1}".  If the instance is new, the version field should be left to its \
+	default value.
+attach-wrongclass: Attempted to attach instance "{0}" of type "{1}", but this \
+	instance is already in the datastore as type "{2}".
+sjvm-acquired-lock: Acquired an exclusive lock "{0}" on oid "{1}".
+sjvm-released-lock: Released lock "{0}".
+conn-not-supported: This data store cannot return connections.
+incremental-flush-not-supported: This data store does not support incremental \
+	flushing.  If you got this error while performing a query, make sure that \
+	you have not set the FlushBeforeQueries option to true, either by \
+	setting that option in your configuration file, or by programmatically \
+	setting the current FetchConfiguration''s FlushBeforeQueries property \
+	to QueryFlushModes.FLUSH_TRUE.
+nontrans-read-not-supported: This data store does not support nontransactional \
+	reads.  Set the NontransactionalRead property to false.
+optimistic-not-supported: This datastore does not support optimistic \
+	transactions.  Set the Optimistic property to false.
+restore-unset: The RestoreValues option is off, so initial values are \
+	not available. Turn on RestoreValues to be able to obtain initial \
+	values.
+mutable-restore-unset: The RestoreValues option is not set to "all", \
+	initial values of mutable fields are not available. Set RestoreValues to \
+	"all" in your properties to be able to obtain initial mutable values.
+initial-unloaded: OpenJPA cannot provide the initial value for field "{0}" \
+	because the field was never loaded before being changed.
+dup-oid-assign: Attempt to assign id "{0}" to new instance "{1}" failed; \
+	there is already an object in the L1 cache with this id. \
+	You must delete this object (in a previous transaction or the current one) \
+	before reusing its id.  This error can also occur when a horizontally \
+	or vertically mapped classes uses auto-increment application identity and \
+	does not use a hierarchy of application identity classes.
+dup-load: Cannot load object with id "{0}".  Instance "{1}" with the same id \
+	already exists in the L1 cache.  This can occur when you \
+	assign an existing id to a new instance, and before flushing attempt to \
+	load the existing instance for that id.
+bad-id-value: The given value "{0}" cannot be converted into an identity \
+	for "{2}".  The value is the wrong type ({1}).
+factory-init: Starting OpenJPA {0}
+factory-properties: Properties: {0}
+inverse-consistency: An inverse inconsistency in the object model was \
+	detected while flushing the field "{0}" of the instance with id "{1}" \
+	in context "{2}".
+no-brokerfactory: You did not name the factory class with the required \
+	property openjpa.BrokerFactory.  Normally this property defaults \
+    appropriately; have you forgotten to include all the OpenJPA jars in your \
+    classpath?
+brokerfactory-excep: There was an error when invoking the static \
+	getInstance method on the named factory class "{0}".  See the \
+	nested exception for details.
+new-brokerfactory-excep: There was an error when invoking the static \
+	newInstance method on the named factory class "{0}".  See the \
+	nested exception for details.
+bad-brokerfactory: Could not invoke the static getInstance method on the \
+	named factory class "{0}".
+bad-new-brokerfactory: Could not invoke the static newInstance method on the \
+	named factory class "{0}".
+bad-brokerfactory-class: The named BrokerFactory "{0}" is not valid.
+instantiate-abstract: Cannot instantiate abstract class of type "{0}" with \
+	object id "{1}"; this may indicate that the inheritance discriminator \
+	for the class is not configured correctly.
+nontrans-proxied: You cannot make a property access object created with "new" \
+	nontransactional.
+no-field: Field "{0}" is not declared in "{1}", or is not managed.
+no-field-index: "{0}" is not the index of any managed field in "{1}".
+cant-cascade-persist: Encountered unmanaged object in persistent field \
+	"{0}" during flush.  However, this field does not \
+	allow cascade persist. Set the cascade attribute for this field to \
+    CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or \
+    "persist" or "all" (JPA orm.xml), or enable cascade-persist globally, \
+    or manually persist the related field value prior to flushing. \
+	You cannot flush unmanaged objects or graphs that have persistent \
+    associations to unmanaged objects.
+cant-cascade-attach: Encountered new object in persistent field \
+	"{0}" during attach.  However, this field does not \
+	allow cascade attach. Set the cascade attribute for this field to \
+    CascadeType.MERGE or CascadeType.ALL (JPA annotations) or \
+    "merge" or "all" (JPA orm.xml). \
+    You cannot attach a reference to a new object without cascading.
+ref-to-deleted: Encountered deleted object "{0}" in persistent field \
+	"{1}" of managed object "{2}" during flush.
+no-version-field: Encountered object "{0}" without a version field during \
+	attach.  In order to attach an object, it must either be enhanced or must \
+	have a version field.
+inmem-agg-proj-var: Queries with aggregates or projections using variables \
+	currently cannot be executed in-memory.  Either set IgnoreCache to true, \
+	set the openjpa.FlushBeforeQueries property to true, or execute the query \
+	before changing any instances in the transaction.  The offending query was \
+	on type "{0}" with filter "{1}".
+merged-order-with-result: This query on candidate type "{0}" with filter "{1}" \
+	involves combining the results of multiple queries in memory. \
+	You have chosen to order the results on "{2}", but you have not selected \
+	this data in your setResult() clause.  Please include this ordering data \
+	in setResult() so that OpenJPA can extract it for in-memory ordering.
+bad-grouping: Your query on type "{0}" with filter "{1}" is invalid.  Your \
+    select and having clauses must only include aggregates or values that also \
+    appear in your grouping clause.
+query-nosupport: The "{0}" query type does not support this operation.
+query-unmapped: You cannot query unmapped type "{0}".
+range-too-big: The range of the query is too big. Start index: "{0}", end \
+	index: "{1}". The range must be less than Integer.MAX_VALUE.
+invalid-range: The query range from {0} to {1} is not valid.
+no-impls: Unable to execute a query on type "{0}".  This class or interface \
+	is not mapped, and does not have any mapped implementors.
+bad-param-name: The parameter name or position "{0}" passed to \
+	execute() is not valid.  All map keys must be a declared parameter \
+	name or a number matching the parameter position. Native queries only \
+	allow the use of positional parameters.
+force-in-mem: This query on type "{0}" must load the entire candidate class \
+	extent and evaluate the query in-memory.  This may be very slow.  The \
+	query must be executed in memory because OpenJPA is configured with \
+	IgnoreCache=false and FlushBeforeQueries=false and \
+	there are dirty instances that may affect the query''s outcome in the \
+	cache.
+cant-exec-inmem: Queries of this type ("{0}") cannot be executed in-memory. \
+	Either set IgnoreCache to true, set the openjpa.FlushBeforeQueries \
+	property to true, or execute the query before changing any instances in \
+	the transaction.
+executing-query: Executing query: {0}
+executing-query-with-params: Executing query: [{0}] with parameters: {1}
+not-unique: The query on candidate type "{0}" with filter "{1}" was \
+	configured to have a unique result, but more than one instance matched \
+	the query.
+no-result: The query on candidate type "{0}" with filter "{1}" was \
+	configured to have a unique result, but no instance matched \
+	the query.
+serialized: Queries that have been serialized do not support this operation.
+read-only: Attempt to modify a read-only query object.
+no-class: A candidate Class must be specified before executing a query.
+no-modify-resultclass: A query that declares a result class cannot be used \
+	to perform bulk updates.
+no-modify-unique: A query that declares unique results cannot be used \
+	to perform bulk updates.
+no-modify-range: A query that declares a result range cannot be used \
+	to perform bulk updates.
+unbound-param: Cannot execute query; the declared parameter "{0}" was \
+	not given a value.
+unbound-params: Cannot execute query; some declared parameters were not given \
+	values.  You must supply a value for each of the following parameters, \
+	in the given order: {0}
+extra-params: More parameters were passed to execute() than were declared: \
+	{1} parameters were specified for query execution, but only {0} \
+	parameters were declared in the query.
+null-primitive-param: Parameter "{0}" was declared with a primitive type, but \
+	has been given a null value.
+merged-aggregate: This query on candidate type "{0}" with filter "{1}" \
+	involves combining the results of multiple sub-queries.  However, because \
+	this query is for aggregate data, OpenJPA cannot combine the sub-query \
+	aggregates into correct final values.
+bad-dec: The {1} declaration "{0}" is \
+	not valid. Variables and imports must be delimited with ";".  Parameters \
+	and orderings must be delimited with ",".  Imports require the "import" \
+	keyword, and orderings require the "ascending" or "descending" keyword.
+mod-bigdecimal: You cannot use the modulo operator (%) on numbers of type \
+	BigDecimal.
+cant-convert: Cannot convert object "{0}" of type "{1}" into an instance of \
+	"{2}".
+bad-method-class: You set the method name of this openjpa.MethodQL query to \
+	"{1}", but class "{0}" is not a valid class name.  Make sure to fully \
+	qualify the class name or to import its package into this query if the \
+	class is not in the query candidate class'' package. 
+method-not-static: Method "{0}" named in the MethodQL query must be static.
+method-return-type-invalid: Method "{0}" named in the MethodQL query must \
+    have a return type that is assignable from ResultObjectProvider. Return \
+    type is: {1}.
+no-method: You must set the query filter to the name of the method to execute \
+	for this MethodQL query instance.
+method-error: There was an error invoking method "{0}" with arguments "{1}".
+bad-param-type: The type "{0}" as used in the parameter declarations \
+	could not be found in the imports.
+cant-set: Result type "{0}" does not have any public fields or setter methods \
+	for the projection or aggregate result element "{1}", nor does it have a \
+	generic put(Object,Object) method that can be used, nor does it have a \
+	public constructor that takes the types {2}.
+pack-err: There was an error packing the projection and/or aggregate results \
+	of the query into result type "{0}".  See the nested Throwable exception \
+	for details.
+pack-instantiation-err: There was an error creating an instance of type "{0}" \
+	when packing the projection and/or aggregate results of the query. Ensure \
+	that you have defined a public no-args constructor in "{0}".
+bad-inmem-method: Method "{0}(StoreContext, ClassMetaData, boolean, Object, \
+	Map, FetchConfiguration)" is not declared in type "{1}". \
+	Check the method name supplied in your MethodQL query filter.  \
+	OpenJPA is attempting to execute this query in-memory; if you implemented \
+    the datastore method instead (a method with the same signature but without \
+    the Object argument) and want this query to execute in the datastore, \
+    either create the query before modifying objects in the current transaction, \
+	set IgnoreCache to true, or set the openjpa.FlushBeforeQueries property to \
+	true.
+bad-datastore-method: Method "{0}(StoreContext, ClassMetaData, boolean, Map, \
+	FetchConfiguration)" is not declared in type "{1}".  Check \
+	the method name supplied in your MethodQL query filter.  OpenJPA is \
+	attempting to execute this query against the datastore; if you implemented \
+	the in-memory method instead (a method with the same signature but with an \
+	Object argument) and want this query to execute in-memory, supply a \
+	Collection of candidates to filter.
+only-update-constants: Bulk update queries when executed in memory \
+	may only update to constant values.
+only-range-constants: Range values must be numeric constants.  Illegal query: \
+    {0}
+no-savepoint-copy: Unable to copy field "{0}" for savepoint.
+savepoint-exists: A savepoint with the name "{0}" already exists.  \
+	Each savepoint name must be unique.
+no-lastsavepoint: Cannot rollback/release last savepoint as no savepoint \
+	has been set.
+no-savepoint: You have not set a savepoint with the name "{0}"
+savepoint-init: This savepoint has already been initialized.
+savepoint-flush-not-supported: The configured SavepointManager does not \
+	support incremental flushing when a savepoint has been set.  You must \
+	release your savepoints before flushing.
+callback-err: Errors occurred processing listener callbacks.  See the nested \
+    exceptions for details.
+bad-agg-listener-hint: Query hint value "{0}" ({1}) cannot be converted into \
+	an aggregate listener.
+bad-filter-listener-hint: Query hint value "{0}" ({1}) cannot be converted \
+	into a filter listener.
+bad-setter-hint-arg: In query hint "{0}", cannot convert hint value "{1}" to \
+    type "{2}".
+detach-val-mismatch: The instance "{0}" is managed by another context and \
+	cannot be inspected for field values.
+detach-val-badsm: The instance "{0}" has an unknown state manager which \
+	prevents field inspection.
+null-oid: Cannot perform find using null object id.
+illegal-op-in-prestore: This operation is illegal when called during \
+	transaction completion.
+no-expressions: The query cannot be executed because it has no \
+	valid expressions.
+null-fg: Attempt to add null/empty fetch group name to fetch configuration.
+null-field: Attempt to add null/empty field name to fetch configuration.
+container-projection: Query projections cannot include array, collection, or \
+    map fields.  Invalid query: "{0}"
+existing-value-override-excep: The generated value processing detected an \
+existing value assigned to this field: {0}.  This existing value was either \
+provided via an initializer or by calling the setter method.  You either need \
+to remove the @GeneratedValue annotation or modify the code to remove the \
+initializer processing.
+invalid-tran-status: The transaction was not in a valid state ({0}) to \
+accept the "{1}" method invocation.  Processing will continue.
+multi-threaded-access: Multiple concurrent threads attempted to access a \
+    single broker. By default brokers are not thread safe; if you require \
+    and/or intend a broker to be accessed by more than one thread, set the \
+    openjpa.Multithreaded property to true to override the default behavior.
+no-saved-fields: No state snapshot is available for instance of type "{0}", \
+    but this instance uses state-comparison for dirty detection.
+cant-serialize-flushed-broker: Serialization not allowed once a broker has \
+    been flushed.
+cant-serialize-pessimistic-broker: Serialization not allowed for brokers with \
+    an active datastore (pessimistic) transaction.
+cant-serialize-connected-broker: Serialization not allowed for brokers with \
+    an active connection to the database.
+no-interface-metadata: No metadata was found for managed interface {0}.
+fetch-configuration-stack-empty: Fetch configuration stack is empty.
+broker-suppressing-exceptions: Suppressing "{0}" exceptions.
diff --git a/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties b/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
index 1446b14..5417036 100644
--- a/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
+++ b/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
@@ -321,3 +321,11 @@
     a jar file, this may be caused by one or more inherited class of the \
     entity not being packaged in the same jar file. Please check all \
     inherited class(es) are packaged in the same jar file.
+cmd-discover-cycle: A cycle was detected while resolving the identity \
+    references for type "{0}".  The original process buffer ordering \
+    will be used.
+repos-initializeEager-none: No persistent metadata found for loading during initialization. \
+    The persistent classes must be listed in persistence unit configuration to be loaded during initialization.
+repos-initializeEager-found: The following classes are being preloaded "{0}".	   
+repos-initializeEager-error: Unexpected error during early loading of entity metadata during initialization. \
+    See nested stacktrace for details.	  
diff --git a/openjpa-kernel/src/test/java/org/apache/openjpa/ee/TestWASManagedRuntime.java b/openjpa-kernel/src/test/java/org/apache/openjpa/ee/TestWASManagedRuntime.java
index b9611e1..f60c8ca 100644
--- a/openjpa-kernel/src/test/java/org/apache/openjpa/ee/TestWASManagedRuntime.java
+++ b/openjpa-kernel/src/test/java/org/apache/openjpa/ee/TestWASManagedRuntime.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.ee;
-
-import junit.framework.TestCase;
-
-import serp.util.Strings;
-
-/**
- * Test class for build transformation performed by WASManagedRuntime.
- *
- */
-public class TestWASManagedRuntime extends TestCase {
-
-    /**
-     * This test will verify that the WASManagedRuntime$WASSynchronization
-     * class was properly modified by the maven build process (reference
-     * the top level pom.xml).  This testcase will not execute properly
-     * within Eclipse since the Eclipse target directory (probably) hasn't
-     * been modified via the maven build.
-     *
-     * @throws ClassNotFoundException
-     */
-    public void testInterfaceAdded() throws ClassNotFoundException {
-
-        String msg = null;
-
-        try {
-            Class.forName(WASManagedRuntime.CLASS);
-            fail("expected an exception to be thrown");
-        } catch (NoClassDefFoundError e) {
-            msg = e.getMessage();
-        }
-        String interfaceName = Strings.
-            getClassName(WASManagedRuntime.INTERFACE);
-        assertTrue("message should have contained "
-            + interfaceName + ", but was '" + msg + "'",
-            msg.indexOf(interfaceName) != -1);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.ee;
+
+import junit.framework.TestCase;
+
+import serp.util.Strings;
+
+/**
+ * Test class for build transformation performed by WASManagedRuntime.
+ *
+ */
+public class TestWASManagedRuntime extends TestCase {
+
+    /**
+     * This test will verify that the WASManagedRuntime$WASSynchronization
+     * class was properly modified by the maven build process (reference
+     * the top level pom.xml).  This testcase will not execute properly
+     * within Eclipse since the Eclipse target directory (probably) hasn't
+     * been modified via the maven build.
+     *
+     * @throws ClassNotFoundException
+     */
+    public void testInterfaceAdded() throws ClassNotFoundException {
+
+        String msg = null;
+
+        try {
+            Class.forName(WASManagedRuntime.CLASS);
+            fail("expected an exception to be thrown");
+        } catch (NoClassDefFoundError e) {
+            msg = e.getMessage();
+        }
+        String interfaceName = Strings.
+            getClassName(WASManagedRuntime.INTERFACE);
+        assertTrue("message should have contained "
+            + interfaceName + ", but was '" + msg + "'",
+            msg.indexOf(interfaceName) != -1);
+    }
+}
diff --git a/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestGetDeclaredMethod.java b/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestGetDeclaredMethod.java
index 1254cd7..ce09582 100644
--- a/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestGetDeclaredMethod.java
+++ b/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestGetDeclaredMethod.java
@@ -1,93 +1,93 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.ArrayList;
-
-import junit.framework.TestCase;
-
-/**
- * Tests that {@link Reflection#getDeclaredMethod(Class, String, Class)}
- * returns the most-derived class's method when called from a type hierarchy.
- * See OPENJPA-251.
- */
-public class TestGetDeclaredMethod extends TestCase {
-
-    public void testGetDeclaredMethod() {
-        Method meth =
-            Reflection.getDeclaredMethod(Impl.class, "getObject", null);
-        assertEquals(Impl.class, meth.getDeclaringClass());
-        assertEquals(String.class, meth.getReturnType());
-    }
-
-    public void testMostDerived() throws NoSuchMethodException {
-        Method impl = Impl.class.getDeclaredMethod("getObject", null);
-        Method iface = Iface.class.getDeclaredMethod("getObject", null);
-        Method other = Other.class.getDeclaredMethod("getObject", null);
-        assertEquals(Impl.class, Reflection.mostDerived(impl, iface)
-            .getDeclaringClass());
-        assertEquals(Impl.class, Reflection.mostDerived(iface, impl)
-            .getDeclaringClass());
-        try {
-            Reflection.mostDerived(iface, other);
-            fail("'iface' and 'other' are not from related types");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    public void testGenerics() throws NoSuchMethodException {
-        List<Method> meths = new ArrayList<Method>();
-        for (Method meth : GenericsImpl.class.getDeclaredMethods()) {
-            if ("getObject".equals(meth.getName()))
-                meths.add(meth);
-        }
-        assertEquals(2, meths.size());
-        assertEquals(String.class, Reflection.mostDerived(meths.get(0),
-            meths.get(1)).getReturnType());
-    }
-    
-    interface Iface {
-        Object getObject();
-    }
-
-    static class Impl implements Iface {
-        public String getObject() {
-            return "string";
-        }
-    }
-
-    static class Other {
-        public String getObject() {
-            return "other";
-        }
-    }
-
-    interface GenericsIface<T> {
-        public T getObject();
-    }
-
-    static class GenericsImpl implements GenericsIface {
-        public String getObject() {
-            return null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests that {@link Reflection#getDeclaredMethod(Class, String, Class)}
+ * returns the most-derived class's method when called from a type hierarchy.
+ * See OPENJPA-251.
+ */
+public class TestGetDeclaredMethod extends TestCase {
+
+    public void testGetDeclaredMethod() {
+        Method meth =
+            Reflection.getDeclaredMethod(Impl.class, "getObject", null);
+        assertEquals(Impl.class, meth.getDeclaringClass());
+        assertEquals(String.class, meth.getReturnType());
+    }
+
+    public void testMostDerived() throws NoSuchMethodException {
+        Method impl = Impl.class.getDeclaredMethod("getObject", null);
+        Method iface = Iface.class.getDeclaredMethod("getObject", null);
+        Method other = Other.class.getDeclaredMethod("getObject", null);
+        assertEquals(Impl.class, Reflection.mostDerived(impl, iface)
+            .getDeclaringClass());
+        assertEquals(Impl.class, Reflection.mostDerived(iface, impl)
+            .getDeclaringClass());
+        try {
+            Reflection.mostDerived(iface, other);
+            fail("'iface' and 'other' are not from related types");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    public void testGenerics() throws NoSuchMethodException {
+        List<Method> meths = new ArrayList<Method>();
+        for (Method meth : GenericsImpl.class.getDeclaredMethods()) {
+            if ("getObject".equals(meth.getName()))
+                meths.add(meth);
+        }
+        assertEquals(2, meths.size());
+        assertEquals(String.class, Reflection.mostDerived(meths.get(0),
+            meths.get(1)).getReturnType());
+    }
+    
+    interface Iface {
+        Object getObject();
+    }
+
+    static class Impl implements Iface {
+        public String getObject() {
+            return "string";
+        }
+    }
+
+    static class Other {
+        public String getObject() {
+            return "other";
+        }
+    }
+
+    interface GenericsIface<T> {
+        public T getObject();
+    }
+
+    static class GenericsImpl implements GenericsIface {
+        public String getObject() {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestPCSubclassNameConversion.java b/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestPCSubclassNameConversion.java
index f337f26..2237cde 100644
--- a/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestPCSubclassNameConversion.java
+++ b/openjpa-kernel/src/test/java/org/apache/openjpa/enhance/TestPCSubclassNameConversion.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import junit.framework.TestCase;
-
-public class TestPCSubclassNameConversion
-    extends TestCase {
-
-    public void testPCSubclassNameConversion() {
-        String name = PCEnhancer.toPCSubclassName(Object.class);
-        assertTrue(PCEnhancer.isPCSubclassName(name));
-        assertEquals(Object.class.getName(),
-            PCEnhancer.toManagedTypeName(name));
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import junit.framework.TestCase;
+
+public class TestPCSubclassNameConversion
+    extends TestCase {
+
+    public void testPCSubclassNameConversion() {
+        String name = PCEnhancer.toPCSubclassName(Object.class);
+        assertTrue(PCEnhancer.isPCSubclassName(name));
+        assertEquals(Object.class.getName(),
+            PCEnhancer.toManagedTypeName(name));
+    }
 }
\ No newline at end of file
diff --git a/openjpa-kernel/src/test/java/org/apache/openjpa/meta/TestMemberProvider.java b/openjpa-kernel/src/test/java/org/apache/openjpa/meta/TestMemberProvider.java
index 32780d9..eb8f78a 100644
--- a/openjpa-kernel/src/test/java/org/apache/openjpa/meta/TestMemberProvider.java
+++ b/openjpa-kernel/src/test/java/org/apache/openjpa/meta/TestMemberProvider.java
@@ -1,62 +1,62 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-import org.apache.openjpa.meta.FieldMetaData.MemberProvider;
-
-public class TestMemberProvider
-    extends TestCase {
-
-    private String field;
-
-    public void testField()
-        throws NoSuchFieldException, IOException, ClassNotFoundException {
-        MemberProvider b = new MemberProvider(
-            getClass().getDeclaredField("field"));
-        MemberProvider b2 = roundtrip(b);
-        assertEquals(b.getMember(), b2.getMember());
-    }
-
-    public void testMethod()
-        throws NoSuchMethodException, IOException, ClassNotFoundException {
-        MemberProvider b = new MemberProvider(
-            getClass().getDeclaredMethod("testMethod", null));
-        MemberProvider b2 = roundtrip(b);
-        assertEquals(b.getMember(), b2.getMember());
-    }
-
-    private MemberProvider roundtrip(MemberProvider other)
-        throws IOException, ClassNotFoundException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        new ObjectOutputStream(out).writeObject(other);
-        out.flush();
-        byte[] bytes = out.toByteArray();
-        out.close();
-
-        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
-        return (MemberProvider) new ObjectInputStream(in).readObject();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+import org.apache.openjpa.meta.FieldMetaData.MemberProvider;
+
+public class TestMemberProvider
+    extends TestCase {
+
+    private String field;
+
+    public void testField()
+        throws NoSuchFieldException, IOException, ClassNotFoundException {
+        MemberProvider b = new MemberProvider(
+            getClass().getDeclaredField("field"));
+        MemberProvider b2 = roundtrip(b);
+        assertEquals(b.getMember(), b2.getMember());
+    }
+
+    public void testMethod()
+        throws NoSuchMethodException, IOException, ClassNotFoundException {
+        MemberProvider b = new MemberProvider(
+            getClass().getDeclaredMethod("testMethod", null));
+        MemberProvider b2 = roundtrip(b);
+        assertEquals(b.getMember(), b2.getMember());
+    }
+
+    private MemberProvider roundtrip(MemberProvider other)
+        throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        new ObjectOutputStream(out).writeObject(other);
+        out.flush();
+        byte[] bytes = out.toByteArray();
+        out.close();
+
+        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
+        return (MemberProvider) new ObjectInputStream(in).readObject();
+    }
+}
diff --git a/openjpa-lib/pom.xml b/openjpa-lib/pom.xml
index 5e8f652..7738d50 100644
--- a/openjpa-lib/pom.xml
+++ b/openjpa-lib/pom.xml
@@ -31,7 +31,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/BootstrapException.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/BootstrapException.java
index b58b0cf..94b98bf 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/BootstrapException.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/BootstrapException.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.conf;
-/**
- * Exception recognized by {@link ProductDerivations bootstrap} framework.
- * 
- * @author Pinaki Poddar
- * @since 0.4.1.4
- *
- */
-public class BootstrapException extends RuntimeException {
-
-	private boolean _fatal = false;
-	
-	public BootstrapException() {
-		super();
-	}
-
-	public BootstrapException(String message) {
-		super(message);
-	}
-
-	public BootstrapException(Throwable cause) {
-		super(cause);
-	}
-
-	public BootstrapException(String message, Throwable cause) {
-		super(message, cause);
-	}
-	
-	public BootstrapException setFatal(boolean fatal) {
-		_fatal = fatal;
-		return this;
-	}
-	
-	public boolean isFatal() {
-		return _fatal;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.conf;
+/**
+ * Exception recognized by {@link ProductDerivations bootstrap} framework.
+ * 
+ * @author Pinaki Poddar
+ * @since 0.4.1.4
+ *
+ */
+public class BootstrapException extends RuntimeException {
+
+	private boolean _fatal = false;
+	
+	public BootstrapException() {
+		super();
+	}
+
+	public BootstrapException(String message) {
+		super(message);
+	}
+
+	public BootstrapException(Throwable cause) {
+		super(cause);
+	}
+
+	public BootstrapException(String message, Throwable cause) {
+		super(message, cause);
+	}
+	
+	public BootstrapException setFatal(boolean fatal) {
+		_fatal = fatal;
+		return this;
+	}
+	
+	public boolean isFatal() {
+		return _fatal;
+	}
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
index d4e4202..c61b2bc 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
@@ -1,721 +1,721 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.conf;
-
-import java.io.File;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.Properties;
-import java.util.TreeSet;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.exception.NestableRuntimeException;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.lib.util.ParseException;
-import org.apache.openjpa.lib.util.StringDistance;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-import serp.util.Strings;
-
-/**
- * Utility methods dealing with configuration.
- *
- * @author Abe White
- * @nojavadoc
- */
-public class Configurations {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (Configurations.class);
-    
-    private static final ConcurrentReferenceHashMap _loaders = new
-        ConcurrentReferenceHashMap(ConcurrentReferenceHashMap.WEAK, 
-                ConcurrentReferenceHashMap.HARD);
-
-    private static final Object NULL_LOADER = "null-loader";
-
-    /**
-     * Return the class name from the given plugin string, or null if none.
-     */
-    public static String getClassName(String plugin) {
-        return getPluginComponent(plugin, true);
-    }
-
-    /**
-     * Return the properties part of the given plugin string, or null if none.
-     */
-    public static String getProperties(String plugin) {
-        return getPluginComponent(plugin, false);
-    }
-
-    /**
-     * Return either the class name or properties string from a plugin string.
-     */
-    private static String getPluginComponent(String plugin, boolean clsName) {
-        if (plugin != null)
-            plugin = plugin.trim();
-        if (StringUtils.isEmpty(plugin))
-            return null;
-
-        int openParen = -1;
-        if (plugin.charAt(plugin.length() - 1) == ')')
-            openParen = plugin.indexOf('(');
-        if (openParen == -1) {
-            int eq = plugin.indexOf('=');
-            if (eq == -1)
-                return (clsName) ? plugin : null;
-            return (clsName) ? null : plugin;
-        }
-
-        // clsName(props) form
-        if (clsName)
-            return plugin.substring(0, openParen).trim();
-        String prop = plugin.substring(openParen + 1,
-            plugin.length() - 1).trim();
-        return (prop.length() == 0) ? null : prop;
-    }
-
-    /**
-     * Combine the given class name and properties into a plugin string.
-     */
-    public static String getPlugin(String clsName, String props) {
-        if (StringUtils.isEmpty(clsName))
-            return props;
-        if (StringUtils.isEmpty(props))
-            return clsName;
-        return clsName + "(" + props + ")";
-    }
-
-    /**
-     * Return a plugin string that combines the properties of the given plugin
-     * strings, where properties of <code>override</code> will override the
-     * same properties of <code>orig</code>.
-     */
-    public static String combinePlugins(String orig, String override) {
-        if (StringUtils.isEmpty(orig))
-            return override;
-        if (StringUtils.isEmpty(override))
-            return orig;
-
-        String origCls = getClassName(orig);
-        String overrideCls = getClassName(override);
-        String cls;
-        if (StringUtils.isEmpty(origCls))
-            cls = overrideCls;
-        else if (StringUtils.isEmpty(overrideCls))
-            cls = origCls;
-        else if (!origCls.equals(overrideCls))
-            return override; // completely different plugin
-        else
-            cls = origCls;
-
-        String origProps = getProperties(orig);
-        String overrideProps = getProperties(override);
-        if (StringUtils.isEmpty(origProps))
-            return getPlugin(cls, overrideProps);
-        if (StringUtils.isEmpty(overrideProps))
-            return getPlugin(cls, origProps);
-
-        Properties props = parseProperties(origProps);
-        props.putAll(parseProperties(overrideProps));
-        return getPlugin(cls, serializeProperties(props)); 
-    }
-
-    /**
-     * Create the instance with the given class name, using the given
-     * class loader. No configuration of the instance is performed by
-     * this method.
-     */
-    public static Object newInstance(String clsName, ClassLoader loader) {
-        return newInstance(clsName, null, null, loader, true);
-    }
-
-    /**
-     * Create and configure an instance with the given class name and
-     * properties.
-     */
-    public static Object newInstance(String clsName, Configuration conf,
-        String props, ClassLoader loader) {
-        Object obj = newInstance(clsName, null, conf, loader, true);
-        configureInstance(obj, conf, props);
-        return obj;
-    }
-
-    /**
-     * Helper method used by members of this package to instantiate plugin
-     * values.
-     */
-    static Object newInstance(String clsName, Value val, Configuration conf,
-        ClassLoader loader, boolean fatal) {
-        if (StringUtils.isEmpty(clsName))
-            return null;
-
-        Class cls = null; 
-
-        while (cls == null) {
-            // can't have a null reference in the map, so use symbolic
-            // constant as key
-            Object key = loader == null ? NULL_LOADER : loader;
-            Map loaderCache = (Map) _loaders.get(key);
-            if (loaderCache == null) { // We don't have a cache for this loader.
-                loaderCache = new ConcurrentHashMap();
-                _loaders.put(key, loaderCache);
-            } else {  // We have a cache for this loader.
-                cls = (Class) loaderCache.get(clsName);
-            }
-
-            if (cls == null) {
-                try {
-                    cls = Strings.toClass(clsName, findDerivedLoader(conf,
-                            loader));
-                    loaderCache.put(clsName, cls);
-                } catch (RuntimeException re) {
-                    if (loader != null)  // Try one more time with loader=null
-                        loader = null;
-                    else {
-                        if (val != null)
-                            re = getCreateException(clsName, val, re);
-                        if (fatal)
-                            throw re;
-                        Log log = (conf == null) ? null : conf
-                                .getConfigurationLog();
-                        if (log != null && log.isErrorEnabled())
-                            log.error(_loc
-                                    .get("plugin-creation-exception", val), re);
-                        return null;
-                    }
-                }
-            }
-        }
-
-        try {
-            return AccessController.doPrivileged(
-                J2DoPrivHelper.newInstanceAction(cls));
-        } catch (Exception e) {
-            if (e instanceof PrivilegedActionException) {
-                e = ((PrivilegedActionException) e).getException();   
-            }
-            RuntimeException re = new NestableRuntimeException(_loc.get
-                ("obj-create", cls).getMessage(), e);
-            if (fatal)
-                throw re;
-            Log log = (conf == null) ? null : conf.getConfigurationLog();
-            if (log != null && log.isErrorEnabled())
-                log.error(_loc.get("plugin-creation-exception", val), re);
-            return null;
-        }
-    }
-
-    /**
-     * Attempt to find a derived loader that delegates to our target loader.
-     * This allows application loaders that delegate appropriately for known
-     * classes first crack at class names.
-     */
-    private static ClassLoader findDerivedLoader(Configuration conf,
-        ClassLoader loader) {
-        // we always prefer the thread loader, because it's the only thing we
-        // can access that isn't bound to the OpenJPA classloader, unless
-        // the conf object is of a custom class
-        ClassLoader ctxLoader = (ClassLoader) AccessController.doPrivileged(
-            J2DoPrivHelper.getContextClassLoaderAction());
-        if (loader == null) {
-            if (ctxLoader != null)
-                return ctxLoader;
-            if (conf != null)
-                return (ClassLoader) AccessController.doPrivileged(
-                    J2DoPrivHelper.getClassLoaderAction(conf.getClass())); 
-            return Configurations.class.getClassLoader();
-        }
-
-        for (ClassLoader parent = ctxLoader; parent != null; 
-            parent = (ClassLoader) AccessController.doPrivileged(
-                J2DoPrivHelper.getParentAction(parent))) {
-            if (parent == loader)
-                return ctxLoader;
-        }
-        if (conf != null) {
-            for (ClassLoader parent = (ClassLoader)
-                AccessController.doPrivileged(
-                    J2DoPrivHelper.getClassLoaderAction(conf.getClass())); 
-                parent != null; 
-                parent = (ClassLoader) AccessController.doPrivileged(
-                    J2DoPrivHelper.getParentAction(parent))) {
-                if (parent == loader)
-                    return (ClassLoader) AccessController.doPrivileged(
-                        J2DoPrivHelper.getClassLoaderAction(conf.getClass())); 
-            }
-        }
-        return loader;
-    }
-
-    /**
-     * Return a List<String> of all the fully-qualified anchors specified in the
-     * properties location listed in <code>opts</code>. If no properties
-     * location is listed in <code>opts</code>, this returns whatever the
-     * product derivations can find in their default configurations.
-     * If the properties location specified in <code>opts</code> already
-     * contains an anchor spec, this returns that anchor. Note that in this
-     * fully-qualified-input case, the logic involving product derivations
-     * and resource parsing is short-circuited, so this method
-     * should not be used as a means to test that a particular anchor is
-     * defined in a given location by invoking with a fully-qualified anchor.
-     *
-     * This does not mutate <code>opts</code>.
-     *
-     * @since 1.1.0
-     */
-    public static List getFullyQualifiedAnchorsInPropertiesLocation(
-        Options opts) {
-        String props = opts.getProperty("properties", "p", null);
-        if (props != null) {
-            int anchorPosition = props.indexOf("#");
-            if (anchorPosition > -1)
-                return Arrays.asList(new String[] { props });
-        }
-
-        return ProductDerivations.getFullyQualifiedAnchorsInPropertiesLocation(
-            props);
-    }
-
-    /**
-     * Set the given {@link Configuration} instance from the command line
-     * options provided. All property names of the given configuration are
-     * recognized; additionally, if a <code>properties</code> or
-     * <code>p</code> argument exists, the resource it
-     * points to will be loaded and set into the given configuration instance.
-     * It can point to either a file or a resource name.
-     */
-    public static void populateConfiguration(Configuration conf, Options opts) {
-        String props = opts.removeProperty("properties", "p", null);
-        ConfigurationProvider provider;
-        if (!StringUtils.isEmpty(props)) {
-            String path = props;
-            String anchor = null;
-            int idx = path.lastIndexOf('#');
-            if (idx != -1) {
-                if (idx < path.length() - 1)
-                    anchor = path.substring(idx + 1);
-                path = path.substring(0, idx);
-                if (path.length() == 0)
-                    throw new MissingResourceException(_loc.get("anchor-only",
-                        props).getMessage(), Configurations.class.getName(), 
-                        props);
-            }
-
-            File file = new File(path);
-            if (((Boolean) AccessController.doPrivileged(J2DoPrivHelper
-                .isFileAction(file))).booleanValue())
-                provider = ProductDerivations.load(file, anchor, null);
-            else {
-                file = new File("META-INF" + File.separatorChar + path);
-                if (((Boolean) AccessController.doPrivileged(J2DoPrivHelper
-                    .isFileAction(file))).booleanValue())
-                    provider = ProductDerivations.load(file, anchor, null);
-                else
-                    provider = ProductDerivations.load(path, anchor, null);
-            }
-            if (provider != null)
-                provider.setInto(conf);
-            else
-                throw new MissingResourceException(_loc.get("no-provider",
-                    props).getMessage(), Configurations.class.getName(), 
-                    props);
-        } else {
-            provider = ProductDerivations.loadDefaults(null);
-            if (provider != null)
-                provider.setInto(conf);
-        }
-        opts.setInto(conf);
-    }
-
-    /**
-     * Helper method to throw an informative description on instantiation error.
-     */
-    private static RuntimeException getCreateException(String clsName,
-        Value val, Exception e) {
-        // re-throw the exception with some better information
-        final String msg;
-        final Object[] params;
-
-        String alias = val.alias(clsName);
-        String[] aliases = val.getAliases();
-        String[] keys;
-        if (aliases.length == 0)
-            keys = aliases;
-        else {
-            keys = new String[aliases.length / 2];
-            for (int i = 0; i < aliases.length; i += 2)
-                keys[i / 2] = aliases[i];
-        }
-
-        String closest;
-        if (keys.length == 0) {
-            msg = "invalid-plugin";
-            params = new Object[]{ val.getProperty(), alias, e.toString(), };
-        } else if ((closest = StringDistance.getClosestLevenshteinDistance
-            (alias, keys, 0.5f)) == null) {
-            msg = "invalid-plugin-aliases";
-            params = new Object[]{
-                val.getProperty(), alias, e.toString(),
-                new TreeSet(Arrays.asList(keys)), };
-        } else {
-            msg = "invalid-plugin-aliases-hint";
-            params = new Object[]{
-                val.getProperty(), alias, e.toString(),
-                new TreeSet(Arrays.asList(keys)), closest, };
-        }
-        return new ParseException(_loc.get(msg, params), e);
-    }
-
-    /**
-     * Configures the given object with the given properties by
-     * matching the properties string to the object's setter
-     * methods. The properties string should be in the form
-     * "prop1=val1, prop2=val2 ...". Does not validate that setter
-     * methods exist for the properties.
-     *
-     * @throws RuntimeException on configuration error
-     */
-    public static void configureInstance(Object obj, Configuration conf,
-        String properties) {
-        configureInstance(obj, conf, properties, null);
-    }
-
-    /**
-     * Configures the given object with the given properties by
-     * matching the properties string to the object's setter
-     * methods. The properties string should be in the form
-     * "prop1=val1, prop2=val2 ...". Validates that setter methods
-     * exist for the properties.
-     *
-     * @throws RuntimeException on configuration error
-     */
-    public static void configureInstance(Object obj, Configuration conf,
-        String properties, String configurationName) {
-        if (obj == null)
-            return;
-
-        Properties props = null;
-        if (!StringUtils.isEmpty(properties))
-            props = parseProperties(properties);
-        configureInstance(obj, conf, props, configurationName);
-    }
-
-    /**
-     * Configures the given object with the given properties by
-     * matching the properties string to the object's setter
-     * methods. Does not validate that setter methods exist for the properties.
-     *
-     * @throws RuntimeException on configuration error
-     */
-    public static void configureInstance(Object obj, Configuration conf,
-        Properties properties) {
-        configureInstance(obj, conf, properties, null);
-    }
-
-    /**
-     * Configures the given object with the given properties by
-     * matching the properties string to the object's setter
-     * methods. If <code>configurationName</code> is
-     * non-<code>null</code>, validates that setter methods exist for
-     * the properties.
-     *
-     * @throws RuntimeException on configuration error
-     */
-    public static void configureInstance(Object obj, Configuration conf,
-        Properties properties, String configurationName) {
-        if (obj == null)
-            return;
-
-        Options opts;
-        if (properties instanceof Options)
-            opts = (Options) properties;
-        else { 
-            opts = new Options();
-            if (properties != null)
-                opts.putAll(properties);
-        }
-
-        Configurable configurable = null;
-        if (conf != null && obj instanceof Configurable)
-            configurable = (Configurable) obj;
-
-        if (configurable != null) {
-            configurable.setConfiguration(conf);
-            configurable.startConfiguration();
-        }
-        Options invalidEntries = opts.setInto(obj);
-        if (obj instanceof GenericConfigurable)
-            ((GenericConfigurable) obj).setInto(invalidEntries);
-
-		if (!invalidEntries.isEmpty() && configurationName != null) {
-			Localizer.Message msg = null;
-			String first = (String) invalidEntries.keySet().iterator().next();
-			if (invalidEntries.keySet().size() == 1 &&
-				first.indexOf('.') == -1) {
-				// if there's just one misspelling and this is not a
-				// path traversal, check for near misses.
-				Collection options = findOptionsFor(obj.getClass());
-				String close = StringDistance.getClosestLevenshteinDistance
-					(first, options, 0.75f);
-				if (close != null)
-					msg = _loc.get("invalid-config-param-hint", new Object[]{
-						configurationName, obj.getClass(), first, close,
-						options, });
-			}
-
-            if (msg == null) {
-                msg = _loc.get("invalid-config-params", new String[]{
-                    configurationName, obj.getClass().getName(),
-                    invalidEntries.keySet().toString(),
-                    findOptionsFor(obj.getClass()).toString(), });
-            }
-            throw new ParseException(msg);
-        }
-        if (configurable != null)
-            configurable.endConfiguration();
-    }
-
-    private static Collection findOptionsFor(Class cls) {
-        Collection c = Options.findOptionsFor(cls);
-        
-        // remove Configurable.setConfiguration() and 
-        // GenericConfigurable.setInto() from the set, if applicable.
-        if (Configurable.class.isAssignableFrom(cls))
-            c.remove("Configuration");
-        if (GenericConfigurable.class.isAssignableFrom(cls))
-            c.remove("Into");
-        
-        return c;
-    }
-
-    /**
-     * Turn a set of properties into a comma-separated string.
-     */
-    public static String serializeProperties(Map map) {
-        if (map == null || map.isEmpty())
-            return null;
-
-        StringBuffer buf = new StringBuffer();
-        Map.Entry entry;
-        String val;
-        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
-            entry = (Map.Entry) itr.next();
-            if (buf.length() > 0)
-                buf.append(", ");
-            buf.append(entry.getKey()).append('=');
-            val = String.valueOf(entry.getValue());
-            if (val.indexOf(',') != -1)
-                buf.append('"').append(val).append('"');
-            else
-                buf.append(val);
-        }
-        return buf.toString();
-    }
-
-    /**
-     * Parse a set of properties from a comma-separated string.
-     */
-    public static Options parseProperties(String properties) {
-        Options opts = new Options();
-        properties = StringUtils.trimToNull(properties);
-        if (properties == null)
-            return opts;
-
-        try {
-            String[] props = Strings.split(properties, ",", 0);
-            int idx;
-            char quote;
-            String prop;
-            String val;
-            for (int i = 0; i < props.length; i++) {
-                idx = props[i].indexOf('=');
-                if (idx == -1) {
-                    // if the key is not assigned to any value, set the
-                    // value to the same thing as the key, and continue.
-                    // This permits GenericConfigurable instances to
-                    // behave meaningfully. We might consider setting the
-                    // value to some well-known "value was not set, but
-                    // key is present" string so that instances getting
-                    // values injected can differentiate between a mentioned
-                    // property and one set to a particular value.
-                    prop = props[i];
-                    val = prop;
-                } else {
-                    prop = props[i].substring(0, idx).trim();
-                    val = props[i].substring(idx + 1).trim();
-                }
-
-                // if the value is quoted, read until the end quote
-                if (((val.startsWith("\"") && val.endsWith("\""))
-                    || (val.startsWith("'") && val.endsWith("'")))
-                    && val.length() > 1)
-                    val = val.substring(1, val.length() - 1);
-                else if (val.startsWith("\"") || val.startsWith("'")) {
-                    quote = val.charAt(0);
-                    StringBuffer buf = new StringBuffer(val.substring(1));
-                    int quotIdx;
-                    while (++i < props.length) {
-                        buf.append(",");
-
-                        quotIdx = props[i].indexOf(quote);
-                        if (quotIdx != -1) {
-                            buf.append(props[i].substring(0, quotIdx));
-                            if (quotIdx + 1 < props[i].length())
-                                buf.append(props[i].substring(quotIdx + 1));
-                            break;
-                        } else
-                            buf.append(props[i]);
-                    }
-                    val = buf.toString();
-                }
-                opts.put(prop, val);
-            }
-            return opts;
-        } catch (RuntimeException re) {
-            throw new ParseException(_loc.get("prop-parse", properties), re);
-        }
-    }
-
-    /**
-     * Looks up the given name in JNDI. If the name is null, null is returned.
-     */
-    public static Object lookup(String name, String userKey, Log log) {
-        if (StringUtils.isEmpty(name))
-            return null;
-
-        Context ctx = null;
-        try {
-            ctx = new InitialContext();
-            Object result = ctx.lookup(name);
-            if (result == null && log != null && log.isWarnEnabled())
-            	log.warn(_loc.get("jndi-lookup-failed", userKey, name));
-            return result;
-        } catch (NamingException ne) {
-            throw new NestableRuntimeException(
-                _loc.get("naming-err", name).getMessage(), ne);
-        } finally {
-            if (ctx != null)
-                try { ctx.close(); } catch (Exception e) {}
-        }
-    }
-
-    /**
-     * Test whether the map contains the given partial key, prefixed with any
-     * possible configuration prefix.
-     */
-    public static boolean containsProperty(String partialKey, Map props) {
-        if (partialKey == null || props == null || props.isEmpty())
-            return false;
-        else
-            return props.containsKey(
-                ProductDerivations.getConfigurationKey(partialKey, props));
-    }
-
-    /**
-     * Get the property under the given partial key, prefixed with any possible
-     * configuration prefix.
-     */
-    public static Object getProperty(String partialKey, Map m) {
-        if (partialKey == null || m == null || m.isEmpty())
-            return null;
-        else 
-            return m.get(ProductDerivations.getConfigurationKey(partialKey, m));
-    }
-
-    /**
-     * Remove the property under the given partial key, prefixed with any
-     * possible configuration prefix.
-     */
-    public static Object removeProperty(String partialKey, Map props) {
-        if (partialKey == null || props == null || props.isEmpty())
-            return null;
-        if (containsProperty(partialKey, props))
-            return props.remove(ProductDerivations.getConfigurationKey(
-                partialKey, props));
-        else
-            return null;
-    }
-
-    /**
-     * Runs <code>runnable</code> against all the anchors in the configuration
-     * pointed to by <code>opts</code>. Each invocation gets a fresh clone of 
-     * <code>opts</code> with the <code>properties</code> option set
-     * appropriately.
-     *
-     * @since 1.1.0
-     */
-    public static boolean runAgainstAllAnchors(Options opts,
-        Configurations.Runnable runnable) {
-        if (opts.containsKey("help") || opts.containsKey("-help")) {
-            return false;
-        }
-        List anchors =
-            Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
-
-        // We use 'properties' below; get rid of 'p' to avoid conflicts. This
-        // relies on knowing what getFullyQualifiedAnchorsInPropertiesLocation
-        // looks for.
-        if (opts.containsKey("p"))
-            opts.remove("p");
-
-        boolean ret = true;
-        if (anchors.size() == 0) {
-            ret = launchRunnable(opts, runnable);
-        } else {
-            for (Iterator iter = anchors.iterator(); iter.hasNext(); ) { 
-                Options clonedOptions = (Options) opts.clone();
-                clonedOptions.setProperty("properties", iter.next().toString());
-                ret &= launchRunnable(clonedOptions, runnable);
-            }
-        }
-        return ret;
-    }
-
-    private static boolean launchRunnable(Options opts,
-        Configurations.Runnable runnable) {
-        boolean ret = true;
-        try {
-            ret = runnable.run(opts);
-        } catch (Exception e) {
-            if (!(e instanceof RuntimeException))
-                throw new RuntimeException(e);
-            else
-                throw (RuntimeException) e;
-        }
-        return ret;
-    }
-
-    public interface Runnable {
-        public boolean run(Options opts) throws Exception;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.conf;
+
+import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.TreeSet;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.exception.NestableRuntimeException;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.lib.util.ParseException;
+import org.apache.openjpa.lib.util.StringDistance;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+import serp.util.Strings;
+
+/**
+ * Utility methods dealing with configuration.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public class Configurations {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (Configurations.class);
+    
+    private static final ConcurrentReferenceHashMap _loaders = new
+        ConcurrentReferenceHashMap(ConcurrentReferenceHashMap.WEAK, 
+                ConcurrentReferenceHashMap.HARD);
+
+    private static final Object NULL_LOADER = "null-loader";
+
+    /**
+     * Return the class name from the given plugin string, or null if none.
+     */
+    public static String getClassName(String plugin) {
+        return getPluginComponent(plugin, true);
+    }
+
+    /**
+     * Return the properties part of the given plugin string, or null if none.
+     */
+    public static String getProperties(String plugin) {
+        return getPluginComponent(plugin, false);
+    }
+
+    /**
+     * Return either the class name or properties string from a plugin string.
+     */
+    private static String getPluginComponent(String plugin, boolean clsName) {
+        if (plugin != null)
+            plugin = plugin.trim();
+        if (StringUtils.isEmpty(plugin))
+            return null;
+
+        int openParen = -1;
+        if (plugin.charAt(plugin.length() - 1) == ')')
+            openParen = plugin.indexOf('(');
+        if (openParen == -1) {
+            int eq = plugin.indexOf('=');
+            if (eq == -1)
+                return (clsName) ? plugin : null;
+            return (clsName) ? null : plugin;
+        }
+
+        // clsName(props) form
+        if (clsName)
+            return plugin.substring(0, openParen).trim();
+        String prop = plugin.substring(openParen + 1,
+            plugin.length() - 1).trim();
+        return (prop.length() == 0) ? null : prop;
+    }
+
+    /**
+     * Combine the given class name and properties into a plugin string.
+     */
+    public static String getPlugin(String clsName, String props) {
+        if (StringUtils.isEmpty(clsName))
+            return props;
+        if (StringUtils.isEmpty(props))
+            return clsName;
+        return clsName + "(" + props + ")";
+    }
+
+    /**
+     * Return a plugin string that combines the properties of the given plugin
+     * strings, where properties of <code>override</code> will override the
+     * same properties of <code>orig</code>.
+     */
+    public static String combinePlugins(String orig, String override) {
+        if (StringUtils.isEmpty(orig))
+            return override;
+        if (StringUtils.isEmpty(override))
+            return orig;
+
+        String origCls = getClassName(orig);
+        String overrideCls = getClassName(override);
+        String cls;
+        if (StringUtils.isEmpty(origCls))
+            cls = overrideCls;
+        else if (StringUtils.isEmpty(overrideCls))
+            cls = origCls;
+        else if (!origCls.equals(overrideCls))
+            return override; // completely different plugin
+        else
+            cls = origCls;
+
+        String origProps = getProperties(orig);
+        String overrideProps = getProperties(override);
+        if (StringUtils.isEmpty(origProps))
+            return getPlugin(cls, overrideProps);
+        if (StringUtils.isEmpty(overrideProps))
+            return getPlugin(cls, origProps);
+
+        Properties props = parseProperties(origProps);
+        props.putAll(parseProperties(overrideProps));
+        return getPlugin(cls, serializeProperties(props)); 
+    }
+
+    /**
+     * Create the instance with the given class name, using the given
+     * class loader. No configuration of the instance is performed by
+     * this method.
+     */
+    public static Object newInstance(String clsName, ClassLoader loader) {
+        return newInstance(clsName, null, null, loader, true);
+    }
+
+    /**
+     * Create and configure an instance with the given class name and
+     * properties.
+     */
+    public static Object newInstance(String clsName, Configuration conf,
+        String props, ClassLoader loader) {
+        Object obj = newInstance(clsName, null, conf, loader, true);
+        configureInstance(obj, conf, props);
+        return obj;
+    }
+
+    /**
+     * Helper method used by members of this package to instantiate plugin
+     * values.
+     */
+    static Object newInstance(String clsName, Value val, Configuration conf,
+        ClassLoader loader, boolean fatal) {
+        if (StringUtils.isEmpty(clsName))
+            return null;
+
+        Class cls = null; 
+
+        while (cls == null) {
+            // can't have a null reference in the map, so use symbolic
+            // constant as key
+            Object key = loader == null ? NULL_LOADER : loader;
+            Map loaderCache = (Map) _loaders.get(key);
+            if (loaderCache == null) { // We don't have a cache for this loader.
+                loaderCache = new ConcurrentHashMap();
+                _loaders.put(key, loaderCache);
+            } else {  // We have a cache for this loader.
+                cls = (Class) loaderCache.get(clsName);
+            }
+
+            if (cls == null) {
+                try {
+                    cls = Strings.toClass(clsName, findDerivedLoader(conf,
+                            loader));
+                    loaderCache.put(clsName, cls);
+                } catch (RuntimeException re) {
+                    if (loader != null)  // Try one more time with loader=null
+                        loader = null;
+                    else {
+                        if (val != null)
+                            re = getCreateException(clsName, val, re);
+                        if (fatal)
+                            throw re;
+                        Log log = (conf == null) ? null : conf
+                                .getConfigurationLog();
+                        if (log != null && log.isErrorEnabled())
+                            log.error(_loc
+                                    .get("plugin-creation-exception", val), re);
+                        return null;
+                    }
+                }
+            }
+        }
+
+        try {
+            return AccessController.doPrivileged(
+                J2DoPrivHelper.newInstanceAction(cls));
+        } catch (Exception e) {
+            if (e instanceof PrivilegedActionException) {
+                e = ((PrivilegedActionException) e).getException();   
+            }
+            RuntimeException re = new NestableRuntimeException(_loc.get
+                ("obj-create", cls).getMessage(), e);
+            if (fatal)
+                throw re;
+            Log log = (conf == null) ? null : conf.getConfigurationLog();
+            if (log != null && log.isErrorEnabled())
+                log.error(_loc.get("plugin-creation-exception", val), re);
+            return null;
+        }
+    }
+
+    /**
+     * Attempt to find a derived loader that delegates to our target loader.
+     * This allows application loaders that delegate appropriately for known
+     * classes first crack at class names.
+     */
+    private static ClassLoader findDerivedLoader(Configuration conf,
+        ClassLoader loader) {
+        // we always prefer the thread loader, because it's the only thing we
+        // can access that isn't bound to the OpenJPA classloader, unless
+        // the conf object is of a custom class
+        ClassLoader ctxLoader = (ClassLoader) AccessController.doPrivileged(
+            J2DoPrivHelper.getContextClassLoaderAction());
+        if (loader == null) {
+            if (ctxLoader != null)
+                return ctxLoader;
+            if (conf != null)
+                return (ClassLoader) AccessController.doPrivileged(
+                    J2DoPrivHelper.getClassLoaderAction(conf.getClass())); 
+            return Configurations.class.getClassLoader();
+        }
+
+        for (ClassLoader parent = ctxLoader; parent != null; 
+            parent = (ClassLoader) AccessController.doPrivileged(
+                J2DoPrivHelper.getParentAction(parent))) {
+            if (parent == loader)
+                return ctxLoader;
+        }
+        if (conf != null) {
+            for (ClassLoader parent = (ClassLoader)
+                AccessController.doPrivileged(
+                    J2DoPrivHelper.getClassLoaderAction(conf.getClass())); 
+                parent != null; 
+                parent = (ClassLoader) AccessController.doPrivileged(
+                    J2DoPrivHelper.getParentAction(parent))) {
+                if (parent == loader)
+                    return (ClassLoader) AccessController.doPrivileged(
+                        J2DoPrivHelper.getClassLoaderAction(conf.getClass())); 
+            }
+        }
+        return loader;
+    }
+
+    /**
+     * Return a List<String> of all the fully-qualified anchors specified in the
+     * properties location listed in <code>opts</code>. If no properties
+     * location is listed in <code>opts</code>, this returns whatever the
+     * product derivations can find in their default configurations.
+     * If the properties location specified in <code>opts</code> already
+     * contains an anchor spec, this returns that anchor. Note that in this
+     * fully-qualified-input case, the logic involving product derivations
+     * and resource parsing is short-circuited, so this method
+     * should not be used as a means to test that a particular anchor is
+     * defined in a given location by invoking with a fully-qualified anchor.
+     *
+     * This does not mutate <code>opts</code>.
+     *
+     * @since 1.1.0
+     */
+    public static List getFullyQualifiedAnchorsInPropertiesLocation(
+        Options opts) {
+        String props = opts.getProperty("properties", "p", null);
+        if (props != null) {
+            int anchorPosition = props.indexOf("#");
+            if (anchorPosition > -1)
+                return Arrays.asList(new String[] { props });
+        }
+
+        return ProductDerivations.getFullyQualifiedAnchorsInPropertiesLocation(
+            props);
+    }
+
+    /**
+     * Set the given {@link Configuration} instance from the command line
+     * options provided. All property names of the given configuration are
+     * recognized; additionally, if a <code>properties</code> or
+     * <code>p</code> argument exists, the resource it
+     * points to will be loaded and set into the given configuration instance.
+     * It can point to either a file or a resource name.
+     */
+    public static void populateConfiguration(Configuration conf, Options opts) {
+        String props = opts.removeProperty("properties", "p", null);
+        ConfigurationProvider provider;
+        if (!StringUtils.isEmpty(props)) {
+            String path = props;
+            String anchor = null;
+            int idx = path.lastIndexOf('#');
+            if (idx != -1) {
+                if (idx < path.length() - 1)
+                    anchor = path.substring(idx + 1);
+                path = path.substring(0, idx);
+                if (path.length() == 0)
+                    throw new MissingResourceException(_loc.get("anchor-only",
+                        props).getMessage(), Configurations.class.getName(), 
+                        props);
+            }
+
+            File file = new File(path);
+            if (((Boolean) AccessController.doPrivileged(J2DoPrivHelper
+                .isFileAction(file))).booleanValue())
+                provider = ProductDerivations.load(file, anchor, null);
+            else {
+                file = new File("META-INF" + File.separatorChar + path);
+                if (((Boolean) AccessController.doPrivileged(J2DoPrivHelper
+                    .isFileAction(file))).booleanValue())
+                    provider = ProductDerivations.load(file, anchor, null);
+                else
+                    provider = ProductDerivations.load(path, anchor, null);
+            }
+            if (provider != null)
+                provider.setInto(conf);
+            else
+                throw new MissingResourceException(_loc.get("no-provider",
+                    props).getMessage(), Configurations.class.getName(), 
+                    props);
+        } else {
+            provider = ProductDerivations.loadDefaults(null);
+            if (provider != null)
+                provider.setInto(conf);
+        }
+        opts.setInto(conf);
+    }
+
+    /**
+     * Helper method to throw an informative description on instantiation error.
+     */
+    private static RuntimeException getCreateException(String clsName,
+        Value val, Exception e) {
+        // re-throw the exception with some better information
+        final String msg;
+        final Object[] params;
+
+        String alias = val.alias(clsName);
+        String[] aliases = val.getAliases();
+        String[] keys;
+        if (aliases.length == 0)
+            keys = aliases;
+        else {
+            keys = new String[aliases.length / 2];
+            for (int i = 0; i < aliases.length; i += 2)
+                keys[i / 2] = aliases[i];
+        }
+
+        String closest;
+        if (keys.length == 0) {
+            msg = "invalid-plugin";
+            params = new Object[]{ val.getProperty(), alias, e.toString(), };
+        } else if ((closest = StringDistance.getClosestLevenshteinDistance
+            (alias, keys, 0.5f)) == null) {
+            msg = "invalid-plugin-aliases";
+            params = new Object[]{
+                val.getProperty(), alias, e.toString(),
+                new TreeSet(Arrays.asList(keys)), };
+        } else {
+            msg = "invalid-plugin-aliases-hint";
+            params = new Object[]{
+                val.getProperty(), alias, e.toString(),
+                new TreeSet(Arrays.asList(keys)), closest, };
+        }
+        return new ParseException(_loc.get(msg, params), e);
+    }
+
+    /**
+     * Configures the given object with the given properties by
+     * matching the properties string to the object's setter
+     * methods. The properties string should be in the form
+     * "prop1=val1, prop2=val2 ...". Does not validate that setter
+     * methods exist for the properties.
+     *
+     * @throws RuntimeException on configuration error
+     */
+    public static void configureInstance(Object obj, Configuration conf,
+        String properties) {
+        configureInstance(obj, conf, properties, null);
+    }
+
+    /**
+     * Configures the given object with the given properties by
+     * matching the properties string to the object's setter
+     * methods. The properties string should be in the form
+     * "prop1=val1, prop2=val2 ...". Validates that setter methods
+     * exist for the properties.
+     *
+     * @throws RuntimeException on configuration error
+     */
+    public static void configureInstance(Object obj, Configuration conf,
+        String properties, String configurationName) {
+        if (obj == null)
+            return;
+
+        Properties props = null;
+        if (!StringUtils.isEmpty(properties))
+            props = parseProperties(properties);
+        configureInstance(obj, conf, props, configurationName);
+    }
+
+    /**
+     * Configures the given object with the given properties by
+     * matching the properties string to the object's setter
+     * methods. Does not validate that setter methods exist for the properties.
+     *
+     * @throws RuntimeException on configuration error
+     */
+    public static void configureInstance(Object obj, Configuration conf,
+        Properties properties) {
+        configureInstance(obj, conf, properties, null);
+    }
+
+    /**
+     * Configures the given object with the given properties by
+     * matching the properties string to the object's setter
+     * methods. If <code>configurationName</code> is
+     * non-<code>null</code>, validates that setter methods exist for
+     * the properties.
+     *
+     * @throws RuntimeException on configuration error
+     */
+    public static void configureInstance(Object obj, Configuration conf,
+        Properties properties, String configurationName) {
+        if (obj == null)
+            return;
+
+        Options opts;
+        if (properties instanceof Options)
+            opts = (Options) properties;
+        else { 
+            opts = new Options();
+            if (properties != null)
+                opts.putAll(properties);
+        }
+
+        Configurable configurable = null;
+        if (conf != null && obj instanceof Configurable)
+            configurable = (Configurable) obj;
+
+        if (configurable != null) {
+            configurable.setConfiguration(conf);
+            configurable.startConfiguration();
+        }
+        Options invalidEntries = opts.setInto(obj);
+        if (obj instanceof GenericConfigurable)
+            ((GenericConfigurable) obj).setInto(invalidEntries);
+
+		if (!invalidEntries.isEmpty() && configurationName != null) {
+			Localizer.Message msg = null;
+			String first = (String) invalidEntries.keySet().iterator().next();
+			if (invalidEntries.keySet().size() == 1 &&
+				first.indexOf('.') == -1) {
+				// if there's just one misspelling and this is not a
+				// path traversal, check for near misses.
+				Collection options = findOptionsFor(obj.getClass());
+				String close = StringDistance.getClosestLevenshteinDistance
+					(first, options, 0.75f);
+				if (close != null)
+					msg = _loc.get("invalid-config-param-hint", new Object[]{
+						configurationName, obj.getClass(), first, close,
+						options, });
+			}
+
+            if (msg == null) {
+                msg = _loc.get("invalid-config-params", new String[]{
+                    configurationName, obj.getClass().getName(),
+                    invalidEntries.keySet().toString(),
+                    findOptionsFor(obj.getClass()).toString(), });
+            }
+            throw new ParseException(msg);
+        }
+        if (configurable != null)
+            configurable.endConfiguration();
+    }
+
+    private static Collection findOptionsFor(Class cls) {
+        Collection c = Options.findOptionsFor(cls);
+        
+        // remove Configurable.setConfiguration() and 
+        // GenericConfigurable.setInto() from the set, if applicable.
+        if (Configurable.class.isAssignableFrom(cls))
+            c.remove("Configuration");
+        if (GenericConfigurable.class.isAssignableFrom(cls))
+            c.remove("Into");
+        
+        return c;
+    }
+
+    /**
+     * Turn a set of properties into a comma-separated string.
+     */
+    public static String serializeProperties(Map map) {
+        if (map == null || map.isEmpty())
+            return null;
+
+        StringBuffer buf = new StringBuffer();
+        Map.Entry entry;
+        String val;
+        for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            if (buf.length() > 0)
+                buf.append(", ");
+            buf.append(entry.getKey()).append('=');
+            val = String.valueOf(entry.getValue());
+            if (val.indexOf(',') != -1)
+                buf.append('"').append(val).append('"');
+            else
+                buf.append(val);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Parse a set of properties from a comma-separated string.
+     */
+    public static Options parseProperties(String properties) {
+        Options opts = new Options();
+        properties = StringUtils.trimToNull(properties);
+        if (properties == null)
+            return opts;
+
+        try {
+            String[] props = Strings.split(properties, ",", 0);
+            int idx;
+            char quote;
+            String prop;
+            String val;
+            for (int i = 0; i < props.length; i++) {
+                idx = props[i].indexOf('=');
+                if (idx == -1) {
+                    // if the key is not assigned to any value, set the
+                    // value to the same thing as the key, and continue.
+                    // This permits GenericConfigurable instances to
+                    // behave meaningfully. We might consider setting the
+                    // value to some well-known "value was not set, but
+                    // key is present" string so that instances getting
+                    // values injected can differentiate between a mentioned
+                    // property and one set to a particular value.
+                    prop = props[i];
+                    val = prop;
+                } else {
+                    prop = props[i].substring(0, idx).trim();
+                    val = props[i].substring(idx + 1).trim();
+                }
+
+                // if the value is quoted, read until the end quote
+                if (((val.startsWith("\"") && val.endsWith("\""))
+                    || (val.startsWith("'") && val.endsWith("'")))
+                    && val.length() > 1)
+                    val = val.substring(1, val.length() - 1);
+                else if (val.startsWith("\"") || val.startsWith("'")) {
+                    quote = val.charAt(0);
+                    StringBuffer buf = new StringBuffer(val.substring(1));
+                    int quotIdx;
+                    while (++i < props.length) {
+                        buf.append(",");
+
+                        quotIdx = props[i].indexOf(quote);
+                        if (quotIdx != -1) {
+                            buf.append(props[i].substring(0, quotIdx));
+                            if (quotIdx + 1 < props[i].length())
+                                buf.append(props[i].substring(quotIdx + 1));
+                            break;
+                        } else
+                            buf.append(props[i]);
+                    }
+                    val = buf.toString();
+                }
+                opts.put(prop, val);
+            }
+            return opts;
+        } catch (RuntimeException re) {
+            throw new ParseException(_loc.get("prop-parse", properties), re);
+        }
+    }
+
+    /**
+     * Looks up the given name in JNDI. If the name is null, null is returned.
+     */
+    public static Object lookup(String name, String userKey, Log log) {
+        if (StringUtils.isEmpty(name))
+            return null;
+
+        Context ctx = null;
+        try {
+            ctx = new InitialContext();
+            Object result = ctx.lookup(name);
+            if (result == null && log != null && log.isWarnEnabled())
+            	log.warn(_loc.get("jndi-lookup-failed", userKey, name));
+            return result;
+        } catch (NamingException ne) {
+            throw new NestableRuntimeException(
+                _loc.get("naming-err", name).getMessage(), ne);
+        } finally {
+            if (ctx != null)
+                try { ctx.close(); } catch (Exception e) {}
+        }
+    }
+
+    /**
+     * Test whether the map contains the given partial key, prefixed with any
+     * possible configuration prefix.
+     */
+    public static boolean containsProperty(String partialKey, Map props) {
+        if (partialKey == null || props == null || props.isEmpty())
+            return false;
+        else
+            return props.containsKey(
+                ProductDerivations.getConfigurationKey(partialKey, props));
+    }
+
+    /**
+     * Get the property under the given partial key, prefixed with any possible
+     * configuration prefix.
+     */
+    public static Object getProperty(String partialKey, Map m) {
+        if (partialKey == null || m == null || m.isEmpty())
+            return null;
+        else 
+            return m.get(ProductDerivations.getConfigurationKey(partialKey, m));
+    }
+
+    /**
+     * Remove the property under the given partial key, prefixed with any
+     * possible configuration prefix.
+     */
+    public static Object removeProperty(String partialKey, Map props) {
+        if (partialKey == null || props == null || props.isEmpty())
+            return null;
+        if (containsProperty(partialKey, props))
+            return props.remove(ProductDerivations.getConfigurationKey(
+                partialKey, props));
+        else
+            return null;
+    }
+
+    /**
+     * Runs <code>runnable</code> against all the anchors in the configuration
+     * pointed to by <code>opts</code>. Each invocation gets a fresh clone of 
+     * <code>opts</code> with the <code>properties</code> option set
+     * appropriately.
+     *
+     * @since 1.1.0
+     */
+    public static boolean runAgainstAllAnchors(Options opts,
+        Configurations.Runnable runnable) {
+        if (opts.containsKey("help") || opts.containsKey("-help")) {
+            return false;
+        }
+        List anchors =
+            Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
+
+        // We use 'properties' below; get rid of 'p' to avoid conflicts. This
+        // relies on knowing what getFullyQualifiedAnchorsInPropertiesLocation
+        // looks for.
+        if (opts.containsKey("p"))
+            opts.remove("p");
+
+        boolean ret = true;
+        if (anchors.size() == 0) {
+            ret = launchRunnable(opts, runnable);
+        } else {
+            for (Iterator iter = anchors.iterator(); iter.hasNext(); ) { 
+                Options clonedOptions = (Options) opts.clone();
+                clonedOptions.setProperty("properties", iter.next().toString());
+                ret &= launchRunnable(clonedOptions, runnable);
+            }
+        }
+        return ret;
+    }
+
+    private static boolean launchRunnable(Options opts,
+        Configurations.Runnable runnable) {
+        boolean ret = true;
+        try {
+            ret = runnable.run(opts);
+        } catch (Exception e) {
+            if (!(e instanceof RuntimeException))
+                throw new RuntimeException(e);
+            else
+                throw (RuntimeException) e;
+        }
+        return ret;
+    }
+
+    public interface Runnable {
+        public boolean run(Options opts) throws Exception;
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ObjectValue.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ObjectValue.java
index 9357849..55d9a26 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ObjectValue.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ObjectValue.java
@@ -1,138 +1,138 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.conf;
-
-import java.security.AccessController;
-
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.ReferenceMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-
-/**
- * An object {@link Value}.
- *
- * @author Abe White
- */
-public class ObjectValue extends Value {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (ObjectValue.class);
-
-    // cache the types' classloader
-    private static ConcurrentReferenceHashMap _classloaderCache =
-        new ConcurrentReferenceHashMap(ReferenceMap.HARD, ReferenceMap.WEAK);
-
-    private Object _value = null;
-
-    public ObjectValue(String prop) {
-        super(prop);
-    }
-
-    /**
-     * The internal value.
-     */
-    public Object get() {
-        return _value;
-    }
-
-    /**
-     * The internal value.
-     */
-    public void set(Object obj) {
-        set(obj, false);
-    }
-
-    /**
-     * The internal value.
-     *
-     * @param derived if true, this value was derived from other properties
-     */
-    public void set(Object obj, boolean derived) {
-        if (!derived) assertChangeable();
-        Object oldValue = _value;
-        _value = obj;
-        if (!derived && !ObjectUtils.equals(obj, oldValue)) {
-            objectChanged();
-            valueChanged();
-        }
-    }
-
-    /**
-     * Instantiate the object as an instance of the given class. Equivalent
-     * to <code>instantiate(type, conf, true)</code>.
-     */
-    public Object instantiate(Class type, Configuration conf) {
-        return instantiate(type, conf, true);
-    }
-
-    /**
-     * Instantiate the object as an instance of the given class.
-     */
-    public Object instantiate(Class type, Configuration conf, boolean fatal) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Allow subclasses to instantiate additional plugins. This method does
-     * not perform configuration.
-     */
-    public Object newInstance(String clsName, Class type, Configuration conf,
-            boolean fatal) {
-        ClassLoader cl = (ClassLoader) _classloaderCache.get(type);
-        if (cl == null) {
-            cl = (ClassLoader) AccessController.doPrivileged(
-                J2DoPrivHelper.getClassLoaderAction(type));
-            if (cl == null) {  // System classloader is returned as null
-                cl = (ClassLoader) AccessController.doPrivileged(
-                    J2DoPrivHelper.getSystemClassLoaderAction()); 
-            }
-            _classloaderCache.put(type, cl);
-        }
-        return Configurations.newInstance(clsName, this, conf, cl, fatal);
-    }
-
-    public Class getValueType() {
-        return Object.class;
-    }
-
-    /**
-     * Implement this method to synchronize internal data with the new
-     * object value.
-     */
-    protected void objectChanged() {
-    }
-
-    protected String getInternalString() {
-        return null;
-    }
-
-    protected void setInternalString(String str) {
-        if (str == null)
-            set(null);
-        else
-            throw new IllegalArgumentException(_loc.get("cant-set-string",
-                getProperty()).getMessage());
-    }
-
-    protected void setInternalObject(Object obj) {
-        set(obj);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.conf;
+
+import java.security.AccessController;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.ReferenceMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+
+/**
+ * An object {@link Value}.
+ *
+ * @author Abe White
+ */
+public class ObjectValue extends Value {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (ObjectValue.class);
+
+    // cache the types' classloader
+    private static ConcurrentReferenceHashMap _classloaderCache =
+        new ConcurrentReferenceHashMap(ReferenceMap.HARD, ReferenceMap.WEAK);
+
+    private Object _value = null;
+
+    public ObjectValue(String prop) {
+        super(prop);
+    }
+
+    /**
+     * The internal value.
+     */
+    public Object get() {
+        return _value;
+    }
+
+    /**
+     * The internal value.
+     */
+    public void set(Object obj) {
+        set(obj, false);
+    }
+
+    /**
+     * The internal value.
+     *
+     * @param derived if true, this value was derived from other properties
+     */
+    public void set(Object obj, boolean derived) {
+        if (!derived) assertChangeable();
+        Object oldValue = _value;
+        _value = obj;
+        if (!derived && !ObjectUtils.equals(obj, oldValue)) {
+            objectChanged();
+            valueChanged();
+        }
+    }
+
+    /**
+     * Instantiate the object as an instance of the given class. Equivalent
+     * to <code>instantiate(type, conf, true)</code>.
+     */
+    public Object instantiate(Class type, Configuration conf) {
+        return instantiate(type, conf, true);
+    }
+
+    /**
+     * Instantiate the object as an instance of the given class.
+     */
+    public Object instantiate(Class type, Configuration conf, boolean fatal) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Allow subclasses to instantiate additional plugins. This method does
+     * not perform configuration.
+     */
+    public Object newInstance(String clsName, Class type, Configuration conf,
+            boolean fatal) {
+        ClassLoader cl = (ClassLoader) _classloaderCache.get(type);
+        if (cl == null) {
+            cl = (ClassLoader) AccessController.doPrivileged(
+                J2DoPrivHelper.getClassLoaderAction(type));
+            if (cl == null) {  // System classloader is returned as null
+                cl = (ClassLoader) AccessController.doPrivileged(
+                    J2DoPrivHelper.getSystemClassLoaderAction()); 
+            }
+            _classloaderCache.put(type, cl);
+        }
+        return Configurations.newInstance(clsName, this, conf, cl, fatal);
+    }
+
+    public Class getValueType() {
+        return Object.class;
+    }
+
+    /**
+     * Implement this method to synchronize internal data with the new
+     * object value.
+     */
+    protected void objectChanged() {
+    }
+
+    protected String getInternalString() {
+        return null;
+    }
+
+    protected void setInternalString(String str) {
+        if (str == null)
+            set(null);
+        else
+            throw new IllegalArgumentException(_loc.get("cant-set-string",
+                getProperty()).getMessage());
+    }
+
+    protected void setInternalObject(Object obj) {
+        set(obj);
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/BreadthFirstWalk.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/BreadthFirstWalk.java
index 16f643a..e40e160 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/BreadthFirstWalk.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/BreadthFirstWalk.java
@@ -1,145 +1,145 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * <p>Performs a breadth-first walk of a given {@link Graph},
- * notifying visitors as it sees each node.  See the BFS algorithm
- * in the book 'Introduction to Algorithms' by Cormen, Leiserson, and
- * Rivest.</p>
- * <p/>
- * <p>Each {@link GraphVisitor} will be notified when a node
- * is colored black (nodeVisited), edge seen (edgeVisited),
- * and a node is seen for the first time, i.e. colored gray (nodeSeen).</p>
- *
- * @author Steve Kim
- * @since 1.0.0
- * @nojavadoc
- */
-public class BreadthFirstWalk {
-
-    private final Graph _graph;
-    private final Set _visitors = new HashSet();
-    private final List _queue = new LinkedList();
-    private final Map _nodeInfo = new HashMap();
-
-    public BreadthFirstWalk(Graph graph) {
-        _graph = graph;
-    }
-
-    /**
-     * Begins the breadth first traversal.
-     */
-    public void walk() {
-        _queue.clear();
-        _nodeInfo.clear();
-
-        Collection nodes = _graph.getNodes();
-        for (Iterator itr = nodes.iterator(); itr.hasNext();)
-            _nodeInfo.put(itr.next(), new NodeInfo());
-
-        Object node;
-        NodeInfo info;
-        for (Iterator itr = nodes.iterator(); itr.hasNext();) {
-            node = itr.next();
-            info = (NodeInfo) _nodeInfo.get(node);
-            if (info.color == NodeInfo.COLOR_WHITE)
-                enqueue(node, info);
-            processQueue();
-        }
-    }
-
-    /**
-     * Process the queue to see what data needs to be obtained.
-     */
-    private void processQueue() {
-        Object node;
-        Object other;
-        NodeInfo info;
-        NodeInfo otherInfo;
-        Collection edges;
-        Edge edge;
-        while (_queue.size() > 0) {
-            node = _queue.remove(0);
-            info = (NodeInfo) _nodeInfo.get(node);
-            visit(node, info);
-
-            edges = _graph.getEdgesFrom(node);
-            for (Iterator itr = edges.iterator(); itr.hasNext();) {
-                edge = (Edge) itr.next();
-                edgeVisited(edge);
-                other = edge.getOther(node);
-                otherInfo = (NodeInfo) _nodeInfo.get(other);
-                if (otherInfo.color == NodeInfo.COLOR_WHITE)
-                    enqueue(other, otherInfo);
-            }
-        }
-    }
-
-    /**
-     * Push the given node onto the queue to be processed.
-     * Notify visitors.
-     */
-    protected void enqueue(Object node, NodeInfo info) {
-        _queue.add(node);
-        info.color = NodeInfo.COLOR_GRAY;
-        for (Iterator i = _visitors.iterator(); i.hasNext();)
-            ((GraphVisitor) i.next()).nodeSeen(node);
-    }
-
-    /**
-     * Visit the node.  Mark the node black and notify visitors.
-     */
-    protected void visit(Object node, NodeInfo info) {
-        info.color = NodeInfo.COLOR_BLACK;
-        for (Iterator i = _visitors.iterator(); i.hasNext();)
-            ((GraphVisitor) i.next()).nodeVisited(node);
-    }
-
-    /**
-     * An edge is seen.  Notify visitors.
-     */
-    protected void edgeVisited(Edge edge) {
-        for (Iterator i = _visitors.iterator(); i.hasNext();)
-            ((GraphVisitor) i.next()).edgeVisited(edge);
-    }
-
-    /**
-     * add a {@link GraphVisitor} to be notified during breadth first search.
-     */
-    public void addGraphVisitor(GraphVisitor visitor) {
-        _visitors.add(visitor);
-    }
-
-    /**
-     * remove a given {@link GraphVisitor} from the listener set.
-     */
-    public void removeGraphVisitor(GraphVisitor visitor) {
-        _visitors.remove(visitor);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <p>Performs a breadth-first walk of a given {@link Graph},
+ * notifying visitors as it sees each node.  See the BFS algorithm
+ * in the book 'Introduction to Algorithms' by Cormen, Leiserson, and
+ * Rivest.</p>
+ * <p/>
+ * <p>Each {@link GraphVisitor} will be notified when a node
+ * is colored black (nodeVisited), edge seen (edgeVisited),
+ * and a node is seen for the first time, i.e. colored gray (nodeSeen).</p>
+ *
+ * @author Steve Kim
+ * @since 1.0.0
+ * @nojavadoc
+ */
+public class BreadthFirstWalk {
+
+    private final Graph _graph;
+    private final Set _visitors = new HashSet();
+    private final List _queue = new LinkedList();
+    private final Map _nodeInfo = new HashMap();
+
+    public BreadthFirstWalk(Graph graph) {
+        _graph = graph;
+    }
+
+    /**
+     * Begins the breadth first traversal.
+     */
+    public void walk() {
+        _queue.clear();
+        _nodeInfo.clear();
+
+        Collection nodes = _graph.getNodes();
+        for (Iterator itr = nodes.iterator(); itr.hasNext();)
+            _nodeInfo.put(itr.next(), new NodeInfo());
+
+        Object node;
+        NodeInfo info;
+        for (Iterator itr = nodes.iterator(); itr.hasNext();) {
+            node = itr.next();
+            info = (NodeInfo) _nodeInfo.get(node);
+            if (info.color == NodeInfo.COLOR_WHITE)
+                enqueue(node, info);
+            processQueue();
+        }
+    }
+
+    /**
+     * Process the queue to see what data needs to be obtained.
+     */
+    private void processQueue() {
+        Object node;
+        Object other;
+        NodeInfo info;
+        NodeInfo otherInfo;
+        Collection edges;
+        Edge edge;
+        while (_queue.size() > 0) {
+            node = _queue.remove(0);
+            info = (NodeInfo) _nodeInfo.get(node);
+            visit(node, info);
+
+            edges = _graph.getEdgesFrom(node);
+            for (Iterator itr = edges.iterator(); itr.hasNext();) {
+                edge = (Edge) itr.next();
+                edgeVisited(edge);
+                other = edge.getOther(node);
+                otherInfo = (NodeInfo) _nodeInfo.get(other);
+                if (otherInfo.color == NodeInfo.COLOR_WHITE)
+                    enqueue(other, otherInfo);
+            }
+        }
+    }
+
+    /**
+     * Push the given node onto the queue to be processed.
+     * Notify visitors.
+     */
+    protected void enqueue(Object node, NodeInfo info) {
+        _queue.add(node);
+        info.color = NodeInfo.COLOR_GRAY;
+        for (Iterator i = _visitors.iterator(); i.hasNext();)
+            ((GraphVisitor) i.next()).nodeSeen(node);
+    }
+
+    /**
+     * Visit the node.  Mark the node black and notify visitors.
+     */
+    protected void visit(Object node, NodeInfo info) {
+        info.color = NodeInfo.COLOR_BLACK;
+        for (Iterator i = _visitors.iterator(); i.hasNext();)
+            ((GraphVisitor) i.next()).nodeVisited(node);
+    }
+
+    /**
+     * An edge is seen.  Notify visitors.
+     */
+    protected void edgeVisited(Edge edge) {
+        for (Iterator i = _visitors.iterator(); i.hasNext();)
+            ((GraphVisitor) i.next()).edgeVisited(edge);
+    }
+
+    /**
+     * add a {@link GraphVisitor} to be notified during breadth first search.
+     */
+    public void addGraphVisitor(GraphVisitor visitor) {
+        _visitors.add(visitor);
+    }
+
+    /**
+     * remove a given {@link GraphVisitor} from the listener set.
+     */
+    public void removeGraphVisitor(GraphVisitor visitor) {
+        _visitors.remove(visitor);
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/DepthFirstAnalysis.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/DepthFirstAnalysis.java
index 0f4693b..f1f5001 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/DepthFirstAnalysis.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/DepthFirstAnalysis.java
@@ -1,358 +1,358 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-import org.apache.openjpa.lib.util.Localizer;
-
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * <p>Performs a depth-first analysis of a given {@link Graph}, caching
- * information about the graph's nodes and edges.  See the DFS algorithm
- * in the book 'Introduction to Algorithms' by Cormen, Leiserson, and
- * Rivest.  The algorithm has been modified to group sibling nodes without
- * connections together during the topological sort.</p>
- *
- * @author Abe White
- * @since 1.0.0
- * @nojavadoc
- */
-public class DepthFirstAnalysis {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (DepthFirstAnalysis.class);
-
-    private final Graph _graph;
-    private final Map _nodeInfo = new HashMap();
-    private Comparator _comp;
-
-    /**
-     * Constructor.  Performs the analysis on the given graph and caches
-     * the resulting information.
-     */
-    public DepthFirstAnalysis(Graph graph) {
-        _graph = graph;
-
-        // initialize node infos
-        Collection nodes = graph.getNodes();
-        for (Iterator itr = nodes.iterator(); itr.hasNext();)
-            _nodeInfo.put(itr.next(), new NodeInfo());
-
-        // visit all nodes -- see intro to algo's book
-        NodeInfo info;
-        Object node;
-        for (Iterator itr = nodes.iterator(); itr.hasNext();) {
-            node = itr.next();
-            info = (NodeInfo) _nodeInfo.get(node);
-            if (info.color == NodeInfo.COLOR_WHITE)
-                visit(graph, node, info, 0, new LinkedList());
-        }
-    }
-
-    /**
-     * Visit a node.  See Introduction to Algorithms book for details.
-     */
-    private int visit(Graph graph, Object node, NodeInfo info, int time, 
-        List path) {
-        // discover node
-        info.color = NodeInfo.COLOR_GRAY;
-
-        // explore all vertices from that node depth first
-        Collection edges = graph.getEdgesFrom(node);
-        Edge edge;
-        Object other;
-        NodeInfo otherInfo;
-        int maxChildTime = time - 1;
-        int childTime;
-        for (Iterator itr = edges.iterator(); itr.hasNext();) {
-            edge = (Edge) itr.next();
-            other = edge.getOther(node);
-            otherInfo = (NodeInfo) _nodeInfo.get(other);
-            if (otherInfo.color == NodeInfo.COLOR_WHITE) {
-                // undiscovered node; recurse into it
-                path.add(edge);
-                childTime = visit(graph, other, otherInfo, time, path);
-                path.remove(edge);
-                edge.setType(Edge.TYPE_TREE);
-            } else if (otherInfo.color == NodeInfo.COLOR_GRAY) {
-                childTime = -1;
-                edge.setType(Edge.TYPE_BACK);
-                // calculate the cycle including this edge
-                edge.setCycle(cycleForBackEdge(edge, path));
-            } else {
-                childTime = otherInfo.finished;
-                edge.setType(Edge.TYPE_FORWARD);
-                // find the cycle including this edge
-                List cycle = new LinkedList();
-                cycle.add(edge);
-                if (cycleForForwardEdge(graph, other, node, cycle)) {
-                    edge.setCycle(cycle);
-                }
-            }
-            maxChildTime = Math.max(maxChildTime, childTime);
-        }
-
-        // finished with node
-        info.color = NodeInfo.COLOR_BLACK;
-        info.finished = maxChildTime + 1;
-        return info.finished;
-    }
-
-    /**
-     * Set the comparator that should be used for ordering groups of nodes
-     * with the same dependencies.
-     */
-    public void setNodeComparator(Comparator comp) {
-        _comp = comp;
-    }
-
-    /**
-     * Return the nodes in topologically-sorted order.  This is often used
-     * to order dependencies.  If each graph edge (u, v) represents a
-     * dependency of v on u, then this method will return the nodes in the
-     * order that they should be evaluated to satisfy all dependencies.  Of
-     * course, if the graph is cyclic (has back edges), then no such ordering
-     * is possible, though this method will still return the correct order
-     * as if edges creating the cycles did not exist.
-     */
-    public List getSortedNodes() {
-        Map.Entry[] entries = (Map.Entry[]) _nodeInfo.entrySet().
-            toArray(new Map.Entry[_nodeInfo.size()]);
-        Arrays.sort(entries, new NodeInfoComparator(_comp));
-        return new NodeList(entries);
-    }
-
-    /**
-     * Return all edges of the given type.  This method can be used to
-     * discover all edges that cause cycles in the graph by passing it
-     * the {@link Edge#TYPE_BACK} or {@link Edge#TYPE_FORWARD} edge type.
-     */
-    public Collection getEdges(int type) {
-        Collection typed = null;
-        Edge edge;
-        Object node;
-        for (Iterator nodes = _graph.getNodes().iterator(); nodes.hasNext();) {
-            node = nodes.next();
-            for (Iterator itr = _graph.getEdgesFrom(node).iterator();
-                itr.hasNext();) {
-                edge = (Edge) itr.next();
-                if (edge.getType() == type) {
-                    if (typed == null)
-                        typed = new ArrayList();
-                    typed.add(edge);
-                }
-            }
-        }
-        return (typed == null) ? Collections.EMPTY_LIST : typed;
-    }
-
-    /**
-     * Return the logical time that the given node was finished in
-     * the graph walk, or -1 if the node is not part of the graph.
-     */
-    public int getFinishedTime(Object node) {
-        NodeInfo info = (NodeInfo) _nodeInfo.get(node);
-        if (info == null)
-            return -1;
-        return info.finished;
-    }
-
-    /**
-     * Returns a list of graph edges forming a cycle. The cycle begins 
-     * with a type {@link Edge#TYPE_BACK} edge.
-     * @param backEdge "Starting" edge of the cycle
-     * @param path Continuous list of graph edges, may be null
-     * @param pos Index of the first edge in path continuing the cycle
-     * @return Cycle starting with a type {@link Edge#TYPE_BACK} edge
-     */
-    private List buildCycle(Edge backEdge, List path, int pos) {
-        int length = path != null ? path.size() - pos : 0;
-        List cycle = new ArrayList(length + 1);
-        cycle.add(0, backEdge);
-        for (int i = 0; i < length; i++) {
-            cycle.add(i + 1, path.get(pos + i));
-        }
-        return cycle;
-    }
-
-    /**
-     * Computes the list of edges forming a cycle. The cycle always exists for
-     * a type {@link Edge#TYPE_BACK} edge. This method should only be called 
-     * for type {@link Edge#TYPE_BACK} edges. 
-     * @param edge Edge where the cycle was detected
-     * @param path Path consisting of edges to the edge's starting node
-     * @return Cycle starting with a type {@link Edge#TYPE_BACK} edge
-     */
-    private List cycleForBackEdge(Edge edge, List path) {
-        if (edge.getType() != Edge.TYPE_BACK) {
-            return null;
-        }
-        
-        List cycle;
-        int pos = 0;
-        if (path != null && !edge.getFrom().equals(edge.getTo())) {
-            // Not a single edge loop
-            pos = findNodeInPath(edge.getTo(), path);
-            assert (pos >= 0): _loc.get("node-not-on-path", edge, edge.getTo()); 
-        } else {
-            assert (edge.getFrom().equals(edge.getTo())): 
-                _loc.get("edge-no-loop", edge).getMessage();
-            path = null;
-        }
-        cycle = buildCycle(edge, path, pos); 
-        assert (cycle != null): _loc.get("cycle-null", edge).getMessage();
-        return cycle;
-    }
-
-    /**
-     * Computes the cycle of edges including node cycleTo. The cycle must not 
-     * necessarily exist. This method should only be called for type 
-     * {@link Edge#TYPE_FORWARD} edges.
-     * @param graph Graph
-     * @param node Current node
-     * @param cycleTo End node for loop
-     * @param path Path from loop end node to current node
-     * @return True if a cycle has been found. The cycle will be contained in
-     * the <code>path</code> parameter.
-     */
-    private boolean cycleForForwardEdge(Graph graph, Object node,
-        Object cycleTo, List path) {                   
-        boolean found = false;
-        Collection edges = graph.getEdgesFrom(node);
-        for (Iterator itr = edges.iterator(); !found && itr.hasNext();) {
-            Edge edge = (Edge) itr.next();
-            Object other = edge.getOther(node);
-            // Single edge loops are ignored
-            if (!node.equals(other)) {
-                if (other.equals(cycleTo)) {
-                    // Cycle complete
-                    path.add(edge);
-                    found = true;
-                } else if (!path.contains(edge)){
-                    // Walk this edge
-                    path.add(edge);
-                    found = cycleForForwardEdge(graph, other, cycleTo, path);
-                    if (!found) {
-                        // Remove edge again
-                        path.remove(edge);                    
-                    }
-                }
-            }
-        }
-        return found;
-    }
-    
-    /**
-     * Finds the position of the edge starting from a particular node in the 
-     * continuous list of edges.
-     * @param node Node on the cycle.
-     * @param path Continuous list of graph edges.
-     * @return Edge index if found, -1 otherwise.
-     */
-    private int findNodeInPath(Object node, List path) {
-        int pos = -1;
-        if (path != null) {
-            for (int i = 0; i < path.size(); i++) {
-                if (((Edge)path.get(i)).getFrom().equals(node)) {
-                    pos = i;
-                }
-            }
-        }
-        return pos;
-    }
-
-    /**
-     * Test, if the analysis didn't find cycles.
-     */
-    public boolean hasNoCycles() {
-        // a) there must not be any back edges
-        if (!getEdges(Edge.TYPE_BACK).isEmpty()) {
-            return false;
-        }
-        // b) there might be forward edges
-        // make sure these don't indicate cycles
-        Collection edges = getEdges(Edge.TYPE_FORWARD);
-        if (!edges.isEmpty()) {
-            for (Iterator itr = edges.iterator(); itr.hasNext();) {
-                Edge edge = (Edge) itr.next();
-                if (edge.getCycle() != null)  {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-    
-    /**
-     * Comparator for toplogically sorting entries in the node info map.
-     */
-    private static class NodeInfoComparator
-        implements Comparator {
-
-        private final Comparator _subComp;
-
-        public NodeInfoComparator(Comparator subComp) {
-            _subComp = subComp;
-        }
-
-        public int compare(Object o1, Object o2) {
-            Map.Entry e1 = (Map.Entry) o1;
-            Map.Entry e2 = (Map.Entry) o2;
-            NodeInfo n1 = (NodeInfo) e1.getValue();
-            NodeInfo n2 = (NodeInfo) e2.getValue();
-
-            // sort by finished order
-            int ret = n1.finished - n2.finished;
-            if (ret == 0 && _subComp != null)
-                ret = _subComp.compare(e1.getKey(), e2.getKey());
-            return ret;
-        }
-    }
-
-    /**
-     *	List of node-to-nodeinfo entries that exposes just the nodes.
-     */
-    private static class NodeList
-        extends AbstractList {
-
-        private final Map.Entry[] _entries;
-
-        public NodeList(Map.Entry[] entries) {
-            _entries = entries;
-        }
-
-        public Object get(int idx) {
-            return _entries[idx].getKey();
-        }
-
-        public int size() {
-            return _entries.length;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+import org.apache.openjpa.lib.util.Localizer;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>Performs a depth-first analysis of a given {@link Graph}, caching
+ * information about the graph's nodes and edges.  See the DFS algorithm
+ * in the book 'Introduction to Algorithms' by Cormen, Leiserson, and
+ * Rivest.  The algorithm has been modified to group sibling nodes without
+ * connections together during the topological sort.</p>
+ *
+ * @author Abe White
+ * @since 1.0.0
+ * @nojavadoc
+ */
+public class DepthFirstAnalysis {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (DepthFirstAnalysis.class);
+
+    private final Graph _graph;
+    private final Map _nodeInfo = new HashMap();
+    private Comparator _comp;
+
+    /**
+     * Constructor.  Performs the analysis on the given graph and caches
+     * the resulting information.
+     */
+    public DepthFirstAnalysis(Graph graph) {
+        _graph = graph;
+
+        // initialize node infos
+        Collection nodes = graph.getNodes();
+        for (Iterator itr = nodes.iterator(); itr.hasNext();)
+            _nodeInfo.put(itr.next(), new NodeInfo());
+
+        // visit all nodes -- see intro to algo's book
+        NodeInfo info;
+        Object node;
+        for (Iterator itr = nodes.iterator(); itr.hasNext();) {
+            node = itr.next();
+            info = (NodeInfo) _nodeInfo.get(node);
+            if (info.color == NodeInfo.COLOR_WHITE)
+                visit(graph, node, info, 0, new LinkedList());
+        }
+    }
+
+    /**
+     * Visit a node.  See Introduction to Algorithms book for details.
+     */
+    private int visit(Graph graph, Object node, NodeInfo info, int time, 
+        List path) {
+        // discover node
+        info.color = NodeInfo.COLOR_GRAY;
+
+        // explore all vertices from that node depth first
+        Collection edges = graph.getEdgesFrom(node);
+        Edge edge;
+        Object other;
+        NodeInfo otherInfo;
+        int maxChildTime = time - 1;
+        int childTime;
+        for (Iterator itr = edges.iterator(); itr.hasNext();) {
+            edge = (Edge) itr.next();
+            other = edge.getOther(node);
+            otherInfo = (NodeInfo) _nodeInfo.get(other);
+            if (otherInfo.color == NodeInfo.COLOR_WHITE) {
+                // undiscovered node; recurse into it
+                path.add(edge);
+                childTime = visit(graph, other, otherInfo, time, path);
+                path.remove(edge);
+                edge.setType(Edge.TYPE_TREE);
+            } else if (otherInfo.color == NodeInfo.COLOR_GRAY) {
+                childTime = -1;
+                edge.setType(Edge.TYPE_BACK);
+                // calculate the cycle including this edge
+                edge.setCycle(cycleForBackEdge(edge, path));
+            } else {
+                childTime = otherInfo.finished;
+                edge.setType(Edge.TYPE_FORWARD);
+                // find the cycle including this edge
+                List cycle = new LinkedList();
+                cycle.add(edge);
+                if (cycleForForwardEdge(graph, other, node, cycle)) {
+                    edge.setCycle(cycle);
+                }
+            }
+            maxChildTime = Math.max(maxChildTime, childTime);
+        }
+
+        // finished with node
+        info.color = NodeInfo.COLOR_BLACK;
+        info.finished = maxChildTime + 1;
+        return info.finished;
+    }
+
+    /**
+     * Set the comparator that should be used for ordering groups of nodes
+     * with the same dependencies.
+     */
+    public void setNodeComparator(Comparator comp) {
+        _comp = comp;
+    }
+
+    /**
+     * Return the nodes in topologically-sorted order.  This is often used
+     * to order dependencies.  If each graph edge (u, v) represents a
+     * dependency of v on u, then this method will return the nodes in the
+     * order that they should be evaluated to satisfy all dependencies.  Of
+     * course, if the graph is cyclic (has back edges), then no such ordering
+     * is possible, though this method will still return the correct order
+     * as if edges creating the cycles did not exist.
+     */
+    public List getSortedNodes() {
+        Map.Entry[] entries = (Map.Entry[]) _nodeInfo.entrySet().
+            toArray(new Map.Entry[_nodeInfo.size()]);
+        Arrays.sort(entries, new NodeInfoComparator(_comp));
+        return new NodeList(entries);
+    }
+
+    /**
+     * Return all edges of the given type.  This method can be used to
+     * discover all edges that cause cycles in the graph by passing it
+     * the {@link Edge#TYPE_BACK} or {@link Edge#TYPE_FORWARD} edge type.
+     */
+    public Collection getEdges(int type) {
+        Collection typed = null;
+        Edge edge;
+        Object node;
+        for (Iterator nodes = _graph.getNodes().iterator(); nodes.hasNext();) {
+            node = nodes.next();
+            for (Iterator itr = _graph.getEdgesFrom(node).iterator();
+                itr.hasNext();) {
+                edge = (Edge) itr.next();
+                if (edge.getType() == type) {
+                    if (typed == null)
+                        typed = new ArrayList();
+                    typed.add(edge);
+                }
+            }
+        }
+        return (typed == null) ? Collections.EMPTY_LIST : typed;
+    }
+
+    /**
+     * Return the logical time that the given node was finished in
+     * the graph walk, or -1 if the node is not part of the graph.
+     */
+    public int getFinishedTime(Object node) {
+        NodeInfo info = (NodeInfo) _nodeInfo.get(node);
+        if (info == null)
+            return -1;
+        return info.finished;
+    }
+
+    /**
+     * Returns a list of graph edges forming a cycle. The cycle begins 
+     * with a type {@link Edge#TYPE_BACK} edge.
+     * @param backEdge "Starting" edge of the cycle
+     * @param path Continuous list of graph edges, may be null
+     * @param pos Index of the first edge in path continuing the cycle
+     * @return Cycle starting with a type {@link Edge#TYPE_BACK} edge
+     */
+    private List buildCycle(Edge backEdge, List path, int pos) {
+        int length = path != null ? path.size() - pos : 0;
+        List cycle = new ArrayList(length + 1);
+        cycle.add(0, backEdge);
+        for (int i = 0; i < length; i++) {
+            cycle.add(i + 1, path.get(pos + i));
+        }
+        return cycle;
+    }
+
+    /**
+     * Computes the list of edges forming a cycle. The cycle always exists for
+     * a type {@link Edge#TYPE_BACK} edge. This method should only be called 
+     * for type {@link Edge#TYPE_BACK} edges. 
+     * @param edge Edge where the cycle was detected
+     * @param path Path consisting of edges to the edge's starting node
+     * @return Cycle starting with a type {@link Edge#TYPE_BACK} edge
+     */
+    private List cycleForBackEdge(Edge edge, List path) {
+        if (edge.getType() != Edge.TYPE_BACK) {
+            return null;
+        }
+        
+        List cycle;
+        int pos = 0;
+        if (path != null && !edge.getFrom().equals(edge.getTo())) {
+            // Not a single edge loop
+            pos = findNodeInPath(edge.getTo(), path);
+            assert (pos >= 0): _loc.get("node-not-on-path", edge, edge.getTo()); 
+        } else {
+            assert (edge.getFrom().equals(edge.getTo())): 
+                _loc.get("edge-no-loop", edge).getMessage();
+            path = null;
+        }
+        cycle = buildCycle(edge, path, pos); 
+        assert (cycle != null): _loc.get("cycle-null", edge).getMessage();
+        return cycle;
+    }
+
+    /**
+     * Computes the cycle of edges including node cycleTo. The cycle must not 
+     * necessarily exist. This method should only be called for type 
+     * {@link Edge#TYPE_FORWARD} edges.
+     * @param graph Graph
+     * @param node Current node
+     * @param cycleTo End node for loop
+     * @param path Path from loop end node to current node
+     * @return True if a cycle has been found. The cycle will be contained in
+     * the <code>path</code> parameter.
+     */
+    private boolean cycleForForwardEdge(Graph graph, Object node,
+        Object cycleTo, List path) {                   
+        boolean found = false;
+        Collection edges = graph.getEdgesFrom(node);
+        for (Iterator itr = edges.iterator(); !found && itr.hasNext();) {
+            Edge edge = (Edge) itr.next();
+            Object other = edge.getOther(node);
+            // Single edge loops are ignored
+            if (!node.equals(other)) {
+                if (other.equals(cycleTo)) {
+                    // Cycle complete
+                    path.add(edge);
+                    found = true;
+                } else if (!path.contains(edge)){
+                    // Walk this edge
+                    path.add(edge);
+                    found = cycleForForwardEdge(graph, other, cycleTo, path);
+                    if (!found) {
+                        // Remove edge again
+                        path.remove(edge);                    
+                    }
+                }
+            }
+        }
+        return found;
+    }
+    
+    /**
+     * Finds the position of the edge starting from a particular node in the 
+     * continuous list of edges.
+     * @param node Node on the cycle.
+     * @param path Continuous list of graph edges.
+     * @return Edge index if found, -1 otherwise.
+     */
+    private int findNodeInPath(Object node, List path) {
+        int pos = -1;
+        if (path != null) {
+            for (int i = 0; i < path.size(); i++) {
+                if (((Edge)path.get(i)).getFrom().equals(node)) {
+                    pos = i;
+                }
+            }
+        }
+        return pos;
+    }
+
+    /**
+     * Test, if the analysis didn't find cycles.
+     */
+    public boolean hasNoCycles() {
+        // a) there must not be any back edges
+        if (!getEdges(Edge.TYPE_BACK).isEmpty()) {
+            return false;
+        }
+        // b) there might be forward edges
+        // make sure these don't indicate cycles
+        Collection edges = getEdges(Edge.TYPE_FORWARD);
+        if (!edges.isEmpty()) {
+            for (Iterator itr = edges.iterator(); itr.hasNext();) {
+                Edge edge = (Edge) itr.next();
+                if (edge.getCycle() != null)  {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * Comparator for toplogically sorting entries in the node info map.
+     */
+    private static class NodeInfoComparator
+        implements Comparator {
+
+        private final Comparator _subComp;
+
+        public NodeInfoComparator(Comparator subComp) {
+            _subComp = subComp;
+        }
+
+        public int compare(Object o1, Object o2) {
+            Map.Entry e1 = (Map.Entry) o1;
+            Map.Entry e2 = (Map.Entry) o2;
+            NodeInfo n1 = (NodeInfo) e1.getValue();
+            NodeInfo n2 = (NodeInfo) e2.getValue();
+
+            // sort by finished order
+            int ret = n1.finished - n2.finished;
+            if (ret == 0 && _subComp != null)
+                ret = _subComp.compare(e1.getKey(), e2.getKey());
+            return ret;
+        }
+    }
+
+    /**
+     *	List of node-to-nodeinfo entries that exposes just the nodes.
+     */
+    private static class NodeList
+        extends AbstractList {
+
+        private final Map.Entry[] _entries;
+
+        public NodeList(Map.Entry[] entries) {
+            _entries = entries;
+        }
+
+        public Object get(int idx) {
+            return _entries[idx].getKey();
+        }
+
+        public int size() {
+            return _entries.length;
+		}
+	}
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Edge.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Edge.java
index 94522a8..aa57109 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Edge.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Edge.java
@@ -1,222 +1,222 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-import java.util.List;
-
-/**
- * <p>A graph edge.  Includes the from and to nodes, an arbitrary user object,
- * and a weight.  Edges can be either directed or undirected.</p>
- *
- * @author Abe White
- * @since 1.0.0
- * @nojavadoc
- */
-public class Edge {
-
-    /**
-     * An edge (u, v) is a tree edge if node v was first discovered by
-     * traversing the edge.
-     */
-    public static final int TYPE_TREE = 1;
-
-    /**
-     * An edge (u, v) is a back edge if it creates a cycle back to an
-     * ancestor in the graph.
-     */
-    public static final int TYPE_BACK = 2;
-
-    /**
-     * An edge (u, v) is a forward edge if it is not a tree or back edge.
-     */
-    public static final int TYPE_FORWARD = 3;
-
-    private final Object _from;
-    private final Object _to;
-    private final boolean _directed;
-
-    private int _type = 0;
-    private double _weight = 0;
-    private Object _userObj = null;
-    private List _cycle = null;
-    private boolean _removedFromGraph = false;
-
-    /**
-     * Constructor.
-     *
-     * @param    from        the node the edge comes from
-     * @param    to            the node the edge goes to
-     * @param    directed    whether the edge is directed
-     */
-    public Edge(Object from, Object to, boolean directed) {
-        if (from == null)
-            throw new NullPointerException("from == null");
-        if (to == null)
-            throw new NullPointerException("to == null");
-        _from = from;
-        _to = to;
-        _directed = directed;
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param    from        the node the edge comes from
-     * @param    to            the node the edge goes to
-     * @param    directed    whether the edge is directed
-     * @param    userObject    an associated object
-     */
-    public Edge(Object from, Object to, boolean directed, Object userObject) {
-        this(from, to, directed);
-        _userObj = userObject;
-    }
-
-    /**
-     * Return the node the edge links from.
-     */
-    public Object getFrom() {
-        return _from;
-    }
-
-    /**
-     * Return the node the edge links to.
-     */
-    public Object getTo() {
-        return _to;
-    }
-
-    /**
-     * Return the node on the opposite end of the given one, or null if the
-     * given node is not part of this edge.
-     */
-    public Object getOther(Object node) {
-        if (_to.equals(node))
-            return _from;
-        if (_from.equals(node))
-            return _to;
-        return null;
-    }
-
-    /**
-     * Return true if this edge links to the given node.  For undirected edges,
-     * this method returns true if either side is equal to the given node.
-     */
-    public boolean isTo(Object node) {
-        return _to.equals(node) || (!_directed && _from.equals(node));
-    }
-
-    /**
-     * Return true if this edge links from the given node.  For undirected
-     * edges, this method returns true if either side is equal to the given
-     * node.
-     */
-    public boolean isFrom(Object node) {
-        return _from.equals(node) || (!_directed && _to.equals(node));
-    }
-
-    /**
-     * Return whether the edge is directed.
-     */
-    public boolean isDirected() {
-        return _directed;
-    }
-
-    /**
-     * Return the weight of the edge.
-     */
-    public double getWeight() {
-        return _weight;
-    }
-
-    /**
-     * Set the weight of the edge.
-     */
-    public void setWeight(double weight) {
-        _weight = weight;
-    }
-
-    /**
-     * Arbitrary user object associated with the edge.
-     */
-    public Object getUserObject() {
-        return _userObj;
-    }
-
-    /**
-     * Arbitrary user object associated with the edge.
-     */
-    public void setUserObject(Object obj) {
-        _userObj = obj;
-    }
-
-    /**
-     * Traversal bookkeeping info.
-     */
-    public int getType() {
-        return _type;
-    }
-
-    /**
-     * Traversal bookkeeping info.
-     */
-    public void setType(int type) {
-        _type = type;
-    }
-
-    /**
-     * List of edges forming a cycle. Only set for TYPE_BACK and TYPE_FORWARD edges.
-     */
-    public List getCycle() {
-        return _cycle;
-    }
-    
-    /**
-     * List of edges forming a cycle. Only set for TYPE_BACK and TYPE_FORWARD edges.
-     */
-    public void setCycle(List cycle) {
-        _cycle = cycle;
-    }
-
-    /**
-     * Returns if this edge is (still) part of the graph.
-     */
-    public boolean isRemovedFromGraph() {
-        return _removedFromGraph;
-    }
-
-    /**
-     * Mark this edge as removed from the graph.
-     */
-    public void setRemovedFromGraph() {
-        this._removedFromGraph = true;
-    }
-
-    /**
-     * Clear traversal info.
-     */
-    public void clearTraversal() {
-        _type = 0;
-        _cycle = null;
-    }
-
-    public String toString() {
-        return super.toString() + "[from=" + getFrom() + ";to=" + getTo()
-            + ";directed=" + isDirected () + ";weight=" + getWeight () + "]";
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+import java.util.List;
+
+/**
+ * <p>A graph edge.  Includes the from and to nodes, an arbitrary user object,
+ * and a weight.  Edges can be either directed or undirected.</p>
+ *
+ * @author Abe White
+ * @since 1.0.0
+ * @nojavadoc
+ */
+public class Edge {
+
+    /**
+     * An edge (u, v) is a tree edge if node v was first discovered by
+     * traversing the edge.
+     */
+    public static final int TYPE_TREE = 1;
+
+    /**
+     * An edge (u, v) is a back edge if it creates a cycle back to an
+     * ancestor in the graph.
+     */
+    public static final int TYPE_BACK = 2;
+
+    /**
+     * An edge (u, v) is a forward edge if it is not a tree or back edge.
+     */
+    public static final int TYPE_FORWARD = 3;
+
+    private final Object _from;
+    private final Object _to;
+    private final boolean _directed;
+
+    private int _type = 0;
+    private double _weight = 0;
+    private Object _userObj = null;
+    private List _cycle = null;
+    private boolean _removedFromGraph = false;
+
+    /**
+     * Constructor.
+     *
+     * @param    from        the node the edge comes from
+     * @param    to            the node the edge goes to
+     * @param    directed    whether the edge is directed
+     */
+    public Edge(Object from, Object to, boolean directed) {
+        if (from == null)
+            throw new NullPointerException("from == null");
+        if (to == null)
+            throw new NullPointerException("to == null");
+        _from = from;
+        _to = to;
+        _directed = directed;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param    from        the node the edge comes from
+     * @param    to            the node the edge goes to
+     * @param    directed    whether the edge is directed
+     * @param    userObject    an associated object
+     */
+    public Edge(Object from, Object to, boolean directed, Object userObject) {
+        this(from, to, directed);
+        _userObj = userObject;
+    }
+
+    /**
+     * Return the node the edge links from.
+     */
+    public Object getFrom() {
+        return _from;
+    }
+
+    /**
+     * Return the node the edge links to.
+     */
+    public Object getTo() {
+        return _to;
+    }
+
+    /**
+     * Return the node on the opposite end of the given one, or null if the
+     * given node is not part of this edge.
+     */
+    public Object getOther(Object node) {
+        if (_to.equals(node))
+            return _from;
+        if (_from.equals(node))
+            return _to;
+        return null;
+    }
+
+    /**
+     * Return true if this edge links to the given node.  For undirected edges,
+     * this method returns true if either side is equal to the given node.
+     */
+    public boolean isTo(Object node) {
+        return _to.equals(node) || (!_directed && _from.equals(node));
+    }
+
+    /**
+     * Return true if this edge links from the given node.  For undirected
+     * edges, this method returns true if either side is equal to the given
+     * node.
+     */
+    public boolean isFrom(Object node) {
+        return _from.equals(node) || (!_directed && _to.equals(node));
+    }
+
+    /**
+     * Return whether the edge is directed.
+     */
+    public boolean isDirected() {
+        return _directed;
+    }
+
+    /**
+     * Return the weight of the edge.
+     */
+    public double getWeight() {
+        return _weight;
+    }
+
+    /**
+     * Set the weight of the edge.
+     */
+    public void setWeight(double weight) {
+        _weight = weight;
+    }
+
+    /**
+     * Arbitrary user object associated with the edge.
+     */
+    public Object getUserObject() {
+        return _userObj;
+    }
+
+    /**
+     * Arbitrary user object associated with the edge.
+     */
+    public void setUserObject(Object obj) {
+        _userObj = obj;
+    }
+
+    /**
+     * Traversal bookkeeping info.
+     */
+    public int getType() {
+        return _type;
+    }
+
+    /**
+     * Traversal bookkeeping info.
+     */
+    public void setType(int type) {
+        _type = type;
+    }
+
+    /**
+     * List of edges forming a cycle. Only set for TYPE_BACK and TYPE_FORWARD edges.
+     */
+    public List getCycle() {
+        return _cycle;
+    }
+    
+    /**
+     * List of edges forming a cycle. Only set for TYPE_BACK and TYPE_FORWARD edges.
+     */
+    public void setCycle(List cycle) {
+        _cycle = cycle;
+    }
+
+    /**
+     * Returns if this edge is (still) part of the graph.
+     */
+    public boolean isRemovedFromGraph() {
+        return _removedFromGraph;
+    }
+
+    /**
+     * Mark this edge as removed from the graph.
+     */
+    public void setRemovedFromGraph() {
+        this._removedFromGraph = true;
+    }
+
+    /**
+     * Clear traversal info.
+     */
+    public void clearTraversal() {
+        _type = 0;
+        _cycle = null;
+    }
+
+    public String toString() {
+        return super.toString() + "[from=" + getFrom() + ";to=" + getTo()
+            + ";directed=" + isDirected () + ";weight=" + getWeight () + "]";
+	}
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Graph.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Graph.java
index 6077e6d..77f9d74 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Graph.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/Graph.java
@@ -1,202 +1,202 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * <p>Graph representation using the adjacency list form.  See the book
- * 'Introduction to Algorithms' by Cormen, Leiserson, and Rivest.</p>
- *
- * @author Abe White
- * @since 1.0.0
- * @nojavadoc
- */
-public class Graph {
-
-    /**
-     * Map each node to list of edges from that node.
-     * Using a LinkedHashMap to ensure order of iterator processing.
-     */ 
-    private final Map _nodes = new LinkedHashMap();
-
-    /**
-     * Clear the graph.
-     */
-    public void clear() {
-        _nodes.clear();
-    }
-
-    /**
-     * Return true if the graph contains the given node.
-     */
-    public boolean containsNode(Object node) {
-        return _nodes.containsKey(node);
-    }
-
-    /**
-     * Return a view of all nodes in the graph.
-     */
-    public Collection getNodes() {
-        return _nodes.keySet();
-    }
-
-    /**
-     * Add a node to the graph.  Adding a node a second time has no effect.
-     */
-    public void addNode(Object node) {
-        if (node == null)
-            throw new NullPointerException("node = null");
-        if (!containsNode(node))
-            _nodes.put(node, null);
-    }
-
-    /**
-     * Remove a node from the graph.  All edges to and from the node
-     * will be cleared.
-     *
-     * @return true if the node was removed, false otherwise
-     */
-    public boolean removeNode(Object node) {
-        boolean rem = containsNode(node);
-        if (rem) {
-            Collection edges = getEdgesTo(node);
-            for (Iterator itr = edges.iterator(); itr.hasNext();)
-                removeEdge((Edge) itr.next());
-            _nodes.remove(node);
-        }
-        return rem;
-    }
-
-    /**
-     * Return all edges in the graph.
-     */
-    public Collection getEdges() {
-        Collection all = new HashSet();
-        Collection edges;
-        for (Iterator itr = _nodes.values().iterator(); itr.hasNext();) {
-            edges = (Collection) itr.next();
-            if (edges != null)
-                all.addAll(edges);
-        }
-        return all;
-    }
-
-    /**
-     * Return all the edges from a particular node.
-     */
-    public Collection getEdgesFrom(Object node) {
-        Collection edges = (Collection) _nodes.get(node);
-        return (edges == null) ? Collections.EMPTY_LIST : edges;
-    }
-
-    /**
-     * Return all the edges to a particular node.
-     */
-    public Collection getEdgesTo(Object node) {
-        Collection edges = getEdges();
-        Collection to = new ArrayList();
-        Edge edge;
-        for (Iterator itr = edges.iterator(); itr.hasNext();) {
-            edge = (Edge) itr.next();
-            if (edge.isTo(node))
-                to.add(edge);
-        }
-        return to;
-    }
-
-    /**
-     * Return all the edges from one node to another.
-     */
-    public Collection getEdges(Object from, Object to) {
-        Collection edges = getEdgesFrom(from);
-        Collection matches = new ArrayList(edges.size());
-        Edge edge;
-        for (Iterator itr = edges.iterator(); itr.hasNext();) {
-            edge = (Edge) itr.next();
-            if (edge.isTo(to))
-                matches.add(edge);
-        }
-        return matches;
-    }
-
-    /**
-     * Add an edge to the graph.
-     */
-    public void addEdge(Edge edge) {
-        if (!containsNode(edge.getTo()))
-            throw new IllegalArgumentException(edge.getTo().toString());
-        if (!containsNode(edge.getFrom()))
-            throw new IllegalArgumentException(edge.getFrom().toString());
-
-        Collection from = (Collection) _nodes.get(edge.getFrom());
-        if (from == null) {
-            from = new ArrayList(3);
-            _nodes.put(edge.getFrom(), from);
-        }
-        from.add(edge);
-
-        if (!edge.isDirected() && !edge.getFrom().equals(edge.getTo())) {
-            Collection to = (Collection) _nodes.get(edge.getTo());
-            if (to == null) {
-                to = new ArrayList(3);
-                _nodes.put(edge.getTo(), to);
-            }
-            to.add(edge);
-        }
-    }
-
-    /**
-     * Remove an edge from the graph.
-     *
-     * @return true if the edge was removed, false if not in the graph
-     */
-    public boolean removeEdge(Edge edge) {
-        Collection edges = (Collection) _nodes.get(edge.getFrom());
-        if (edges == null)
-            return false;
-        boolean rem = edges.remove(edge);
-        if (rem && !edge.isDirected()) {
-            edges = (Collection) _nodes.get(edge.getTo());
-            if (edges != null)
-                edges.remove(edge);
-        }
-        return rem;
-    }
-
-    /**
-     *	Clear all nodes and edges of the bookkeeping information from their
-     *	last traversal.
-     */
-    public void clearTraversal() {
-        Collection edges;
-        for (Iterator vals = _nodes.values().iterator(); vals.hasNext();) {
-            edges = (Collection) vals.next();
-            if (edges != null)
-                for (Iterator ed = edges.iterator(); ed.hasNext();)
-                    ((Edge) ed.next()).clearTraversal ();
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * <p>Graph representation using the adjacency list form.  See the book
+ * 'Introduction to Algorithms' by Cormen, Leiserson, and Rivest.</p>
+ *
+ * @author Abe White
+ * @since 1.0.0
+ * @nojavadoc
+ */
+public class Graph {
+
+    /**
+     * Map each node to list of edges from that node.
+     * Using a LinkedHashMap to ensure order of iterator processing.
+     */ 
+    private final Map _nodes = new LinkedHashMap();
+
+    /**
+     * Clear the graph.
+     */
+    public void clear() {
+        _nodes.clear();
+    }
+
+    /**
+     * Return true if the graph contains the given node.
+     */
+    public boolean containsNode(Object node) {
+        return _nodes.containsKey(node);
+    }
+
+    /**
+     * Return a view of all nodes in the graph.
+     */
+    public Collection getNodes() {
+        return _nodes.keySet();
+    }
+
+    /**
+     * Add a node to the graph.  Adding a node a second time has no effect.
+     */
+    public void addNode(Object node) {
+        if (node == null)
+            throw new NullPointerException("node = null");
+        if (!containsNode(node))
+            _nodes.put(node, null);
+    }
+
+    /**
+     * Remove a node from the graph.  All edges to and from the node
+     * will be cleared.
+     *
+     * @return true if the node was removed, false otherwise
+     */
+    public boolean removeNode(Object node) {
+        boolean rem = containsNode(node);
+        if (rem) {
+            Collection edges = getEdgesTo(node);
+            for (Iterator itr = edges.iterator(); itr.hasNext();)
+                removeEdge((Edge) itr.next());
+            _nodes.remove(node);
+        }
+        return rem;
+    }
+
+    /**
+     * Return all edges in the graph.
+     */
+    public Collection getEdges() {
+        Collection all = new HashSet();
+        Collection edges;
+        for (Iterator itr = _nodes.values().iterator(); itr.hasNext();) {
+            edges = (Collection) itr.next();
+            if (edges != null)
+                all.addAll(edges);
+        }
+        return all;
+    }
+
+    /**
+     * Return all the edges from a particular node.
+     */
+    public Collection getEdgesFrom(Object node) {
+        Collection edges = (Collection) _nodes.get(node);
+        return (edges == null) ? Collections.EMPTY_LIST : edges;
+    }
+
+    /**
+     * Return all the edges to a particular node.
+     */
+    public Collection getEdgesTo(Object node) {
+        Collection edges = getEdges();
+        Collection to = new ArrayList();
+        Edge edge;
+        for (Iterator itr = edges.iterator(); itr.hasNext();) {
+            edge = (Edge) itr.next();
+            if (edge.isTo(node))
+                to.add(edge);
+        }
+        return to;
+    }
+
+    /**
+     * Return all the edges from one node to another.
+     */
+    public Collection getEdges(Object from, Object to) {
+        Collection edges = getEdgesFrom(from);
+        Collection matches = new ArrayList(edges.size());
+        Edge edge;
+        for (Iterator itr = edges.iterator(); itr.hasNext();) {
+            edge = (Edge) itr.next();
+            if (edge.isTo(to))
+                matches.add(edge);
+        }
+        return matches;
+    }
+
+    /**
+     * Add an edge to the graph.
+     */
+    public void addEdge(Edge edge) {
+        if (!containsNode(edge.getTo()))
+            throw new IllegalArgumentException(edge.getTo().toString());
+        if (!containsNode(edge.getFrom()))
+            throw new IllegalArgumentException(edge.getFrom().toString());
+
+        Collection from = (Collection) _nodes.get(edge.getFrom());
+        if (from == null) {
+            from = new ArrayList(3);
+            _nodes.put(edge.getFrom(), from);
+        }
+        from.add(edge);
+
+        if (!edge.isDirected() && !edge.getFrom().equals(edge.getTo())) {
+            Collection to = (Collection) _nodes.get(edge.getTo());
+            if (to == null) {
+                to = new ArrayList(3);
+                _nodes.put(edge.getTo(), to);
+            }
+            to.add(edge);
+        }
+    }
+
+    /**
+     * Remove an edge from the graph.
+     *
+     * @return true if the edge was removed, false if not in the graph
+     */
+    public boolean removeEdge(Edge edge) {
+        Collection edges = (Collection) _nodes.get(edge.getFrom());
+        if (edges == null)
+            return false;
+        boolean rem = edges.remove(edge);
+        if (rem && !edge.isDirected()) {
+            edges = (Collection) _nodes.get(edge.getTo());
+            if (edges != null)
+                edges.remove(edge);
+        }
+        return rem;
+    }
+
+    /**
+     *	Clear all nodes and edges of the bookkeeping information from their
+     *	last traversal.
+     */
+    public void clearTraversal() {
+        Collection edges;
+        for (Iterator vals = _nodes.values().iterator(); vals.hasNext();) {
+            edges = (Collection) vals.next();
+            if (edges != null)
+                for (Iterator ed = edges.iterator(); ed.hasNext();)
+                    ((Edge) ed.next()).clearTraversal ();
+		}
+	}
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/GraphVisitor.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/GraphVisitor.java
index 852602d..b9c67ff 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/GraphVisitor.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/GraphVisitor.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-/**
- * <p>A helper interface that allows third parties to be notified of
- * graph events during graph traversals</p>
- *
- * @author Steve Kim
- * @since 1.0.0
- * @nojavadoc
- */
-public interface GraphVisitor {
-
-    /**
-     * May not be called.  The meaning of this method is dependent
-     * on the traversal being used.  See each appropriate graph
-     * walker for details.
-     */
-    public void nodeSeen(Object node);
-
-    /**
-     * will only be called once per node
-     */
-    public void nodeVisited(Object node);
-
-    /**
-     * may visit the node twice (both sides)
-     */
-    public void edgeVisited(Edge edge);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+/**
+ * <p>A helper interface that allows third parties to be notified of
+ * graph events during graph traversals</p>
+ *
+ * @author Steve Kim
+ * @since 1.0.0
+ * @nojavadoc
+ */
+public interface GraphVisitor {
+
+    /**
+     * May not be called.  The meaning of this method is dependent
+     * on the traversal being used.  See each appropriate graph
+     * walker for details.
+     */
+    public void nodeSeen(Object node);
+
+    /**
+     * will only be called once per node
+     */
+    public void nodeVisited(Object node);
+
+    /**
+     * may visit the node twice (both sides)
+     */
+    public void edgeVisited(Edge edge);
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/NodeInfo.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/NodeInfo.java
index c3dbe01..9ece659 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/NodeInfo.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/graph/NodeInfo.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-/**
- * <p>Struct used to track graph node information during traversal.</p>
- *
- * @author Abe White
- * @since 1.0.0
- */
-class NodeInfo {
-
-    public static final int COLOR_WHITE = 0;
-    public static final int COLOR_GRAY = 1;
-    public static final int COLOR_BLACK = 2;
-
-    public int finished = 0;
-    public int color = COLOR_WHITE;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+/**
+ * <p>Struct used to track graph node information during traversal.</p>
+ *
+ * @author Abe White
+ * @since 1.0.0
+ */
+class NodeInfo {
+
+    public static final int COLOR_WHITE = 0;
+    public static final int COLOR_GRAY = 1;
+    public static final int COLOR_BLACK = 2;
+
+    public int finished = 0;
+    public int color = COLOR_WHITE;
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DecoratingDataSource.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DecoratingDataSource.java
index 81269c9..66fdd78 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DecoratingDataSource.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DecoratingDataSource.java
@@ -1,103 +1,103 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.jdbc;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import javax.sql.DataSource;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Delegating data source that maintains a list of {@link ConnectionDecorator}s.
- *
- * @author Abe White
- * @nojavadoc
- */
-public class DecoratingDataSource extends DelegatingDataSource {
-
-    private List _decorators = new CopyOnWriteArrayList();
-
-    /**
-     * Constructor. Supply wrapped data source.
-     */
-    public DecoratingDataSource(DataSource ds) {
-        super(ds);
-    }
-
-    /**
-     * Return a read-only list of connection decorators in the order they were
-     * added.
-     */
-    public Collection getDecorators() {
-        return Collections.unmodifiableCollection(_decorators);
-    }
-
-    /**
-     * Add a connection decorator.
-     */
-    public void addDecorator(ConnectionDecorator decorator) {
-        if (decorator != null)
-            _decorators.add(decorator);
-    }
-
-    /**
-     * Add multiple connection decorators efficiently.
-     */
-    public void addDecorators(Collection decorators) {
-        if (decorators != null)
-            _decorators.addAll(decorators);
-    }
-
-    /**
-     * Remove a connection decorator.
-     */
-    public boolean removeDecorator(ConnectionDecorator decorator) {
-        return _decorators.remove(decorator);
-    }
-
-    /**
-     * Clear all decorators.
-     */
-    public void clearDecorators() {
-        _decorators.clear();
-    }
-
-    public Connection getConnection() throws SQLException {
-        Connection conn = super.getConnection();
-        return decorate(conn);
-    }
-
-    public Connection getConnection(String user, String pass)
-        throws SQLException {
-        Connection conn = super.getConnection(user, pass);
-        return decorate(conn);
-    }
-
-    private Connection decorate(Connection conn) throws SQLException {
-        if (!_decorators.isEmpty())
-            for (Iterator itr = _decorators.iterator(); itr.hasNext();)
-                conn = ((ConnectionDecorator) itr.next()).decorate(conn);
-        return conn;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import javax.sql.DataSource;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Delegating data source that maintains a list of {@link ConnectionDecorator}s.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public class DecoratingDataSource extends DelegatingDataSource {
+
+    private List _decorators = new CopyOnWriteArrayList();
+
+    /**
+     * Constructor. Supply wrapped data source.
+     */
+    public DecoratingDataSource(DataSource ds) {
+        super(ds);
+    }
+
+    /**
+     * Return a read-only list of connection decorators in the order they were
+     * added.
+     */
+    public Collection getDecorators() {
+        return Collections.unmodifiableCollection(_decorators);
+    }
+
+    /**
+     * Add a connection decorator.
+     */
+    public void addDecorator(ConnectionDecorator decorator) {
+        if (decorator != null)
+            _decorators.add(decorator);
+    }
+
+    /**
+     * Add multiple connection decorators efficiently.
+     */
+    public void addDecorators(Collection decorators) {
+        if (decorators != null)
+            _decorators.addAll(decorators);
+    }
+
+    /**
+     * Remove a connection decorator.
+     */
+    public boolean removeDecorator(ConnectionDecorator decorator) {
+        return _decorators.remove(decorator);
+    }
+
+    /**
+     * Clear all decorators.
+     */
+    public void clearDecorators() {
+        _decorators.clear();
+    }
+
+    public Connection getConnection() throws SQLException {
+        Connection conn = super.getConnection();
+        return decorate(conn);
+    }
+
+    public Connection getConnection(String user, String pass)
+        throws SQLException {
+        Connection conn = super.getConnection(user, pass);
+        return decorate(conn);
+    }
+
+    private Connection decorate(Connection conn) throws SQLException {
+        if (!_decorators.isEmpty())
+            for (Iterator itr = _decorators.iterator(); itr.hasNext();)
+                conn = ((ConnectionDecorator) itr.next()).decorate(conn);
+        return conn;
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingDatabaseMetaData.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingDatabaseMetaData.java
index 1ceadd6..6f3b4e0 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingDatabaseMetaData.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingDatabaseMetaData.java
@@ -1,773 +1,773 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.jdbc;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * Wrapper around a DatabaseMetadata instance.
- *
- * @author Marc Prud'hommeaux
- */
-public class DelegatingDatabaseMetaData implements DatabaseMetaData {
-
-    private final DatabaseMetaData _metaData;
-    private final Connection _conn;
-
-    public DelegatingDatabaseMetaData(DatabaseMetaData metaData,
-        Connection conn) {
-        _conn = conn;
-        _metaData = metaData;
-    }
-
-    /**
-     * Return the base underlying database metadata.
-     */
-    public DatabaseMetaData getInnermostDelegate() {
-        return _metaData instanceof DelegatingDatabaseMetaData ?
-            ((DelegatingDatabaseMetaData) _metaData).getInnermostDelegate()
-            : _metaData;
-    }
-
-    public int hashCode() {
-        return getInnermostDelegate().hashCode();
-    }
-
-    public boolean equals(Object other) {
-        if (other == this)
-            return true;
-        if (other instanceof DelegatingDatabaseMetaData)
-            other = ((DelegatingDatabaseMetaData) other)
-                .getInnermostDelegate();
-        return getInnermostDelegate().equals(other);
-    }
-
-    public String toString() {
-        StringBuffer buf = new StringBuffer("metadata ").append(hashCode());
-        buf.append("[").append(_metaData.toString()).append("]");
-        return buf.toString();
-    }
-
-    public boolean allProceduresAreCallable() throws SQLException {
-        return _metaData.allProceduresAreCallable();
-    }
-
-    public boolean allTablesAreSelectable() throws SQLException {
-        return _metaData.allTablesAreSelectable();
-    }
-
-    public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
-        return _metaData.dataDefinitionCausesTransactionCommit();
-    }
-
-    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
-        return _metaData.dataDefinitionIgnoredInTransactions();
-    }
-
-    public boolean deletesAreDetected(int type) throws SQLException {
-        return _metaData.deletesAreDetected(type);
-    }
-
-    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
-        return _metaData.doesMaxRowSizeIncludeBlobs();
-    }
-
-    public ResultSet getBestRowIdentifier(String catalog,
-        String schema, String table, int scope, boolean nullable)
-        throws SQLException {
-        return _metaData.getBestRowIdentifier(catalog, schema,
-            table, scope, nullable);
-    }
-
-    public ResultSet getCatalogs() throws SQLException {
-        return _metaData.getCatalogs();
-    }
-
-    public String getCatalogSeparator() throws SQLException {
-        return _metaData.getCatalogSeparator();
-    }
-
-    public String getCatalogTerm() throws SQLException {
-        return _metaData.getCatalogTerm();
-    }
-
-    public ResultSet getColumnPrivileges(String catalog, String schema,
-        String table, String columnNamePattern) throws SQLException {
-        return _metaData.getColumnPrivileges(catalog, schema,
-            table, columnNamePattern);
-    }
-
-    public ResultSet getColumns(String catalog, String schemaPattern,
-        String tableNamePattern, String columnNamePattern) throws SQLException {
-        return _metaData.getColumns(catalog, schemaPattern,
-            tableNamePattern, columnNamePattern);
-    }
-
-    public Connection getConnection() throws SQLException {
-        return _conn;
-    }
-
-    public ResultSet getCrossReference(String primaryCatalog,
-        String primarySchema, String primaryTable, String foreignCatalog,
-        String foreignSchema, String foreignTable) throws SQLException {
-        return _metaData.getCrossReference(primaryCatalog, primarySchema,
-            primaryTable, foreignCatalog, foreignSchema, foreignTable);
-    }
-
-    public String getDatabaseProductName() throws SQLException {
-        return _metaData.getDatabaseProductName();
-    }
-
-    public String getDatabaseProductVersion() throws SQLException {
-        return _metaData.getDatabaseProductVersion();
-    }
-
-    public int getDefaultTransactionIsolation() throws SQLException {
-        return _metaData.getDefaultTransactionIsolation();
-    }
-
-    public int getDriverMajorVersion() {
-        return _metaData.getDriverMajorVersion();
-    }
-
-    public int getDriverMinorVersion() {
-        return _metaData.getDriverMinorVersion();
-    }
-
-    public String getDriverName() throws SQLException {
-        return _metaData.getDriverName();
-    }
-
-    public String getDriverVersion() throws SQLException {
-        return _metaData.getDriverVersion();
-    }
-
-    public ResultSet getExportedKeys(String catalog, String schema,
-        String table) throws SQLException {
-        return _metaData.getExportedKeys(catalog, schema, table);
-    }
-
-    public String getExtraNameCharacters() throws SQLException {
-        return _metaData.getExtraNameCharacters();
-    }
-
-    public String getIdentifierQuoteString() throws SQLException {
-        return _metaData.getIdentifierQuoteString();
-    }
-
-    public ResultSet getImportedKeys(String catalog, String schema,
-        String table) throws SQLException {
-        return _metaData.getImportedKeys(catalog, schema, table);
-    }
-
-    public ResultSet getIndexInfo(String catalog, String schema,
-        String table, boolean unique, boolean approximate) throws SQLException {
-        return _metaData.getIndexInfo(catalog, schema, table, unique,
-            approximate);
-    }
-
-    public int getMaxBinaryLiteralLength() throws SQLException {
-        return _metaData.getMaxBinaryLiteralLength();
-    }
-
-    public int getMaxCatalogNameLength() throws SQLException {
-        return _metaData.getMaxCatalogNameLength();
-    }
-
-    public int getMaxCharLiteralLength() throws SQLException {
-        return _metaData.getMaxCharLiteralLength();
-    }
-
-    public int getMaxColumnNameLength() throws SQLException {
-        return _metaData.getMaxColumnNameLength();
-    }
-
-    public int getMaxColumnsInGroupBy() throws SQLException {
-        return _metaData.getMaxColumnsInGroupBy();
-    }
-
-    public int getMaxColumnsInIndex() throws SQLException {
-        return _metaData.getMaxColumnsInIndex();
-    }
-
-    public int getMaxColumnsInOrderBy() throws SQLException {
-        return _metaData.getMaxColumnsInOrderBy();
-    }
-
-    public int getMaxColumnsInSelect() throws SQLException {
-        return _metaData.getMaxColumnsInSelect();
-    }
-
-    public int getMaxColumnsInTable() throws SQLException {
-        return _metaData.getMaxColumnsInTable();
-    }
-
-    public int getMaxConnections() throws SQLException {
-        return _metaData.getMaxConnections();
-    }
-
-    public int getMaxCursorNameLength() throws SQLException {
-        return _metaData.getMaxCursorNameLength();
-    }
-
-    public int getMaxIndexLength() throws SQLException {
-        return _metaData.getMaxIndexLength();
-    }
-
-    public int getMaxProcedureNameLength() throws SQLException {
-        return _metaData.getMaxProcedureNameLength();
-    }
-
-    public int getMaxRowSize() throws SQLException {
-        return _metaData.getMaxRowSize();
-    }
-
-    public int getMaxSchemaNameLength() throws SQLException {
-        return _metaData.getMaxSchemaNameLength();
-    }
-
-    public int getMaxStatementLength() throws SQLException {
-        return _metaData.getMaxStatementLength();
-    }
-
-    public int getMaxStatements() throws SQLException {
-        return _metaData.getMaxStatements();
-    }
-
-    public int getMaxTableNameLength() throws SQLException {
-        return _metaData.getMaxTableNameLength();
-    }
-
-    public int getMaxTablesInSelect() throws SQLException {
-        return _metaData.getMaxTablesInSelect();
-    }
-
-    public int getMaxUserNameLength() throws SQLException {
-        return _metaData.getMaxUserNameLength();
-    }
-
-    public String getNumericFunctions() throws SQLException {
-        return _metaData.getNumericFunctions();
-    }
-
-    public ResultSet getPrimaryKeys(String catalog, String schema, String table)
-        throws SQLException {
-        return _metaData.getPrimaryKeys(catalog, schema, table);
-    }
-
-    public ResultSet getProcedureColumns(String catalog, String schemaPattern,
-        String procedureNamePattern, String columnNamePattern)
-        throws SQLException {
-        return _metaData.getProcedureColumns(catalog, schemaPattern,
-            procedureNamePattern, columnNamePattern);
-    }
-
-    public ResultSet getProcedures(String catalog, String schemaPattern,
-        String procedureNamePattern) throws SQLException {
-        return _metaData.getProcedures(catalog, schemaPattern,
-            procedureNamePattern);
-    }
-
-    public String getProcedureTerm() throws SQLException {
-        return _metaData.getProcedureTerm();
-    }
-
-    public ResultSet getSchemas() throws SQLException {
-        return _metaData.getSchemas();
-    }
-
-    public String getSchemaTerm() throws SQLException {
-        return _metaData.getSchemaTerm();
-    }
-
-    public String getSearchStringEscape() throws SQLException {
-        return _metaData.getSearchStringEscape();
-    }
-
-    public String getSQLKeywords() throws SQLException {
-        return _metaData.getSQLKeywords();
-    }
-
-    public String getStringFunctions() throws SQLException {
-        return _metaData.getStringFunctions();
-    }
-
-    public String getSystemFunctions() throws SQLException {
-        return _metaData.getSystemFunctions();
-    }
-
-    public ResultSet getTablePrivileges(String catalog,
-        String schemaPattern, String tableNamePattern) throws SQLException {
-        return _metaData.getTablePrivileges(catalog, schemaPattern,
-            tableNamePattern);
-    }
-
-    public ResultSet getTables(String catalog, String schemaPattern,
-        String tableNamePattern, String[] types) throws SQLException {
-        return _metaData.getTables(catalog, schemaPattern,
-            tableNamePattern, types);
-    }
-
-    public ResultSet getTableTypes() throws SQLException {
-        return _metaData.getTableTypes();
-    }
-
-    public String getTimeDateFunctions() throws SQLException {
-        return _metaData.getTimeDateFunctions();
-    }
-
-    public ResultSet getTypeInfo() throws SQLException {
-        return _metaData.getTypeInfo();
-    }
-
-    public ResultSet getUDTs(String catalog, String schemaPattern,
-        String typeNamePattern, int[] types) throws SQLException {
-        return _metaData.getUDTs(catalog, schemaPattern,
-            typeNamePattern, types);
-    }
-
-    public String getURL() throws SQLException {
-        return _metaData.getURL();
-    }
-
-    public String getUserName() throws SQLException {
-        return _metaData.getUserName();
-    }
-
-    public ResultSet getVersionColumns(String catalog,
-        String schema, String table) throws SQLException {
-        return _metaData.getVersionColumns(catalog, schema, table);
-    }
-
-    public boolean insertsAreDetected(int type) throws SQLException {
-        return _metaData.insertsAreDetected(type);
-    }
-
-    public boolean isCatalogAtStart() throws SQLException {
-        return _metaData.isCatalogAtStart();
-    }
-
-    public boolean isReadOnly() throws SQLException {
-        return _metaData.isReadOnly();
-    }
-
-    public boolean nullPlusNonNullIsNull() throws SQLException {
-        return _metaData.nullPlusNonNullIsNull();
-    }
-
-    public boolean nullsAreSortedAtEnd() throws SQLException {
-        return _metaData.nullsAreSortedAtEnd();
-    }
-
-    public boolean nullsAreSortedAtStart() throws SQLException {
-        return _metaData.nullsAreSortedAtStart();
-    }
-
-    public boolean nullsAreSortedHigh() throws SQLException {
-        return _metaData.nullsAreSortedHigh();
-    }
-
-    public boolean nullsAreSortedLow() throws SQLException {
-        return _metaData.nullsAreSortedLow();
-    }
-
-    public boolean othersDeletesAreVisible(int type) throws SQLException {
-        return _metaData.othersDeletesAreVisible(type);
-    }
-
-    public boolean othersInsertsAreVisible(int type) throws SQLException {
-        return _metaData.othersInsertsAreVisible(type);
-    }
-
-    public boolean othersUpdatesAreVisible(int type) throws SQLException {
-        return _metaData.othersUpdatesAreVisible(type);
-    }
-
-    public boolean ownDeletesAreVisible(int type) throws SQLException {
-        return _metaData.ownDeletesAreVisible(type);
-    }
-
-    public boolean ownInsertsAreVisible(int type) throws SQLException {
-        return _metaData.ownInsertsAreVisible(type);
-    }
-
-    public boolean ownUpdatesAreVisible(int type) throws SQLException {
-        return _metaData.ownUpdatesAreVisible(type);
-    }
-
-    public boolean storesLowerCaseIdentifiers() throws SQLException {
-        return _metaData.storesLowerCaseIdentifiers();
-    }
-
-    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
-        return _metaData.storesLowerCaseQuotedIdentifiers();
-    }
-
-    public boolean storesMixedCaseIdentifiers() throws SQLException {
-        return _metaData.storesMixedCaseIdentifiers();
-    }
-
-    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
-        return _metaData.storesMixedCaseQuotedIdentifiers();
-    }
-
-    public boolean storesUpperCaseIdentifiers() throws SQLException {
-        return _metaData.storesUpperCaseIdentifiers();
-    }
-
-    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
-        return _metaData.storesUpperCaseQuotedIdentifiers();
-    }
-
-    public boolean supportsAlterTableWithAddColumn() throws SQLException {
-        return _metaData.supportsAlterTableWithAddColumn();
-    }
-
-    public boolean supportsAlterTableWithDropColumn() throws SQLException {
-        return _metaData.supportsAlterTableWithDropColumn();
-    }
-
-    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
-        return _metaData.supportsANSI92EntryLevelSQL();
-    }
-
-    public boolean supportsANSI92FullSQL() throws SQLException {
-        return _metaData.supportsANSI92FullSQL();
-    }
-
-    public boolean supportsANSI92IntermediateSQL() throws SQLException {
-        return _metaData.supportsANSI92IntermediateSQL();
-    }
-
-    public boolean supportsBatchUpdates() throws SQLException {
-        return _metaData.supportsBatchUpdates();
-    }
-
-    public boolean supportsCatalogsInDataManipulation() throws SQLException {
-        return _metaData.supportsCatalogsInDataManipulation();
-    }
-
-    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
-        return _metaData.supportsCatalogsInIndexDefinitions();
-    }
-
-    public boolean supportsCatalogsInPrivilegeDefinitions()
-        throws SQLException {
-        return _metaData.supportsCatalogsInPrivilegeDefinitions();
-    }
-
-    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
-        return _metaData.supportsCatalogsInProcedureCalls();
-    }
-
-    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
-        return _metaData.supportsCatalogsInTableDefinitions();
-    }
-
-    public boolean supportsColumnAliasing() throws SQLException {
-        return _metaData.supportsColumnAliasing();
-    }
-
-    public boolean supportsConvert() throws SQLException {
-        return _metaData.supportsConvert();
-    }
-
-    public boolean supportsConvert(int fromType, int toType)
-        throws SQLException {
-        return _metaData.supportsConvert(fromType, toType);
-    }
-
-    public boolean supportsCoreSQLGrammar() throws SQLException {
-        return _metaData.supportsCoreSQLGrammar();
-    }
-
-    public boolean supportsCorrelatedSubqueries() throws SQLException {
-        return _metaData.supportsCorrelatedSubqueries();
-    }
-
-    public boolean supportsDataDefinitionAndDataManipulationTransactions()
-        throws SQLException {
-        return _metaData
-            .supportsDataDefinitionAndDataManipulationTransactions();
-    }
-
-    public boolean supportsDataManipulationTransactionsOnly()
-        throws SQLException {
-        return _metaData.supportsDataManipulationTransactionsOnly();
-    }
-
-    public boolean supportsDifferentTableCorrelationNames()
-        throws SQLException {
-        return _metaData.supportsDifferentTableCorrelationNames();
-    }
-
-    public boolean supportsExpressionsInOrderBy() throws SQLException {
-        return _metaData.supportsExpressionsInOrderBy();
-    }
-
-    public boolean supportsExtendedSQLGrammar() throws SQLException {
-        return _metaData.supportsExtendedSQLGrammar();
-    }
-
-    public boolean supportsFullOuterJoins() throws SQLException {
-        return _metaData.supportsFullOuterJoins();
-    }
-
-    public boolean supportsGroupBy() throws SQLException {
-        return _metaData.supportsGroupBy();
-    }
-
-    public boolean supportsGroupByBeyondSelect() throws SQLException {
-        return _metaData.supportsGroupByBeyondSelect();
-    }
-
-    public boolean supportsGroupByUnrelated() throws SQLException {
-        return _metaData.supportsGroupByUnrelated();
-    }
-
-    public boolean supportsIntegrityEnhancementFacility() throws SQLException {
-        return _metaData.supportsIntegrityEnhancementFacility();
-    }
-
-    public boolean supportsLikeEscapeClause() throws SQLException {
-        return _metaData.supportsLikeEscapeClause();
-    }
-
-    public boolean supportsLimitedOuterJoins() throws SQLException {
-        return _metaData.supportsLimitedOuterJoins();
-    }
-
-    public boolean supportsMinimumSQLGrammar() throws SQLException {
-        return _metaData.supportsMinimumSQLGrammar();
-    }
-
-    public boolean supportsMixedCaseIdentifiers() throws SQLException {
-        return _metaData.supportsMixedCaseIdentifiers();
-    }
-
-    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
-        return _metaData.supportsMixedCaseQuotedIdentifiers();
-    }
-
-    public boolean supportsMultipleResultSets() throws SQLException {
-        return _metaData.supportsMultipleResultSets();
-    }
-
-    public boolean supportsMultipleTransactions() throws SQLException {
-        return _metaData.supportsMultipleTransactions();
-    }
-
-    public boolean supportsNonNullableColumns() throws SQLException {
-        return _metaData.supportsNonNullableColumns();
-    }
-
-    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
-        return _metaData.supportsOpenCursorsAcrossCommit();
-    }
-
-    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
-        return _metaData.supportsOpenCursorsAcrossRollback();
-    }
-
-    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
-        return _metaData.supportsOpenStatementsAcrossCommit();
-    }
-
-    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
-        return _metaData.supportsOpenStatementsAcrossRollback();
-    }
-
-    public boolean supportsOrderByUnrelated() throws SQLException {
-        return _metaData.supportsOrderByUnrelated();
-    }
-
-    public boolean supportsOuterJoins() throws SQLException {
-        return _metaData.supportsOuterJoins();
-    }
-
-    public boolean supportsPositionedDelete() throws SQLException {
-        return _metaData.supportsPositionedDelete();
-    }
-
-    public boolean supportsPositionedUpdate() throws SQLException {
-        return _metaData.supportsPositionedUpdate();
-    }
-
-    public boolean supportsResultSetConcurrency(int type, int concurrency)
-        throws SQLException {
-        return _metaData.supportsResultSetConcurrency(type, concurrency);
-    }
-
-    public boolean supportsResultSetType(int type) throws SQLException {
-        return _metaData.supportsResultSetType(type);
-    }
-
-    public boolean supportsSchemasInDataManipulation() throws SQLException {
-        return _metaData.supportsSchemasInDataManipulation();
-    }
-
-    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
-        return _metaData.supportsSchemasInIndexDefinitions();
-    }
-
-    public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
-        return _metaData.supportsSchemasInPrivilegeDefinitions();
-    }
-
-    public boolean supportsSchemasInProcedureCalls() throws SQLException {
-        return _metaData.supportsSchemasInProcedureCalls();
-    }
-
-    public boolean supportsSchemasInTableDefinitions() throws SQLException {
-        return _metaData.supportsSchemasInTableDefinitions();
-    }
-
-    public boolean supportsSelectForUpdate() throws SQLException {
-        return _metaData.supportsSelectForUpdate();
-    }
-
-    public boolean supportsStoredProcedures() throws SQLException {
-        return _metaData.supportsStoredProcedures();
-    }
-
-    public boolean supportsSubqueriesInComparisons() throws SQLException {
-        return _metaData.supportsSubqueriesInComparisons();
-    }
-
-    public boolean supportsSubqueriesInExists() throws SQLException {
-        return _metaData.supportsSubqueriesInExists();
-    }
-
-    public boolean supportsSubqueriesInIns() throws SQLException {
-        return _metaData.supportsSubqueriesInIns();
-    }
-
-    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
-        return _metaData.supportsSubqueriesInQuantifieds();
-    }
-
-    public boolean supportsTableCorrelationNames() throws SQLException {
-        return _metaData.supportsTableCorrelationNames();
-    }
-
-    public boolean supportsTransactionIsolationLevel(int level)
-        throws SQLException {
-        return _metaData.supportsTransactionIsolationLevel(level);
-    }
-
-    public boolean supportsTransactions() throws SQLException {
-        return _metaData.supportsTransactions();
-    }
-
-    public boolean supportsUnion() throws SQLException {
-        return _metaData.supportsUnion();
-    }
-
-    public boolean supportsUnionAll() throws SQLException {
-        return _metaData.supportsUnionAll();
-    }
-
-    public boolean updatesAreDetected(int type) throws SQLException {
-        return _metaData.updatesAreDetected(type);
-    }
-
-    public boolean usesLocalFilePerTable() throws SQLException {
-        return _metaData.usesLocalFilePerTable();
-    }
-
-    public boolean usesLocalFiles() throws SQLException {
-        return _metaData.usesLocalFiles();
-    }
-
-    // JDBC 3.0 methods(unsupported) follow; these are required to be able to
-    // compile against JDK 1.4
-
-    public boolean supportsSavepoints() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean supportsNamedParameters() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean supportsMultipleOpenResults() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean supportsGetGeneratedKeys() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public ResultSet getSuperTypes(String catalog, String schemaPatter,
-        String typeNamePattern) throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public ResultSet getSuperTables(String catalog, String schemaPatter,
-        String tableNamePattern) throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public ResultSet getAttributes(String catalog, String schemaPatter,
-        String typeNamePattern, String attributeNamePattern)
-        throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean supportsResultSetHoldability(int holdability)
-        throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public int getResultSetHoldability() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public int getDatabaseMajorVersion() throws SQLException {
-        return _metaData.getDatabaseMajorVersion();
-    }
-
-    public int getDatabaseMinorVersion() throws SQLException {
-        return _metaData.getDatabaseMinorVersion();
-    }
-
-    public int getJDBCMajorVersion() throws SQLException {
-        return _metaData.getJDBCMajorVersion();
-    }
-
-    public int getJDBCMinorVersion() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public int getSQLStateType() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean locatorsUpdateCopy() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean supportsStatementPooling() throws SQLException {
-        throw new UnsupportedOperationException();
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Wrapper around a DatabaseMetadata instance.
+ *
+ * @author Marc Prud'hommeaux
+ */
+public class DelegatingDatabaseMetaData implements DatabaseMetaData {
+
+    private final DatabaseMetaData _metaData;
+    private final Connection _conn;
+
+    public DelegatingDatabaseMetaData(DatabaseMetaData metaData,
+        Connection conn) {
+        _conn = conn;
+        _metaData = metaData;
+    }
+
+    /**
+     * Return the base underlying database metadata.
+     */
+    public DatabaseMetaData getInnermostDelegate() {
+        return _metaData instanceof DelegatingDatabaseMetaData ?
+            ((DelegatingDatabaseMetaData) _metaData).getInnermostDelegate()
+            : _metaData;
+    }
+
+    public int hashCode() {
+        return getInnermostDelegate().hashCode();
+    }
+
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (other instanceof DelegatingDatabaseMetaData)
+            other = ((DelegatingDatabaseMetaData) other)
+                .getInnermostDelegate();
+        return getInnermostDelegate().equals(other);
+    }
+
+    public String toString() {
+        StringBuffer buf = new StringBuffer("metadata ").append(hashCode());
+        buf.append("[").append(_metaData.toString()).append("]");
+        return buf.toString();
+    }
+
+    public boolean allProceduresAreCallable() throws SQLException {
+        return _metaData.allProceduresAreCallable();
+    }
+
+    public boolean allTablesAreSelectable() throws SQLException {
+        return _metaData.allTablesAreSelectable();
+    }
+
+    public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+        return _metaData.dataDefinitionCausesTransactionCommit();
+    }
+
+    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+        return _metaData.dataDefinitionIgnoredInTransactions();
+    }
+
+    public boolean deletesAreDetected(int type) throws SQLException {
+        return _metaData.deletesAreDetected(type);
+    }
+
+    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+        return _metaData.doesMaxRowSizeIncludeBlobs();
+    }
+
+    public ResultSet getBestRowIdentifier(String catalog,
+        String schema, String table, int scope, boolean nullable)
+        throws SQLException {
+        return _metaData.getBestRowIdentifier(catalog, schema,
+            table, scope, nullable);
+    }
+
+    public ResultSet getCatalogs() throws SQLException {
+        return _metaData.getCatalogs();
+    }
+
+    public String getCatalogSeparator() throws SQLException {
+        return _metaData.getCatalogSeparator();
+    }
+
+    public String getCatalogTerm() throws SQLException {
+        return _metaData.getCatalogTerm();
+    }
+
+    public ResultSet getColumnPrivileges(String catalog, String schema,
+        String table, String columnNamePattern) throws SQLException {
+        return _metaData.getColumnPrivileges(catalog, schema,
+            table, columnNamePattern);
+    }
+
+    public ResultSet getColumns(String catalog, String schemaPattern,
+        String tableNamePattern, String columnNamePattern) throws SQLException {
+        return _metaData.getColumns(catalog, schemaPattern,
+            tableNamePattern, columnNamePattern);
+    }
+
+    public Connection getConnection() throws SQLException {
+        return _conn;
+    }
+
+    public ResultSet getCrossReference(String primaryCatalog,
+        String primarySchema, String primaryTable, String foreignCatalog,
+        String foreignSchema, String foreignTable) throws SQLException {
+        return _metaData.getCrossReference(primaryCatalog, primarySchema,
+            primaryTable, foreignCatalog, foreignSchema, foreignTable);
+    }
+
+    public String getDatabaseProductName() throws SQLException {
+        return _metaData.getDatabaseProductName();
+    }
+
+    public String getDatabaseProductVersion() throws SQLException {
+        return _metaData.getDatabaseProductVersion();
+    }
+
+    public int getDefaultTransactionIsolation() throws SQLException {
+        return _metaData.getDefaultTransactionIsolation();
+    }
+
+    public int getDriverMajorVersion() {
+        return _metaData.getDriverMajorVersion();
+    }
+
+    public int getDriverMinorVersion() {
+        return _metaData.getDriverMinorVersion();
+    }
+
+    public String getDriverName() throws SQLException {
+        return _metaData.getDriverName();
+    }
+
+    public String getDriverVersion() throws SQLException {
+        return _metaData.getDriverVersion();
+    }
+
+    public ResultSet getExportedKeys(String catalog, String schema,
+        String table) throws SQLException {
+        return _metaData.getExportedKeys(catalog, schema, table);
+    }
+
+    public String getExtraNameCharacters() throws SQLException {
+        return _metaData.getExtraNameCharacters();
+    }
+
+    public String getIdentifierQuoteString() throws SQLException {
+        return _metaData.getIdentifierQuoteString();
+    }
+
+    public ResultSet getImportedKeys(String catalog, String schema,
+        String table) throws SQLException {
+        return _metaData.getImportedKeys(catalog, schema, table);
+    }
+
+    public ResultSet getIndexInfo(String catalog, String schema,
+        String table, boolean unique, boolean approximate) throws SQLException {
+        return _metaData.getIndexInfo(catalog, schema, table, unique,
+            approximate);
+    }
+
+    public int getMaxBinaryLiteralLength() throws SQLException {
+        return _metaData.getMaxBinaryLiteralLength();
+    }
+
+    public int getMaxCatalogNameLength() throws SQLException {
+        return _metaData.getMaxCatalogNameLength();
+    }
+
+    public int getMaxCharLiteralLength() throws SQLException {
+        return _metaData.getMaxCharLiteralLength();
+    }
+
+    public int getMaxColumnNameLength() throws SQLException {
+        return _metaData.getMaxColumnNameLength();
+    }
+
+    public int getMaxColumnsInGroupBy() throws SQLException {
+        return _metaData.getMaxColumnsInGroupBy();
+    }
+
+    public int getMaxColumnsInIndex() throws SQLException {
+        return _metaData.getMaxColumnsInIndex();
+    }
+
+    public int getMaxColumnsInOrderBy() throws SQLException {
+        return _metaData.getMaxColumnsInOrderBy();
+    }
+
+    public int getMaxColumnsInSelect() throws SQLException {
+        return _metaData.getMaxColumnsInSelect();
+    }
+
+    public int getMaxColumnsInTable() throws SQLException {
+        return _metaData.getMaxColumnsInTable();
+    }
+
+    public int getMaxConnections() throws SQLException {
+        return _metaData.getMaxConnections();
+    }
+
+    public int getMaxCursorNameLength() throws SQLException {
+        return _metaData.getMaxCursorNameLength();
+    }
+
+    public int getMaxIndexLength() throws SQLException {
+        return _metaData.getMaxIndexLength();
+    }
+
+    public int getMaxProcedureNameLength() throws SQLException {
+        return _metaData.getMaxProcedureNameLength();
+    }
+
+    public int getMaxRowSize() throws SQLException {
+        return _metaData.getMaxRowSize();
+    }
+
+    public int getMaxSchemaNameLength() throws SQLException {
+        return _metaData.getMaxSchemaNameLength();
+    }
+
+    public int getMaxStatementLength() throws SQLException {
+        return _metaData.getMaxStatementLength();
+    }
+
+    public int getMaxStatements() throws SQLException {
+        return _metaData.getMaxStatements();
+    }
+
+    public int getMaxTableNameLength() throws SQLException {
+        return _metaData.getMaxTableNameLength();
+    }
+
+    public int getMaxTablesInSelect() throws SQLException {
+        return _metaData.getMaxTablesInSelect();
+    }
+
+    public int getMaxUserNameLength() throws SQLException {
+        return _metaData.getMaxUserNameLength();
+    }
+
+    public String getNumericFunctions() throws SQLException {
+        return _metaData.getNumericFunctions();
+    }
+
+    public ResultSet getPrimaryKeys(String catalog, String schema, String table)
+        throws SQLException {
+        return _metaData.getPrimaryKeys(catalog, schema, table);
+    }
+
+    public ResultSet getProcedureColumns(String catalog, String schemaPattern,
+        String procedureNamePattern, String columnNamePattern)
+        throws SQLException {
+        return _metaData.getProcedureColumns(catalog, schemaPattern,
+            procedureNamePattern, columnNamePattern);
+    }
+
+    public ResultSet getProcedures(String catalog, String schemaPattern,
+        String procedureNamePattern) throws SQLException {
+        return _metaData.getProcedures(catalog, schemaPattern,
+            procedureNamePattern);
+    }
+
+    public String getProcedureTerm() throws SQLException {
+        return _metaData.getProcedureTerm();
+    }
+
+    public ResultSet getSchemas() throws SQLException {
+        return _metaData.getSchemas();
+    }
+
+    public String getSchemaTerm() throws SQLException {
+        return _metaData.getSchemaTerm();
+    }
+
+    public String getSearchStringEscape() throws SQLException {
+        return _metaData.getSearchStringEscape();
+    }
+
+    public String getSQLKeywords() throws SQLException {
+        return _metaData.getSQLKeywords();
+    }
+
+    public String getStringFunctions() throws SQLException {
+        return _metaData.getStringFunctions();
+    }
+
+    public String getSystemFunctions() throws SQLException {
+        return _metaData.getSystemFunctions();
+    }
+
+    public ResultSet getTablePrivileges(String catalog,
+        String schemaPattern, String tableNamePattern) throws SQLException {
+        return _metaData.getTablePrivileges(catalog, schemaPattern,
+            tableNamePattern);
+    }
+
+    public ResultSet getTables(String catalog, String schemaPattern,
+        String tableNamePattern, String[] types) throws SQLException {
+        return _metaData.getTables(catalog, schemaPattern,
+            tableNamePattern, types);
+    }
+
+    public ResultSet getTableTypes() throws SQLException {
+        return _metaData.getTableTypes();
+    }
+
+    public String getTimeDateFunctions() throws SQLException {
+        return _metaData.getTimeDateFunctions();
+    }
+
+    public ResultSet getTypeInfo() throws SQLException {
+        return _metaData.getTypeInfo();
+    }
+
+    public ResultSet getUDTs(String catalog, String schemaPattern,
+        String typeNamePattern, int[] types) throws SQLException {
+        return _metaData.getUDTs(catalog, schemaPattern,
+            typeNamePattern, types);
+    }
+
+    public String getURL() throws SQLException {
+        return _metaData.getURL();
+    }
+
+    public String getUserName() throws SQLException {
+        return _metaData.getUserName();
+    }
+
+    public ResultSet getVersionColumns(String catalog,
+        String schema, String table) throws SQLException {
+        return _metaData.getVersionColumns(catalog, schema, table);
+    }
+
+    public boolean insertsAreDetected(int type) throws SQLException {
+        return _metaData.insertsAreDetected(type);
+    }
+
+    public boolean isCatalogAtStart() throws SQLException {
+        return _metaData.isCatalogAtStart();
+    }
+
+    public boolean isReadOnly() throws SQLException {
+        return _metaData.isReadOnly();
+    }
+
+    public boolean nullPlusNonNullIsNull() throws SQLException {
+        return _metaData.nullPlusNonNullIsNull();
+    }
+
+    public boolean nullsAreSortedAtEnd() throws SQLException {
+        return _metaData.nullsAreSortedAtEnd();
+    }
+
+    public boolean nullsAreSortedAtStart() throws SQLException {
+        return _metaData.nullsAreSortedAtStart();
+    }
+
+    public boolean nullsAreSortedHigh() throws SQLException {
+        return _metaData.nullsAreSortedHigh();
+    }
+
+    public boolean nullsAreSortedLow() throws SQLException {
+        return _metaData.nullsAreSortedLow();
+    }
+
+    public boolean othersDeletesAreVisible(int type) throws SQLException {
+        return _metaData.othersDeletesAreVisible(type);
+    }
+
+    public boolean othersInsertsAreVisible(int type) throws SQLException {
+        return _metaData.othersInsertsAreVisible(type);
+    }
+
+    public boolean othersUpdatesAreVisible(int type) throws SQLException {
+        return _metaData.othersUpdatesAreVisible(type);
+    }
+
+    public boolean ownDeletesAreVisible(int type) throws SQLException {
+        return _metaData.ownDeletesAreVisible(type);
+    }
+
+    public boolean ownInsertsAreVisible(int type) throws SQLException {
+        return _metaData.ownInsertsAreVisible(type);
+    }
+
+    public boolean ownUpdatesAreVisible(int type) throws SQLException {
+        return _metaData.ownUpdatesAreVisible(type);
+    }
+
+    public boolean storesLowerCaseIdentifiers() throws SQLException {
+        return _metaData.storesLowerCaseIdentifiers();
+    }
+
+    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+        return _metaData.storesLowerCaseQuotedIdentifiers();
+    }
+
+    public boolean storesMixedCaseIdentifiers() throws SQLException {
+        return _metaData.storesMixedCaseIdentifiers();
+    }
+
+    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+        return _metaData.storesMixedCaseQuotedIdentifiers();
+    }
+
+    public boolean storesUpperCaseIdentifiers() throws SQLException {
+        return _metaData.storesUpperCaseIdentifiers();
+    }
+
+    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+        return _metaData.storesUpperCaseQuotedIdentifiers();
+    }
+
+    public boolean supportsAlterTableWithAddColumn() throws SQLException {
+        return _metaData.supportsAlterTableWithAddColumn();
+    }
+
+    public boolean supportsAlterTableWithDropColumn() throws SQLException {
+        return _metaData.supportsAlterTableWithDropColumn();
+    }
+
+    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+        return _metaData.supportsANSI92EntryLevelSQL();
+    }
+
+    public boolean supportsANSI92FullSQL() throws SQLException {
+        return _metaData.supportsANSI92FullSQL();
+    }
+
+    public boolean supportsANSI92IntermediateSQL() throws SQLException {
+        return _metaData.supportsANSI92IntermediateSQL();
+    }
+
+    public boolean supportsBatchUpdates() throws SQLException {
+        return _metaData.supportsBatchUpdates();
+    }
+
+    public boolean supportsCatalogsInDataManipulation() throws SQLException {
+        return _metaData.supportsCatalogsInDataManipulation();
+    }
+
+    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+        return _metaData.supportsCatalogsInIndexDefinitions();
+    }
+
+    public boolean supportsCatalogsInPrivilegeDefinitions()
+        throws SQLException {
+        return _metaData.supportsCatalogsInPrivilegeDefinitions();
+    }
+
+    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+        return _metaData.supportsCatalogsInProcedureCalls();
+    }
+
+    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+        return _metaData.supportsCatalogsInTableDefinitions();
+    }
+
+    public boolean supportsColumnAliasing() throws SQLException {
+        return _metaData.supportsColumnAliasing();
+    }
+
+    public boolean supportsConvert() throws SQLException {
+        return _metaData.supportsConvert();
+    }
+
+    public boolean supportsConvert(int fromType, int toType)
+        throws SQLException {
+        return _metaData.supportsConvert(fromType, toType);
+    }
+
+    public boolean supportsCoreSQLGrammar() throws SQLException {
+        return _metaData.supportsCoreSQLGrammar();
+    }
+
+    public boolean supportsCorrelatedSubqueries() throws SQLException {
+        return _metaData.supportsCorrelatedSubqueries();
+    }
+
+    public boolean supportsDataDefinitionAndDataManipulationTransactions()
+        throws SQLException {
+        return _metaData
+            .supportsDataDefinitionAndDataManipulationTransactions();
+    }
+
+    public boolean supportsDataManipulationTransactionsOnly()
+        throws SQLException {
+        return _metaData.supportsDataManipulationTransactionsOnly();
+    }
+
+    public boolean supportsDifferentTableCorrelationNames()
+        throws SQLException {
+        return _metaData.supportsDifferentTableCorrelationNames();
+    }
+
+    public boolean supportsExpressionsInOrderBy() throws SQLException {
+        return _metaData.supportsExpressionsInOrderBy();
+    }
+
+    public boolean supportsExtendedSQLGrammar() throws SQLException {
+        return _metaData.supportsExtendedSQLGrammar();
+    }
+
+    public boolean supportsFullOuterJoins() throws SQLException {
+        return _metaData.supportsFullOuterJoins();
+    }
+
+    public boolean supportsGroupBy() throws SQLException {
+        return _metaData.supportsGroupBy();
+    }
+
+    public boolean supportsGroupByBeyondSelect() throws SQLException {
+        return _metaData.supportsGroupByBeyondSelect();
+    }
+
+    public boolean supportsGroupByUnrelated() throws SQLException {
+        return _metaData.supportsGroupByUnrelated();
+    }
+
+    public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+        return _metaData.supportsIntegrityEnhancementFacility();
+    }
+
+    public boolean supportsLikeEscapeClause() throws SQLException {
+        return _metaData.supportsLikeEscapeClause();
+    }
+
+    public boolean supportsLimitedOuterJoins() throws SQLException {
+        return _metaData.supportsLimitedOuterJoins();
+    }
+
+    public boolean supportsMinimumSQLGrammar() throws SQLException {
+        return _metaData.supportsMinimumSQLGrammar();
+    }
+
+    public boolean supportsMixedCaseIdentifiers() throws SQLException {
+        return _metaData.supportsMixedCaseIdentifiers();
+    }
+
+    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+        return _metaData.supportsMixedCaseQuotedIdentifiers();
+    }
+
+    public boolean supportsMultipleResultSets() throws SQLException {
+        return _metaData.supportsMultipleResultSets();
+    }
+
+    public boolean supportsMultipleTransactions() throws SQLException {
+        return _metaData.supportsMultipleTransactions();
+    }
+
+    public boolean supportsNonNullableColumns() throws SQLException {
+        return _metaData.supportsNonNullableColumns();
+    }
+
+    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+        return _metaData.supportsOpenCursorsAcrossCommit();
+    }
+
+    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+        return _metaData.supportsOpenCursorsAcrossRollback();
+    }
+
+    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+        return _metaData.supportsOpenStatementsAcrossCommit();
+    }
+
+    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+        return _metaData.supportsOpenStatementsAcrossRollback();
+    }
+
+    public boolean supportsOrderByUnrelated() throws SQLException {
+        return _metaData.supportsOrderByUnrelated();
+    }
+
+    public boolean supportsOuterJoins() throws SQLException {
+        return _metaData.supportsOuterJoins();
+    }
+
+    public boolean supportsPositionedDelete() throws SQLException {
+        return _metaData.supportsPositionedDelete();
+    }
+
+    public boolean supportsPositionedUpdate() throws SQLException {
+        return _metaData.supportsPositionedUpdate();
+    }
+
+    public boolean supportsResultSetConcurrency(int type, int concurrency)
+        throws SQLException {
+        return _metaData.supportsResultSetConcurrency(type, concurrency);
+    }
+
+    public boolean supportsResultSetType(int type) throws SQLException {
+        return _metaData.supportsResultSetType(type);
+    }
+
+    public boolean supportsSchemasInDataManipulation() throws SQLException {
+        return _metaData.supportsSchemasInDataManipulation();
+    }
+
+    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+        return _metaData.supportsSchemasInIndexDefinitions();
+    }
+
+    public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+        return _metaData.supportsSchemasInPrivilegeDefinitions();
+    }
+
+    public boolean supportsSchemasInProcedureCalls() throws SQLException {
+        return _metaData.supportsSchemasInProcedureCalls();
+    }
+
+    public boolean supportsSchemasInTableDefinitions() throws SQLException {
+        return _metaData.supportsSchemasInTableDefinitions();
+    }
+
+    public boolean supportsSelectForUpdate() throws SQLException {
+        return _metaData.supportsSelectForUpdate();
+    }
+
+    public boolean supportsStoredProcedures() throws SQLException {
+        return _metaData.supportsStoredProcedures();
+    }
+
+    public boolean supportsSubqueriesInComparisons() throws SQLException {
+        return _metaData.supportsSubqueriesInComparisons();
+    }
+
+    public boolean supportsSubqueriesInExists() throws SQLException {
+        return _metaData.supportsSubqueriesInExists();
+    }
+
+    public boolean supportsSubqueriesInIns() throws SQLException {
+        return _metaData.supportsSubqueriesInIns();
+    }
+
+    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+        return _metaData.supportsSubqueriesInQuantifieds();
+    }
+
+    public boolean supportsTableCorrelationNames() throws SQLException {
+        return _metaData.supportsTableCorrelationNames();
+    }
+
+    public boolean supportsTransactionIsolationLevel(int level)
+        throws SQLException {
+        return _metaData.supportsTransactionIsolationLevel(level);
+    }
+
+    public boolean supportsTransactions() throws SQLException {
+        return _metaData.supportsTransactions();
+    }
+
+    public boolean supportsUnion() throws SQLException {
+        return _metaData.supportsUnion();
+    }
+
+    public boolean supportsUnionAll() throws SQLException {
+        return _metaData.supportsUnionAll();
+    }
+
+    public boolean updatesAreDetected(int type) throws SQLException {
+        return _metaData.updatesAreDetected(type);
+    }
+
+    public boolean usesLocalFilePerTable() throws SQLException {
+        return _metaData.usesLocalFilePerTable();
+    }
+
+    public boolean usesLocalFiles() throws SQLException {
+        return _metaData.usesLocalFiles();
+    }
+
+    // JDBC 3.0 methods(unsupported) follow; these are required to be able to
+    // compile against JDK 1.4
+
+    public boolean supportsSavepoints() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean supportsNamedParameters() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean supportsMultipleOpenResults() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean supportsGetGeneratedKeys() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public ResultSet getSuperTypes(String catalog, String schemaPatter,
+        String typeNamePattern) throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public ResultSet getSuperTables(String catalog, String schemaPatter,
+        String tableNamePattern) throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public ResultSet getAttributes(String catalog, String schemaPatter,
+        String typeNamePattern, String attributeNamePattern)
+        throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean supportsResultSetHoldability(int holdability)
+        throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getResultSetHoldability() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getDatabaseMajorVersion() throws SQLException {
+        return _metaData.getDatabaseMajorVersion();
+    }
+
+    public int getDatabaseMinorVersion() throws SQLException {
+        return _metaData.getDatabaseMinorVersion();
+    }
+
+    public int getJDBCMajorVersion() throws SQLException {
+        return _metaData.getJDBCMajorVersion();
+    }
+
+    public int getJDBCMinorVersion() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getSQLStateType() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean locatorsUpdateCopy() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean supportsStatementPooling() throws SQLException {
+        throw new UnsupportedOperationException();
+    }
+}
+
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/JDBCEventConnectionDecorator.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/JDBCEventConnectionDecorator.java
index 52ed8f2..b9714b1 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/JDBCEventConnectionDecorator.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/JDBCEventConnectionDecorator.java
@@ -1,295 +1,295 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.jdbc;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-
-/**
- * Manages the firing of {@link JDBCEvent}s.
- *
- * @author Abe White
- * @nojavadoc
- */
-public class JDBCEventConnectionDecorator extends AbstractConcurrentEventManager
-    implements ConnectionDecorator {
-
-    public Connection decorate(Connection conn) {
-        if (!hasListeners())
-            return conn;
-        return new EventConnection(conn);
-    }
-
-    /**
-     * Fire the given event to all listeners. Prevents creation of an
-     * event object when there are no listeners.
-     */
-    private JDBCEvent fireEvent(Connection source, short type,
-        JDBCEvent associatedEvent, Statement stmnt, String sql) {
-        if (!hasListeners())
-            return null;
-
-        JDBCEvent event = new JDBCEvent(source, type, associatedEvent,
-            stmnt, sql);
-        fireEvent(event);
-        return event;
-    }
-
-    /**
-     * Fire the given event to all listeners.
-     */
-    protected void fireEvent(Object event, Object listener) {
-        JDBCListener listen = (JDBCListener) listener;
-        JDBCEvent ev = (JDBCEvent) event;
-        switch (ev.getType()) {
-            case JDBCEvent.BEFORE_PREPARE_STATEMENT:
-                listen.beforePrepareStatement(ev);
-                break;
-            case JDBCEvent.AFTER_PREPARE_STATEMENT:
-                listen.afterPrepareStatement(ev);
-                break;
-            case JDBCEvent.BEFORE_CREATE_STATEMENT:
-                listen.beforeCreateStatement(ev);
-                break;
-            case JDBCEvent.AFTER_CREATE_STATEMENT:
-                listen.afterCreateStatement(ev);
-                break;
-            case JDBCEvent.BEFORE_EXECUTE_STATEMENT:
-                listen.beforeExecuteStatement(ev);
-                break;
-            case JDBCEvent.AFTER_EXECUTE_STATEMENT:
-                listen.afterExecuteStatement(ev);
-                break;
-            case JDBCEvent.BEFORE_COMMIT:
-                listen.beforeCommit(ev);
-                break;
-            case JDBCEvent.AFTER_COMMIT:
-                listen.afterCommit(ev);
-                break;
-            case JDBCEvent.BEFORE_ROLLBACK:
-                listen.beforeRollback(ev);
-                break;
-            case JDBCEvent.AFTER_ROLLBACK:
-                listen.afterRollback(ev);
-                break;
-            case JDBCEvent.AFTER_CONNECT:
-                listen.afterConnect(ev);
-                break;
-            case JDBCEvent.BEFORE_CLOSE:
-                listen.beforeClose(ev);
-                break;
-        }
-    }
-
-    /**
-     * Fires events as appropriate.
-     */
-    private class EventConnection extends DelegatingConnection {
-
-        public EventConnection(Connection conn) {
-            super(conn);
-            fireEvent(getDelegate(), JDBCEvent.AFTER_CONNECT, null, null, null);
-        }
-
-        public void commit() throws SQLException {
-            JDBCEvent before = fireEvent(getDelegate(),
-                JDBCEvent.BEFORE_COMMIT, null, null, null);
-            try {
-                super.commit();
-            } finally {
-                fireEvent(getDelegate(), JDBCEvent.AFTER_COMMIT, before,
-                    null, null);
-            }
-        }
-
-        public void rollback() throws SQLException {
-            JDBCEvent before = fireEvent(getDelegate(),
-                JDBCEvent.BEFORE_ROLLBACK, null, null, null);
-            try {
-                super.rollback();
-            } finally {
-                fireEvent(getDelegate(), JDBCEvent.AFTER_ROLLBACK, before,
-                    null, null);
-            }
-        }
-
-        protected Statement createStatement(boolean wrap) throws SQLException {
-            JDBCEvent before = fireEvent(getDelegate(),
-                JDBCEvent.BEFORE_CREATE_STATEMENT, null, null, null);
-            Statement stmnt = null;
-            try {
-                stmnt = new EventStatement(super.createStatement(false),
-                    EventConnection.this);
-            } finally {
-                fireEvent(getDelegate(), JDBCEvent.AFTER_CREATE_STATEMENT,
-                    before, stmnt, null);
-            }
-            return stmnt;
-        }
-
-        protected Statement createStatement(int rsType, int rsConcur,
-            boolean wrap) throws SQLException {
-            JDBCEvent before = fireEvent(getDelegate(),
-                JDBCEvent.BEFORE_CREATE_STATEMENT, null, null, null);
-            Statement stmnt = null;
-            try {
-                stmnt = new EventStatement(super.createStatement
-                    (rsType, rsConcur, false), EventConnection.this);
-            } finally {
-                fireEvent(getDelegate(), JDBCEvent.AFTER_CREATE_STATEMENT,
-                    before, stmnt, null);
-            }
-            return stmnt;
-        }
-
-        protected PreparedStatement prepareStatement(String sql, boolean wrap)
-            throws SQLException {
-            JDBCEvent before = fireEvent(getDelegate(),
-                JDBCEvent.BEFORE_PREPARE_STATEMENT, null, null, sql);
-            PreparedStatement stmnt = null;
-            try {
-                stmnt = new EventPreparedStatement(super.prepareStatement
-                    (sql, false), EventConnection.this, sql);
-            } finally {
-                fireEvent(getDelegate(), JDBCEvent.AFTER_PREPARE_STATEMENT,
-                    before, stmnt, sql);
-            }
-            return stmnt;
-        }
-
-        protected PreparedStatement prepareStatement(String sql, int rsType,
-            int rsConcur, boolean wrap) throws SQLException {
-            JDBCEvent before = fireEvent(getDelegate(),
-                JDBCEvent.BEFORE_PREPARE_STATEMENT, null, null, sql);
-            PreparedStatement stmnt = null;
-            try {
-                stmnt = new EventPreparedStatement(super.prepareStatement
-                    (sql, rsType, rsConcur, false), EventConnection.this, sql);
-            } finally {
-                fireEvent(getDelegate(), JDBCEvent.AFTER_PREPARE_STATEMENT,
-                    before, stmnt, sql);
-            }
-            return stmnt;
-        }
-
-        public void close() throws SQLException {
-            try {
-                fireEvent(getDelegate(), JDBCEvent.BEFORE_CLOSE,
-                    null, null, null);
-            } finally {
-                super.close();
-            }
-        }
-    }
-
-    /**
-     * Fires events as appropriate.
-     */
-    private class EventPreparedStatement extends DelegatingPreparedStatement {
-
-        private final EventConnection _conn;
-        private final String _sql;
-
-        public EventPreparedStatement(PreparedStatement ps,
-            EventConnection conn, String sql) {
-            super(ps, conn);
-            _conn = conn;
-            _sql = sql;
-        }
-
-        public int executeUpdate() throws SQLException {
-            JDBCEvent before = fireEvent(_conn.getDelegate(),
-                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), _sql);
-            try {
-                return super.executeUpdate();
-            } finally {
-                fireEvent(_conn.getDelegate(),
-                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
-                    getDelegate(), _sql);
-            }
-        }
-
-        protected ResultSet executeQuery(boolean wrap) throws SQLException {
-            JDBCEvent before = fireEvent(_conn.getDelegate(),
-                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), _sql);
-            try {
-                return super.executeQuery(wrap);
-            } finally {
-                fireEvent(_conn.getDelegate(),
-                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
-                    getDelegate(), _sql);
-            }
-        }
-
-        public int[] executeBatch() throws SQLException {
-            JDBCEvent before = fireEvent(_conn.getDelegate(),
-                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), _sql);
-            try {
-                return super.executeBatch();
-            } finally {
-                fireEvent(_conn.getDelegate(),
-                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
-                    getDelegate(), _sql);
-            }
-        }
-    }
-
-    /**
-     * Fires events as appropriate.
-     */
-    private class EventStatement extends DelegatingStatement {
-
-        private final EventConnection _conn;
-
-        public EventStatement(Statement stmnt, EventConnection conn) {
-            super(stmnt, conn);
-            _conn = conn;
-        }
-
-        public int executeUpdate(String sql) throws SQLException {
-            JDBCEvent before = fireEvent(_conn.getDelegate(),
-                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), sql);
-            try {
-                return super.executeUpdate(sql);
-            } finally {
-                fireEvent(_conn.getDelegate(),
-                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
-                    getDelegate(), sql);
-            }
-        }
-
-        protected ResultSet executeQuery(String sql, boolean wrap)
-            throws SQLException {
-            JDBCEvent before = fireEvent(_conn.getDelegate(),
-                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), sql);
-            try {
-                return super.executeQuery(sql, wrap);
-            } finally {
-                fireEvent(_conn.getDelegate(),
-                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
-                    getDelegate(), sql);
-            }
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+
+/**
+ * Manages the firing of {@link JDBCEvent}s.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public class JDBCEventConnectionDecorator extends AbstractConcurrentEventManager
+    implements ConnectionDecorator {
+
+    public Connection decorate(Connection conn) {
+        if (!hasListeners())
+            return conn;
+        return new EventConnection(conn);
+    }
+
+    /**
+     * Fire the given event to all listeners. Prevents creation of an
+     * event object when there are no listeners.
+     */
+    private JDBCEvent fireEvent(Connection source, short type,
+        JDBCEvent associatedEvent, Statement stmnt, String sql) {
+        if (!hasListeners())
+            return null;
+
+        JDBCEvent event = new JDBCEvent(source, type, associatedEvent,
+            stmnt, sql);
+        fireEvent(event);
+        return event;
+    }
+
+    /**
+     * Fire the given event to all listeners.
+     */
+    protected void fireEvent(Object event, Object listener) {
+        JDBCListener listen = (JDBCListener) listener;
+        JDBCEvent ev = (JDBCEvent) event;
+        switch (ev.getType()) {
+            case JDBCEvent.BEFORE_PREPARE_STATEMENT:
+                listen.beforePrepareStatement(ev);
+                break;
+            case JDBCEvent.AFTER_PREPARE_STATEMENT:
+                listen.afterPrepareStatement(ev);
+                break;
+            case JDBCEvent.BEFORE_CREATE_STATEMENT:
+                listen.beforeCreateStatement(ev);
+                break;
+            case JDBCEvent.AFTER_CREATE_STATEMENT:
+                listen.afterCreateStatement(ev);
+                break;
+            case JDBCEvent.BEFORE_EXECUTE_STATEMENT:
+                listen.beforeExecuteStatement(ev);
+                break;
+            case JDBCEvent.AFTER_EXECUTE_STATEMENT:
+                listen.afterExecuteStatement(ev);
+                break;
+            case JDBCEvent.BEFORE_COMMIT:
+                listen.beforeCommit(ev);
+                break;
+            case JDBCEvent.AFTER_COMMIT:
+                listen.afterCommit(ev);
+                break;
+            case JDBCEvent.BEFORE_ROLLBACK:
+                listen.beforeRollback(ev);
+                break;
+            case JDBCEvent.AFTER_ROLLBACK:
+                listen.afterRollback(ev);
+                break;
+            case JDBCEvent.AFTER_CONNECT:
+                listen.afterConnect(ev);
+                break;
+            case JDBCEvent.BEFORE_CLOSE:
+                listen.beforeClose(ev);
+                break;
+        }
+    }
+
+    /**
+     * Fires events as appropriate.
+     */
+    private class EventConnection extends DelegatingConnection {
+
+        public EventConnection(Connection conn) {
+            super(conn);
+            fireEvent(getDelegate(), JDBCEvent.AFTER_CONNECT, null, null, null);
+        }
+
+        public void commit() throws SQLException {
+            JDBCEvent before = fireEvent(getDelegate(),
+                JDBCEvent.BEFORE_COMMIT, null, null, null);
+            try {
+                super.commit();
+            } finally {
+                fireEvent(getDelegate(), JDBCEvent.AFTER_COMMIT, before,
+                    null, null);
+            }
+        }
+
+        public void rollback() throws SQLException {
+            JDBCEvent before = fireEvent(getDelegate(),
+                JDBCEvent.BEFORE_ROLLBACK, null, null, null);
+            try {
+                super.rollback();
+            } finally {
+                fireEvent(getDelegate(), JDBCEvent.AFTER_ROLLBACK, before,
+                    null, null);
+            }
+        }
+
+        protected Statement createStatement(boolean wrap) throws SQLException {
+            JDBCEvent before = fireEvent(getDelegate(),
+                JDBCEvent.BEFORE_CREATE_STATEMENT, null, null, null);
+            Statement stmnt = null;
+            try {
+                stmnt = new EventStatement(super.createStatement(false),
+                    EventConnection.this);
+            } finally {
+                fireEvent(getDelegate(), JDBCEvent.AFTER_CREATE_STATEMENT,
+                    before, stmnt, null);
+            }
+            return stmnt;
+        }
+
+        protected Statement createStatement(int rsType, int rsConcur,
+            boolean wrap) throws SQLException {
+            JDBCEvent before = fireEvent(getDelegate(),
+                JDBCEvent.BEFORE_CREATE_STATEMENT, null, null, null);
+            Statement stmnt = null;
+            try {
+                stmnt = new EventStatement(super.createStatement
+                    (rsType, rsConcur, false), EventConnection.this);
+            } finally {
+                fireEvent(getDelegate(), JDBCEvent.AFTER_CREATE_STATEMENT,
+                    before, stmnt, null);
+            }
+            return stmnt;
+        }
+
+        protected PreparedStatement prepareStatement(String sql, boolean wrap)
+            throws SQLException {
+            JDBCEvent before = fireEvent(getDelegate(),
+                JDBCEvent.BEFORE_PREPARE_STATEMENT, null, null, sql);
+            PreparedStatement stmnt = null;
+            try {
+                stmnt = new EventPreparedStatement(super.prepareStatement
+                    (sql, false), EventConnection.this, sql);
+            } finally {
+                fireEvent(getDelegate(), JDBCEvent.AFTER_PREPARE_STATEMENT,
+                    before, stmnt, sql);
+            }
+            return stmnt;
+        }
+
+        protected PreparedStatement prepareStatement(String sql, int rsType,
+            int rsConcur, boolean wrap) throws SQLException {
+            JDBCEvent before = fireEvent(getDelegate(),
+                JDBCEvent.BEFORE_PREPARE_STATEMENT, null, null, sql);
+            PreparedStatement stmnt = null;
+            try {
+                stmnt = new EventPreparedStatement(super.prepareStatement
+                    (sql, rsType, rsConcur, false), EventConnection.this, sql);
+            } finally {
+                fireEvent(getDelegate(), JDBCEvent.AFTER_PREPARE_STATEMENT,
+                    before, stmnt, sql);
+            }
+            return stmnt;
+        }
+
+        public void close() throws SQLException {
+            try {
+                fireEvent(getDelegate(), JDBCEvent.BEFORE_CLOSE,
+                    null, null, null);
+            } finally {
+                super.close();
+            }
+        }
+    }
+
+    /**
+     * Fires events as appropriate.
+     */
+    private class EventPreparedStatement extends DelegatingPreparedStatement {
+
+        private final EventConnection _conn;
+        private final String _sql;
+
+        public EventPreparedStatement(PreparedStatement ps,
+            EventConnection conn, String sql) {
+            super(ps, conn);
+            _conn = conn;
+            _sql = sql;
+        }
+
+        public int executeUpdate() throws SQLException {
+            JDBCEvent before = fireEvent(_conn.getDelegate(),
+                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), _sql);
+            try {
+                return super.executeUpdate();
+            } finally {
+                fireEvent(_conn.getDelegate(),
+                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
+                    getDelegate(), _sql);
+            }
+        }
+
+        protected ResultSet executeQuery(boolean wrap) throws SQLException {
+            JDBCEvent before = fireEvent(_conn.getDelegate(),
+                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), _sql);
+            try {
+                return super.executeQuery(wrap);
+            } finally {
+                fireEvent(_conn.getDelegate(),
+                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
+                    getDelegate(), _sql);
+            }
+        }
+
+        public int[] executeBatch() throws SQLException {
+            JDBCEvent before = fireEvent(_conn.getDelegate(),
+                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), _sql);
+            try {
+                return super.executeBatch();
+            } finally {
+                fireEvent(_conn.getDelegate(),
+                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
+                    getDelegate(), _sql);
+            }
+        }
+    }
+
+    /**
+     * Fires events as appropriate.
+     */
+    private class EventStatement extends DelegatingStatement {
+
+        private final EventConnection _conn;
+
+        public EventStatement(Statement stmnt, EventConnection conn) {
+            super(stmnt, conn);
+            _conn = conn;
+        }
+
+        public int executeUpdate(String sql) throws SQLException {
+            JDBCEvent before = fireEvent(_conn.getDelegate(),
+                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), sql);
+            try {
+                return super.executeUpdate(sql);
+            } finally {
+                fireEvent(_conn.getDelegate(),
+                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
+                    getDelegate(), sql);
+            }
+        }
+
+        protected ResultSet executeQuery(String sql, boolean wrap)
+            throws SQLException {
+            JDBCEvent before = fireEvent(_conn.getDelegate(),
+                JDBCEvent.BEFORE_EXECUTE_STATEMENT, null, getDelegate(), sql);
+            try {
+                return super.executeQuery(sql, wrap);
+            } finally {
+                fireEvent(_conn.getDelegate(),
+                    JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
+                    getDelegate(), sql);
+            }
+        }
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryAdapter.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryAdapter.java
index 0bc0d85..7b178d9 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryAdapter.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryAdapter.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.log;
-
-import java.util.Map;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Base type that aids in adapting an external log framework to the
- * {@link LogFactory}.
- *
- * @author Abe White
- */
-public abstract class LogFactoryAdapter implements LogFactory {
-
-    // cache category to log adapters
-    private Map _logs = new ConcurrentHashMap();
-
-    public Log getLog(String channel) {
-        // no locking; OK if same adapter created multiple times
-        Log log = (Log) _logs.get(channel);
-        if (log == null) {
-            log = newLogAdapter(channel);
-            _logs.put(channel, log);
-        }
-        return log;
-    }
-
-    /**
-     * Return a log adapter for the given channel. This method may be called
-     * multiple times for the same channel in concurrent situations.
-     */
-    protected abstract Log newLogAdapter(String channel);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.log;
+
+import java.util.Map;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Base type that aids in adapting an external log framework to the
+ * {@link LogFactory}.
+ *
+ * @author Abe White
+ */
+public abstract class LogFactoryAdapter implements LogFactory {
+
+    // cache category to log adapters
+    private Map _logs = new ConcurrentHashMap();
+
+    public Log getLog(String channel) {
+        // no locking; OK if same adapter created multiple times
+        Log log = (Log) _logs.get(channel);
+        if (log == null) {
+            log = newLogAdapter(channel);
+            _logs.put(channel, log);
+        }
+        return log;
+    }
+
+    /**
+     * Return a log adapter for the given channel. This method may be called
+     * multiple times for the same channel in concurrent situations.
+     */
+    protected abstract Log newLogAdapter(String channel);
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryImpl.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryImpl.java
index b9b7a65..24c2580 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryImpl.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/LogFactoryImpl.java
@@ -1,368 +1,368 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.openjpa.lib.conf.Configurable;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.GenericConfigurable;
-import org.apache.openjpa.lib.util.Files;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Options;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Default {@link LogFactory} implementation. For ease of automatic
- * configuration, this implementation keys on only the last dot-separated
- * token of the log channel name.
- *
- * @author Patrick Linskey
- */
-public class LogFactoryImpl 
-    implements LogFactory, GenericConfigurable, Configurable {
-
-    private static Localizer _loc = Localizer.forPackage(LogFactoryImpl.class);
-    private static Localizer _locEn = Localizer.forPackage(
-        LogFactoryImpl.class, Locale.ENGLISH);
-
-    public static final String TRACE_STR = _locEn.get("log-trace").getMessage();
-    public static final String INFO_STR = _locEn.get("log-info").getMessage();
-    public static final String WARN_STR = _locEn.get("log-warn").getMessage();
-    public static final String ERROR_STR = _locEn.get("log-error").getMessage();
-    public static final String FATAL_STR = _locEn.get("log-fatal").getMessage();
-
-    public static final String STDOUT = "stdout";
-    public static final String STDERR = "stderr";
-
-    private static final String NEWLINE = J2DoPrivHelper.getLineSeparator();
-
-    /**
-     * The time at which this factory was initialized.
-     */
-    protected final long initializationMillis;
-
-    /**
-     * The {@link Log}s that this factory manages, keyed by log channel name.
-     */
-    private Map _logs = new ConcurrentHashMap(); // <String,Log>
-
-    /**
-     * The default logging level.
-     */
-    private short _defaultLogLevel = Log.INFO;
-
-    /**
-     * Storage for logging level configuration specified at configuration time.
-     */
-    private Map _configuredLevels = new HashMap(); // <String,Integer>
-
-    /**
-     * The stream to write to. Defaults to System.err.
-     */
-    private PrintStream _out = System.err;
-
-    /**
-     * A token to add to all log messages. If <code>null</code>, the 
-     * configuration's id will be used.
-     */
-    private String _diagContext = null;
-    private boolean _diagContextComputed = false;
-    
-    private Configuration _conf;
-
-
-    public LogFactoryImpl() {
-        initializationMillis = System.currentTimeMillis();
-    }
-
-    public Log getLog(String channel) {
-        // no locking; ok if same log created multiple times
-        LogImpl l = (LogImpl) _logs.get(channel);
-        if (l == null) {
-            l = newLogImpl();
-            l.setChannel(channel);
-            Short lvl = (Short) _configuredLevels.get(shorten(channel));
-            l.setLevel(lvl == null ? _defaultLogLevel : lvl.shortValue());
-            _logs.put(channel, l);
-        }
-        return l;
-    }
-
-    /**
-     * Create a new log. The log will be cached.
-     */
-    protected LogImpl newLogImpl() {
-        return new LogImpl();
-    }
-
-    /**
-     * The string name of the default level for unconfigured log channels;
-     * used for automatic configuration.
-     */
-    public void setDefaultLevel(String level) {
-        _defaultLogLevel = getLevel(level);
-    }
-
-    /**
-     * The default level for unconfigured log channels.
-     */
-    public short getDefaultLevel() {
-        return _defaultLogLevel;
-    }
-
-    /**
-     * The default level for unconfigured log channels.
-     */
-    public void setDefaultLevel(short level) {
-        _defaultLogLevel = level;
-    }
-
-    /**
-     * A string to prefix all log messages with. Set to
-     * <code>null</code> to use the configuration's Id property setting.
-     */
-    public void setDiagnosticContext(String val) {
-        _diagContext = val;
-    }
-
-    /**
-     * A string to prefix all log messages with. Set to
-     * <code>null</code> to use the configuration's Id property setting.
-     */
-    public String getDiagnosticContext() {
-        if (!_diagContextComputed) {
-            // this initialization has to happen lazily because there is no
-            // guarantee that conf.getId() will be populated by the time that
-            // endConfiguration() is called.
-            if (_diagContext == null && _conf != null) {
-                _diagContext = _conf.getId();
-            }
-            if ("".equals(_diagContext))
-                _diagContext = null;
-            _diagContextComputed = true;
-        }
-        return _diagContext;
-    }
-
-    /**
-     * The stream to write to. Recognized values are: <code>stdout</code>
-     * and <code>stderr</code>. Any other value will be considered a file name.
-     */
-    public void setFile(String file) {
-        if (STDOUT.equals(file))
-            _out = System.out;
-        else if (STDERR.equals(file))
-            _out = System.err;
-        else {
-            File f = Files.getFile(file, null);
-            try {
-                _out = new PrintStream((FileOutputStream)
-                    AccessController.doPrivileged(
-                        J2DoPrivHelper.newFileOutputStreamAction(
-                            (String) AccessController.doPrivileged(
-                                J2DoPrivHelper.getCanonicalPathAction(f)),
-                            true)));
-            } catch (PrivilegedActionException pae) {
-                throw new IllegalArgumentException(_loc.get("log-bad-file",
-                        file) + " " + pae.getException());
-            } catch (IOException ioe) {
-                throw new IllegalArgumentException(_loc.get("log-bad-file",
-                    file) + " " + ioe.toString());
-            }
-        }
-    }
-
-    /**
-     * The stream to write to.
-     */
-    public PrintStream getStream() {
-        return _out;
-    }
-
-    /**
-     * The stream to write to.
-     */
-    public void setStream(PrintStream stream) {
-        if (stream == null)
-            throw new NullPointerException("stream == null");
-        _out = stream;
-    }
-
-    /**
-     * Returns a string representation of the specified log level constant.
-     */
-    public static String getLevelName(short level) {
-        switch (level) {
-            case Log.TRACE:
-                return TRACE_STR;
-            case Log.INFO:
-                return INFO_STR;
-            case Log.WARN:
-                return WARN_STR;
-            case Log.ERROR:
-                return ERROR_STR;
-            case Log.FATAL:
-                return FATAL_STR;
-            default:
-                return _locEn.get("log-unknown").getMessage();
-        }
-    }
-
-    /**
-     * Returns a symbolic constant for the specified string level.
-     */
-    public static short getLevel(String str) {
-        str = str.toUpperCase(Locale.ENGLISH).trim();
-        short val = TRACE_STR.equals(str) ? Log.TRACE :
-            INFO_STR.equals(str) ? Log.INFO :
-                WARN_STR.equals(str) ? Log.WARN :
-                    ERROR_STR.equals(str) ? Log.ERROR :
-                        FATAL_STR.equals(str) ? Log.FATAL : -1;
-
-        if (val == -1)
-            throw new IllegalArgumentException
-                (_loc.get("log-bad-constant", str).getMessage());
-
-        return val;
-    }
-
-    // ---------- Configurable implementation ----------
-    
-    public void setConfiguration(Configuration conf) {
-        _conf = conf;
-    }
-    
-    public void startConfiguration() {
-    }
-
-    public void endConfiguration() {
-    }
-
-    // ---------- GenericConfigurable implementation ----------
-
-    public void setInto(Options opts) {
-        if (!opts.isEmpty()) {
-            Map.Entry e;
-            for (Iterator iter = opts.entrySet().iterator(); iter.hasNext();) {
-                e = (Map.Entry) iter.next();
-                _configuredLevels.put(shorten((String) e.getKey()),
-                    new Short(getLevel((String) e.getValue())));
-            }
-            opts.clear();
-        }
-    }
-
-    private static String shorten(String channel) {
-        return channel.substring(channel.lastIndexOf('.') + 1);
-    }
-
-    /**
-     * A simple implementation of the {@link Log} interface. Writes
-     * output to stderr.
-     */
-    public class LogImpl extends AbstractLog {
-
-        private short _level = INFO;
-        private String _channel;
-
-        protected boolean isEnabled(short level) {
-            return level >= _level;
-        }
-
-        protected void log(short level, String message, Throwable t) {
-            String msg = formatMessage(level, message, t);
-            synchronized (_out) {
-                _out.print(msg);
-            }
-        }
-
-        /**
-         * Convert <code>message</code> into a string ready to be written to
-         * the log. The string should include the terminating newline.
-         *
-         * @param t may be null
-         */
-        protected String formatMessage(short level, String message,
-            Throwable t) {
-            // we write to a StringBuffer and then flush it all at
-            // once as a single line, since some environments(e.g., JBoss)
-            // override the System output stream to flush any calls
-            // to write without regard to line breaks, making the
-            // output incomprehensibe.
-            StringBuffer buf = new StringBuffer();
-
-            buf.append(getOffset());
-            buf.append("  ");
-            if (getDiagnosticContext() != null)
-                buf.append(getDiagnosticContext()).append("  ");
-            buf.append(getLevelName(level));
-            if (level == INFO || level == WARN)
-                buf.append(" ");
-            buf.append("  [");
-            buf.append(Thread.currentThread().getName());
-            buf.append("] ");
-            buf.append(_channel);
-            buf.append(" - ");
-            buf.append(message);
-            buf.append(NEWLINE);
-
-            if (t != null) {
-                StringWriter swriter = new StringWriter();
-                PrintWriter pwriter = new PrintWriter(swriter);
-                t.printStackTrace(pwriter);
-                pwriter.flush();
-                buf.append(swriter.toString());
-            }
-            return buf.toString();
-        }
-
-        private long getOffset() {
-            return System.currentTimeMillis() - initializationMillis;
-        }
-
-        public void setChannel(String val) {
-            _channel = val;
-        }
-
-        public String getChannel() {
-            return _channel;
-        }
-
-        public void setLevel(short val) {
-            _level = val;
-        }
-
-        public short getLevel() {
-            return _level;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.GenericConfigurable;
+import org.apache.openjpa.lib.util.Files;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Default {@link LogFactory} implementation. For ease of automatic
+ * configuration, this implementation keys on only the last dot-separated
+ * token of the log channel name.
+ *
+ * @author Patrick Linskey
+ */
+public class LogFactoryImpl 
+    implements LogFactory, GenericConfigurable, Configurable {
+
+    private static Localizer _loc = Localizer.forPackage(LogFactoryImpl.class);
+    private static Localizer _locEn = Localizer.forPackage(
+        LogFactoryImpl.class, Locale.ENGLISH);
+
+    public static final String TRACE_STR = _locEn.get("log-trace").getMessage();
+    public static final String INFO_STR = _locEn.get("log-info").getMessage();
+    public static final String WARN_STR = _locEn.get("log-warn").getMessage();
+    public static final String ERROR_STR = _locEn.get("log-error").getMessage();
+    public static final String FATAL_STR = _locEn.get("log-fatal").getMessage();
+
+    public static final String STDOUT = "stdout";
+    public static final String STDERR = "stderr";
+
+    private static final String NEWLINE = J2DoPrivHelper.getLineSeparator();
+
+    /**
+     * The time at which this factory was initialized.
+     */
+    protected final long initializationMillis;
+
+    /**
+     * The {@link Log}s that this factory manages, keyed by log channel name.
+     */
+    private Map _logs = new ConcurrentHashMap(); // <String,Log>
+
+    /**
+     * The default logging level.
+     */
+    private short _defaultLogLevel = Log.INFO;
+
+    /**
+     * Storage for logging level configuration specified at configuration time.
+     */
+    private Map _configuredLevels = new HashMap(); // <String,Integer>
+
+    /**
+     * The stream to write to. Defaults to System.err.
+     */
+    private PrintStream _out = System.err;
+
+    /**
+     * A token to add to all log messages. If <code>null</code>, the 
+     * configuration's id will be used.
+     */
+    private String _diagContext = null;
+    private boolean _diagContextComputed = false;
+    
+    private Configuration _conf;
+
+
+    public LogFactoryImpl() {
+        initializationMillis = System.currentTimeMillis();
+    }
+
+    public Log getLog(String channel) {
+        // no locking; ok if same log created multiple times
+        LogImpl l = (LogImpl) _logs.get(channel);
+        if (l == null) {
+            l = newLogImpl();
+            l.setChannel(channel);
+            Short lvl = (Short) _configuredLevels.get(shorten(channel));
+            l.setLevel(lvl == null ? _defaultLogLevel : lvl.shortValue());
+            _logs.put(channel, l);
+        }
+        return l;
+    }
+
+    /**
+     * Create a new log. The log will be cached.
+     */
+    protected LogImpl newLogImpl() {
+        return new LogImpl();
+    }
+
+    /**
+     * The string name of the default level for unconfigured log channels;
+     * used for automatic configuration.
+     */
+    public void setDefaultLevel(String level) {
+        _defaultLogLevel = getLevel(level);
+    }
+
+    /**
+     * The default level for unconfigured log channels.
+     */
+    public short getDefaultLevel() {
+        return _defaultLogLevel;
+    }
+
+    /**
+     * The default level for unconfigured log channels.
+     */
+    public void setDefaultLevel(short level) {
+        _defaultLogLevel = level;
+    }
+
+    /**
+     * A string to prefix all log messages with. Set to
+     * <code>null</code> to use the configuration's Id property setting.
+     */
+    public void setDiagnosticContext(String val) {
+        _diagContext = val;
+    }
+
+    /**
+     * A string to prefix all log messages with. Set to
+     * <code>null</code> to use the configuration's Id property setting.
+     */
+    public String getDiagnosticContext() {
+        if (!_diagContextComputed) {
+            // this initialization has to happen lazily because there is no
+            // guarantee that conf.getId() will be populated by the time that
+            // endConfiguration() is called.
+            if (_diagContext == null && _conf != null) {
+                _diagContext = _conf.getId();
+            }
+            if ("".equals(_diagContext))
+                _diagContext = null;
+            _diagContextComputed = true;
+        }
+        return _diagContext;
+    }
+
+    /**
+     * The stream to write to. Recognized values are: <code>stdout</code>
+     * and <code>stderr</code>. Any other value will be considered a file name.
+     */
+    public void setFile(String file) {
+        if (STDOUT.equals(file))
+            _out = System.out;
+        else if (STDERR.equals(file))
+            _out = System.err;
+        else {
+            File f = Files.getFile(file, null);
+            try {
+                _out = new PrintStream((FileOutputStream)
+                    AccessController.doPrivileged(
+                        J2DoPrivHelper.newFileOutputStreamAction(
+                            (String) AccessController.doPrivileged(
+                                J2DoPrivHelper.getCanonicalPathAction(f)),
+                            true)));
+            } catch (PrivilegedActionException pae) {
+                throw new IllegalArgumentException(_loc.get("log-bad-file",
+                        file) + " " + pae.getException());
+            } catch (IOException ioe) {
+                throw new IllegalArgumentException(_loc.get("log-bad-file",
+                    file) + " " + ioe.toString());
+            }
+        }
+    }
+
+    /**
+     * The stream to write to.
+     */
+    public PrintStream getStream() {
+        return _out;
+    }
+
+    /**
+     * The stream to write to.
+     */
+    public void setStream(PrintStream stream) {
+        if (stream == null)
+            throw new NullPointerException("stream == null");
+        _out = stream;
+    }
+
+    /**
+     * Returns a string representation of the specified log level constant.
+     */
+    public static String getLevelName(short level) {
+        switch (level) {
+            case Log.TRACE:
+                return TRACE_STR;
+            case Log.INFO:
+                return INFO_STR;
+            case Log.WARN:
+                return WARN_STR;
+            case Log.ERROR:
+                return ERROR_STR;
+            case Log.FATAL:
+                return FATAL_STR;
+            default:
+                return _locEn.get("log-unknown").getMessage();
+        }
+    }
+
+    /**
+     * Returns a symbolic constant for the specified string level.
+     */
+    public static short getLevel(String str) {
+        str = str.toUpperCase(Locale.ENGLISH).trim();
+        short val = TRACE_STR.equals(str) ? Log.TRACE :
+            INFO_STR.equals(str) ? Log.INFO :
+                WARN_STR.equals(str) ? Log.WARN :
+                    ERROR_STR.equals(str) ? Log.ERROR :
+                        FATAL_STR.equals(str) ? Log.FATAL : -1;
+
+        if (val == -1)
+            throw new IllegalArgumentException
+                (_loc.get("log-bad-constant", str).getMessage());
+
+        return val;
+    }
+
+    // ---------- Configurable implementation ----------
+    
+    public void setConfiguration(Configuration conf) {
+        _conf = conf;
+    }
+    
+    public void startConfiguration() {
+    }
+
+    public void endConfiguration() {
+    }
+
+    // ---------- GenericConfigurable implementation ----------
+
+    public void setInto(Options opts) {
+        if (!opts.isEmpty()) {
+            Map.Entry e;
+            for (Iterator iter = opts.entrySet().iterator(); iter.hasNext();) {
+                e = (Map.Entry) iter.next();
+                _configuredLevels.put(shorten((String) e.getKey()),
+                    new Short(getLevel((String) e.getValue())));
+            }
+            opts.clear();
+        }
+    }
+
+    private static String shorten(String channel) {
+        return channel.substring(channel.lastIndexOf('.') + 1);
+    }
+
+    /**
+     * A simple implementation of the {@link Log} interface. Writes
+     * output to stderr.
+     */
+    public class LogImpl extends AbstractLog {
+
+        private short _level = INFO;
+        private String _channel;
+
+        protected boolean isEnabled(short level) {
+            return level >= _level;
+        }
+
+        protected void log(short level, String message, Throwable t) {
+            String msg = formatMessage(level, message, t);
+            synchronized (_out) {
+                _out.print(msg);
+            }
+        }
+
+        /**
+         * Convert <code>message</code> into a string ready to be written to
+         * the log. The string should include the terminating newline.
+         *
+         * @param t may be null
+         */
+        protected String formatMessage(short level, String message,
+            Throwable t) {
+            // we write to a StringBuffer and then flush it all at
+            // once as a single line, since some environments(e.g., JBoss)
+            // override the System output stream to flush any calls
+            // to write without regard to line breaks, making the
+            // output incomprehensibe.
+            StringBuffer buf = new StringBuffer();
+
+            buf.append(getOffset());
+            buf.append("  ");
+            if (getDiagnosticContext() != null)
+                buf.append(getDiagnosticContext()).append("  ");
+            buf.append(getLevelName(level));
+            if (level == INFO || level == WARN)
+                buf.append(" ");
+            buf.append("  [");
+            buf.append(Thread.currentThread().getName());
+            buf.append("] ");
+            buf.append(_channel);
+            buf.append(" - ");
+            buf.append(message);
+            buf.append(NEWLINE);
+
+            if (t != null) {
+                StringWriter swriter = new StringWriter();
+                PrintWriter pwriter = new PrintWriter(swriter);
+                t.printStackTrace(pwriter);
+                pwriter.flush();
+                buf.append(swriter.toString());
+            }
+            return buf.toString();
+        }
+
+        private long getOffset() {
+            return System.currentTimeMillis() - initializationMillis;
+        }
+
+        public void setChannel(String val) {
+            _channel = val;
+        }
+
+        public String getChannel() {
+            return _channel;
+        }
+
+        public void setLevel(short val) {
+            _level = val;
+        }
+
+        public short getLevel() {
+            return _level;
+        }
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/MultiLogFactory.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/MultiLogFactory.java
index 13fb9fc..7c05693 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/MultiLogFactory.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/log/MultiLogFactory.java
@@ -1,193 +1,193 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * A LogFactory implementation to pass events through multiple
- * LogFactory implementations(such as log4j and LogPanelFactory).
- *
- * @author Steve Kim
- */
-public class MultiLogFactory implements LogFactory {
-
-    private List _delegates;
-
-    /**
-     * Create an instance with the given delegates.
-     */
-    public MultiLogFactory(LogFactory d1, LogFactory d2) {
-        this(new LogFactory[]{ d1, d2 });
-    }
-
-    /**
-     * Create an instance with the given delegates.
-     */
-    public MultiLogFactory(LogFactory d1, LogFactory d2, LogFactory d3) {
-        this(new LogFactory[]{ d1, d2, d3 });
-    }
-
-    /**
-     * Create an instance with the given delegates.
-     */
-    public MultiLogFactory(LogFactory[] delegates) {
-        _delegates = new CopyOnWriteArrayList(Arrays.asList(delegates));
-    }
-
-    public void addLogFactory(LogFactory factory) {
-        _delegates.add(factory);
-    }
-
-    public void removeLogFactory(LogFactory factory) {
-        _delegates.remove(factory);
-    }
-
-    /**
-     * Returns the delegates that this MultiLogFactory delegates messages to.
-     */
-    public LogFactory[] getDelegates() {
-        return (LogFactory[]) _delegates.toArray(new LogFactory[0]);
-    }
-
-    /**
-     * Returns a Log impl that combines all logs.
-     */
-    public synchronized Log getLog(String channel) {
-        List logs = new ArrayList(_delegates.size());
-        for (Iterator i = _delegates.iterator(); i.hasNext();) {
-            LogFactory f = (LogFactory) i.next();
-            if (f != null) {
-                Log l = f.getLog(channel);
-                if (l != null)
-                    logs.add(l);
-            }
-        }
-        return new MultiLog((Log[]) logs.toArray(new Log[logs.size()]));
-    }
-
-    /**
-     * Combinatory Log impl.
-     */
-    private static class MultiLog implements Log {
-
-        private Log[] _logs;
-
-        public MultiLog(Log[] logs) {
-            _logs = logs;
-        }
-
-        /**
-         * Return the logs that this log delegates to.
-         */
-        public Log[] getDelegates() {
-            return _logs;
-        }
-
-        public void trace(Object msg) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].trace(msg);
-        }
-
-        public void trace(Object msg, Throwable t) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].trace(msg, t);
-        }
-
-        public void info(Object msg) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].info(msg);
-        }
-
-        public void info(Object msg, Throwable t) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].info(msg, t);
-        }
-
-        public void warn(Object msg) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].warn(msg);
-        }
-
-        public void warn(Object msg, Throwable t) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].warn(msg, t);
-        }
-
-        public void error(Object msg) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].error(msg);
-        }
-
-        public void error(Object msg, Throwable t) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].error(msg, t);
-        }
-
-        public void fatal(Object msg) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].fatal(msg);
-        }
-
-        public void fatal(Object msg, Throwable t) {
-            for (int i = 0; i < _logs.length; i++)
-                _logs[i].fatal(msg, t);
-        }
-
-        public boolean isTraceEnabled() {
-            for (int i = 0; i < _logs.length; i++)
-                if (_logs[i].isTraceEnabled())
-                    return true;
-            return false;
-        }
-
-        public boolean isInfoEnabled() {
-            for (int i = 0; i < _logs.length; i++)
-                if (_logs[i].isInfoEnabled())
-                    return true;
-            return false;
-        }
-
-        public boolean isWarnEnabled() {
-            for (int i = 0; i < _logs.length; i++)
-                if (_logs[i].isWarnEnabled())
-                    return true;
-            return false;
-        }
-
-        public boolean isErrorEnabled() {
-            for (int i = 0; i < _logs.length; i++)
-                if (_logs[i].isErrorEnabled())
-                    return true;
-            return false;
-        }
-
-        public boolean isFatalEnabled() {
-            for (int i = 0; i < _logs.length; i++)
-                if (_logs[i].isFatalEnabled())
-                    return true;
-            return false;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A LogFactory implementation to pass events through multiple
+ * LogFactory implementations(such as log4j and LogPanelFactory).
+ *
+ * @author Steve Kim
+ */
+public class MultiLogFactory implements LogFactory {
+
+    private List _delegates;
+
+    /**
+     * Create an instance with the given delegates.
+     */
+    public MultiLogFactory(LogFactory d1, LogFactory d2) {
+        this(new LogFactory[]{ d1, d2 });
+    }
+
+    /**
+     * Create an instance with the given delegates.
+     */
+    public MultiLogFactory(LogFactory d1, LogFactory d2, LogFactory d3) {
+        this(new LogFactory[]{ d1, d2, d3 });
+    }
+
+    /**
+     * Create an instance with the given delegates.
+     */
+    public MultiLogFactory(LogFactory[] delegates) {
+        _delegates = new CopyOnWriteArrayList(Arrays.asList(delegates));
+    }
+
+    public void addLogFactory(LogFactory factory) {
+        _delegates.add(factory);
+    }
+
+    public void removeLogFactory(LogFactory factory) {
+        _delegates.remove(factory);
+    }
+
+    /**
+     * Returns the delegates that this MultiLogFactory delegates messages to.
+     */
+    public LogFactory[] getDelegates() {
+        return (LogFactory[]) _delegates.toArray(new LogFactory[0]);
+    }
+
+    /**
+     * Returns a Log impl that combines all logs.
+     */
+    public synchronized Log getLog(String channel) {
+        List logs = new ArrayList(_delegates.size());
+        for (Iterator i = _delegates.iterator(); i.hasNext();) {
+            LogFactory f = (LogFactory) i.next();
+            if (f != null) {
+                Log l = f.getLog(channel);
+                if (l != null)
+                    logs.add(l);
+            }
+        }
+        return new MultiLog((Log[]) logs.toArray(new Log[logs.size()]));
+    }
+
+    /**
+     * Combinatory Log impl.
+     */
+    private static class MultiLog implements Log {
+
+        private Log[] _logs;
+
+        public MultiLog(Log[] logs) {
+            _logs = logs;
+        }
+
+        /**
+         * Return the logs that this log delegates to.
+         */
+        public Log[] getDelegates() {
+            return _logs;
+        }
+
+        public void trace(Object msg) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].trace(msg);
+        }
+
+        public void trace(Object msg, Throwable t) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].trace(msg, t);
+        }
+
+        public void info(Object msg) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].info(msg);
+        }
+
+        public void info(Object msg, Throwable t) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].info(msg, t);
+        }
+
+        public void warn(Object msg) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].warn(msg);
+        }
+
+        public void warn(Object msg, Throwable t) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].warn(msg, t);
+        }
+
+        public void error(Object msg) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].error(msg);
+        }
+
+        public void error(Object msg, Throwable t) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].error(msg, t);
+        }
+
+        public void fatal(Object msg) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].fatal(msg);
+        }
+
+        public void fatal(Object msg, Throwable t) {
+            for (int i = 0; i < _logs.length; i++)
+                _logs[i].fatal(msg, t);
+        }
+
+        public boolean isTraceEnabled() {
+            for (int i = 0; i < _logs.length; i++)
+                if (_logs[i].isTraceEnabled())
+                    return true;
+            return false;
+        }
+
+        public boolean isInfoEnabled() {
+            for (int i = 0; i < _logs.length; i++)
+                if (_logs[i].isInfoEnabled())
+                    return true;
+            return false;
+        }
+
+        public boolean isWarnEnabled() {
+            for (int i = 0; i < _logs.length; i++)
+                if (_logs[i].isWarnEnabled())
+                    return true;
+            return false;
+        }
+
+        public boolean isErrorEnabled() {
+            for (int i = 0; i < _logs.length; i++)
+                if (_logs[i].isErrorEnabled())
+                    return true;
+            return false;
+        }
+
+        public boolean isFatalEnabled() {
+            for (int i = 0; i < _logs.length; i++)
+                if (_logs[i].isFatalEnabled())
+                    return true;
+            return false;
+        }
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/AbstractNonSequentialResultList.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/AbstractNonSequentialResultList.java
index 0bbf333..9acd5d6 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/AbstractNonSequentialResultList.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/AbstractNonSequentialResultList.java
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
 
@@ -145,6 +146,10 @@
         return list.toArray(a);
     }
 
+    public List subList(int fromIndex, int toIndex) {
+        throw new UnsupportedOperationException();
+    }
+
     private class Itr extends AbstractListIterator {
 
         private int _idx = 0;
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/LazyForwardResultList.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/LazyForwardResultList.java
index 7b3049f..f3a84b9 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/LazyForwardResultList.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/LazyForwardResultList.java
@@ -152,6 +152,11 @@
         return other == this;
     }
 
+    public List subList(int fromIndex, int toIndex) {
+        assertOpen();
+        return _list.subList(fromIndex, toIndex);
+    }
+
     private class Itr extends AbstractListIterator {
 
         private int _idx = 0;
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/ListResultList.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/ListResultList.java
index 5f3d2b2..145c164 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/ListResultList.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/ListResultList.java
@@ -120,4 +120,9 @@
     public Object writeReplace() {
         return _list;
     }
+
+    public List subList(int fromIndex, int toIndex) {
+        assertOpen();
+        return _list.subList(fromIndex, toIndex);
+    }
 }
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Bytes.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Bytes.java
index 8330205..9eebc56 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Bytes.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Bytes.java
@@ -1,167 +1,167 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.util;
-
-/**
- * This class came from the Apache Commons Id sandbox project in support
- * of the UUIDGenerator implementation.
- *
- * <p>Static methods for managing byte arrays (all methods follow Big
- * Endian order where most significant bits are in front).</p>
- */
-public final class Bytes {
-
-    /**
-     * <p>Hide constructor in utility class.</p>
-     */
-    private Bytes() {
-    }
-
-    /**
-     * Appends two bytes array into one.
-     *
-     * @param a A byte[].
-     * @param b A byte[].
-     * @return A byte[].
-     */
-    public static byte[] append(byte[] a, byte[] b) {
-        byte[] z = new byte[a.length + b.length];
-        System.arraycopy(a, 0, z, 0, a.length);
-        System.arraycopy(b, 0, z, a.length, b.length);
-        return z;
-    }
-
-    /**
-     * Returns a 8-byte array built from a long.
-     *
-     * @param n The number to convert.
-     * @return A byte[].
-     */
-    public static byte[] toBytes(long n) {
-        return toBytes(n, new byte[8]);
-    }
-
-    /**
-     * Build a 8-byte array from a long.  No check is performed on the
-     * array length.
-     *
-     * @param n The number to convert.
-     * @param b The array to fill.
-     * @return A byte[].
-     */
-    public static byte[] toBytes(long n, byte[] b) {
-        b[7] = (byte) (n);
-        n >>>= 8;
-        b[6] = (byte) (n);
-        n >>>= 8;
-        b[5] = (byte) (n);
-        n >>>= 8;
-        b[4] = (byte) (n);
-        n >>>= 8;
-        b[3] = (byte) (n);
-        n >>>= 8;
-        b[2] = (byte) (n);
-        n >>>= 8;
-        b[1] = (byte) (n);
-        n >>>= 8;
-        b[0] = (byte) (n);
-
-        return b;
-    }
-
-    /**
-     * Build a long from first 8 bytes of the array.
-     *
-     * @param b The byte[] to convert.
-     * @return A long.
-     */
-    public static long toLong(byte[] b) {
-        return ((((long) b[7]) & 0xFF)
-                + ((((long) b[6]) & 0xFF) << 8)
-                + ((((long) b[5]) & 0xFF) << 16)
-                + ((((long) b[4]) & 0xFF) << 24)
-                + ((((long) b[3]) & 0xFF) << 32)
-                + ((((long) b[2]) & 0xFF) << 40)
-                + ((((long) b[1]) & 0xFF) << 48)
-                + ((((long) b[0]) & 0xFF) << 56));
-    }
-
-    /**
-    * Compares two byte arrays for equality.
-    *
-    * @param a A byte[].
-    * @param b A byte[].
-    * @return True if the arrays have identical contents.
-    */
-    public static boolean areEqual(byte[] a, byte[] b) {
-        int aLength = a.length;
-        if (aLength != b.length) {
-            return false;
-        }
-
-        for (int i = 0; i < aLength; i++) {
-            if (a[i] != b[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Compares two byte arrays as specified by <code>Comparable</code>.
-     *
-     * @param lhs - left hand value in the comparison operation.
-     * @param rhs - right hand value in the comparison operation.
-     * @return  a negative integer, zero, or a positive integer as 
-     * <code>lhs</code> is less than, equal to, or greater than 
-     * <code>rhs</code>.
-     */
-    public static int compareTo(byte[] lhs, byte[] rhs) {
-        if (lhs == rhs) {
-            return 0;
-        }
-        if (lhs == null) {
-            return -1;
-        }
-        if (rhs == null) {
-            return +1;
-        }
-        if (lhs.length != rhs.length) {
-            return ((lhs.length < rhs.length) ? -1 : +1);
-        }
-        for (int i = 0; i < lhs.length; i++) {
-            if (lhs[i] < rhs[i]) {
-                return -1;
-            } else if (lhs[i] > rhs[i]) {
-                return 1;
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * Build a short from first 2 bytes of the array.
-     *
-     * @param b The byte[] to convert.
-     * @return A short.
-     */
-    public static short toShort(byte[] b) {
-        return  (short) ((b[1] & 0xFF) + ((b[0] & 0xFF) << 8));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.util;
+
+/**
+ * This class came from the Apache Commons Id sandbox project in support
+ * of the UUIDGenerator implementation.
+ *
+ * <p>Static methods for managing byte arrays (all methods follow Big
+ * Endian order where most significant bits are in front).</p>
+ */
+public final class Bytes {
+
+    /**
+     * <p>Hide constructor in utility class.</p>
+     */
+    private Bytes() {
+    }
+
+    /**
+     * Appends two bytes array into one.
+     *
+     * @param a A byte[].
+     * @param b A byte[].
+     * @return A byte[].
+     */
+    public static byte[] append(byte[] a, byte[] b) {
+        byte[] z = new byte[a.length + b.length];
+        System.arraycopy(a, 0, z, 0, a.length);
+        System.arraycopy(b, 0, z, a.length, b.length);
+        return z;
+    }
+
+    /**
+     * Returns a 8-byte array built from a long.
+     *
+     * @param n The number to convert.
+     * @return A byte[].
+     */
+    public static byte[] toBytes(long n) {
+        return toBytes(n, new byte[8]);
+    }
+
+    /**
+     * Build a 8-byte array from a long.  No check is performed on the
+     * array length.
+     *
+     * @param n The number to convert.
+     * @param b The array to fill.
+     * @return A byte[].
+     */
+    public static byte[] toBytes(long n, byte[] b) {
+        b[7] = (byte) (n);
+        n >>>= 8;
+        b[6] = (byte) (n);
+        n >>>= 8;
+        b[5] = (byte) (n);
+        n >>>= 8;
+        b[4] = (byte) (n);
+        n >>>= 8;
+        b[3] = (byte) (n);
+        n >>>= 8;
+        b[2] = (byte) (n);
+        n >>>= 8;
+        b[1] = (byte) (n);
+        n >>>= 8;
+        b[0] = (byte) (n);
+
+        return b;
+    }
+
+    /**
+     * Build a long from first 8 bytes of the array.
+     *
+     * @param b The byte[] to convert.
+     * @return A long.
+     */
+    public static long toLong(byte[] b) {
+        return ((((long) b[7]) & 0xFF)
+                + ((((long) b[6]) & 0xFF) << 8)
+                + ((((long) b[5]) & 0xFF) << 16)
+                + ((((long) b[4]) & 0xFF) << 24)
+                + ((((long) b[3]) & 0xFF) << 32)
+                + ((((long) b[2]) & 0xFF) << 40)
+                + ((((long) b[1]) & 0xFF) << 48)
+                + ((((long) b[0]) & 0xFF) << 56));
+    }
+
+    /**
+    * Compares two byte arrays for equality.
+    *
+    * @param a A byte[].
+    * @param b A byte[].
+    * @return True if the arrays have identical contents.
+    */
+    public static boolean areEqual(byte[] a, byte[] b) {
+        int aLength = a.length;
+        if (aLength != b.length) {
+            return false;
+        }
+
+        for (int i = 0; i < aLength; i++) {
+            if (a[i] != b[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Compares two byte arrays as specified by <code>Comparable</code>.
+     *
+     * @param lhs - left hand value in the comparison operation.
+     * @param rhs - right hand value in the comparison operation.
+     * @return  a negative integer, zero, or a positive integer as 
+     * <code>lhs</code> is less than, equal to, or greater than 
+     * <code>rhs</code>.
+     */
+    public static int compareTo(byte[] lhs, byte[] rhs) {
+        if (lhs == rhs) {
+            return 0;
+        }
+        if (lhs == null) {
+            return -1;
+        }
+        if (rhs == null) {
+            return +1;
+        }
+        if (lhs.length != rhs.length) {
+            return ((lhs.length < rhs.length) ? -1 : +1);
+        }
+        for (int i = 0; i < lhs.length; i++) {
+            if (lhs[i] < rhs[i]) {
+                return -1;
+            } else if (lhs[i] > rhs[i]) {
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Build a short from first 2 bytes of the array.
+     *
+     * @param b The byte[] to convert.
+     * @return A short.
+     */
+    public static short toShort(byte[] b) {
+        return  (short) ((b[1] & 0xFF) + ((b[0] & 0xFF) << 8));
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPriv5Helper.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPriv5Helper.java
index cf42913..82a3edc 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPriv5Helper.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPriv5Helper.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.util;
-
-import java.lang.reflect.AnnotatedElement;
-import java.security.PrivilegedAction;
-
-/**
- * Helper class to obtain the Privilege(Exception)Action object to perform
- * Java 2 doPrivilege security sensitive function call in the following
- * methods:
- * <ul>
- * <li>AnnotatedElement.getAnnotations
- * <li>AnnotatedElement.getDeclaredAnnotations
- * <li>AnnotatedElement.isAnnotationPresent
- * </ul>
- *
- * @author Albert Lee
- */
-
-public abstract class J2DoPriv5Helper extends J2DoPrivHelper {
-
-    /**
-     * Return a PrivilegeAction object for AnnotatedElement.getAnnotations().
-     *
-     * Requires security policy:
-     *   'permission java.lang.RuntimePermission "accessDeclaredMembers";'
-     *
-     * @return Annotation[]
-     */
-    public static final PrivilegedAction getAnnotationsAction(
-        final AnnotatedElement element) {
-        return new PrivilegedAction() {
-            public Object run() {
-                return element.getAnnotations();
-            }
-        };
-    }
-
-    /**
-     * Return a PrivilegeAction object for
-     *   AnnotatedElement.getDeclaredAnnotations().
-     *
-     * Requires security policy:
-     *   'permission java.lang.RuntimePermission "accessDeclaredMembers";'
-     *
-     * @return Annotation[]
-     */
-    public static final PrivilegedAction getDeclaredAnnotationsAction(
-        final AnnotatedElement element) {
-        return new PrivilegedAction() {
-            public Object run() {
-                return element.getDeclaredAnnotations();
-            }
-        };
-    }
-
-    /**
-     * Return a PrivilegeAction object for
-     *   AnnotatedElement.isAnnotationPresent().
-     *
-     * Requires security policy:
-     *   'permission java.lang.RuntimePermission "accessDeclaredMembers";'
-     *
-     * @return Boolean
-     */
-    public static final PrivilegedAction isAnnotationPresentAction(
-        final AnnotatedElement element, final Class annotationClazz) {
-        return new PrivilegedAction() {
-            public Object run() {
-                return element.isAnnotationPresent(annotationClazz)
-                    ? Boolean.TRUE : Boolean.FALSE;
-            }
-        };
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.util;
+
+import java.lang.reflect.AnnotatedElement;
+import java.security.PrivilegedAction;
+
+/**
+ * Helper class to obtain the Privilege(Exception)Action object to perform
+ * Java 2 doPrivilege security sensitive function call in the following
+ * methods:
+ * <ul>
+ * <li>AnnotatedElement.getAnnotations
+ * <li>AnnotatedElement.getDeclaredAnnotations
+ * <li>AnnotatedElement.isAnnotationPresent
+ * </ul>
+ *
+ * @author Albert Lee
+ */
+
+public abstract class J2DoPriv5Helper extends J2DoPrivHelper {
+
+    /**
+     * Return a PrivilegeAction object for AnnotatedElement.getAnnotations().
+     *
+     * Requires security policy:
+     *   'permission java.lang.RuntimePermission "accessDeclaredMembers";'
+     *
+     * @return Annotation[]
+     */
+    public static final PrivilegedAction getAnnotationsAction(
+        final AnnotatedElement element) {
+        return new PrivilegedAction() {
+            public Object run() {
+                return element.getAnnotations();
+            }
+        };
+    }
+
+    /**
+     * Return a PrivilegeAction object for
+     *   AnnotatedElement.getDeclaredAnnotations().
+     *
+     * Requires security policy:
+     *   'permission java.lang.RuntimePermission "accessDeclaredMembers";'
+     *
+     * @return Annotation[]
+     */
+    public static final PrivilegedAction getDeclaredAnnotationsAction(
+        final AnnotatedElement element) {
+        return new PrivilegedAction() {
+            public Object run() {
+                return element.getDeclaredAnnotations();
+            }
+        };
+    }
+
+    /**
+     * Return a PrivilegeAction object for
+     *   AnnotatedElement.isAnnotationPresent().
+     *
+     * Requires security policy:
+     *   'permission java.lang.RuntimePermission "accessDeclaredMembers";'
+     *
+     * @return Boolean
+     */
+    public static final PrivilegedAction isAnnotationPresentAction(
+        final AnnotatedElement element, final Class annotationClazz) {
+        return new PrivilegedAction() {
+            public Object run() {
+                return element.isAnnotationPresent(annotationClazz)
+                    ? Boolean.TRUE : Boolean.FALSE;
+            }
+        };
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
index 35b3af3..919258c 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
@@ -905,9 +905,9 @@
      *   
      * @return MultiClassLoader
      */
-    public static final PrivilegedAction newMultiClassLoaderAction() {
+    public static final PrivilegedAction<MultiClassLoader> newMultiClassLoaderAction() {
         return new PrivilegedAction() {
-            public Object run() {
+            public MultiClassLoader run() {
                 return new MultiClassLoader();
             }
         };
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Localizer.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Localizer.java
index a82b2f7..f5a04ea 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Localizer.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/Localizer.java
@@ -1,302 +1,302 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.util;
-
-import java.security.AccessController;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.Properties;
-import java.util.ResourceBundle;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-/**
- * The Localizer provides convenient access to localized
- * strings. It inlcudes built-in support for parameter substitution through
- * the use of the {@link MessageFormat} utility.
- * Strings are stored in per-package {@link Properties} files.
- * The property file for the default locale must be named
- * <code>localizer.properties</code>. Additional locales can be supported
- * through additional property files using the naming conventions specified
- * in the {@link ResourceBundle} class. For example, the german locale
- * could be supported through a <code>localizer_de_DE.properties</code> file.
- *
- * @author Abe White
- */
-public class Localizer {
-
-    // static cache of package+loc name to localizer mappings
-    private static final Map _localizers = new ConcurrentHashMap();
-
-    // list of resource providers to delegate to when locating resources
-    private static final Collection _providers = new CopyOnWriteArraySet
-        (Arrays.asList(new Object[]{
-            new SimpleResourceBundleProvider(),
-            new StreamResourceBundleProvider(),
-            new ZipResourceBundleProvider(), }));
-
-    /**
-     * Return a Localizer instance that will access the properties file
-     * in the package of the given class using the system default locale.
-     *
-     * @see #forPackage(Class,Locale)
-     */
-    public static Localizer forPackage(Class cls) {
-        return forPackage(cls, null);
-    }
-
-    /**
-     * Return a Localizer instance that will access the properties file
-     * in the package of the given class using the given locale.
-     *
-     * @param cls the class whose package to check for the localized
-     * properties file; if null, the system will check for
-     * a top-level properties file
-     * @param locale the locale to which strings should be localized; if
-     * null, the system default will be assumed
-     */
-    public static Localizer forPackage(Class cls, Locale locale) {
-        if (locale == null)
-            locale = Locale.getDefault();
-
-        int dot = (cls == null) ? -1 : cls.getName().lastIndexOf('.');
-        String pkg;
-        String file;
-        if (dot == -1) {
-            pkg = "";
-            file = "localizer";
-        } else {
-            pkg = cls.getName().substring(0, dot);
-            file = pkg + ".localizer";
-        }
-        String key = file + locale.toString();
-
-        // no locking; ok if bundle created multiple times
-        // check for cached version
-        Localizer loc = (Localizer) _localizers.get(key);
-        if (loc != null)
-            return loc;
-        else {
-            loc = new Localizer(pkg, file, locale,
-                cls == null ? null:(ClassLoader) AccessController.doPrivileged(
-                    J2DoPrivHelper.getClassLoaderAction(cls)));
-            _localizers.put(key, loc);
-            return loc;
-        }
-    }
-
-    /**
-     * Register a resource provider.
-     */
-    public static void addProvider(ResourceBundleProvider provider) {
-        _providers.add(provider);
-    }
-
-    /**
-     * Remove a resource provider.
-     */
-    public static boolean removeProvider(ResourceBundleProvider provider) {
-        return _providers.remove(provider);
-    }
-
-    private String _file;
-    private String _pkg;
-    private ResourceBundle _bundle = null;
-    private Locale _locale;
-    private ClassLoader _loader;
-
-    private Localizer(String pkg, String f, Locale locale, ClassLoader loader) {
-        _pkg = pkg;
-        _file = f;
-        _locale = locale;
-        _loader = loader;
-    }
-
-    private ResourceBundle getBundle() {
-        // no locking; it's ok to create multiple bundles
-        if (_bundle == null) {
-            // find resource bundle
-            for (Iterator itr = _providers.iterator();
-                itr.hasNext() && _bundle == null; ) {
-                _bundle = ((ResourceBundleProvider) itr.next())
-                    .findResource(_file, _locale, _loader);
-            }
-        }
-        return _bundle;
-    }
-
-    /**
-     * Return the localized string matching the given key.
-     */
-    public Message get(String key) {
-        return get(key, null);
-    }
-
-    /**
-     * Return the localized string matching the given key.
-     */
-    public Message getFatal(String key) {
-        return getFatal(key, null);
-    }
-
-    /**
-     * Return the localized string matching the given key. The given
-     * <code>sub</code> object will be packed into an array and substituted
-     * into the found string according to the rules of the
-     * {@link MessageFormat} class.
-     *
-     * @see #get(String)
-     */
-    public Message get(String key, Object sub) {
-        return get(key, new Object[]{ sub });
-    }
-
-    /**
-     * Return the localized string matching the given key. The given
-     * <code>sub</code> object will be packed into an array and substituted
-     * into the found string according to the rules of the
-     * {@link MessageFormat} class.
-     *
-     * @see #getFatal(String)
-     */
-    public Message getFatal(String key, Object sub) {
-        return getFatal(key, new Object[]{ sub });
-    }
-
-    /**
-     * Return the localized string for the given key.
-     *
-     * @see #get(String,Object)
-     */
-    public Message get(String key, Object sub1, Object sub2) {
-        return get(key, new Object[]{ sub1, sub2 });
-    }
-
-    /**
-     * Return the localized string for the given key.
-     *
-     * @see #getFatal(String,Object)
-     */
-    public Message getFatal(String key, Object sub1, Object sub2) {
-        return getFatal(key, new Object[]{ sub1, sub2 });
-    }
-
-    /**
-     * Return the localized string for the given key.
-     *
-     * @see #get(String,Object)
-     */
-    public Message get(String key, Object sub1, Object sub2, Object sub3) {
-        return get(key, new Object[]{ sub1, sub2, sub3 });
-    }
-
-    /**
-     * Return the localized string matching the given key. The given
-     * <code>subs</code> objects will be substituted
-     * into the found string according to the rules of the
-     * {@link MessageFormat} class.
-     *
-     * @see #get(String)
-     */
-    public Message get(String key, Object[] subs) {
-        return new Message(_pkg, getBundle(), key, subs, false);
-    }
-
-    /**
-     * Return the localized string matching the given key. The given
-     * <code>subs</code> objects will be substituted
-     * into the found string according to the rules of the
-     * {@link MessageFormat} class.
-     *
-     * @see #getFatal(String)
-     */
-    public Message getFatal(String key, Object[] subs) {
-        return new Message(_pkg, getBundle(), key, subs, true);
-    }
-
-    /**
-     * A <code>Message</code> can provide a localized message via the
-     * {@link #getMessage} method call, and can also provide the original key,
-     * package, and substitution array that were used to assemble the message.
-     */
-    public static class Message {
-
-        private final String _pkg;
-        private final String _key;
-        private final Object[] _subs;
-        private final String _localizedMessage;
-
-        private Message(String packageName, ResourceBundle bundle, String key,
-            Object[] subs, boolean fatal) {
-            if (bundle == null && fatal)
-                throw new MissingResourceException(key, key, key);
-
-            _pkg = packageName;
-            _key = key;
-            _subs = subs;
-            if (bundle == null) {
-                _localizedMessage = key;
-            } else {
-                String localized = null;
-                try {
-                    localized = bundle.getString(key);
-                } catch (MissingResourceException mre) {
-                    if (fatal)
-                        throw mre;
-                }
-                _localizedMessage = (localized == null) ? key : localized;
-            }
-        }
-
-        /**
-         * The localized message.
-         */
-        public String getMessage() {
-            return MessageFormat.format(_localizedMessage, _subs);
-        }
-
-        /**
-         * The unique key for the localized message.
-         */
-        public String getKey() {
-            return _key;
-        }
-
-        /**
-         * Substitutions inserted into the message.
-         */
-        public Object[] getSubstitutions() {
-            return _subs;
-        }
-
-        public String getPackageName() {
-            return _pkg;
-        }
-
-        public String toString() {
-            return getMessage();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.util;
+
+import java.security.AccessController;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * The Localizer provides convenient access to localized
+ * strings. It inlcudes built-in support for parameter substitution through
+ * the use of the {@link MessageFormat} utility.
+ * Strings are stored in per-package {@link Properties} files.
+ * The property file for the default locale must be named
+ * <code>localizer.properties</code>. Additional locales can be supported
+ * through additional property files using the naming conventions specified
+ * in the {@link ResourceBundle} class. For example, the german locale
+ * could be supported through a <code>localizer_de_DE.properties</code> file.
+ *
+ * @author Abe White
+ */
+public class Localizer {
+
+    // static cache of package+loc name to localizer mappings
+    private static final Map _localizers = new ConcurrentHashMap();
+
+    // list of resource providers to delegate to when locating resources
+    private static final Collection _providers = new CopyOnWriteArraySet
+        (Arrays.asList(new Object[]{
+            new SimpleResourceBundleProvider(),
+            new StreamResourceBundleProvider(),
+            new ZipResourceBundleProvider(), }));
+
+    /**
+     * Return a Localizer instance that will access the properties file
+     * in the package of the given class using the system default locale.
+     *
+     * @see #forPackage(Class,Locale)
+     */
+    public static Localizer forPackage(Class cls) {
+        return forPackage(cls, null);
+    }
+
+    /**
+     * Return a Localizer instance that will access the properties file
+     * in the package of the given class using the given locale.
+     *
+     * @param cls the class whose package to check for the localized
+     * properties file; if null, the system will check for
+     * a top-level properties file
+     * @param locale the locale to which strings should be localized; if
+     * null, the system default will be assumed
+     */
+    public static Localizer forPackage(Class cls, Locale locale) {
+        if (locale == null)
+            locale = Locale.getDefault();
+
+        int dot = (cls == null) ? -1 : cls.getName().lastIndexOf('.');
+        String pkg;
+        String file;
+        if (dot == -1) {
+            pkg = "";
+            file = "localizer";
+        } else {
+            pkg = cls.getName().substring(0, dot);
+            file = pkg + ".localizer";
+        }
+        String key = file + locale.toString();
+
+        // no locking; ok if bundle created multiple times
+        // check for cached version
+        Localizer loc = (Localizer) _localizers.get(key);
+        if (loc != null)
+            return loc;
+        else {
+            loc = new Localizer(pkg, file, locale,
+                cls == null ? null:(ClassLoader) AccessController.doPrivileged(
+                    J2DoPrivHelper.getClassLoaderAction(cls)));
+            _localizers.put(key, loc);
+            return loc;
+        }
+    }
+
+    /**
+     * Register a resource provider.
+     */
+    public static void addProvider(ResourceBundleProvider provider) {
+        _providers.add(provider);
+    }
+
+    /**
+     * Remove a resource provider.
+     */
+    public static boolean removeProvider(ResourceBundleProvider provider) {
+        return _providers.remove(provider);
+    }
+
+    private String _file;
+    private String _pkg;
+    private ResourceBundle _bundle = null;
+    private Locale _locale;
+    private ClassLoader _loader;
+
+    private Localizer(String pkg, String f, Locale locale, ClassLoader loader) {
+        _pkg = pkg;
+        _file = f;
+        _locale = locale;
+        _loader = loader;
+    }
+
+    private ResourceBundle getBundle() {
+        // no locking; it's ok to create multiple bundles
+        if (_bundle == null) {
+            // find resource bundle
+            for (Iterator itr = _providers.iterator();
+                itr.hasNext() && _bundle == null; ) {
+                _bundle = ((ResourceBundleProvider) itr.next())
+                    .findResource(_file, _locale, _loader);
+            }
+        }
+        return _bundle;
+    }
+
+    /**
+     * Return the localized string matching the given key.
+     */
+    public Message get(String key) {
+        return get(key, null);
+    }
+
+    /**
+     * Return the localized string matching the given key.
+     */
+    public Message getFatal(String key) {
+        return getFatal(key, null);
+    }
+
+    /**
+     * Return the localized string matching the given key. The given
+     * <code>sub</code> object will be packed into an array and substituted
+     * into the found string according to the rules of the
+     * {@link MessageFormat} class.
+     *
+     * @see #get(String)
+     */
+    public Message get(String key, Object sub) {
+        return get(key, new Object[]{ sub });
+    }
+
+    /**
+     * Return the localized string matching the given key. The given
+     * <code>sub</code> object will be packed into an array and substituted
+     * into the found string according to the rules of the
+     * {@link MessageFormat} class.
+     *
+     * @see #getFatal(String)
+     */
+    public Message getFatal(String key, Object sub) {
+        return getFatal(key, new Object[]{ sub });
+    }
+
+    /**
+     * Return the localized string for the given key.
+     *
+     * @see #get(String,Object)
+     */
+    public Message get(String key, Object sub1, Object sub2) {
+        return get(key, new Object[]{ sub1, sub2 });
+    }
+
+    /**
+     * Return the localized string for the given key.
+     *
+     * @see #getFatal(String,Object)
+     */
+    public Message getFatal(String key, Object sub1, Object sub2) {
+        return getFatal(key, new Object[]{ sub1, sub2 });
+    }
+
+    /**
+     * Return the localized string for the given key.
+     *
+     * @see #get(String,Object)
+     */
+    public Message get(String key, Object sub1, Object sub2, Object sub3) {
+        return get(key, new Object[]{ sub1, sub2, sub3 });
+    }
+
+    /**
+     * Return the localized string matching the given key. The given
+     * <code>subs</code> objects will be substituted
+     * into the found string according to the rules of the
+     * {@link MessageFormat} class.
+     *
+     * @see #get(String)
+     */
+    public Message get(String key, Object[] subs) {
+        return new Message(_pkg, getBundle(), key, subs, false);
+    }
+
+    /**
+     * Return the localized string matching the given key. The given
+     * <code>subs</code> objects will be substituted
+     * into the found string according to the rules of the
+     * {@link MessageFormat} class.
+     *
+     * @see #getFatal(String)
+     */
+    public Message getFatal(String key, Object[] subs) {
+        return new Message(_pkg, getBundle(), key, subs, true);
+    }
+
+    /**
+     * A <code>Message</code> can provide a localized message via the
+     * {@link #getMessage} method call, and can also provide the original key,
+     * package, and substitution array that were used to assemble the message.
+     */
+    public static class Message {
+
+        private final String _pkg;
+        private final String _key;
+        private final Object[] _subs;
+        private final String _localizedMessage;
+
+        private Message(String packageName, ResourceBundle bundle, String key,
+            Object[] subs, boolean fatal) {
+            if (bundle == null && fatal)
+                throw new MissingResourceException(key, key, key);
+
+            _pkg = packageName;
+            _key = key;
+            _subs = subs;
+            if (bundle == null) {
+                _localizedMessage = key;
+            } else {
+                String localized = null;
+                try {
+                    localized = bundle.getString(key);
+                } catch (MissingResourceException mre) {
+                    if (fatal)
+                        throw mre;
+                }
+                _localizedMessage = (localized == null) ? key : localized;
+            }
+        }
+
+        /**
+         * The localized message.
+         */
+        public String getMessage() {
+            return MessageFormat.format(_localizedMessage, _subs);
+        }
+
+        /**
+         * The unique key for the localized message.
+         */
+        public String getKey() {
+            return _key;
+        }
+
+        /**
+         * Substitutions inserted into the message.
+         */
+        public Object[] getSubstitutions() {
+            return _subs;
+        }
+
+        public String getPackageName() {
+            return _pkg;
+        }
+
+        public String toString() {
+            return getMessage();
+        }
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/TimestampHelper.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/TimestampHelper.java
index ddff2af..96dfd32 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/TimestampHelper.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/TimestampHelper.java
@@ -1,61 +1,61 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.util;
-
-import java.sql.Timestamp;
-
-/**
- * Helper base class attempts to return java.sql.Timestamp object with
- * nanosecond precision. 
- * 
- * @author Albert Lee
- */
-public class TimestampHelper {
-
-    // number of millisecond, mircoseconds and nanoseconds in one second.
-    protected static final long MilliMuliplier = 1000L;
-    protected static final long MicroMuliplier = MilliMuliplier * 1000L;
-    protected static final long NanoMuliplier = MicroMuliplier * 1000L;
-
-    // number of seconds passed 1970/1/1 00:00:00 GMT.
-    private static long sec0;
-    // fraction of seconds passed 1970/1/1 00:00:00 GMT, offset by
-    // the base System.nanoTime (nano0), in nanosecond unit.
-    private static long nano0;
-
-    static {
-        // initialize base time in second and fraction of second (ns).
-        long curTime = System.currentTimeMillis();
-        sec0 = curTime / MilliMuliplier;
-        nano0 = (curTime % MilliMuliplier) * MicroMuliplier - System.nanoTime();
-    }
-
-    /*
-     * Return a java.sql.Timestamp object of current time.
-     */
-    public static Timestamp getNanoPrecisionTimestamp() {
-        long nano_delta = nano0 + System.nanoTime();
-        long sec1 = sec0 + (nano_delta / NanoMuliplier);
-        long nano1 = nano_delta % NanoMuliplier;
-
-        Timestamp rtnTs = new Timestamp(sec1 * MilliMuliplier);
-        rtnTs.setNanos((int) nano1);
-        return rtnTs;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.util;
+
+import java.sql.Timestamp;
+
+/**
+ * Helper base class attempts to return java.sql.Timestamp object with
+ * nanosecond precision. 
+ * 
+ * @author Albert Lee
+ */
+public class TimestampHelper {
+
+    // number of millisecond, mircoseconds and nanoseconds in one second.
+    protected static final long MilliMuliplier = 1000L;
+    protected static final long MicroMuliplier = MilliMuliplier * 1000L;
+    protected static final long NanoMuliplier = MicroMuliplier * 1000L;
+
+    // number of seconds passed 1970/1/1 00:00:00 GMT.
+    private static long sec0;
+    // fraction of seconds passed 1970/1/1 00:00:00 GMT, offset by
+    // the base System.nanoTime (nano0), in nanosecond unit.
+    private static long nano0;
+
+    static {
+        // initialize base time in second and fraction of second (ns).
+        long curTime = System.currentTimeMillis();
+        sec0 = curTime / MilliMuliplier;
+        nano0 = (curTime % MilliMuliplier) * MicroMuliplier - System.nanoTime();
+    }
+
+    /*
+     * Return a java.sql.Timestamp object of current time.
+     */
+    public static Timestamp getNanoPrecisionTimestamp() {
+        long nano_delta = nano0 + System.nanoTime();
+        long sec1 = sec0 + (nano_delta / NanoMuliplier);
+        long nano1 = nano_delta % NanoMuliplier;
+
+        Timestamp rtnTs = new Timestamp(sec1 * MilliMuliplier);
+        rtnTs.setNanos((int) nano1);
+        return rtnTs;
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java
index 08c6c3c..e5dadba 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/NullSafeConcurrentHashMap.java
@@ -1,416 +1,416 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.util.concurrent;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.Enumeration;
-import java.util.Set;
-import java.util.Collection;
-import java.util.AbstractSet;
-import java.util.Iterator;
-import java.util.AbstractCollection;
-import java.util.Random;
-import java.util.HashSet;
-import java.util.TreeSet;
-
-import org.apache.commons.collections.set.MapBackedSet;
-
-/**
- * A subclass of {@link ConcurrentHashMap} that allows null keys and values.
- * In exchange, it weakens the contract of {@link #putIfAbsent} and the other
- * concurrent methods added in {@link #ConcurrentHashMap}.
- *
- * @since 1.1.0
- */
-public class NullSafeConcurrentHashMap extends ConcurrentHashMap {
-
-    private enum Markers {
-        NULL,
-        MAP_BACKED_SET_DUMMY_VAL
-    }
-
-    // The second argument is used within MapBackedSet as the value for
-    // all the key-val pairs that are put into the underlying Map. This
-    // is required for our usage since ConcurrentHashMap does not allow
-    // null values.
-    private Set randomKeys = MapBackedSet.decorate(
-        new ConcurrentHashMap(), Markers.MAP_BACKED_SET_DUMMY_VAL);
-
-    private Random random = new Random();
-
-    public NullSafeConcurrentHashMap(int size, float load,
-        int concurrencyLevel) {
-        super(size, load, concurrencyLevel);
-    }
-
-    public NullSafeConcurrentHashMap() {
-    }
-
-    /**
-     * Returns internal representation for object.
-     */
-    private static Object maskNull(Object o) {
-        return (o == null ? Markers.NULL : o);
-    }
-
-    /**
-     * Returns object represented by specified internal representation.
-     */
-    private static Object unmaskNull(Object o) {
-        return (o == Markers.NULL ? null : o);
-    }
-
-    public Entry removeRandom() {
-        // this doesn't just use randomEntryIterator() because that iterator
-        // has weaker concurrency guarantees than this method. In particular,
-        // this method will continue to attempt to remove random entries even
-        // as other threads remove the same entries, whereas the random
-        // iterator may return values that have been removed.
-
-        for (Iterator iter = randomKeys.iterator(); iter.hasNext(); ) {
-            // randomKeys contains null-masked data
-            Object key = iter.next();
-            if (key != null && randomKeys.remove(key)) {
-                Object val = super.remove(key);
-                if (val != null)
-                    return new EntryImpl(unmaskNull(key), unmaskNull(val));
-            }
-        }
-
-        // if randomKeys is empty, fall back to non-random behavior.
-        for (Iterator iter = super.keySet().iterator(); iter.hasNext(); ) {
-            Object key = iter.next();
-            if (key == null)
-                continue;
-            Object val = super.remove(key);
-            if (val != null)
-                return new EntryImpl(unmaskNull(key), unmaskNull(val));
-        }
-        return null;
-    }
-
-    /**
-     * The returned data structure should not be shared among multiple
-     * threads.
-     */
-    public Iterator<Entry> randomEntryIterator() {
-        return new Iterator<Entry>() {
-
-            Iterator randomIter = randomKeys.iterator();
-            Iterator nonRandomIter = NullSafeConcurrentHashMap.super.keySet()
-                .iterator();
-
-            Set returned = new HashSet();
-            Entry next;
-            boolean nextSet = false;
-
-            public boolean hasNext() {
-                // we've set the next value and we haven't returned it yet
-                if (nextSet)
-                    return true;
-
-                // compute the next value. If the computation returns null,
-                // return false. Else, store the next value and return true.
-                Object nextKey;
-                Object nextValue;
-                if (randomIter.hasNext()) {
-                    nextKey = randomIter.next();
-                    nextValue = NullSafeConcurrentHashMap.super.get(nextKey);
-                    if (nextValue != null) {
-                        returned.add(nextKey);
-                        next = new EntryImpl(unmaskNull(nextKey),
-                            unmaskNull(nextValue));
-                        nextSet = true;
-                        return true;
-                    }
-                }
-
-                while (nonRandomIter.hasNext()) {
-                    nextKey = nonRandomIter.next();
-
-                    if (returned.contains(nextKey))
-                        continue;
-
-                    nextValue = NullSafeConcurrentHashMap.super.get(nextKey);
-                    if (nextValue != null) {
-                        returned.add(nextKey);
-                        next = new EntryImpl(unmaskNull(nextKey),
-                            unmaskNull(nextValue));
-                        nextSet = true;
-                        return true;
-                    }
-                }
-                return false;
-            }
-
-            public Entry next() {
-                // hasNext() will initialize this.next
-                if (!nextSet && !hasNext())
-                    return null;
-
-                // if we get here, then we're about to return a next value
-                nextSet = false;
-                
-                if (containsKey(next.getKey()))
-                    return next;
-
-                // something has changed since the last iteration (presumably
-                // due to multi-threaded access to the underlying data
-                // structure); recurse
-                return next();
-            }
-
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
-
-    @Override
-    public Object remove(Object key) {
-        Object maskedKey = maskNull(key);
-        Object val = unmaskNull(super.remove(maskedKey));
-        randomKeys.remove(maskedKey);
-        return val;
-    }
-
-    @Override
-    public boolean remove(Object key, Object value) {
-        Object maskedKey = maskNull(key);
-        boolean val = super.remove(maskedKey, maskNull(value));
-        randomKeys.remove(maskedKey);
-        return val;
-    }
-
-    @Override
-    public boolean replace(Object key, Object oldValue, Object newValue) {
-        return super.replace(maskNull(key), maskNull(oldValue),
-            maskNull(newValue));
-    }
-
-    @Override
-    public Object replace(Object key, Object value) {
-        return unmaskNull(super.replace(maskNull(key), maskNull(value)));
-    }
-
-    @Override
-    public Object putIfAbsent(Object key, Object value) {
-        Object maskedKey = maskNull(key);
-        Object superVal = super.putIfAbsent(maskedKey, maskNull(value));
-        addRandomKey(maskedKey);
-        return unmaskNull(superVal);
-    }
-
-    @Override
-    public Object put(Object key, Object value) {
-        Object maskedKey = maskNull(key);
-        Object superVal = super.put(maskedKey, maskNull(value));
-        addRandomKey(maskedKey);
-        return unmaskNull(superVal);
-    }
-
-    /**
-     * Potentially adds <code>maskedKey</ccode> to the set of random keys
-     * to be removed by {@link #removeRandom()}.
-     *
-     * @since 1.1.0
-     */
-    private void addRandomKey(Object maskedKey) {
-        // Add one in every three keys to the set. Only do this when
-        // there are less than 16 elements in the random key set; this
-        // means that the algorithm will be pseudo-random for up to
-        // 16 removes (either via removeRandom() or normal remove()
-        // calls) that have no intervening put() calls.
-        if (random != null && randomKeys.size() < 16 && random.nextInt(10) < 3)
-            randomKeys.add(maskedKey);
-    }
-
-    @Override
-    public Object get(Object key) {
-        return unmaskNull(super.get(maskNull(key)));
-    }
-
-    @Override
-    public boolean containsKey(Object key) {
-        return super.containsKey(maskNull(key));
-    }
-
-    @Override
-    public boolean containsValue(Object value) {
-        return super.containsValue(maskNull(value));
-    }
-
-    @Override
-    public boolean contains(Object value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Enumeration elements() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Set entrySet() {
-        return new TranslatingSet(super.entrySet()) {
-            protected Object unmask(Object internal) {
-                final Entry e = (Entry) internal;
-                return new Entry() {
-
-                    public Object getKey() {
-                        return unmaskNull(e.getKey());
-                    }
-
-                    public Object getValue() {
-                        return unmaskNull(e.getValue());
-                    }
-
-                    public Object setValue(Object value) {
-                        return unmaskNull(e.setValue(maskNull(value)));
-                    }
-
-                    @Override
-                    public int hashCode() {
-                        return e.hashCode();
-                    }
-                };
-            }
-        };
-    }
-
-    @Override
-    public Enumeration keys() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Set keySet() {
-        return new TranslatingSet(super.keySet()) {
-            protected Object unmask(Object internal) {
-                return unmaskNull(internal);
-            }
-        };
-    }
-
-    @Override
-    public Collection values() {
-        return new TranslatingCollection(super.values()) {
-
-            protected Object unmask(Object internal) {
-                return unmaskNull(internal);
-            }
-        };
-    }
-
-    private abstract class TranslatingSet extends AbstractSet {
-
-        private Set backingSet;
-
-        private TranslatingSet(Set backing) {
-            this.backingSet = backing;
-        }
-
-        protected abstract Object unmask(Object internal);
-
-        public Iterator iterator() {
-            final Iterator iterator = backingSet.iterator();
-            return new Iterator() {
-                public boolean hasNext() {
-                    return iterator.hasNext();
-                }
-
-                public Object next() {
-                    return unmask(iterator.next());
-                }
-
-                public void remove() {
-                    iterator.remove();
-                }
-            };
-        }
-
-        public int size() {
-            return backingSet.size();
-        }
-    }
-
-    private abstract class TranslatingCollection extends AbstractCollection {
-
-        private Collection backingCollection;
-
-        private TranslatingCollection(Collection backing) {
-            this.backingCollection = backing;
-        }
-
-        protected abstract Object unmask(Object internal);
-
-        public Iterator iterator() {
-            final Iterator iterator = backingCollection.iterator();
-            return new Iterator() {
-                public boolean hasNext() {
-                    return iterator.hasNext();
-                }
-
-                public Object next() {
-                    return unmask(iterator.next());
-                }
-
-                public void remove() {
-                    iterator.remove();
-                }
-            };
-        }
-
-        public int size() {
-            return backingCollection.size();
-        }
-    }
-
-    private class EntryImpl implements Entry {
-
-        final Object key;
-        final Object val;
-
-        private EntryImpl(Object key, Object val) {
-            this.key = key;
-            this.val = val;
-        }
-
-        public Object getKey() {
-            return key;
-        }
-
-        public Object getValue() {
-            return val;
-        }
-
-        public Object setValue(Object value) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public interface KeyFilter {
-
-        /**
-         * @param key may be null
-         * @return whether or not <code>key</code> shuold be excluded
-         */
-        public boolean exclude(Object key);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.util.concurrent;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Enumeration;
+import java.util.Set;
+import java.util.Collection;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.AbstractCollection;
+import java.util.Random;
+import java.util.HashSet;
+import java.util.TreeSet;
+
+import org.apache.commons.collections.set.MapBackedSet;
+
+/**
+ * A subclass of {@link ConcurrentHashMap} that allows null keys and values.
+ * In exchange, it weakens the contract of {@link #putIfAbsent} and the other
+ * concurrent methods added in {@link #ConcurrentHashMap}.
+ *
+ * @since 1.1.0
+ */
+public class NullSafeConcurrentHashMap extends ConcurrentHashMap {
+
+    private enum Markers {
+        NULL,
+        MAP_BACKED_SET_DUMMY_VAL
+    }
+
+    // The second argument is used within MapBackedSet as the value for
+    // all the key-val pairs that are put into the underlying Map. This
+    // is required for our usage since ConcurrentHashMap does not allow
+    // null values.
+    private Set randomKeys = MapBackedSet.decorate(
+        new ConcurrentHashMap(), Markers.MAP_BACKED_SET_DUMMY_VAL);
+
+    private Random random = new Random();
+
+    public NullSafeConcurrentHashMap(int size, float load,
+        int concurrencyLevel) {
+        super(size, load, concurrencyLevel);
+    }
+
+    public NullSafeConcurrentHashMap() {
+    }
+
+    /**
+     * Returns internal representation for object.
+     */
+    private static Object maskNull(Object o) {
+        return (o == null ? Markers.NULL : o);
+    }
+
+    /**
+     * Returns object represented by specified internal representation.
+     */
+    private static Object unmaskNull(Object o) {
+        return (o == Markers.NULL ? null : o);
+    }
+
+    public Entry removeRandom() {
+        // this doesn't just use randomEntryIterator() because that iterator
+        // has weaker concurrency guarantees than this method. In particular,
+        // this method will continue to attempt to remove random entries even
+        // as other threads remove the same entries, whereas the random
+        // iterator may return values that have been removed.
+
+        for (Iterator iter = randomKeys.iterator(); iter.hasNext(); ) {
+            // randomKeys contains null-masked data
+            Object key = iter.next();
+            if (key != null && randomKeys.remove(key)) {
+                Object val = super.remove(key);
+                if (val != null)
+                    return new EntryImpl(unmaskNull(key), unmaskNull(val));
+            }
+        }
+
+        // if randomKeys is empty, fall back to non-random behavior.
+        for (Iterator iter = super.keySet().iterator(); iter.hasNext(); ) {
+            Object key = iter.next();
+            if (key == null)
+                continue;
+            Object val = super.remove(key);
+            if (val != null)
+                return new EntryImpl(unmaskNull(key), unmaskNull(val));
+        }
+        return null;
+    }
+
+    /**
+     * The returned data structure should not be shared among multiple
+     * threads.
+     */
+    public Iterator<Entry> randomEntryIterator() {
+        return new Iterator<Entry>() {
+
+            Iterator randomIter = randomKeys.iterator();
+            Iterator nonRandomIter = NullSafeConcurrentHashMap.super.keySet()
+                .iterator();
+
+            Set returned = new HashSet();
+            Entry next;
+            boolean nextSet = false;
+
+            public boolean hasNext() {
+                // we've set the next value and we haven't returned it yet
+                if (nextSet)
+                    return true;
+
+                // compute the next value. If the computation returns null,
+                // return false. Else, store the next value and return true.
+                Object nextKey;
+                Object nextValue;
+                if (randomIter.hasNext()) {
+                    nextKey = randomIter.next();
+                    nextValue = NullSafeConcurrentHashMap.super.get(nextKey);
+                    if (nextValue != null) {
+                        returned.add(nextKey);
+                        next = new EntryImpl(unmaskNull(nextKey),
+                            unmaskNull(nextValue));
+                        nextSet = true;
+                        return true;
+                    }
+                }
+
+                while (nonRandomIter.hasNext()) {
+                    nextKey = nonRandomIter.next();
+
+                    if (returned.contains(nextKey))
+                        continue;
+
+                    nextValue = NullSafeConcurrentHashMap.super.get(nextKey);
+                    if (nextValue != null) {
+                        returned.add(nextKey);
+                        next = new EntryImpl(unmaskNull(nextKey),
+                            unmaskNull(nextValue));
+                        nextSet = true;
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            public Entry next() {
+                // hasNext() will initialize this.next
+                if (!nextSet && !hasNext())
+                    return null;
+
+                // if we get here, then we're about to return a next value
+                nextSet = false;
+                
+                if (containsKey(next.getKey()))
+                    return next;
+
+                // something has changed since the last iteration (presumably
+                // due to multi-threaded access to the underlying data
+                // structure); recurse
+                return next();
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    @Override
+    public Object remove(Object key) {
+        Object maskedKey = maskNull(key);
+        Object val = unmaskNull(super.remove(maskedKey));
+        randomKeys.remove(maskedKey);
+        return val;
+    }
+
+    @Override
+    public boolean remove(Object key, Object value) {
+        Object maskedKey = maskNull(key);
+        boolean val = super.remove(maskedKey, maskNull(value));
+        randomKeys.remove(maskedKey);
+        return val;
+    }
+
+    @Override
+    public boolean replace(Object key, Object oldValue, Object newValue) {
+        return super.replace(maskNull(key), maskNull(oldValue),
+            maskNull(newValue));
+    }
+
+    @Override
+    public Object replace(Object key, Object value) {
+        return unmaskNull(super.replace(maskNull(key), maskNull(value)));
+    }
+
+    @Override
+    public Object putIfAbsent(Object key, Object value) {
+        Object maskedKey = maskNull(key);
+        Object superVal = super.putIfAbsent(maskedKey, maskNull(value));
+        addRandomKey(maskedKey);
+        return unmaskNull(superVal);
+    }
+
+    @Override
+    public Object put(Object key, Object value) {
+        Object maskedKey = maskNull(key);
+        Object superVal = super.put(maskedKey, maskNull(value));
+        addRandomKey(maskedKey);
+        return unmaskNull(superVal);
+    }
+
+    /**
+     * Potentially adds <code>maskedKey</ccode> to the set of random keys
+     * to be removed by {@link #removeRandom()}.
+     *
+     * @since 1.1.0
+     */
+    private void addRandomKey(Object maskedKey) {
+        // Add one in every three keys to the set. Only do this when
+        // there are less than 16 elements in the random key set; this
+        // means that the algorithm will be pseudo-random for up to
+        // 16 removes (either via removeRandom() or normal remove()
+        // calls) that have no intervening put() calls.
+        if (random != null && randomKeys.size() < 16 && random.nextInt(10) < 3)
+            randomKeys.add(maskedKey);
+    }
+
+    @Override
+    public Object get(Object key) {
+        return unmaskNull(super.get(maskNull(key)));
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return super.containsKey(maskNull(key));
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return super.containsValue(maskNull(value));
+    }
+
+    @Override
+    public boolean contains(Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Enumeration elements() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set entrySet() {
+        return new TranslatingSet(super.entrySet()) {
+            protected Object unmask(Object internal) {
+                final Entry e = (Entry) internal;
+                return new Entry() {
+
+                    public Object getKey() {
+                        return unmaskNull(e.getKey());
+                    }
+
+                    public Object getValue() {
+                        return unmaskNull(e.getValue());
+                    }
+
+                    public Object setValue(Object value) {
+                        return unmaskNull(e.setValue(maskNull(value)));
+                    }
+
+                    @Override
+                    public int hashCode() {
+                        return e.hashCode();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public Enumeration keys() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set keySet() {
+        return new TranslatingSet(super.keySet()) {
+            protected Object unmask(Object internal) {
+                return unmaskNull(internal);
+            }
+        };
+    }
+
+    @Override
+    public Collection values() {
+        return new TranslatingCollection(super.values()) {
+
+            protected Object unmask(Object internal) {
+                return unmaskNull(internal);
+            }
+        };
+    }
+
+    private abstract class TranslatingSet extends AbstractSet {
+
+        private Set backingSet;
+
+        private TranslatingSet(Set backing) {
+            this.backingSet = backing;
+        }
+
+        protected abstract Object unmask(Object internal);
+
+        public Iterator iterator() {
+            final Iterator iterator = backingSet.iterator();
+            return new Iterator() {
+                public boolean hasNext() {
+                    return iterator.hasNext();
+                }
+
+                public Object next() {
+                    return unmask(iterator.next());
+                }
+
+                public void remove() {
+                    iterator.remove();
+                }
+            };
+        }
+
+        public int size() {
+            return backingSet.size();
+        }
+    }
+
+    private abstract class TranslatingCollection extends AbstractCollection {
+
+        private Collection backingCollection;
+
+        private TranslatingCollection(Collection backing) {
+            this.backingCollection = backing;
+        }
+
+        protected abstract Object unmask(Object internal);
+
+        public Iterator iterator() {
+            final Iterator iterator = backingCollection.iterator();
+            return new Iterator() {
+                public boolean hasNext() {
+                    return iterator.hasNext();
+                }
+
+                public Object next() {
+                    return unmask(iterator.next());
+                }
+
+                public void remove() {
+                    iterator.remove();
+                }
+            };
+        }
+
+        public int size() {
+            return backingCollection.size();
+        }
+    }
+
+    private class EntryImpl implements Entry {
+
+        final Object key;
+        final Object val;
+
+        private EntryImpl(Object key, Object val) {
+            this.key = key;
+            this.val = val;
+        }
+
+        public Object getKey() {
+            return key;
+        }
+
+        public Object getValue() {
+            return val;
+        }
+
+        public Object setValue(Object value) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public interface KeyFilter {
+
+        /**
+         * @param key may be null
+         * @return whether or not <code>key</code> shuold be excluded
+         */
+        public boolean exclude(Object key);
+    }
+}
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java
index c31e26d..c001a4c 100644
--- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/SizedConcurrentHashMap.java
@@ -1,128 +1,128 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.util.concurrent;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.Map;
-import java.util.Iterator;
-import java.util.Set;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-
-import org.apache.openjpa.lib.util.SizedMap;
-
-/**
- * An implementation of {@link SizedMap} that uses JDK1.5 concurrency primitives
- *
- * @since 1.1.0
- */
-public class SizedConcurrentHashMap
-    extends NullSafeConcurrentHashMap
-    implements SizedMap, ConcurrentMap, Serializable {
-
-    private int maxSize;
-
-    /**
-     * @param size the maximum size of this map. If additional elements are
-     * put into the map, overflow will be removed via calls to
-     * {@link #overflowRemoved}.
-     * @param load the load factor for the underlying map
-     * @param concurrencyLevel the concurrency level for the underlying map
-     *
-     * @see ConcurrentHashMap
-     */
-    public SizedConcurrentHashMap(int size, float load, int concurrencyLevel) {
-        super(size, load, concurrencyLevel);
-        setMaxSize(size);
-    }
-
-    @Override
-    public Object putIfAbsent(Object key, Object value) {
-        if (maxSize != Integer.MAX_VALUE)
-            removeOverflow(true);
-        return super.putIfAbsent(key, value);
-    }
-
-    @Override
-    public Object put(Object key, Object value) {
-        if (maxSize != Integer.MAX_VALUE)
-            removeOverflow(true);
-        return super.put(key, value);
-    }
-
-    public int getMaxSize() {
-        return maxSize;
-    }
-
-    public void setMaxSize(int max) {
-        if (max < 0)
-            throw new IllegalArgumentException(String.valueOf(max));
-        maxSize = max;
-
-        removeOverflow(false);
-    }
-
-    /**
-     * Equivalent to <code>removeOverflow(false)</code>.
-     */
-    protected void removeOverflow() {
-        removeOverflow(false);
-    }
-
-    /**
-     * Removes overflow. If <code>forPut</code> is <code>true</code>, then
-     * this uses <code>size() + 1</code> when computing size.
-     */
-    protected void removeOverflow(boolean forPut) {
-        int sizeToCompareTo = forPut ? maxSize - 1 : maxSize;
-        while (size() > sizeToCompareTo) {
-            Entry entry = removeRandom();
-            // if removeRandom() returns null, break out of the loop. Of course,
-            // since we're not locking, the size might not actually be null
-            // when we do this. But this prevents weird race conditions from
-            // putting this thread into more loops.
-            if (entry == null)
-                break;
-            overflowRemoved(entry.getKey(), entry.getValue());
-        }
-    }
-
-    public boolean isFull() {
-        return size() >= maxSize;
-    }
-
-    /**
-     * This implementation does nothing.
-     */
-    public void overflowRemoved(Object key, Object value) {
-    }
-
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        out.defaultWriteObject();
-        out.writeInt(maxSize);
-    }
-
-    private void readObject(ObjectInputStream in)
-        throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        maxSize = in.readInt();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.util.concurrent;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.Set;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+import org.apache.openjpa.lib.util.SizedMap;
+
+/**
+ * An implementation of {@link SizedMap} that uses JDK1.5 concurrency primitives
+ *
+ * @since 1.1.0
+ */
+public class SizedConcurrentHashMap
+    extends NullSafeConcurrentHashMap
+    implements SizedMap, ConcurrentMap, Serializable {
+
+    private int maxSize;
+
+    /**
+     * @param size the maximum size of this map. If additional elements are
+     * put into the map, overflow will be removed via calls to
+     * {@link #overflowRemoved}.
+     * @param load the load factor for the underlying map
+     * @param concurrencyLevel the concurrency level for the underlying map
+     *
+     * @see ConcurrentHashMap
+     */
+    public SizedConcurrentHashMap(int size, float load, int concurrencyLevel) {
+        super(size, load, concurrencyLevel);
+        setMaxSize(size);
+    }
+
+    @Override
+    public Object putIfAbsent(Object key, Object value) {
+        if (maxSize != Integer.MAX_VALUE)
+            removeOverflow(true);
+        return super.putIfAbsent(key, value);
+    }
+
+    @Override
+    public Object put(Object key, Object value) {
+        if (maxSize != Integer.MAX_VALUE)
+            removeOverflow(true);
+        return super.put(key, value);
+    }
+
+    public int getMaxSize() {
+        return maxSize;
+    }
+
+    public void setMaxSize(int max) {
+        if (max < 0)
+            throw new IllegalArgumentException(String.valueOf(max));
+        maxSize = max;
+
+        removeOverflow(false);
+    }
+
+    /**
+     * Equivalent to <code>removeOverflow(false)</code>.
+     */
+    protected void removeOverflow() {
+        removeOverflow(false);
+    }
+
+    /**
+     * Removes overflow. If <code>forPut</code> is <code>true</code>, then
+     * this uses <code>size() + 1</code> when computing size.
+     */
+    protected void removeOverflow(boolean forPut) {
+        int sizeToCompareTo = forPut ? maxSize - 1 : maxSize;
+        while (size() > sizeToCompareTo) {
+            Entry entry = removeRandom();
+            // if removeRandom() returns null, break out of the loop. Of course,
+            // since we're not locking, the size might not actually be null
+            // when we do this. But this prevents weird race conditions from
+            // putting this thread into more loops.
+            if (entry == null)
+                break;
+            overflowRemoved(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public boolean isFull() {
+        return size() >= maxSize;
+    }
+
+    /**
+     * This implementation does nothing.
+     */
+    public void overflowRemoved(Object key, Object value) {
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+        out.writeInt(maxSize);
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        maxSize = in.readInt();
+    }
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestXMLCaseConversions.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestXMLCaseConversions.java
index f56d359..fcea58d 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestXMLCaseConversions.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestXMLCaseConversions.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.conf;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-
-public class TestXMLCaseConversions extends TestCase {
-
-    public void testToXMLName() {
-        assertEquals("easy-xml-conversion", 
-            ConfigurationImpl.toXMLName("easyXmlConversion"));
-        assertEquals("initial-caps", 
-            ConfigurationImpl.toXMLName("InitialCaps"));
-        assertEquals("nodash", 
-            ConfigurationImpl.toXMLName("nodash"));
-        assertEquals("anothernodash", 
-            ConfigurationImpl.toXMLName("Anothernodash"));
-        assertEquals("multiple-caps", 
-            ConfigurationImpl.toXMLName("MUltipleCaps"));
-        assertEquals("trailing-multi-caps", 
-            ConfigurationImpl.toXMLName("TrailingMultiCAPS"));
-        assertEquals("two-i-nner-caps", 
-            ConfigurationImpl.toXMLName("TwoINnerCaps"));
-        assertEquals("four-inn-er-caps", 
-            ConfigurationImpl.toXMLName("FourINNErCaps"));
-        assertEquals("inner-3-number", 
-            ConfigurationImpl.toXMLName("Inner3Number"));
-        assertEquals("inner-03-number", 
-            ConfigurationImpl.toXMLName("Inner03Number"));
-    }
-    
-    public static void main(String[] args) throws IOException {
-        BufferedReader r = new BufferedReader (new FileReader(new File(args[0])));
-        while (true) {
-            String s = r.readLine();
-            if (s == null)
-                break;
-            System.out.println(s + ": " + ConfigurationImpl.toXMLName(s));
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.conf;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+
+public class TestXMLCaseConversions extends TestCase {
+
+    public void testToXMLName() {
+        assertEquals("easy-xml-conversion", 
+            ConfigurationImpl.toXMLName("easyXmlConversion"));
+        assertEquals("initial-caps", 
+            ConfigurationImpl.toXMLName("InitialCaps"));
+        assertEquals("nodash", 
+            ConfigurationImpl.toXMLName("nodash"));
+        assertEquals("anothernodash", 
+            ConfigurationImpl.toXMLName("Anothernodash"));
+        assertEquals("multiple-caps", 
+            ConfigurationImpl.toXMLName("MUltipleCaps"));
+        assertEquals("trailing-multi-caps", 
+            ConfigurationImpl.toXMLName("TrailingMultiCAPS"));
+        assertEquals("two-i-nner-caps", 
+            ConfigurationImpl.toXMLName("TwoINnerCaps"));
+        assertEquals("four-inn-er-caps", 
+            ConfigurationImpl.toXMLName("FourINNErCaps"));
+        assertEquals("inner-3-number", 
+            ConfigurationImpl.toXMLName("Inner3Number"));
+        assertEquals("inner-03-number", 
+            ConfigurationImpl.toXMLName("Inner03Number"));
+    }
+    
+    public static void main(String[] args) throws IOException {
+        BufferedReader r = new BufferedReader (new FileReader(new File(args[0])));
+        while (true) {
+            String s = r.readLine();
+            if (s == null)
+                break;
+            System.out.println(s + ": " + ConfigurationImpl.toXMLName(s));
+        }
+    }
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java
index 48a1a6e..e06648d 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/test/ConfigurationTestProductDerivation.java
@@ -1,109 +1,109 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.conf.test;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.util.MissingResourceException;
-import java.util.Properties;
-
-import org.apache.openjpa.lib.conf.AbstractProductDerivation;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.conf.MapConfigurationProvider;
-import org.apache.openjpa.lib.conf.ProductDerivation;
-
-/**
- * A Product Derivation to test loading of global and default configuration with
- * System settings.  Reads its global from a file specified by 
- * <code>"openjpatest.properties"</code> system property.
- *
- * @author Pinaki Poddar
- * @author Abe White
- */
-public class ConfigurationTestProductDerivation 
-    extends AbstractProductDerivation {
-    
-    public static boolean closed = false;
-
-    public int getType() {
-        return ProductDerivation.TYPE_PRODUCT;
-    }
-    
-    public void beforeConfigurationClose(Configuration conf) {
-        closed = true;
-    }
-
-    public ConfigurationProvider loadGlobals(ClassLoader loader)
-        throws IOException {
-        return load(null, loader);
-    }
-
-    public ConfigurationProvider load(String rsrc, ClassLoader loader)
-        throws IOException {
-        if (rsrc == null)
-            rsrc = System.getProperty("openjpatest.properties");
-        if (rsrc == null || !rsrc.endsWith(".properties"))
-            return null;
-
-        URL url = findResource(rsrc, loader);
-        if (url == null)
-            throw new MissingResourceException(rsrc, getClass().getName(), 
-                rsrc);
-
-        InputStream in = url.openStream();
-        Properties props = new Properties();
-        if (in != null) {
-            try {
-                props.load(in);
-                return new MapConfigurationProvider(props);
-            } finally {
-                try { in.close(); } catch (Exception e) {}
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Locate the given resource.
-     */
-    private URL findResource(String rsrc, ClassLoader loader)
-        throws IOException {
-        if (loader != null)
-            return loader.getResource(rsrc);
-
-        // in jbuilder the classloader can be null
-        URL url = null;
-        loader = getClass().getClassLoader();
-        if (loader != null)
-            url = loader.getResource(rsrc);
-        if (url == null) {
-            loader = Thread.currentThread().getContextClassLoader();
-            if (loader != null)
-                url = loader.getResource(rsrc);
-        }
-        if (url == null) {
-            loader = ClassLoader.getSystemClassLoader();
-            if (loader != null)
-                url = loader.getResource(rsrc);
-        }
-        return url;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.conf.test;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.Properties;
+
+import org.apache.openjpa.lib.conf.AbstractProductDerivation;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.conf.MapConfigurationProvider;
+import org.apache.openjpa.lib.conf.ProductDerivation;
+
+/**
+ * A Product Derivation to test loading of global and default configuration with
+ * System settings.  Reads its global from a file specified by 
+ * <code>"openjpatest.properties"</code> system property.
+ *
+ * @author Pinaki Poddar
+ * @author Abe White
+ */
+public class ConfigurationTestProductDerivation 
+    extends AbstractProductDerivation {
+    
+    public static boolean closed = false;
+
+    public int getType() {
+        return ProductDerivation.TYPE_PRODUCT;
+    }
+    
+    public void beforeConfigurationClose(Configuration conf) {
+        closed = true;
+    }
+
+    public ConfigurationProvider loadGlobals(ClassLoader loader)
+        throws IOException {
+        return load(null, loader);
+    }
+
+    public ConfigurationProvider load(String rsrc, ClassLoader loader)
+        throws IOException {
+        if (rsrc == null)
+            rsrc = System.getProperty("openjpatest.properties");
+        if (rsrc == null || !rsrc.endsWith(".properties"))
+            return null;
+
+        URL url = findResource(rsrc, loader);
+        if (url == null)
+            throw new MissingResourceException(rsrc, getClass().getName(), 
+                rsrc);
+
+        InputStream in = url.openStream();
+        Properties props = new Properties();
+        if (in != null) {
+            try {
+                props.load(in);
+                return new MapConfigurationProvider(props);
+            } finally {
+                try { in.close(); } catch (Exception e) {}
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Locate the given resource.
+     */
+    private URL findResource(String rsrc, ClassLoader loader)
+        throws IOException {
+        if (loader != null)
+            return loader.getResource(rsrc);
+
+        // in jbuilder the classloader can be null
+        URL url = null;
+        loader = getClass().getClassLoader();
+        if (loader != null)
+            url = loader.getResource(rsrc);
+        if (url == null) {
+            loader = Thread.currentThread().getContextClassLoader();
+            if (loader != null)
+                url = loader.getResource(rsrc);
+        }
+        if (url == null) {
+            loader = ClassLoader.getSystemClassLoader();
+            if (loader != null)
+                url = loader.getResource(rsrc);
+        }
+        return url;
+    }
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestDepthFirstAnalysis.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestDepthFirstAnalysis.java
index 40c663c..1df2851 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestDepthFirstAnalysis.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestDepthFirstAnalysis.java
@@ -1,152 +1,152 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.openjpa.lib.test.AbstractTestCase;
-
-/**
- * <p>Tests the {@link DepthFirstAnalysis} type.</p>
- *
- * @author Abe White
- */
-public class TestDepthFirstAnalysis
-    extends AbstractTestCase {
-
-    private DepthFirstAnalysis _dfa = null;
-
-    public void setUp() {
-        setUpGraph1();   
-    }
-    
-    public void setUpGraph1() {
-        Graph graph = new Graph();
-        Object node1 = new Object();
-        Object node2 = new Object();
-        Object node3 = new Object();
-        Object node4 = new Object();
-        graph.addNode(node1);
-        graph.addNode(node2);
-        graph.addNode(node3);
-        graph.addNode(node4);
-        graph.addEdge(new Edge(node1, node2, true));
-        graph.addEdge(new Edge(node2, node3, true));
-        graph.addEdge(new Edge(node3, node1, true));
-        graph.addEdge(new Edge(node3, node4, true));
-        graph.addEdge(new Edge(node2, node2, true));
-        _dfa = new DepthFirstAnalysis(graph);
-    }
-
-    public void setUpGraph2() {
-        Graph graph = new Graph();
-        Integer node1 = new Integer(1);
-        Integer node2 = new Integer(2);
-        Integer node3 = new Integer(3);
-        Integer node4 = new Integer(4);
-        Integer node5 = new Integer(5);
-        graph.addNode(node2);  // has to be first node for testcase
-        graph.addNode(node5);
-        graph.addNode(node4);
-        graph.addNode(node3);
-        graph.addNode(node1);
-        graph.addEdge(new Edge(node5, node4, true));
-        graph.addEdge(new Edge(node4, node3, true));
-        graph.addEdge(new Edge(node3, node3, true));
-        graph.addEdge(new Edge(node3, node2, true));
-        graph.addEdge(new Edge(node2, node5, true));
-        graph.addEdge(new Edge(node2, node4, true));
-        graph.addEdge(new Edge(node1, node4, true));
-        _dfa = new DepthFirstAnalysis(graph);
-    }
-
-    public void testNodeSorting() {
-        Collection nodes = _dfa.getSortedNodes();
-        assertEquals(4, nodes.size());
-
-        int time = 0;
-        Object node;
-        for (Iterator itr = nodes.iterator(); itr.hasNext();) {
-            node = itr.next();
-            assertTrue(time <= _dfa.getFinishedTime(node));
-            time = _dfa.getFinishedTime(node);
-        }
-    }
-
-    public void testEdgeTyping() {
-        Collection edges = _dfa.getEdges(Edge.TYPE_BACK);
-        assertEquals(2, edges.size());
-        Iterator itr = edges.iterator();
-        Edge edge0 = (Edge) itr.next();
-        Edge edge1 = (Edge) itr.next();
-        assertTrue((edge0.getTo().equals(edge0.getFrom()))
-                || edge1.getTo().equals(edge1.getFrom()));
-    }
-
-    public void testBackEdges() {
-        setUpGraph2();
-        Collection edges = _dfa.getEdges(Edge.TYPE_BACK);
-        assertEquals(2, edges.size());
-        Iterator itr = edges.iterator();
-        Edge edge0 = (Edge) itr.next();
-        Edge edge1 = (Edge) itr.next();
-        if (edge0.getTo().equals(edge0.getFrom())) {
-            assertTrue(edge0.getCycle() != null && edge0.getCycle().size() == 1);
-            List cycle = edge1.getCycle();
-            assertTrue(cycle != null && cycle.size() == 4);
-            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(3)).getTo()));
-        } else if (edge1.getTo().equals(edge1.getFrom())) {
-            assertTrue(edge1.getCycle() != null && edge1.getCycle().size() == 1);            
-            assertTrue(edge1 == edge1.getCycle());
-            List cycle = edge0.getCycle();
-            assertTrue(cycle != null && cycle.size() == 4);
-            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(3)).getTo()));
-        } else {
-            // should not happen
-            assertFalse(true);
-        }
-    }
-    
-    public void testForwardEdges() {
-        setUpGraph2();
-        Collection edges = _dfa.getEdges(Edge.TYPE_FORWARD);
-        assertEquals(2, edges.size());
-        Iterator itr = edges.iterator();
-        Edge edge0 = (Edge) itr.next();
-        Edge edge1 = (Edge) itr.next();
-        if (edge0.getCycle() == null) {
-            List cycle = edge1.getCycle();
-            assertTrue(cycle != null && cycle.size() == 3);
-            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(2)).getTo()));
-        } else if (edge1.getCycle() == null) {
-            List cycle = edge0.getCycle();
-            assertTrue(cycle != null && cycle.size() == 3);
-            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(2)).getTo()));
-        } else {
-            // should not happen
-            assertFalse(true);
-        }
-    }
-    
-    public static void main(String[] args) {
-        main(TestDepthFirstAnalysis.class);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.openjpa.lib.test.AbstractTestCase;
+
+/**
+ * <p>Tests the {@link DepthFirstAnalysis} type.</p>
+ *
+ * @author Abe White
+ */
+public class TestDepthFirstAnalysis
+    extends AbstractTestCase {
+
+    private DepthFirstAnalysis _dfa = null;
+
+    public void setUp() {
+        setUpGraph1();   
+    }
+    
+    public void setUpGraph1() {
+        Graph graph = new Graph();
+        Object node1 = new Object();
+        Object node2 = new Object();
+        Object node3 = new Object();
+        Object node4 = new Object();
+        graph.addNode(node1);
+        graph.addNode(node2);
+        graph.addNode(node3);
+        graph.addNode(node4);
+        graph.addEdge(new Edge(node1, node2, true));
+        graph.addEdge(new Edge(node2, node3, true));
+        graph.addEdge(new Edge(node3, node1, true));
+        graph.addEdge(new Edge(node3, node4, true));
+        graph.addEdge(new Edge(node2, node2, true));
+        _dfa = new DepthFirstAnalysis(graph);
+    }
+
+    public void setUpGraph2() {
+        Graph graph = new Graph();
+        Integer node1 = new Integer(1);
+        Integer node2 = new Integer(2);
+        Integer node3 = new Integer(3);
+        Integer node4 = new Integer(4);
+        Integer node5 = new Integer(5);
+        graph.addNode(node2);  // has to be first node for testcase
+        graph.addNode(node5);
+        graph.addNode(node4);
+        graph.addNode(node3);
+        graph.addNode(node1);
+        graph.addEdge(new Edge(node5, node4, true));
+        graph.addEdge(new Edge(node4, node3, true));
+        graph.addEdge(new Edge(node3, node3, true));
+        graph.addEdge(new Edge(node3, node2, true));
+        graph.addEdge(new Edge(node2, node5, true));
+        graph.addEdge(new Edge(node2, node4, true));
+        graph.addEdge(new Edge(node1, node4, true));
+        _dfa = new DepthFirstAnalysis(graph);
+    }
+
+    public void testNodeSorting() {
+        Collection nodes = _dfa.getSortedNodes();
+        assertEquals(4, nodes.size());
+
+        int time = 0;
+        Object node;
+        for (Iterator itr = nodes.iterator(); itr.hasNext();) {
+            node = itr.next();
+            assertTrue(time <= _dfa.getFinishedTime(node));
+            time = _dfa.getFinishedTime(node);
+        }
+    }
+
+    public void testEdgeTyping() {
+        Collection edges = _dfa.getEdges(Edge.TYPE_BACK);
+        assertEquals(2, edges.size());
+        Iterator itr = edges.iterator();
+        Edge edge0 = (Edge) itr.next();
+        Edge edge1 = (Edge) itr.next();
+        assertTrue((edge0.getTo().equals(edge0.getFrom()))
+                || edge1.getTo().equals(edge1.getFrom()));
+    }
+
+    public void testBackEdges() {
+        setUpGraph2();
+        Collection edges = _dfa.getEdges(Edge.TYPE_BACK);
+        assertEquals(2, edges.size());
+        Iterator itr = edges.iterator();
+        Edge edge0 = (Edge) itr.next();
+        Edge edge1 = (Edge) itr.next();
+        if (edge0.getTo().equals(edge0.getFrom())) {
+            assertTrue(edge0.getCycle() != null && edge0.getCycle().size() == 1);
+            List cycle = edge1.getCycle();
+            assertTrue(cycle != null && cycle.size() == 4);
+            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(3)).getTo()));
+        } else if (edge1.getTo().equals(edge1.getFrom())) {
+            assertTrue(edge1.getCycle() != null && edge1.getCycle().size() == 1);            
+            assertTrue(edge1 == edge1.getCycle());
+            List cycle = edge0.getCycle();
+            assertTrue(cycle != null && cycle.size() == 4);
+            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(3)).getTo()));
+        } else {
+            // should not happen
+            assertFalse(true);
+        }
+    }
+    
+    public void testForwardEdges() {
+        setUpGraph2();
+        Collection edges = _dfa.getEdges(Edge.TYPE_FORWARD);
+        assertEquals(2, edges.size());
+        Iterator itr = edges.iterator();
+        Edge edge0 = (Edge) itr.next();
+        Edge edge1 = (Edge) itr.next();
+        if (edge0.getCycle() == null) {
+            List cycle = edge1.getCycle();
+            assertTrue(cycle != null && cycle.size() == 3);
+            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(2)).getTo()));
+        } else if (edge1.getCycle() == null) {
+            List cycle = edge0.getCycle();
+            assertTrue(cycle != null && cycle.size() == 3);
+            assertTrue(((Edge)cycle.get(0)).getFrom().equals(((Edge)cycle.get(2)).getTo()));
+        } else {
+            // should not happen
+            assertFalse(true);
+        }
+    }
+    
+    public static void main(String[] args) {
+        main(TestDepthFirstAnalysis.class);
+    }
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestGraph.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestGraph.java
index 2c93755..3b21530 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestGraph.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/graph/TestGraph.java
@@ -1,148 +1,148 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.graph;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.openjpa.lib.test.AbstractTestCase;
-
-/**
- * <p>Tests the {@link Graph} type, and in so doing implicitly tests the
- * {@link Edge} as well.</p>
- *
- * @author Abe White
- */
-public class TestGraph
-    extends AbstractTestCase {
-
-    private Graph _graph = new Graph();
-    private Object _node1 = new Object();
-    private Object _node2 = new Object();
-    private Object _node3 = new Object();
-    private Edge _edge1 = new Edge(_node1, _node2, true);
-    private Edge _edge2 = new Edge(_node2, _node3, true);
-    private Edge _edge3 = new Edge(_node1, _node3, false);
-    private Edge _edge4 = new Edge(_node2, _node2, false);
-
-    public void setUp() {
-        _graph.addNode(_node1);
-        _graph.addNode(_node2);
-        _graph.addNode(_node3);
-        _graph.addEdge(_edge1);
-        _graph.addEdge(_edge2);
-        _graph.addEdge(_edge3);
-        _graph.addEdge(_edge4);
-    }
-
-    /**
-     * Tests adding and retrieving nodes and edges.
-     */
-    public void testAddRetrieve() {
-        assertEquals(3, _graph.getNodes().size());
-        assertEquals(4, _graph.getEdges().size());
-
-        Collection edges = _graph.getEdgesFrom(_node1);
-        assertEquals(2, edges.size());
-        Iterator itr = edges.iterator();
-        Edge edge0 = (Edge) itr.next();
-        Edge edge1 = (Edge) itr.next();
-        assertTrue((edge0 == _edge1 && edge1 == _edge3)
-            || (edge0 == _edge3 && edge1 == _edge1));
-
-        edges = _graph.getEdgesTo(_node1);
-        assertEquals(1, edges.size());
-        assertEquals(_edge3, edges.iterator().next());
-
-        edges = _graph.getEdges(_node1, _node3);
-        assertEquals(1, edges.size());
-        assertEquals(_edge3, edges.iterator().next());
-        edges = _graph.getEdges(_node3, _node1);
-        assertEquals(1, edges.size());
-        assertEquals(_edge3, edges.iterator().next());
-
-        edges = _graph.getEdgesFrom(_node2);
-        assertEquals(2, edges.size());
-        itr = edges.iterator();
-        edge0 = (Edge) itr.next();
-        edge1 = (Edge) itr.next();
-        assertTrue((edge0 == _edge2 && edge1 == _edge4)
-            || (edge0 == _edge4 && edge1 == _edge2));
-
-        edges = _graph.getEdgesTo(_node2);
-        assertEquals(2, edges.size());
-        itr = edges.iterator();
-        edge0 = (Edge) itr.next();
-        edge1 = (Edge) itr.next();
-        assertTrue((edge0 == _edge1 && edge1 == _edge4)
-            || (edge0 == _edge4 && edge1 == _edge1));
-
-        edges = _graph.getEdges(_node2, _node2);
-        assertEquals(1, edges.size());
-        assertEquals(_edge4, edges.iterator().next());
-
-        edges = _graph.getEdgesFrom(_node3);
-        assertEquals(1, edges.size());
-        assertEquals(_edge3, edges.iterator().next());
-    }
-
-    /**
-     * Test removing edges.
-     */
-    public void testRemoveEdges() {
-        assertTrue(_graph.removeEdge(_edge2));
-        Collection edges = _graph.getEdgesFrom(_node2);
-        assertEquals(1, edges.size());
-        assertEquals(_edge4, edges.iterator().next());
-
-        assertTrue(_graph.removeEdge(_edge3));
-        edges = _graph.getEdgesFrom(_node1);
-        assertEquals(1, edges.size());
-        assertEquals(_edge1, edges.iterator().next());
-        edges = _graph.getEdgesTo(_node1);
-        assertEquals(0, edges.size());
-        edges = _graph.getEdgesTo(_node3);
-        assertEquals(0, edges.size());
-        edges = _graph.getEdgesFrom(_node3);
-        assertEquals(0, edges.size());
-    }
-
-    /**
-     * Test removing nodes.
-     */
-    public void testRemoveNodes() {
-        assertTrue(_graph.removeNode(_node3));
-        Collection edges = _graph.getEdges();
-        assertEquals(2, edges.size());
-        Iterator itr = edges.iterator();
-        Edge edge0 = (Edge) itr.next();
-        Edge edge1 = (Edge) itr.next();
-        assertTrue((edge0 == _edge1 && edge1 == _edge4)
-            || (edge0 == _edge4 && edge1 == _edge1));
-        edges = _graph.getEdgesFrom(_node1);
-        assertEquals(1, edges.size());
-        assertEquals(_edge1, edges.iterator().next());
-        edges = _graph.getEdgesTo(_node1);
-        assertEquals(0, edges.size());
-    }
-
-    public static void main(String[] args) {
-        main(TestGraph.class);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.graph;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.openjpa.lib.test.AbstractTestCase;
+
+/**
+ * <p>Tests the {@link Graph} type, and in so doing implicitly tests the
+ * {@link Edge} as well.</p>
+ *
+ * @author Abe White
+ */
+public class TestGraph
+    extends AbstractTestCase {
+
+    private Graph _graph = new Graph();
+    private Object _node1 = new Object();
+    private Object _node2 = new Object();
+    private Object _node3 = new Object();
+    private Edge _edge1 = new Edge(_node1, _node2, true);
+    private Edge _edge2 = new Edge(_node2, _node3, true);
+    private Edge _edge3 = new Edge(_node1, _node3, false);
+    private Edge _edge4 = new Edge(_node2, _node2, false);
+
+    public void setUp() {
+        _graph.addNode(_node1);
+        _graph.addNode(_node2);
+        _graph.addNode(_node3);
+        _graph.addEdge(_edge1);
+        _graph.addEdge(_edge2);
+        _graph.addEdge(_edge3);
+        _graph.addEdge(_edge4);
+    }
+
+    /**
+     * Tests adding and retrieving nodes and edges.
+     */
+    public void testAddRetrieve() {
+        assertEquals(3, _graph.getNodes().size());
+        assertEquals(4, _graph.getEdges().size());
+
+        Collection edges = _graph.getEdgesFrom(_node1);
+        assertEquals(2, edges.size());
+        Iterator itr = edges.iterator();
+        Edge edge0 = (Edge) itr.next();
+        Edge edge1 = (Edge) itr.next();
+        assertTrue((edge0 == _edge1 && edge1 == _edge3)
+            || (edge0 == _edge3 && edge1 == _edge1));
+
+        edges = _graph.getEdgesTo(_node1);
+        assertEquals(1, edges.size());
+        assertEquals(_edge3, edges.iterator().next());
+
+        edges = _graph.getEdges(_node1, _node3);
+        assertEquals(1, edges.size());
+        assertEquals(_edge3, edges.iterator().next());
+        edges = _graph.getEdges(_node3, _node1);
+        assertEquals(1, edges.size());
+        assertEquals(_edge3, edges.iterator().next());
+
+        edges = _graph.getEdgesFrom(_node2);
+        assertEquals(2, edges.size());
+        itr = edges.iterator();
+        edge0 = (Edge) itr.next();
+        edge1 = (Edge) itr.next();
+        assertTrue((edge0 == _edge2 && edge1 == _edge4)
+            || (edge0 == _edge4 && edge1 == _edge2));
+
+        edges = _graph.getEdgesTo(_node2);
+        assertEquals(2, edges.size());
+        itr = edges.iterator();
+        edge0 = (Edge) itr.next();
+        edge1 = (Edge) itr.next();
+        assertTrue((edge0 == _edge1 && edge1 == _edge4)
+            || (edge0 == _edge4 && edge1 == _edge1));
+
+        edges = _graph.getEdges(_node2, _node2);
+        assertEquals(1, edges.size());
+        assertEquals(_edge4, edges.iterator().next());
+
+        edges = _graph.getEdgesFrom(_node3);
+        assertEquals(1, edges.size());
+        assertEquals(_edge3, edges.iterator().next());
+    }
+
+    /**
+     * Test removing edges.
+     */
+    public void testRemoveEdges() {
+        assertTrue(_graph.removeEdge(_edge2));
+        Collection edges = _graph.getEdgesFrom(_node2);
+        assertEquals(1, edges.size());
+        assertEquals(_edge4, edges.iterator().next());
+
+        assertTrue(_graph.removeEdge(_edge3));
+        edges = _graph.getEdgesFrom(_node1);
+        assertEquals(1, edges.size());
+        assertEquals(_edge1, edges.iterator().next());
+        edges = _graph.getEdgesTo(_node1);
+        assertEquals(0, edges.size());
+        edges = _graph.getEdgesTo(_node3);
+        assertEquals(0, edges.size());
+        edges = _graph.getEdgesFrom(_node3);
+        assertEquals(0, edges.size());
+    }
+
+    /**
+     * Test removing nodes.
+     */
+    public void testRemoveNodes() {
+        assertTrue(_graph.removeNode(_node3));
+        Collection edges = _graph.getEdges();
+        assertEquals(2, edges.size());
+        Iterator itr = edges.iterator();
+        Edge edge0 = (Edge) itr.next();
+        Edge edge1 = (Edge) itr.next();
+        assertTrue((edge0 == _edge1 && edge1 == _edge4)
+            || (edge0 == _edge4 && edge1 == _edge1));
+        edges = _graph.getEdgesFrom(_node1);
+        assertEquals(1, edges.size());
+        assertEquals(_edge1, edges.iterator().next());
+        edges = _graph.getEdgesTo(_node1);
+        assertEquals(0, edges.size());
+    }
+
+    public static void main(String[] args) {
+        main(TestGraph.class);
+	}
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/ResultListTest.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/ResultListTest.java
index cb39557..9155809 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/ResultListTest.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/ResultListTest.java
@@ -37,9 +37,16 @@
 
     private ResultList[] _lists = null;
 
+    protected boolean subListSupported = false;
+    
     public ResultListTest(String test) {
         super(test);
     }
+    
+    public ResultListTest(String test, boolean supportSubList) {
+        super(test);
+        subListSupported = supportSubList;
+    }
 
     /**
      * Return a result list to use with the given provider.
@@ -269,4 +276,20 @@
             assertTrue(list.isEmpty());
         }
     }
+
+    public void testSubList() {
+        ResultObjectProvider[] rops = getResultObjectProviders
+            (Collections.EMPTY_LIST);
+        for (int i = 0; i < rops.length; i++) {
+            ResultList list = getResultList(rops[i]);
+            try {
+                List subList = list.subList(0, 0);
+                if (subListSupported == false)
+                    fail("Should not support subList.");
+            } catch (UnsupportedOperationException e) {
+                if (subListSupported == true)
+                    fail("Should support subList.");
+            }
+        }
+    }
 }
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestEagerResultList.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestEagerResultList.java
index fa1830c..6e4e222 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestEagerResultList.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestEagerResultList.java
@@ -26,7 +26,7 @@
 public class TestEagerResultList extends ResultListTest {
 
     public TestEagerResultList(String test) {
-        super(test);
+        super(test, true);
     }
 
     protected ResultList getResultList(ResultObjectProvider provider) {
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestLazyForwardResultList.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestLazyForwardResultList.java
index f3b209f..3eb6484 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestLazyForwardResultList.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestLazyForwardResultList.java
@@ -26,7 +26,7 @@
 public class TestLazyForwardResultList extends ResultListTest {
 
     public TestLazyForwardResultList(String test) {
-        super(test);
+        super(test, true);
     }
 
     protected ResultList getResultList(ResultObjectProvider provider) {
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestListResultList.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestListResultList.java
index a943536..41e4de4 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestListResultList.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/rop/TestListResultList.java
@@ -26,7 +26,7 @@
 public class TestListResultList extends ResultListTest {
 
     public TestListResultList(String test) {
-        super(test);
+        super(test, true);
     }
 
     protected ResultList getResultList(ResultObjectProvider provider) {
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java
index 0495c18..49a389f 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.java
@@ -1,1115 +1,1115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.test;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URL;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.textui.TestRunner;
-import org.apache.regexp.RE;
-import org.apache.regexp.RESyntaxException;
-import org.apache.regexp.REUtil;
-import org.apache.tools.ant.AntClassLoader;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.ProjectHelper;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.log.LogFactoryImpl;
-import org.apache.openjpa.lib.util.Localizer;
-
-/**
- * TestCase framework to run various tests against solarmetric code.
- * This class contains various utility methods for the following functions:
- * <ul>
- * <li>Using multiple, isolated ClassLoaders</li>
- * <li>Running a test in multiple concurrent threads</li>
- * <li>Assertion helpers</li>
- * <li>Creating random Strings, numbers, etc.</li>
- * </ul>
- *
- * @author Marc Prud'hommeaux
- * @author Patrick Linskey
- */
-public abstract class AbstractTestCase extends TestCase {
-
-    public static final String TEST_METHODS =
-        System.getProperty(AbstractTestCase.class.getName() + ".testMethods");
-    public static final long PLATFORM_ALL = 2 << 1;
-    public static final long PLATFORM_UNKNOWN = 2 << 2;
-
-    public static final String SKIP_TOKEN = "SOLARSKIP";
-    public static final String SKIP_DELIMITER = "|";
-
-    private static final Localizer _loc =
-        Localizer.forPackage(AbstractTestCase.class);
-
-    private Log log = null;
-
-    private static Map _times = new HashMap();
-
-    private static AbstractTestCase _lastTest = null;
-
-    private static WatchdogThread _watchdog = new WatchdogThread();
-    private long _timeout;
-
-    /**
-     * Constructor. Create a test case with the specified name.
-     */
-    public AbstractTestCase(String test) {
-        super(test);
-    }
-
-    public AbstractTestCase() {
-    }
-
-    protected final Log getLog() {
-        if (log == null)
-            log = newLog();
-        return log;
-    }
-
-    protected Log newLog() {
-        // this implementation leaves much to be desired, as it just
-        // creates a new LogFactoryImpl each time, and does not apply
-        // any configurations.
-        return new LogFactoryImpl().getLog(getLogName());
-    }
-
-    protected String getLogName() {
-        return "com.solarmetric.Runtime";
-    }
-
-    /**
-     * Called before the watchdog thread is about to kill the entire
-     * JVM due to a test case's timeout. This method offers the
-     * ability to try to resolve whatever contention is taking place
-     * in the test. It will be given 10 seconds to try to end the
-     * test peacefully before the watchdog exits the JVM.
-     */
-    protected void preTimeout() {
-    }
-
-    public void run(TestResult result) {
-        if (skipTest()) {
-            // keep track of the tests we skip so that we can get an
-            // idea in the autobuild status
-            System.err.println(SKIP_TOKEN + SKIP_DELIMITER
-                + ("" + getClass().getName())
-                + "." + getName() + SKIP_DELIMITER);
-            return;
-        }
-
-        if (_lastTest != null && _lastTest.getClass() != getClass()) {
-            try {
-                _lastTest.tearDownTestClass();
-            } catch (Throwable t) {
-                getLog().error(null, t);
-            }
-        }
-
-        if (_lastTest == null || _lastTest.getClass() != getClass()) {
-            try {
-                setUpTestClass();
-            } catch (Throwable t) {
-                getLog().error(null, t);
-            }
-        }
-
-        _lastTest = this;
-
-        // inform the watchdog thread that we are entering the test
-        _watchdog.enteringTest(this);
-        try {
-            super.run(result);
-        } finally {
-            _watchdog.leavingTest(this);
-        }
-    }
-
-    /**
-     * If this test should be skipped given the current
-     * environment, return <code>true</code>. This allows a unit test
-     * class to disable test cases on a per-method granularity, and
-     * prevents the test from showing up as a passed test just
-     * because it was skipped.
-     * For example, if a particular test case method should not be
-     * run against a certain database, this method could check the
-     * name of the test result and the current database configuration
-     * in order to make the decision:
-     * <p/>
-     * <code> protected boolean skipTest() {
-     * // don't run with pointbase: it uses a DataSource, which
-     * // can't be translated into a JBoss DataSource configuration.
-     * if ("testJBoss".equals(getName()) &&
-     * getCurrentPlatform() == PLATFORM_POINTBASE)
-     * return true;
-     * }
-     * </code>
-     * If you want to disable execution of an entire test case
-     * class for a given database, you might want to add the class to
-     * the excluded test list in that database's properties file.
-     */
-    protected boolean skipTest() {
-        if (TEST_METHODS != null && TEST_METHODS.length() > 0)
-            return TEST_METHODS.indexOf(getName()) == -1;
-
-        return false;
-    }
-
-    /**
-     * This method is called before the first test in this test class
-     * is executed.
-     */
-    public void setUpTestClass() throws Exception {
-    }
-
-    /**
-     * This method is called after the last test in this test class
-     * is executed. It can be used to do things like clean up
-     * large, slow processes that may have been started.
-     */
-    public void tearDownTestClass() throws Exception {
-    }
-
-    public void tearDown() throws Exception {
-        if ("true".equals(System.getProperty("meminfo")))
-            printMemoryInfo();
-
-        super.tearDown();
-    }
-
-    //////////////////////////
-    // Generating random data
-    //////////////////////////
-
-    /**
-     * Support method to get a random Integer for testing.
-     */
-    public static Integer randomInt() {
-        return new Integer((int) (Math.random() * Integer.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Character for testing.
-     */
-    public static Character randomChar() {
-        char [] TEST_CHAR_ARRAY = new char []{
-            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
-            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
-            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
-            '2', '3', '4', '5', '6', '7', '8', '9' };
-
-        return new Character(TEST_CHAR_ARRAY[
-            (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
-    }
-
-    /**
-     * Support method to get a random Long for testing.
-     */
-    public static Long randomLong() {
-        return new Long((long) (Math.random() * Long.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Short for testing.
-     */
-    public static Short randomShort() {
-        return new Short((short) (Math.random() * Short.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Double for testing.
-     */
-    public static Double randomDouble() {
-        return new Double((double) (Math.round(Math.random() * 5000d)) / 1000d);
-    }
-
-    /**
-     * Support method to get a random Float for testing.
-     */
-    public static Float randomFloat() {
-        return new Float((float) (Math.round(Math.random() * 5000f)) / 1000f);
-    }
-
-    /**
-     * Support method to get a random Byte for testing.
-     */
-    public static Byte randomByte() {
-        return new Byte((byte) (Math.random() * Byte.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Boolean for testing.
-     */
-    public static Boolean randomBoolean() {
-        return new Boolean(Math.random() > 0.5 ? true : false);
-    }
-
-    /**
-     * Support method to get a random Date for testing.
-     */
-    public static Date randomDate() {
-        long millis = (long) (Math.random() * System.currentTimeMillis());
-
-        // round millis to the nearest 1000: this is because some
-        // databases do not store the milliseconds correctly(e.g., MySQL).
-        // This is a really a bug we should fix. FC #27.
-        millis -= (millis % 1000);
-
-        return new Date(millis);
-    }
-
-    /**
-     * Support method to get a random String for testing.
-     */
-    public static String randomString() {
-        // default to a small string, in case column sizes are
-        // limited(such as with a string primary key)
-        return randomString(50);
-    }
-
-    /**
-     * Support method to get a random String for testing.
-     */
-    public static String randomString(int len) {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
-            buf.append(randomChar());
-        return buf.toString();
-    }
-
-    /**
-     * Support method to get a random clob for testing.
-     */
-    public static String randomClob() {
-        StringBuffer sbuf = new StringBuffer();
-        while (sbuf.length() < (5 * 1024)) { // at least 5K
-            sbuf.append(randomString(1024));
-        }
-
-        return sbuf.toString();
-    }
-
-    /**
-     * Support method to get a random BigInteger for testing.
-     */
-    public static BigInteger randomBigInteger() {
-        // too many of our test databases don't support bigints > MAX_LONG:
-        // I don't like it, but for now, let's only test below MAX_LONG
-        BigInteger lng = new BigInteger(
-            ((long) (Math.random() * Long.MAX_VALUE)) + "");
-
-        BigInteger multiplier = new BigInteger("1");
-        // (1 + (int)(Math.random() * 10000)) + "");
-        if (Math.random() < 0.5)
-            multiplier = multiplier.multiply(new BigInteger("-1"));
-
-        return lng.multiply(multiplier);
-    }
-
-    /**
-     * Support method to get a random BigDecimal for testing.
-     */
-    public static BigDecimal randomBigDecimal() {
-        BigInteger start = randomBigInteger();
-        String str = start.toString();
-        // truncate off the last 8 digits: we still get some
-        // overflows with lame databases.
-        for (int i = 0; i < 8; i++)
-            if (str.length() > 2)
-                str = str.substring(0, str.length() - 1);
-        start = new BigInteger(str);
-
-        String val = start + "." + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10))
-            + ((int) (Math.random() * 10));
-
-        return new BigDecimal(val);
-    }
-
-    /**
-     * Support method to get a random blob for testing.
-     */
-    public static byte[] randomBlob() {
-        // up to 100K blob
-        byte [] blob = new byte [(int) (Math.random() * 1024 * 100)];
-        for (int i = 0; i < blob.length; i++)
-            blob[i] = randomByte().byteValue();
-
-        return blob;
-    }
-
-    /**
-     * Invoke setters for pimitives and primitive wrappers on the
-     * specified object.
-     */
-    public static Object randomizeBean(Object bean)
-        throws IntrospectionException, IllegalAccessException,
-        InvocationTargetException {
-        BeanInfo info = Introspector.getBeanInfo(bean.getClass());
-        PropertyDescriptor [] props = info.getPropertyDescriptors();
-        for (int i = 0; i < props.length; i++) {
-            Method write = props[i].getWriteMethod();
-            if (write == null)
-                continue;
-
-            Class [] params = write.getParameterTypes();
-            if (params == null || params.length != 1)
-                continue;
-
-            Class paramType = params[0];
-            Object arg = null;
-
-            if (paramType == boolean.class || paramType == Boolean.class)
-                arg = randomBoolean();
-            else if (paramType == byte.class || paramType == Byte.class)
-                arg = randomByte();
-            else if (paramType == char.class || paramType == Character.class)
-                arg = randomChar();
-            else if (paramType == short.class || paramType == Short.class)
-                arg = randomShort();
-            else if (paramType == int.class || paramType == Integer.class)
-                arg = randomInt();
-            else if (paramType == long.class || paramType == Long.class)
-                arg = randomLong();
-            else if (paramType == double.class || paramType == Double.class)
-                arg = randomDouble();
-            else if (paramType == float.class || paramType == Float.class)
-                arg = randomFloat();
-            else if (paramType == String.class)
-                arg = randomString();
-            else if (paramType == BigInteger.class)
-                arg = randomBigInteger();
-            else if (paramType == BigDecimal.class)
-                arg = randomBigDecimal();
-            else if (paramType == Date.class)
-                arg = randomDate();
-
-            if (arg != null)
-                write.invoke(bean, new Object []{ arg });
-        }
-
-        return bean;
-    }
-
-    /**
-     * Utility method to start a profile.
-     *
-     * @see #endProfile(String)
-     */
-    public void startProfile(String name) {
-        _times.put(name, new Long(System.currentTimeMillis()));
-    }
-
-    /**
-     * Utility to end the profile and print out the time. Example usage:
-     * <p/>
-     * <pre><code> startProfile("Some long task"); doSomeLongTask();
-     * endProfile("Some long task");
-     * </code></pre>
-     *
-     * @param name
-     * @return the amount of time that this profile invocation took, or
-     *         -1 if <code>name</code> was never started.
-     */
-    public long endProfile(String name) {
-        Long time = (Long) _times.remove(name);
-
-        long elapsed = -1;
-        if (time != null)
-            elapsed = System.currentTimeMillis() - time.longValue();
-
-        getLog().info(_loc.get("profile-info", name,
-            (time == null ? "???" : "" + elapsed)));
-        return elapsed;
-    }
-
-    /////////////////////////
-    // ClassLoader functions
-    /////////////////////////
-
-    /**
-     * Create a ClassLoader that will not use the parent
-     * ClassLoader to resolve classes. This is useful for
-     * testing interactions between Kodo in running
-     * in ClassLoaderA and instances in ClassLoaderB.
-     */
-    public ClassLoader createIsolatedClassLoader() {
-        return new IsolatedClassLoader();
-    }
-
-    public NestedClassLoader createNestedClassLoader() {
-        return new NestedClassLoader(false);
-    }
-
-    public NestedClassLoader createNestedParentClassLoader() {
-        return new NestedClassLoader(true);
-    }
-
-    /**
-     * Reload the specified class in an isolated ClassLoader.
-     *
-     * @param target the target class to load
-     * @return the Class as reloaded in an new ClassLoader
-     */
-    public Class isolate(Class target) throws ClassNotFoundException {
-        Class result = isolate(target.getName());
-        assertTrue(result != target);
-        assertNotEquals(result, target);
-        assertTrue(result.getClassLoader() != target.getClassLoader());
-        return result;
-    }
-
-    public Class isolate(String target) throws ClassNotFoundException {
-        ClassLoader il = createIsolatedClassLoader();
-        Class result = il.loadClass(target);
-        assertEquals(result.getName(), target);
-
-        return result;
-    }
-
-    public Class nest(Class target) throws ClassNotFoundException {
-        ClassLoader il = createNestedClassLoader();
-        Class result = il.loadClass(target.getName());
-        assertTrue(result != target);
-        assertNotEquals(result, target);
-        assertTrue(result.getClassLoader() != target.getClassLoader());
-        assertEquals(result.getName(), target.getName());
-
-        return result;
-    }
-
-    public Object isolateNew(Class target)
-        throws ClassNotFoundException, IllegalAccessException,
-        InstantiationException {
-        return isolate(target).newInstance();
-    }
-
-    private static class NestedClassLoader extends AntClassLoader {
-
-        public NestedClassLoader(boolean useParent) {
-            super(ClassLoader.getSystemClassLoader(), useParent);
-
-            for (StringTokenizer cltok = new StringTokenizer(
-                System.getProperty("java.class.path"), File.pathSeparator);
-                cltok.hasMoreTokens();) {
-                String path = cltok.nextToken();
-
-                // only load test paths, not jar files
-                if (path.indexOf(".jar") != -1)
-                    continue;
-                if (path.indexOf(".zip") != -1)
-                    continue;
-
-                addPathElement(path);
-            }
-
-            try {
-                if (!useParent) {
-                    assertTrue(loadClass
-                        (AbstractTestCase.class.getName()).getClassLoader()
-                        != AbstractTestCase.class.getClassLoader());
-                }
-            } catch (ClassNotFoundException cnfe) {
-                fail(cnfe.toString());
-            }
-        }
-
-        public Class findClass(String name) throws ClassNotFoundException {
-            // don't isolate PC and related classes in kodo.enhnace
-            if (name.indexOf(".enhance.") != -1)
-                throw new ClassNotFoundException(name);
-            if (name.indexOf("/enhance/") != -1)
-                throw new ClassNotFoundException(name);
-            return super.findClass(name);
-        }
-    }
-
-    /**
-     * A ClassLoader that is completely isolated with respect to
-     * any classes that are loaded in the System ClassLoader.
-     *
-     * @author Marc Prud'hommeaux
-     */
-    private static class IsolatedClassLoader extends NestedClassLoader {
-
-        public IsolatedClassLoader() {
-            super(false);
-            setIsolated(false);
-        }
-    }
-
-    ///////////////
-    // Collections
-    ///////////////
-
-    /**
-     * Validate that the specified {@link Collection} fulfills the
-     * Collection contract as specified by the Collections API.
-     * <p/>
-     * <strong>Note</strong>: does not validate mutable operations
-     */
-    public static void validateCollection(Collection collection) {
-        int size = collection.size();
-        int iterated = 0;
-        // ensure we can walk along the iterator
-        for (Iterator i = collection.iterator(); i.hasNext();) {
-            iterated++;
-            i.next();
-        }
-
-        // ensure the number of values iterated is the same as the list size
-        assertEquals(size, iterated);
-
-        // also validate the list
-        if (collection instanceof List) {
-            List ll = new ArrayList();
-            for (int i = 0; i < 100; i++)
-                ll.add(new Integer(i));
-            validateList((List) ll);
-            validateList((List) collection);
-        }
-    }
-
-    /**
-     * Validate that the specified {@link List} fulfills the
-     * List contract as specified by the Collections API.
-     * <p/>
-     * <strong>Note</strong>: does not validate mutable operations
-     */
-    public static void validateList(List list) {
-        Object [] coreValues = list.toArray();
-        Object [] values1 = new Object [list.size()];
-        Object [] values2 = new Object [list.size()];
-        Object [] values3 = new Object [list.size()];
-        Object [] values4 = new Object [list.size()];
-
-        // fill sequential index access list
-        for (int i = 0; i < list.size(); i++)
-            values1[i] = list.get(i);
-
-        // fill sequential list
-        int index = 0;
-        ListIterator iter;
-        for (iter = list.listIterator(0); iter.hasNext();) {
-            assertEquals(index, iter.nextIndex());
-            assertEquals(index, iter.previousIndex() + 1);
-            values2[index] = iter.next();
-            assertTrue(list.contains(values2[index]));
-            index++;
-        }
-
-        // ensure NoSuchElementException is thrown as appropriate
-        try {
-            iter.next();
-            fail("next() should have resulted in a NoSuchElementException");
-        } catch (NoSuchElementException e) {
-        } // as expected
-
-        // fill reverse sequential list
-        int back = 0;
-        for (iter = list.listIterator(list.size()); iter.hasPrevious();) {
-            assertEquals(index, iter.previousIndex() + 1);
-            assertEquals(index, iter.nextIndex());
-            values3[--index] = iter.previous();
-            back++;
-        }
-        assertEquals(list.size(), back);
-
-        // ensure NoSuchElementException is thrown as appropriate
-        try {
-            iter.previous();
-            fail("previous() should have resulted in a "
-                + "NoSuchElementException");
-        } catch (NoSuchElementException e) {
-        } // as expected
-
-        // fill random access list
-        List indices = new LinkedList();
-        for (int i = 0; i < list.size(); i++)
-            indices.add(new Integer(i));
-
-        for (int i = 0; i < list.size(); i++) {
-            int rand = (int) (Math.random() * indices.size());
-            Integer randIndex = (Integer) indices.remove(rand);
-            values4[randIndex.intValue()] = list.get(randIndex.intValue());
-        }
-
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values1));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values1));
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values2));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values2));
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values4));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values4));
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values3));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values3));
-    }
-
-    /**
-     * Assert that the given List contain the exact same
-     * elements. This is different than the normal List contract, which
-     * states that list1.equals(list2) if each element e1.equals(e2).
-     * This method asserts that e1 == n2.
-     */
-    public static void assertIdentical(List c1, List c2) {
-        assertEquals(c1.size(), c2.size());
-        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
-            i1.hasNext() && i2.hasNext();)
-            assertTrue(i1.next() == i2.next());
-    }
-
-    /**
-     * Assert that the collection parameter is already ordered
-     * according to the specified comparator.
-     */
-    public void assertOrdered(Collection c, Comparator comp) {
-        List l1 = new LinkedList(c);
-        List l2 = new LinkedList(c);
-        assertEquals(l1, l2);
-        Collections.sort(l2, comp);
-        assertEquals(l1, l2);
-        Collections.sort(l1, comp);
-        assertEquals(l1, l2);
-    }
-
-    ////////////////////
-    // Assertion Helpers
-    ////////////////////
-
-    public void assertNotEquals(Object a, Object b) {
-        if (a == null && b != null)
-            return;
-        if (a != null && b == null)
-            return;
-        if (!(a.equals(b)))
-            return;
-        if (!(b.equals(a)))
-            return;
-
-        fail("expected !<" + a + ">.equals(<" + b + ">)");
-    }
-
-    public void assertSize(int size, Object ob) {
-        if (ob == null) {
-            assertEquals(size, 0);
-            return;
-        }
-
-        if (ob instanceof Collection)
-            ob = ((Collection) ob).iterator();
-        if (ob instanceof Iterator) {
-            Iterator i = (Iterator) ob;
-            int count = 0;
-            while (i.hasNext()) {
-                count++;
-                i.next();
-            }
-
-            assertEquals(size, count);
-        } else
-            fail("assertSize: expected Collection, Iterator, "
-                + "Query, or Extent, but got " + ob.getClass().getName());
-    }
-
-    /////////////////////
-    // Generic utilities
-    /////////////////////
-
-    public void copy(File from, File to) throws IOException {
-        copy(new FileInputStream(from), to);
-    }
-
-    public void copy(InputStream in, File to) throws IOException {
-        FileOutputStream fout = new FileOutputStream(to);
-
-        byte[] b = new byte[1024];
-
-        for (int n = 0; (n = in.read(b)) != -1;)
-            fout.write(b, 0, n);
-    }
-
-    /**
-     * Print out information on memory usage.
-     */
-    public void printMemoryInfo() {
-        Runtime rt = Runtime.getRuntime();
-        long total = rt.totalMemory();
-        long free = rt.freeMemory();
-        long used = total - free;
-
-        NumberFormat nf = NumberFormat.getInstance();
-        getLog().warn(_loc.get("mem-info",
-            nf.format(used),
-            nf.format(total),
-            nf.format(free)));
-    }
-
-    /**
-     * Return a list of all values iterated by the given iterator.
-     */
-    public static List iteratorToList(Iterator i) {
-        LinkedList list = new LinkedList();
-        while (i.hasNext())
-            list.add(i.next());
-        return list;
-    }
-
-    /**
-     * Return an array of the objects iterated by the given iterator.
-     */
-    public static Object [] iteratorToArray(Iterator i, Class [] clazz) {
-        return iteratorToList(i).toArray(clazz);
-    }
-
-    /**
-     * Run ant on the specified build file.
-     *
-     * @param buildFile the build file to use
-     * @param target the name of the target to invoke
-     */
-    public void ant(File buildFile, String target) {
-        assertTrue(buildFile.isFile());
-
-        Project project = new Project();
-        project.init();
-        project.setUserProperty("ant.file", buildFile.getAbsolutePath());
-        ProjectHelper.configureProject(project, buildFile);
-        project.executeTarget(target);
-    }
-
-    /**
-     * Serialize and deserialize the object.
-     *
-     * @param validateEquality make sure the hashCode and equals
-     * methods hold true
-     */
-    public static Object roundtrip(Object orig, boolean validateEquality)
-        throws IOException, ClassNotFoundException {
-        assertNotNull(orig);
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(bout);
-        out.writeObject(orig);
-        ByteArrayInputStream bin = new ByteArrayInputStream(
-            bout.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bin);
-        Object result = in.readObject();
-
-        if (validateEquality) {
-            assertEquals(orig, result);
-            assertEquals(orig.hashCode(), result.hashCode());
-        }
-
-        return result;
-    }
-
-    /**
-     * @return true if the specified input matches the regular expression regex.
-     */
-    public static boolean matches(String regex, String input)
-        throws RESyntaxException {
-        RE re = REUtil.createRE(regex);
-        return re.match(input);
-    }
-
-    public static void assertMatches(String regex, String input) {
-        try {
-            if (!(matches(regex, input)))
-                fail("Expected regular expression: <" + regex + ">"
-                    + " did not match: <" + input + ">");
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    public static void assertNotMatches(String regex, String input) {
-        try {
-            if (matches(regex, input))
-                fail("Regular expression: <" + regex + ">"
-                    + " should not match: <" + input + ">");
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    /**
-     * Check the list if strings and return the ones that match
-     * the specified match.
-     */
-    public static List matches(String regex, Collection input)
-        throws RESyntaxException {
-        List matches = new ArrayList();
-        for (Iterator i = input.iterator(); i.hasNext();) {
-            String check = (String) i.next();
-            if (matches(regex, check))
-                matches.add(check);
-        }
-
-        return matches;
-    }
-
-    /**
-     * Assert that the specified collection of Strings contains at least
-     * one string that matches the specified regular expression.
-     */
-    public static void assertMatches(String regex, Collection input) {
-        try {
-            if (matches(regex, input).size() == 0)
-                fail("The specified list of size " + input.size()
-                    + " did not contain any strings that match the"
-                    + " specified regular expression(\"" + regex + "\")");
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    /**
-     * Assert that the specified collection of Strings does not match
-     * the specified regular expression.
-     */
-    public static void assertNotMatches(String regex, Collection input) {
-        try {
-            List matches;
-
-            if (((matches = matches(regex, input))).size() > 0)
-                fail("The specified list of size " + input.size()
-                    + " did contain one or more strings that matchs the"
-                    + " specified illegal regular expression"
-                    + " (\"" + regex + "\")."
-                    + " First example of a matching message is: "
-                    + matches.iterator().next());
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    /**
-     * To be called by the child. E.g.:
-     * <code> public static void main(String [] args) { main(TestBug375.class);
-     * }
-     * </code>
-     */
-    public static void main(Class c) {
-        TestRunner.run(c);
-    }
-
-    /**
-     * To be called by child. Figures out the class from the calling context.
-     */
-    public static void main() {
-        String caller = new SecurityManager() {
-            public String toString() {
-                return getClassContext()[2].getName();
-            }
-        }.toString();
-
-        try {
-            main(Class.forName(caller));
-        } catch (ClassNotFoundException cnfe) {
-            throw new RuntimeException(cnfe.toString());
-        }
-    }
-
-    /**
-     * Returns the jar file in which the class is contained.
-     *
-     * @return the jar file, or none if the class is not in a jar
-     * @throws FileNotFoundException if the jar file cannot located
-     */
-    public static File getJarFile(Class clazz) throws FileNotFoundException {
-        URL url = clazz.getResource(clazz.getName().substring(
-            clazz.getName().lastIndexOf(".") + 1) + ".class");
-        if (url == null)
-            throw new FileNotFoundException(clazz.toString());
-
-        String file = url.getFile();
-        if (file == null)
-            throw new FileNotFoundException(url.toString());
-        int index = file.indexOf("!");
-        if (index == -1)
-            throw new FileNotFoundException(file);
-
-        file = file.substring(0, index);
-        file = file.substring("file:".length());
-
-        File f = new File(file);
-        if (!(f.isFile()))
-            throw new FileNotFoundException(file);
-
-        return f.getAbsoluteFile();
-    }
-
-    /**
-     * The number of milliseconds each test case will have for a timeout.
-     */
-    public void setTimeout(long timeout) {
-        _timeout = timeout;
-    }
-
-    /**
-     * The number of milliseconds each test case will have for a timeout.
-     */
-    public long getTimeout() {
-        return _timeout;
-    }
-
-    /**
-     * A watchdog that just exits the JVM if a test has not completed in
-     * a certain amount of time. This speeds up the mechanism of determining
-     * if a timeout has occurred, since we can exit the entire test run
-     * if a test hasn't completed in a shorted amount of time than
-     * the global test timeout.
-     *
-     * @author Marc Prud'hommeaux
-     */
-    private static class WatchdogThread extends Thread {
-
-        private final long _timeoutms;
-        private long _endtime = -1;
-        private AbstractTestCase _curtest = null;
-
-        public WatchdogThread() {
-            super("Kodo test case watchdog thread");
-            setDaemon(true);
-
-            int timeoutMin = new Integer
-                (System.getProperty("autobuild.testcase.timeout", "20"))
-                .intValue();
-
-            _timeoutms = timeoutMin * 60 * 1000;
-        }
-
-        public void run() {
-            while (true) {
-                try {
-                    sleep(200);
-                } catch (InterruptedException ie) {
-                }
-
-                if (_endtime > 0 && System.currentTimeMillis() > _endtime) {
-                    Thread preTimeout = new Thread
-                        ("Attempting pre-timeout for " + _curtest) {
-                        public void run() {
-                            _curtest.preTimeout();
-                        }
-                    };
-                    preTimeout.start();
-
-                    // wait a little while for the pre-timeout
-                    // thread to complete
-                    try {
-                        preTimeout.join(10 * 1000);
-                    } catch (Exception e) {
-                    }
-
-                    // give it a few more seconds...
-                    try {
-                        sleep(5 * 1000);
-                    } catch (Exception e) {
-                    }
-
-                    // new endtime? resume...
-                    if (System.currentTimeMillis() < _endtime)
-                        continue;
-
-                    new Exception("test case "
-                        + (_curtest != null ? _curtest.getName()
-                        : "UNKNOWN") + " timed out after "
-                        + _timeoutms + "ms").printStackTrace();
-
-                    // also run "killall -QUIT java" to try to grab
-                    // a stack trace
-                    try {
-                        Runtime.getRuntime().exec
-                            (new String[]{ "killall", "-QUIT", "java" });
-                    } catch (Exception e) {
-                    }
-
-                    try {
-                        sleep(1000);
-                    } catch (InterruptedException ie) {
-                    }
-
-                    // now actually exit
-                    System.exit(111);
-                }
-            }
-        }
-
-        public synchronized void enteringTest(AbstractTestCase test) {
-            long timeout = test.getTimeout();
-            if (timeout <= 0)
-                timeout = _timeoutms;
-
-            _endtime = System.currentTimeMillis() + timeout;
-            _curtest = test;
-
-            if (!isAlive())
-                start();
-        }
-
-        public synchronized void leavingTest(AbstractTestCase test) {
-            _endtime = -1;
-            _curtest = null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.test;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.textui.TestRunner;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+import org.apache.regexp.REUtil;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.log.LogFactoryImpl;
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * TestCase framework to run various tests against solarmetric code.
+ * This class contains various utility methods for the following functions:
+ * <ul>
+ * <li>Using multiple, isolated ClassLoaders</li>
+ * <li>Running a test in multiple concurrent threads</li>
+ * <li>Assertion helpers</li>
+ * <li>Creating random Strings, numbers, etc.</li>
+ * </ul>
+ *
+ * @author Marc Prud'hommeaux
+ * @author Patrick Linskey
+ */
+public abstract class AbstractTestCase extends TestCase {
+
+    public static final String TEST_METHODS =
+        System.getProperty(AbstractTestCase.class.getName() + ".testMethods");
+    public static final long PLATFORM_ALL = 2 << 1;
+    public static final long PLATFORM_UNKNOWN = 2 << 2;
+
+    public static final String SKIP_TOKEN = "SOLARSKIP";
+    public static final String SKIP_DELIMITER = "|";
+
+    private static final Localizer _loc =
+        Localizer.forPackage(AbstractTestCase.class);
+
+    private Log log = null;
+
+    private static Map _times = new HashMap();
+
+    private static AbstractTestCase _lastTest = null;
+
+    private static WatchdogThread _watchdog = new WatchdogThread();
+    private long _timeout;
+
+    /**
+     * Constructor. Create a test case with the specified name.
+     */
+    public AbstractTestCase(String test) {
+        super(test);
+    }
+
+    public AbstractTestCase() {
+    }
+
+    protected final Log getLog() {
+        if (log == null)
+            log = newLog();
+        return log;
+    }
+
+    protected Log newLog() {
+        // this implementation leaves much to be desired, as it just
+        // creates a new LogFactoryImpl each time, and does not apply
+        // any configurations.
+        return new LogFactoryImpl().getLog(getLogName());
+    }
+
+    protected String getLogName() {
+        return "com.solarmetric.Runtime";
+    }
+
+    /**
+     * Called before the watchdog thread is about to kill the entire
+     * JVM due to a test case's timeout. This method offers the
+     * ability to try to resolve whatever contention is taking place
+     * in the test. It will be given 10 seconds to try to end the
+     * test peacefully before the watchdog exits the JVM.
+     */
+    protected void preTimeout() {
+    }
+
+    public void run(TestResult result) {
+        if (skipTest()) {
+            // keep track of the tests we skip so that we can get an
+            // idea in the autobuild status
+            System.err.println(SKIP_TOKEN + SKIP_DELIMITER
+                + ("" + getClass().getName())
+                + "." + getName() + SKIP_DELIMITER);
+            return;
+        }
+
+        if (_lastTest != null && _lastTest.getClass() != getClass()) {
+            try {
+                _lastTest.tearDownTestClass();
+            } catch (Throwable t) {
+                getLog().error(null, t);
+            }
+        }
+
+        if (_lastTest == null || _lastTest.getClass() != getClass()) {
+            try {
+                setUpTestClass();
+            } catch (Throwable t) {
+                getLog().error(null, t);
+            }
+        }
+
+        _lastTest = this;
+
+        // inform the watchdog thread that we are entering the test
+        _watchdog.enteringTest(this);
+        try {
+            super.run(result);
+        } finally {
+            _watchdog.leavingTest(this);
+        }
+    }
+
+    /**
+     * If this test should be skipped given the current
+     * environment, return <code>true</code>. This allows a unit test
+     * class to disable test cases on a per-method granularity, and
+     * prevents the test from showing up as a passed test just
+     * because it was skipped.
+     * For example, if a particular test case method should not be
+     * run against a certain database, this method could check the
+     * name of the test result and the current database configuration
+     * in order to make the decision:
+     * <p/>
+     * <code> protected boolean skipTest() {
+     * // don't run with pointbase: it uses a DataSource, which
+     * // can't be translated into a JBoss DataSource configuration.
+     * if ("testJBoss".equals(getName()) &&
+     * getCurrentPlatform() == PLATFORM_POINTBASE)
+     * return true;
+     * }
+     * </code>
+     * If you want to disable execution of an entire test case
+     * class for a given database, you might want to add the class to
+     * the excluded test list in that database's properties file.
+     */
+    protected boolean skipTest() {
+        if (TEST_METHODS != null && TEST_METHODS.length() > 0)
+            return TEST_METHODS.indexOf(getName()) == -1;
+
+        return false;
+    }
+
+    /**
+     * This method is called before the first test in this test class
+     * is executed.
+     */
+    public void setUpTestClass() throws Exception {
+    }
+
+    /**
+     * This method is called after the last test in this test class
+     * is executed. It can be used to do things like clean up
+     * large, slow processes that may have been started.
+     */
+    public void tearDownTestClass() throws Exception {
+    }
+
+    public void tearDown() throws Exception {
+        if ("true".equals(System.getProperty("meminfo")))
+            printMemoryInfo();
+
+        super.tearDown();
+    }
+
+    //////////////////////////
+    // Generating random data
+    //////////////////////////
+
+    /**
+     * Support method to get a random Integer for testing.
+     */
+    public static Integer randomInt() {
+        return new Integer((int) (Math.random() * Integer.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Character for testing.
+     */
+    public static Character randomChar() {
+        char [] TEST_CHAR_ARRAY = new char []{
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
+            '2', '3', '4', '5', '6', '7', '8', '9' };
+
+        return new Character(TEST_CHAR_ARRAY[
+            (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
+    }
+
+    /**
+     * Support method to get a random Long for testing.
+     */
+    public static Long randomLong() {
+        return new Long((long) (Math.random() * Long.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Short for testing.
+     */
+    public static Short randomShort() {
+        return new Short((short) (Math.random() * Short.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Double for testing.
+     */
+    public static Double randomDouble() {
+        return new Double((double) (Math.round(Math.random() * 5000d)) / 1000d);
+    }
+
+    /**
+     * Support method to get a random Float for testing.
+     */
+    public static Float randomFloat() {
+        return new Float((float) (Math.round(Math.random() * 5000f)) / 1000f);
+    }
+
+    /**
+     * Support method to get a random Byte for testing.
+     */
+    public static Byte randomByte() {
+        return new Byte((byte) (Math.random() * Byte.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Boolean for testing.
+     */
+    public static Boolean randomBoolean() {
+        return new Boolean(Math.random() > 0.5 ? true : false);
+    }
+
+    /**
+     * Support method to get a random Date for testing.
+     */
+    public static Date randomDate() {
+        long millis = (long) (Math.random() * System.currentTimeMillis());
+
+        // round millis to the nearest 1000: this is because some
+        // databases do not store the milliseconds correctly(e.g., MySQL).
+        // This is a really a bug we should fix. FC #27.
+        millis -= (millis % 1000);
+
+        return new Date(millis);
+    }
+
+    /**
+     * Support method to get a random String for testing.
+     */
+    public static String randomString() {
+        // default to a small string, in case column sizes are
+        // limited(such as with a string primary key)
+        return randomString(50);
+    }
+
+    /**
+     * Support method to get a random String for testing.
+     */
+    public static String randomString(int len) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
+            buf.append(randomChar());
+        return buf.toString();
+    }
+
+    /**
+     * Support method to get a random clob for testing.
+     */
+    public static String randomClob() {
+        StringBuffer sbuf = new StringBuffer();
+        while (sbuf.length() < (5 * 1024)) { // at least 5K
+            sbuf.append(randomString(1024));
+        }
+
+        return sbuf.toString();
+    }
+
+    /**
+     * Support method to get a random BigInteger for testing.
+     */
+    public static BigInteger randomBigInteger() {
+        // too many of our test databases don't support bigints > MAX_LONG:
+        // I don't like it, but for now, let's only test below MAX_LONG
+        BigInteger lng = new BigInteger(
+            ((long) (Math.random() * Long.MAX_VALUE)) + "");
+
+        BigInteger multiplier = new BigInteger("1");
+        // (1 + (int)(Math.random() * 10000)) + "");
+        if (Math.random() < 0.5)
+            multiplier = multiplier.multiply(new BigInteger("-1"));
+
+        return lng.multiply(multiplier);
+    }
+
+    /**
+     * Support method to get a random BigDecimal for testing.
+     */
+    public static BigDecimal randomBigDecimal() {
+        BigInteger start = randomBigInteger();
+        String str = start.toString();
+        // truncate off the last 8 digits: we still get some
+        // overflows with lame databases.
+        for (int i = 0; i < 8; i++)
+            if (str.length() > 2)
+                str = str.substring(0, str.length() - 1);
+        start = new BigInteger(str);
+
+        String val = start + "." + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10))
+            + ((int) (Math.random() * 10));
+
+        return new BigDecimal(val);
+    }
+
+    /**
+     * Support method to get a random blob for testing.
+     */
+    public static byte[] randomBlob() {
+        // up to 100K blob
+        byte [] blob = new byte [(int) (Math.random() * 1024 * 100)];
+        for (int i = 0; i < blob.length; i++)
+            blob[i] = randomByte().byteValue();
+
+        return blob;
+    }
+
+    /**
+     * Invoke setters for pimitives and primitive wrappers on the
+     * specified object.
+     */
+    public static Object randomizeBean(Object bean)
+        throws IntrospectionException, IllegalAccessException,
+        InvocationTargetException {
+        BeanInfo info = Introspector.getBeanInfo(bean.getClass());
+        PropertyDescriptor [] props = info.getPropertyDescriptors();
+        for (int i = 0; i < props.length; i++) {
+            Method write = props[i].getWriteMethod();
+            if (write == null)
+                continue;
+
+            Class [] params = write.getParameterTypes();
+            if (params == null || params.length != 1)
+                continue;
+
+            Class paramType = params[0];
+            Object arg = null;
+
+            if (paramType == boolean.class || paramType == Boolean.class)
+                arg = randomBoolean();
+            else if (paramType == byte.class || paramType == Byte.class)
+                arg = randomByte();
+            else if (paramType == char.class || paramType == Character.class)
+                arg = randomChar();
+            else if (paramType == short.class || paramType == Short.class)
+                arg = randomShort();
+            else if (paramType == int.class || paramType == Integer.class)
+                arg = randomInt();
+            else if (paramType == long.class || paramType == Long.class)
+                arg = randomLong();
+            else if (paramType == double.class || paramType == Double.class)
+                arg = randomDouble();
+            else if (paramType == float.class || paramType == Float.class)
+                arg = randomFloat();
+            else if (paramType == String.class)
+                arg = randomString();
+            else if (paramType == BigInteger.class)
+                arg = randomBigInteger();
+            else if (paramType == BigDecimal.class)
+                arg = randomBigDecimal();
+            else if (paramType == Date.class)
+                arg = randomDate();
+
+            if (arg != null)
+                write.invoke(bean, new Object []{ arg });
+        }
+
+        return bean;
+    }
+
+    /**
+     * Utility method to start a profile.
+     *
+     * @see #endProfile(String)
+     */
+    public void startProfile(String name) {
+        _times.put(name, new Long(System.currentTimeMillis()));
+    }
+
+    /**
+     * Utility to end the profile and print out the time. Example usage:
+     * <p/>
+     * <pre><code> startProfile("Some long task"); doSomeLongTask();
+     * endProfile("Some long task");
+     * </code></pre>
+     *
+     * @param name
+     * @return the amount of time that this profile invocation took, or
+     *         -1 if <code>name</code> was never started.
+     */
+    public long endProfile(String name) {
+        Long time = (Long) _times.remove(name);
+
+        long elapsed = -1;
+        if (time != null)
+            elapsed = System.currentTimeMillis() - time.longValue();
+
+        getLog().info(_loc.get("profile-info", name,
+            (time == null ? "???" : "" + elapsed)));
+        return elapsed;
+    }
+
+    /////////////////////////
+    // ClassLoader functions
+    /////////////////////////
+
+    /**
+     * Create a ClassLoader that will not use the parent
+     * ClassLoader to resolve classes. This is useful for
+     * testing interactions between Kodo in running
+     * in ClassLoaderA and instances in ClassLoaderB.
+     */
+    public ClassLoader createIsolatedClassLoader() {
+        return new IsolatedClassLoader();
+    }
+
+    public NestedClassLoader createNestedClassLoader() {
+        return new NestedClassLoader(false);
+    }
+
+    public NestedClassLoader createNestedParentClassLoader() {
+        return new NestedClassLoader(true);
+    }
+
+    /**
+     * Reload the specified class in an isolated ClassLoader.
+     *
+     * @param target the target class to load
+     * @return the Class as reloaded in an new ClassLoader
+     */
+    public Class isolate(Class target) throws ClassNotFoundException {
+        Class result = isolate(target.getName());
+        assertTrue(result != target);
+        assertNotEquals(result, target);
+        assertTrue(result.getClassLoader() != target.getClassLoader());
+        return result;
+    }
+
+    public Class isolate(String target) throws ClassNotFoundException {
+        ClassLoader il = createIsolatedClassLoader();
+        Class result = il.loadClass(target);
+        assertEquals(result.getName(), target);
+
+        return result;
+    }
+
+    public Class nest(Class target) throws ClassNotFoundException {
+        ClassLoader il = createNestedClassLoader();
+        Class result = il.loadClass(target.getName());
+        assertTrue(result != target);
+        assertNotEquals(result, target);
+        assertTrue(result.getClassLoader() != target.getClassLoader());
+        assertEquals(result.getName(), target.getName());
+
+        return result;
+    }
+
+    public Object isolateNew(Class target)
+        throws ClassNotFoundException, IllegalAccessException,
+        InstantiationException {
+        return isolate(target).newInstance();
+    }
+
+    private static class NestedClassLoader extends AntClassLoader {
+
+        public NestedClassLoader(boolean useParent) {
+            super(ClassLoader.getSystemClassLoader(), useParent);
+
+            for (StringTokenizer cltok = new StringTokenizer(
+                System.getProperty("java.class.path"), File.pathSeparator);
+                cltok.hasMoreTokens();) {
+                String path = cltok.nextToken();
+
+                // only load test paths, not jar files
+                if (path.indexOf(".jar") != -1)
+                    continue;
+                if (path.indexOf(".zip") != -1)
+                    continue;
+
+                addPathElement(path);
+            }
+
+            try {
+                if (!useParent) {
+                    assertTrue(loadClass
+                        (AbstractTestCase.class.getName()).getClassLoader()
+                        != AbstractTestCase.class.getClassLoader());
+                }
+            } catch (ClassNotFoundException cnfe) {
+                fail(cnfe.toString());
+            }
+        }
+
+        public Class findClass(String name) throws ClassNotFoundException {
+            // don't isolate PC and related classes in kodo.enhnace
+            if (name.indexOf(".enhance.") != -1)
+                throw new ClassNotFoundException(name);
+            if (name.indexOf("/enhance/") != -1)
+                throw new ClassNotFoundException(name);
+            return super.findClass(name);
+        }
+    }
+
+    /**
+     * A ClassLoader that is completely isolated with respect to
+     * any classes that are loaded in the System ClassLoader.
+     *
+     * @author Marc Prud'hommeaux
+     */
+    private static class IsolatedClassLoader extends NestedClassLoader {
+
+        public IsolatedClassLoader() {
+            super(false);
+            setIsolated(false);
+        }
+    }
+
+    ///////////////
+    // Collections
+    ///////////////
+
+    /**
+     * Validate that the specified {@link Collection} fulfills the
+     * Collection contract as specified by the Collections API.
+     * <p/>
+     * <strong>Note</strong>: does not validate mutable operations
+     */
+    public static void validateCollection(Collection collection) {
+        int size = collection.size();
+        int iterated = 0;
+        // ensure we can walk along the iterator
+        for (Iterator i = collection.iterator(); i.hasNext();) {
+            iterated++;
+            i.next();
+        }
+
+        // ensure the number of values iterated is the same as the list size
+        assertEquals(size, iterated);
+
+        // also validate the list
+        if (collection instanceof List) {
+            List ll = new ArrayList();
+            for (int i = 0; i < 100; i++)
+                ll.add(new Integer(i));
+            validateList((List) ll);
+            validateList((List) collection);
+        }
+    }
+
+    /**
+     * Validate that the specified {@link List} fulfills the
+     * List contract as specified by the Collections API.
+     * <p/>
+     * <strong>Note</strong>: does not validate mutable operations
+     */
+    public static void validateList(List list) {
+        Object [] coreValues = list.toArray();
+        Object [] values1 = new Object [list.size()];
+        Object [] values2 = new Object [list.size()];
+        Object [] values3 = new Object [list.size()];
+        Object [] values4 = new Object [list.size()];
+
+        // fill sequential index access list
+        for (int i = 0; i < list.size(); i++)
+            values1[i] = list.get(i);
+
+        // fill sequential list
+        int index = 0;
+        ListIterator iter;
+        for (iter = list.listIterator(0); iter.hasNext();) {
+            assertEquals(index, iter.nextIndex());
+            assertEquals(index, iter.previousIndex() + 1);
+            values2[index] = iter.next();
+            assertTrue(list.contains(values2[index]));
+            index++;
+        }
+
+        // ensure NoSuchElementException is thrown as appropriate
+        try {
+            iter.next();
+            fail("next() should have resulted in a NoSuchElementException");
+        } catch (NoSuchElementException e) {
+        } // as expected
+
+        // fill reverse sequential list
+        int back = 0;
+        for (iter = list.listIterator(list.size()); iter.hasPrevious();) {
+            assertEquals(index, iter.previousIndex() + 1);
+            assertEquals(index, iter.nextIndex());
+            values3[--index] = iter.previous();
+            back++;
+        }
+        assertEquals(list.size(), back);
+
+        // ensure NoSuchElementException is thrown as appropriate
+        try {
+            iter.previous();
+            fail("previous() should have resulted in a "
+                + "NoSuchElementException");
+        } catch (NoSuchElementException e) {
+        } // as expected
+
+        // fill random access list
+        List indices = new LinkedList();
+        for (int i = 0; i < list.size(); i++)
+            indices.add(new Integer(i));
+
+        for (int i = 0; i < list.size(); i++) {
+            int rand = (int) (Math.random() * indices.size());
+            Integer randIndex = (Integer) indices.remove(rand);
+            values4[randIndex.intValue()] = list.get(randIndex.intValue());
+        }
+
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values1));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values1));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values2));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values2));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values4));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values4));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values3));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values3));
+    }
+
+    /**
+     * Assert that the given List contain the exact same
+     * elements. This is different than the normal List contract, which
+     * states that list1.equals(list2) if each element e1.equals(e2).
+     * This method asserts that e1 == n2.
+     */
+    public static void assertIdentical(List c1, List c2) {
+        assertEquals(c1.size(), c2.size());
+        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
+            i1.hasNext() && i2.hasNext();)
+            assertTrue(i1.next() == i2.next());
+    }
+
+    /**
+     * Assert that the collection parameter is already ordered
+     * according to the specified comparator.
+     */
+    public void assertOrdered(Collection c, Comparator comp) {
+        List l1 = new LinkedList(c);
+        List l2 = new LinkedList(c);
+        assertEquals(l1, l2);
+        Collections.sort(l2, comp);
+        assertEquals(l1, l2);
+        Collections.sort(l1, comp);
+        assertEquals(l1, l2);
+    }
+
+    ////////////////////
+    // Assertion Helpers
+    ////////////////////
+
+    public void assertNotEquals(Object a, Object b) {
+        if (a == null && b != null)
+            return;
+        if (a != null && b == null)
+            return;
+        if (!(a.equals(b)))
+            return;
+        if (!(b.equals(a)))
+            return;
+
+        fail("expected !<" + a + ">.equals(<" + b + ">)");
+    }
+
+    public void assertSize(int size, Object ob) {
+        if (ob == null) {
+            assertEquals(size, 0);
+            return;
+        }
+
+        if (ob instanceof Collection)
+            ob = ((Collection) ob).iterator();
+        if (ob instanceof Iterator) {
+            Iterator i = (Iterator) ob;
+            int count = 0;
+            while (i.hasNext()) {
+                count++;
+                i.next();
+            }
+
+            assertEquals(size, count);
+        } else
+            fail("assertSize: expected Collection, Iterator, "
+                + "Query, or Extent, but got " + ob.getClass().getName());
+    }
+
+    /////////////////////
+    // Generic utilities
+    /////////////////////
+
+    public void copy(File from, File to) throws IOException {
+        copy(new FileInputStream(from), to);
+    }
+
+    public void copy(InputStream in, File to) throws IOException {
+        FileOutputStream fout = new FileOutputStream(to);
+
+        byte[] b = new byte[1024];
+
+        for (int n = 0; (n = in.read(b)) != -1;)
+            fout.write(b, 0, n);
+    }
+
+    /**
+     * Print out information on memory usage.
+     */
+    public void printMemoryInfo() {
+        Runtime rt = Runtime.getRuntime();
+        long total = rt.totalMemory();
+        long free = rt.freeMemory();
+        long used = total - free;
+
+        NumberFormat nf = NumberFormat.getInstance();
+        getLog().warn(_loc.get("mem-info",
+            nf.format(used),
+            nf.format(total),
+            nf.format(free)));
+    }
+
+    /**
+     * Return a list of all values iterated by the given iterator.
+     */
+    public static List iteratorToList(Iterator i) {
+        LinkedList list = new LinkedList();
+        while (i.hasNext())
+            list.add(i.next());
+        return list;
+    }
+
+    /**
+     * Return an array of the objects iterated by the given iterator.
+     */
+    public static Object [] iteratorToArray(Iterator i, Class [] clazz) {
+        return iteratorToList(i).toArray(clazz);
+    }
+
+    /**
+     * Run ant on the specified build file.
+     *
+     * @param buildFile the build file to use
+     * @param target the name of the target to invoke
+     */
+    public void ant(File buildFile, String target) {
+        assertTrue(buildFile.isFile());
+
+        Project project = new Project();
+        project.init();
+        project.setUserProperty("ant.file", buildFile.getAbsolutePath());
+        ProjectHelper.configureProject(project, buildFile);
+        project.executeTarget(target);
+    }
+
+    /**
+     * Serialize and deserialize the object.
+     *
+     * @param validateEquality make sure the hashCode and equals
+     * methods hold true
+     */
+    public static Object roundtrip(Object orig, boolean validateEquality)
+        throws IOException, ClassNotFoundException {
+        assertNotNull(orig);
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.writeObject(orig);
+        ByteArrayInputStream bin = new ByteArrayInputStream(
+            bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bin);
+        Object result = in.readObject();
+
+        if (validateEquality) {
+            assertEquals(orig, result);
+            assertEquals(orig.hashCode(), result.hashCode());
+        }
+
+        return result;
+    }
+
+    /**
+     * @return true if the specified input matches the regular expression regex.
+     */
+    public static boolean matches(String regex, String input)
+        throws RESyntaxException {
+        RE re = REUtil.createRE(regex);
+        return re.match(input);
+    }
+
+    public static void assertMatches(String regex, String input) {
+        try {
+            if (!(matches(regex, input)))
+                fail("Expected regular expression: <" + regex + ">"
+                    + " did not match: <" + input + ">");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    public static void assertNotMatches(String regex, String input) {
+        try {
+            if (matches(regex, input))
+                fail("Regular expression: <" + regex + ">"
+                    + " should not match: <" + input + ">");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * Check the list if strings and return the ones that match
+     * the specified match.
+     */
+    public static List matches(String regex, Collection input)
+        throws RESyntaxException {
+        List matches = new ArrayList();
+        for (Iterator i = input.iterator(); i.hasNext();) {
+            String check = (String) i.next();
+            if (matches(regex, check))
+                matches.add(check);
+        }
+
+        return matches;
+    }
+
+    /**
+     * Assert that the specified collection of Strings contains at least
+     * one string that matches the specified regular expression.
+     */
+    public static void assertMatches(String regex, Collection input) {
+        try {
+            if (matches(regex, input).size() == 0)
+                fail("The specified list of size " + input.size()
+                    + " did not contain any strings that match the"
+                    + " specified regular expression(\"" + regex + "\")");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * Assert that the specified collection of Strings does not match
+     * the specified regular expression.
+     */
+    public static void assertNotMatches(String regex, Collection input) {
+        try {
+            List matches;
+
+            if (((matches = matches(regex, input))).size() > 0)
+                fail("The specified list of size " + input.size()
+                    + " did contain one or more strings that matchs the"
+                    + " specified illegal regular expression"
+                    + " (\"" + regex + "\")."
+                    + " First example of a matching message is: "
+                    + matches.iterator().next());
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * To be called by the child. E.g.:
+     * <code> public static void main(String [] args) { main(TestBug375.class);
+     * }
+     * </code>
+     */
+    public static void main(Class c) {
+        TestRunner.run(c);
+    }
+
+    /**
+     * To be called by child. Figures out the class from the calling context.
+     */
+    public static void main() {
+        String caller = new SecurityManager() {
+            public String toString() {
+                return getClassContext()[2].getName();
+            }
+        }.toString();
+
+        try {
+            main(Class.forName(caller));
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException(cnfe.toString());
+        }
+    }
+
+    /**
+     * Returns the jar file in which the class is contained.
+     *
+     * @return the jar file, or none if the class is not in a jar
+     * @throws FileNotFoundException if the jar file cannot located
+     */
+    public static File getJarFile(Class clazz) throws FileNotFoundException {
+        URL url = clazz.getResource(clazz.getName().substring(
+            clazz.getName().lastIndexOf(".") + 1) + ".class");
+        if (url == null)
+            throw new FileNotFoundException(clazz.toString());
+
+        String file = url.getFile();
+        if (file == null)
+            throw new FileNotFoundException(url.toString());
+        int index = file.indexOf("!");
+        if (index == -1)
+            throw new FileNotFoundException(file);
+
+        file = file.substring(0, index);
+        file = file.substring("file:".length());
+
+        File f = new File(file);
+        if (!(f.isFile()))
+            throw new FileNotFoundException(file);
+
+        return f.getAbsoluteFile();
+    }
+
+    /**
+     * The number of milliseconds each test case will have for a timeout.
+     */
+    public void setTimeout(long timeout) {
+        _timeout = timeout;
+    }
+
+    /**
+     * The number of milliseconds each test case will have for a timeout.
+     */
+    public long getTimeout() {
+        return _timeout;
+    }
+
+    /**
+     * A watchdog that just exits the JVM if a test has not completed in
+     * a certain amount of time. This speeds up the mechanism of determining
+     * if a timeout has occurred, since we can exit the entire test run
+     * if a test hasn't completed in a shorted amount of time than
+     * the global test timeout.
+     *
+     * @author Marc Prud'hommeaux
+     */
+    private static class WatchdogThread extends Thread {
+
+        private final long _timeoutms;
+        private long _endtime = -1;
+        private AbstractTestCase _curtest = null;
+
+        public WatchdogThread() {
+            super("Kodo test case watchdog thread");
+            setDaemon(true);
+
+            int timeoutMin = new Integer
+                (System.getProperty("autobuild.testcase.timeout", "20"))
+                .intValue();
+
+            _timeoutms = timeoutMin * 60 * 1000;
+        }
+
+        public void run() {
+            while (true) {
+                try {
+                    sleep(200);
+                } catch (InterruptedException ie) {
+                }
+
+                if (_endtime > 0 && System.currentTimeMillis() > _endtime) {
+                    Thread preTimeout = new Thread
+                        ("Attempting pre-timeout for " + _curtest) {
+                        public void run() {
+                            _curtest.preTimeout();
+                        }
+                    };
+                    preTimeout.start();
+
+                    // wait a little while for the pre-timeout
+                    // thread to complete
+                    try {
+                        preTimeout.join(10 * 1000);
+                    } catch (Exception e) {
+                    }
+
+                    // give it a few more seconds...
+                    try {
+                        sleep(5 * 1000);
+                    } catch (Exception e) {
+                    }
+
+                    // new endtime? resume...
+                    if (System.currentTimeMillis() < _endtime)
+                        continue;
+
+                    new Exception("test case "
+                        + (_curtest != null ? _curtest.getName()
+                        : "UNKNOWN") + " timed out after "
+                        + _timeoutms + "ms").printStackTrace();
+
+                    // also run "killall -QUIT java" to try to grab
+                    // a stack trace
+                    try {
+                        Runtime.getRuntime().exec
+                            (new String[]{ "killall", "-QUIT", "java" });
+                    } catch (Exception e) {
+                    }
+
+                    try {
+                        sleep(1000);
+                    } catch (InterruptedException ie) {
+                    }
+
+                    // now actually exit
+                    System.exit(111);
+                }
+            }
+        }
+
+        public synchronized void enteringTest(AbstractTestCase test) {
+            long timeout = test.getTimeout();
+            if (timeout <= 0)
+                timeout = _timeoutms;
+
+            _endtime = System.currentTimeMillis() + timeout;
+            _curtest = test;
+
+            if (!isAlive())
+                start();
+        }
+
+        public synchronized void leavingTest(AbstractTestCase test) {
+            _endtime = -1;
+            _curtest = null;
+        }
+    }
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java
index d976d2c..bfb6538 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestAbstractEventManager.java
@@ -1,100 +1,100 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.util;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-
-/**
- * Tests the {@link AbstractConcurrentEventManager}.
- *
- * @author Abe White
- */
-public class TestAbstractEventManager extends TestCase {
-
-    private EventManager _em = new EventManager();
-
-    public TestAbstractEventManager(String test) {
-        super(test);
-    }
-
-    public void testReentrantAdd() {
-        Listener l1 = new Listener(Listener.ADD);
-        Listener l2 = new Listener(Listener.NONE);
-        _em.addListener(l1);
-        _em.addListener(l2);
-        _em.fireEvent(new Object());
-        assertTrue(l1.fired);
-        assertTrue(l2.fired);
-        assertEquals(3, _em.getListeners().size());
-    }
-
-    public void testReentrantRemove() {
-        Listener l1 = new Listener(Listener.REMOVE);
-        Listener l2 = new Listener(Listener.NONE);
-        _em.addListener(l1);
-        _em.addListener(l2);
-        _em.fireEvent(new Object());
-        assertTrue(l1.fired);
-        assertTrue(l2.fired);
-        assertEquals(1, _em.getListeners().size());
-        assertFalse(_em.getListeners().contains(l1));
-    }
-
-    public static Test suite() {
-        return new TestSuite(TestAbstractEventManager.class);
-    }
-
-    public static void main(String[] args) {
-        TestRunner.run(suite());
-    }
-
-    private static class EventManager extends AbstractConcurrentEventManager {
-
-        protected void fireEvent(Object event, Object listener) {
-            ((Listener) listener).fire();
-        }
-    }
-
-    private class Listener {
-
-        public static final int NONE = 0;
-        public static final int ADD = 1;
-        public static final int REMOVE = 2;
-
-        public boolean fired;
-        private final int _action;
-
-        public Listener(int action) {
-            _action = action;
-        }
-
-        public void fire() {
-            fired = true;
-            if (_action == ADD)
-                _em.addListener(new Listener(NONE));
-            else if (_action == REMOVE)
-                assertTrue(_em.removeListener(this));
-        }
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.util;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+
+/**
+ * Tests the {@link AbstractConcurrentEventManager}.
+ *
+ * @author Abe White
+ */
+public class TestAbstractEventManager extends TestCase {
+
+    private EventManager _em = new EventManager();
+
+    public TestAbstractEventManager(String test) {
+        super(test);
+    }
+
+    public void testReentrantAdd() {
+        Listener l1 = new Listener(Listener.ADD);
+        Listener l2 = new Listener(Listener.NONE);
+        _em.addListener(l1);
+        _em.addListener(l2);
+        _em.fireEvent(new Object());
+        assertTrue(l1.fired);
+        assertTrue(l2.fired);
+        assertEquals(3, _em.getListeners().size());
+    }
+
+    public void testReentrantRemove() {
+        Listener l1 = new Listener(Listener.REMOVE);
+        Listener l2 = new Listener(Listener.NONE);
+        _em.addListener(l1);
+        _em.addListener(l2);
+        _em.fireEvent(new Object());
+        assertTrue(l1.fired);
+        assertTrue(l2.fired);
+        assertEquals(1, _em.getListeners().size());
+        assertFalse(_em.getListeners().contains(l1));
+    }
+
+    public static Test suite() {
+        return new TestSuite(TestAbstractEventManager.class);
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    private static class EventManager extends AbstractConcurrentEventManager {
+
+        protected void fireEvent(Object event, Object listener) {
+            ((Listener) listener).fire();
+        }
+    }
+
+    private class Listener {
+
+        public static final int NONE = 0;
+        public static final int ADD = 1;
+        public static final int REMOVE = 2;
+
+        public boolean fired;
+        private final int _action;
+
+        public Listener(int action) {
+            _action = action;
+        }
+
+        public void fire() {
+            fired = true;
+            if (_action == ADD)
+                _em.addListener(new Listener(NONE));
+            else if (_action == REMOVE)
+                assertTrue(_em.removeListener(this));
+        }
+    }
+}
+
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestPropertiesParser.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestPropertiesParser.java
index e2f50e4..6110d8e 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestPropertiesParser.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/TestPropertiesParser.java
@@ -1,400 +1,400 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.lib.util;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.StringBufferInputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
-
-import junit.framework.TestCase;
-import org.apache.openjpa.lib.util.FormatPreservingProperties.DuplicateKeyException;
-
-// things to test:
-// - delimiters in keys
-// - escape chars, including \:, \= in files(as generated by Properties)
-// - unicode
-// - non-String keys / vals
-// - list() method behavior
-
-public class TestPropertiesParser extends TestCase {
-
-    private static final String LS = System.getProperty( "line.separator" );
-
-    public void testSimpleProperties() throws IOException {
-        StringBuffer buf = new StringBuffer();
-        buf.append("key: value" + LS);
-        buf.append("key2: value2"); // no EOL -- this is intentional
-        Properties p = toProperties(buf.toString());
-        assertProperties(new String[][]{
-            { "key", "value" }, { "key2", "value2" } }, p);
-    }
-
-    public void testComments() throws IOException {
-        StringBuffer buf = new StringBuffer();
-        buf.append("# this is a comment" + LS);
-        buf.append(" # another one, with leading whitespace	" + LS);
-        buf.append(" 	# 	and more with interesting whitespace	" + LS);
-        buf.append("! and with a ! delimiter" + LS);
-        buf.append("! and with escape \t chars" + LS);
-        buf.append("#and a comment with no whitespace" + LS);
-        Properties p = toProperties(buf.toString());
-        assertEquals(0, p.size());
-    }
-
-    public void testMixedContent() throws IOException {
-        StringBuffer buf = new StringBuffer();
-        buf.append("# this is a comment" + LS);
-        buf.append(" # another one, with leading whitespace	" + LS);
-        buf.append("foo: bar#baz" + LS);
-        buf.append("! and with a ! delimiter" + LS);
-        buf.append("! and with escape \t chars" + LS);
-        Properties p = toProperties(buf.toString());
-        assertProperties(new String[][]{ { "foo", "bar#baz" } }, p);
-    }
-
-    public void testMultiLineInput() throws IOException {
-        String s = "foo: bar\\" + LS + "more line goes here";
-        Properties p = toProperties(s);
-        assertProperties(
-            new String[][]{ { "foo", "barmore line goes here" } }, p);
-    }
-
-    public void testEmptyLines() throws IOException {
-        Properties p = toProperties(LS + "foo: bar" + LS + LS + "baz: val");
-        assertProperties(new String[][]{ { "foo", "bar" }, { "baz", "val" } },
-            p);
-    }
-
-    public void testAddProperties() throws IOException {
-        // intentionally left out the trailing end line
-        String s = "foo: bar" + LS + "baz: val";
-        Properties p = toProperties(s);
-        assertProperties(new String[][]{ { "foo", "bar" }, { "baz", "val" } },
-            p);
-
-        p.put("new-key", "val1");
-        p.put("new-key-2", "val2");
-        p.put("another-new-key", "val3");
-        assertRoundTrip(s + LS + "new-key: val1" + LS + "new-key-2: val2" + LS +
-            "another-new-key: val3" + LS, p);
-    }
-
-    public void testAddAndMutateProperties() throws IOException {
-        // intentionally left out the trailing end line
-        Properties p = toProperties("foo: bar" + LS + "baz: val");
-        assertProperties(new String[][]{ { "foo", "bar" }, { "baz", "val" } },
-            p);
-
-        p.put("new-key", "new value");
-        p.put("foo", "barbar");
-        assertRoundTrip("foo: barbar" + LS + "baz: val" + LS 
-            + "new-key: new value" + LS, p);
-    }
-
-    public void testEscapedEquals() throws IOException {
-        Properties p = toProperties("foo=bar\\=WARN,baz\\=TRACE");
-        assertProperties(new String[][]{ { "foo", "bar=WARN,baz=TRACE" } }, p);
-    }
-
-    public void testLineTypes() throws IOException {
-        StringBuffer buf = new StringBuffer();
-        buf.append("   !comment" + LS + " \t  " + LS + "name = no" + LS + "    "
-            + "#morec\tomm\\" + LS + "ents" + LS + LS + "  dog=no\\cat   " + LS 
-            + "burps    :" + LS + "test=" + LS + "date today" + LS + LS + LS 
-            + "long\\" + LS + "   value=tryin \\" + LS + " "
-            + "gto" + LS + "4:vier" + LS + "vier     :4");
-        Properties p = toProperties(buf.toString());
-        assertProperties(new String[][]{
-            { "name", "no" }, { "ents", "" }, { "dog", "nocat   " },
-            { "burps", "" }, { "test", "" }, { "date", "today" },
-            { "longvalue", "tryin gto" }, { "4", "vier" }, { "vier", "4" },
-        }, p);
-    }
-
-    public void testSpecialChars() throws Throwable {
-        testSpecialChars(false, true);
-        testSpecialChars(true, true);
-        testSpecialChars(false, false);
-        testSpecialChars(true, false);
-    }
-
-    /**
-     * Test that special characters work.
-     *
-     * @param formattingProps if true, test against the
-     * FormatPreservingProperties, otherwise test
-     * against a normal Properties instance(for validation of the test case).
-     * @param value whether to test the key or the value
-     */
-    public void testSpecialChars(boolean formattingProps, boolean value)
-        throws Throwable {
-        List valueList = new ArrayList(Arrays.asList(new String[]{
-            "xxyy", "xx\\yy", "xx" + LS + "yy", "xx\\nyy", "xx\tyy", "xx\\tyy",
-            "xx\ryy", "xx\\ryy", "xx\fyy", "xx\\fyy", "xx\r" + LS + "\\\t\r\t" 
-            + LS + "yy",
-            "xx\\r" + LS + "\\\t\\r\t\\nyy",
-            "xx\r" + LS + "\\\\\\\\\\\\\\\\\\\\\\\\\\\t\r\t" + LS + "yy",
-            "C:\\Program Files\\Some Application\\OpenJPA\\My File.dat", }));
-
-        // also store every individual character
-        for (char c = 'a'; c < 'Z'; c++) {
-            valueList.add(new String(new char[]{ c }));
-            valueList.add(new String(new char[]{ c, '\\', c }));
-            valueList.add(new String(new char[]{ '\\', c }));
-        }
-
-        String[] values = (String[]) valueList.toArray(new String[0]);
-
-        final String dummy = "XXX";
-
-        for (int i = 0; i < values.length; i++) {
-            // test special characters in either keys or values
-            String val = value ? values[i] : dummy;
-            String key = value ? dummy : values[i];
-
-            Properties p = formattingProps ?
-                new FormatPreservingProperties() : new Properties();
-            if (p instanceof FormatPreservingProperties) {
-                // set these properties so we behave the same way as
-                // java.util.Properties
-                ((FormatPreservingProperties) p).setDefaultEntryDelimiter('=');
-                ((FormatPreservingProperties) p).
-                    setAddWhitespaceAfterDelimiter(false);
-            }
-
-            p.setProperty(key, val);
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            p.store(out, null);
-
-            Properties copy = new Properties();
-            copy.setProperty(key, val);
-            ByteArrayOutputStream copyOut = new ByteArrayOutputStream();
-            copy.store(copyOut, null);
-
-            p = formattingProps ?
-                new FormatPreservingProperties() : new Properties();
-
-            InputStream in = new BufferedInputStream
-                (new ByteArrayInputStream(out.toByteArray()));
-
-            try {
-                // make sure that the 2 properties serialized are the same
-                String copyOutString = stripComments(copyOut.toByteArray());
-                String outString = stripComments(out.toByteArray());
-                assertEquals(copyOutString, outString);
-
-                p.load(in);
-
-                assertNotNull("Property \"" + key + "\" was null",
-                    p.getProperty(key));
-                assertEquals(val.trim(), p.getProperty(key).trim());
-            } catch (Throwable ioe) {
-                if (!formattingProps)
-                    throw ioe;
-
-                // bug(1211, ioe,
-                // "Cannot store backslash in FormatPreservingProperties");
-                throw ioe;
-            }
-        }
-    }
-
-    static Character randomChar() {
-        char [] TEST_CHAR_ARRAY = new char []{
-            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
-            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
-            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
-            '2', '3', '4', '5', '6', '7', '8', '9' };
-
-        return new Character(TEST_CHAR_ARRAY[
-            (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
-    }
-
-    static String randomString(int len) {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
-            buf.append(randomChar());
-        return buf.toString();
-    }
-
-    public void testEquivalentStore() throws IOException {
-        Properties p1 = new Properties();
-        FormatPreservingProperties p2 = new FormatPreservingProperties();
-
-        ((FormatPreservingProperties) p2).setDefaultEntryDelimiter('=');
-        ((FormatPreservingProperties) p2).setAddWhitespaceAfterDelimiter(false);
-
-        String[] values =
-            new String[] { 
-                "x", 
-                "x" + LS + "y", 
-                "x\\ny", 
-                "x\ty", 
-                "x\\ty",
-                "x\fy", 
-                "x\\fy", 
-                "x\ry", 
-                "x\\ry", 
-                "C:\\Foo Bar\\Baz",
-                randomString(5).replace('a', '\\'),
-                randomString(500).replace('a', '\\'),
-                randomString(5000).replace('a', '\\'), 
-                };
-
-        for (int i = 0; i < values.length; i++) {
-            p1.clear();
-            p2.clear();
-
-            p1.setProperty("xxx", values[i]);
-            p2.setProperty("xxx", values[i]);
-
-            ByteArrayOutputStream out1 = new ByteArrayOutputStream();
-            ByteArrayOutputStream out2 = new ByteArrayOutputStream();
-
-            p1.store(out1, null);
-            p2.store(out2, null);
-
-            String s1 = new String(out1.toByteArray());
-            String s2 = new String(out2.toByteArray());
-
-            assertTrue("Expected <" + s1 + "> but was <" + s2 + ">",
-                s1.indexOf(s2) != -1);
-        }
-    }
-
-    static String stripComments(byte[] bytes) throws IOException {
-        BufferedReader reader = new BufferedReader(new InputStreamReader
-            (new ByteArrayInputStream(bytes)));
-        StringBuffer sbuf = new StringBuffer();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            // skip comments
-            if (line.trim().startsWith("#"))
-                continue;
-
-            sbuf.append(line);
-            sbuf.append(LS);
-        }
-
-        return sbuf.toString();
-    }
-
-    public void testDuplicateProperties() throws IOException {
-        FormatPreservingProperties p = new FormatPreservingProperties();
-        try {
-            toProperties("foo=bar" + LS + "foo=baz", p);
-            fail("expected duplicate keys to cause exception");
-        } catch (DuplicateKeyException e) {
-            // expected
-        }
-
-        // now test the expected behavior when duplicates are allowed.
-        p = new FormatPreservingProperties();
-        p.setAllowDuplicates(true);
-        toProperties("foo=bar" + LS + "foo=baz", p);
-        assertProperties(new String[][]{ { "foo", "baz" } }, p);
-    }
-
-    public void testMultipleLoads() throws IOException {
-        String props = "foo=bar" + LS + "baz=quux";
-        String props2 = "a=b" + LS + "c=d";
-        Properties vanilla = new Properties();
-        vanilla.load(new BufferedInputStream
-            (new StringBufferInputStream(props)));
-        vanilla.load(new BufferedInputStream
-            (new StringBufferInputStream(props2)));
-
-        Properties p = new FormatPreservingProperties();
-        p.load(new BufferedInputStream(new StringBufferInputStream(props)));
-        p.load(new BufferedInputStream(new StringBufferInputStream(props2)));
-        assertPropertiesSame(vanilla, p);
-    }
-
-    protected FormatPreservingProperties toProperties(String s)
-        throws IOException {
-        return toProperties(s, new FormatPreservingProperties());
-    }
-
-    protected FormatPreservingProperties toProperties(String s,
-        FormatPreservingProperties p) throws IOException {
-        Properties vanilla = new Properties();
-        vanilla.load(new StringBufferInputStream(s));
-
-        p.load(new StringBufferInputStream(s));
-        assertRoundTrip(s, p);
-
-        assertPropertiesSame(vanilla, p);
-
-        return p;
-    }
-
-    private void assertRoundTrip(String s, Properties p) throws IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        p.store(out, null);
-        assertEquals(s, out.toString());
-
-        // also check serializable
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        new ObjectOutputStream(bout).writeObject(p);
-
-        try {
-            FormatPreservingProperties deserialized =
-                (FormatPreservingProperties) new ObjectInputStream
-                    (new ByteArrayInputStream(bout.toByteArray())).
-                    readObject();
-            assertEquals(p, deserialized);
-
-            out = new ByteArrayOutputStream();
-            deserialized.store(out, null);
-            assertEquals(s, out.toString());
-        } catch (ClassNotFoundException cnfe) {
-            fail(cnfe + "");
-        }
-    }
-
-    public static void assertEquals(String expected, String actual) {
-        if (expected == actual)
-            return;
-
-        if (expected == null || !expected.equals(actual))
-            fail("Expected <" + expected + "> but was <" + actual + ">");
-    }
-
-    private void assertPropertiesSame(Properties vanilla, Properties p) {
-        assertEquals(vanilla, p);
-    }
-
-    protected void assertProperties(String[][] strings, Properties p) {
-        for (int i = 0; i < strings.length; i++)
-            assertEquals(strings[i][1], p.get(strings[i][0]));
-
-        assertEquals(strings.length, p.size());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.lib.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.StringBufferInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+import org.apache.openjpa.lib.util.FormatPreservingProperties.DuplicateKeyException;
+
+// things to test:
+// - delimiters in keys
+// - escape chars, including \:, \= in files(as generated by Properties)
+// - unicode
+// - non-String keys / vals
+// - list() method behavior
+
+public class TestPropertiesParser extends TestCase {
+
+    private static final String LS = System.getProperty( "line.separator" );
+
+    public void testSimpleProperties() throws IOException {
+        StringBuffer buf = new StringBuffer();
+        buf.append("key: value" + LS);
+        buf.append("key2: value2"); // no EOL -- this is intentional
+        Properties p = toProperties(buf.toString());
+        assertProperties(new String[][]{
+            { "key", "value" }, { "key2", "value2" } }, p);
+    }
+
+    public void testComments() throws IOException {
+        StringBuffer buf = new StringBuffer();
+        buf.append("# this is a comment" + LS);
+        buf.append(" # another one, with leading whitespace	" + LS);
+        buf.append(" 	# 	and more with interesting whitespace	" + LS);
+        buf.append("! and with a ! delimiter" + LS);
+        buf.append("! and with escape \t chars" + LS);
+        buf.append("#and a comment with no whitespace" + LS);
+        Properties p = toProperties(buf.toString());
+        assertEquals(0, p.size());
+    }
+
+    public void testMixedContent() throws IOException {
+        StringBuffer buf = new StringBuffer();
+        buf.append("# this is a comment" + LS);
+        buf.append(" # another one, with leading whitespace	" + LS);
+        buf.append("foo: bar#baz" + LS);
+        buf.append("! and with a ! delimiter" + LS);
+        buf.append("! and with escape \t chars" + LS);
+        Properties p = toProperties(buf.toString());
+        assertProperties(new String[][]{ { "foo", "bar#baz" } }, p);
+    }
+
+    public void testMultiLineInput() throws IOException {
+        String s = "foo: bar\\" + LS + "more line goes here";
+        Properties p = toProperties(s);
+        assertProperties(
+            new String[][]{ { "foo", "barmore line goes here" } }, p);
+    }
+
+    public void testEmptyLines() throws IOException {
+        Properties p = toProperties(LS + "foo: bar" + LS + LS + "baz: val");
+        assertProperties(new String[][]{ { "foo", "bar" }, { "baz", "val" } },
+            p);
+    }
+
+    public void testAddProperties() throws IOException {
+        // intentionally left out the trailing end line
+        String s = "foo: bar" + LS + "baz: val";
+        Properties p = toProperties(s);
+        assertProperties(new String[][]{ { "foo", "bar" }, { "baz", "val" } },
+            p);
+
+        p.put("new-key", "val1");
+        p.put("new-key-2", "val2");
+        p.put("another-new-key", "val3");
+        assertRoundTrip(s + LS + "new-key: val1" + LS + "new-key-2: val2" + LS +
+            "another-new-key: val3" + LS, p);
+    }
+
+    public void testAddAndMutateProperties() throws IOException {
+        // intentionally left out the trailing end line
+        Properties p = toProperties("foo: bar" + LS + "baz: val");
+        assertProperties(new String[][]{ { "foo", "bar" }, { "baz", "val" } },
+            p);
+
+        p.put("new-key", "new value");
+        p.put("foo", "barbar");
+        assertRoundTrip("foo: barbar" + LS + "baz: val" + LS 
+            + "new-key: new value" + LS, p);
+    }
+
+    public void testEscapedEquals() throws IOException {
+        Properties p = toProperties("foo=bar\\=WARN,baz\\=TRACE");
+        assertProperties(new String[][]{ { "foo", "bar=WARN,baz=TRACE" } }, p);
+    }
+
+    public void testLineTypes() throws IOException {
+        StringBuffer buf = new StringBuffer();
+        buf.append("   !comment" + LS + " \t  " + LS + "name = no" + LS + "    "
+            + "#morec\tomm\\" + LS + "ents" + LS + LS + "  dog=no\\cat   " + LS 
+            + "burps    :" + LS + "test=" + LS + "date today" + LS + LS + LS 
+            + "long\\" + LS + "   value=tryin \\" + LS + " "
+            + "gto" + LS + "4:vier" + LS + "vier     :4");
+        Properties p = toProperties(buf.toString());
+        assertProperties(new String[][]{
+            { "name", "no" }, { "ents", "" }, { "dog", "nocat   " },
+            { "burps", "" }, { "test", "" }, { "date", "today" },
+            { "longvalue", "tryin gto" }, { "4", "vier" }, { "vier", "4" },
+        }, p);
+    }
+
+    public void testSpecialChars() throws Throwable {
+        testSpecialChars(false, true);
+        testSpecialChars(true, true);
+        testSpecialChars(false, false);
+        testSpecialChars(true, false);
+    }
+
+    /**
+     * Test that special characters work.
+     *
+     * @param formattingProps if true, test against the
+     * FormatPreservingProperties, otherwise test
+     * against a normal Properties instance(for validation of the test case).
+     * @param value whether to test the key or the value
+     */
+    public void testSpecialChars(boolean formattingProps, boolean value)
+        throws Throwable {
+        List valueList = new ArrayList(Arrays.asList(new String[]{
+            "xxyy", "xx\\yy", "xx" + LS + "yy", "xx\\nyy", "xx\tyy", "xx\\tyy",
+            "xx\ryy", "xx\\ryy", "xx\fyy", "xx\\fyy", "xx\r" + LS + "\\\t\r\t" 
+            + LS + "yy",
+            "xx\\r" + LS + "\\\t\\r\t\\nyy",
+            "xx\r" + LS + "\\\\\\\\\\\\\\\\\\\\\\\\\\\t\r\t" + LS + "yy",
+            "C:\\Program Files\\Some Application\\OpenJPA\\My File.dat", }));
+
+        // also store every individual character
+        for (char c = 'a'; c < 'Z'; c++) {
+            valueList.add(new String(new char[]{ c }));
+            valueList.add(new String(new char[]{ c, '\\', c }));
+            valueList.add(new String(new char[]{ '\\', c }));
+        }
+
+        String[] values = (String[]) valueList.toArray(new String[0]);
+
+        final String dummy = "XXX";
+
+        for (int i = 0; i < values.length; i++) {
+            // test special characters in either keys or values
+            String val = value ? values[i] : dummy;
+            String key = value ? dummy : values[i];
+
+            Properties p = formattingProps ?
+                new FormatPreservingProperties() : new Properties();
+            if (p instanceof FormatPreservingProperties) {
+                // set these properties so we behave the same way as
+                // java.util.Properties
+                ((FormatPreservingProperties) p).setDefaultEntryDelimiter('=');
+                ((FormatPreservingProperties) p).
+                    setAddWhitespaceAfterDelimiter(false);
+            }
+
+            p.setProperty(key, val);
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            p.store(out, null);
+
+            Properties copy = new Properties();
+            copy.setProperty(key, val);
+            ByteArrayOutputStream copyOut = new ByteArrayOutputStream();
+            copy.store(copyOut, null);
+
+            p = formattingProps ?
+                new FormatPreservingProperties() : new Properties();
+
+            InputStream in = new BufferedInputStream
+                (new ByteArrayInputStream(out.toByteArray()));
+
+            try {
+                // make sure that the 2 properties serialized are the same
+                String copyOutString = stripComments(copyOut.toByteArray());
+                String outString = stripComments(out.toByteArray());
+                assertEquals(copyOutString, outString);
+
+                p.load(in);
+
+                assertNotNull("Property \"" + key + "\" was null",
+                    p.getProperty(key));
+                assertEquals(val.trim(), p.getProperty(key).trim());
+            } catch (Throwable ioe) {
+                if (!formattingProps)
+                    throw ioe;
+
+                // bug(1211, ioe,
+                // "Cannot store backslash in FormatPreservingProperties");
+                throw ioe;
+            }
+        }
+    }
+
+    static Character randomChar() {
+        char [] TEST_CHAR_ARRAY = new char []{
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
+            '2', '3', '4', '5', '6', '7', '8', '9' };
+
+        return new Character(TEST_CHAR_ARRAY[
+            (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
+    }
+
+    static String randomString(int len) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
+            buf.append(randomChar());
+        return buf.toString();
+    }
+
+    public void testEquivalentStore() throws IOException {
+        Properties p1 = new Properties();
+        FormatPreservingProperties p2 = new FormatPreservingProperties();
+
+        ((FormatPreservingProperties) p2).setDefaultEntryDelimiter('=');
+        ((FormatPreservingProperties) p2).setAddWhitespaceAfterDelimiter(false);
+
+        String[] values =
+            new String[] { 
+                "x", 
+                "x" + LS + "y", 
+                "x\\ny", 
+                "x\ty", 
+                "x\\ty",
+                "x\fy", 
+                "x\\fy", 
+                "x\ry", 
+                "x\\ry", 
+                "C:\\Foo Bar\\Baz",
+                randomString(5).replace('a', '\\'),
+                randomString(500).replace('a', '\\'),
+                randomString(5000).replace('a', '\\'), 
+                };
+
+        for (int i = 0; i < values.length; i++) {
+            p1.clear();
+            p2.clear();
+
+            p1.setProperty("xxx", values[i]);
+            p2.setProperty("xxx", values[i]);
+
+            ByteArrayOutputStream out1 = new ByteArrayOutputStream();
+            ByteArrayOutputStream out2 = new ByteArrayOutputStream();
+
+            p1.store(out1, null);
+            p2.store(out2, null);
+
+            String s1 = new String(out1.toByteArray());
+            String s2 = new String(out2.toByteArray());
+
+            assertTrue("Expected <" + s1 + "> but was <" + s2 + ">",
+                s1.indexOf(s2) != -1);
+        }
+    }
+
+    static String stripComments(byte[] bytes) throws IOException {
+        BufferedReader reader = new BufferedReader(new InputStreamReader
+            (new ByteArrayInputStream(bytes)));
+        StringBuffer sbuf = new StringBuffer();
+        String line;
+        while ((line = reader.readLine()) != null) {
+            // skip comments
+            if (line.trim().startsWith("#"))
+                continue;
+
+            sbuf.append(line);
+            sbuf.append(LS);
+        }
+
+        return sbuf.toString();
+    }
+
+    public void testDuplicateProperties() throws IOException {
+        FormatPreservingProperties p = new FormatPreservingProperties();
+        try {
+            toProperties("foo=bar" + LS + "foo=baz", p);
+            fail("expected duplicate keys to cause exception");
+        } catch (DuplicateKeyException e) {
+            // expected
+        }
+
+        // now test the expected behavior when duplicates are allowed.
+        p = new FormatPreservingProperties();
+        p.setAllowDuplicates(true);
+        toProperties("foo=bar" + LS + "foo=baz", p);
+        assertProperties(new String[][]{ { "foo", "baz" } }, p);
+    }
+
+    public void testMultipleLoads() throws IOException {
+        String props = "foo=bar" + LS + "baz=quux";
+        String props2 = "a=b" + LS + "c=d";
+        Properties vanilla = new Properties();
+        vanilla.load(new BufferedInputStream
+            (new StringBufferInputStream(props)));
+        vanilla.load(new BufferedInputStream
+            (new StringBufferInputStream(props2)));
+
+        Properties p = new FormatPreservingProperties();
+        p.load(new BufferedInputStream(new StringBufferInputStream(props)));
+        p.load(new BufferedInputStream(new StringBufferInputStream(props2)));
+        assertPropertiesSame(vanilla, p);
+    }
+
+    protected FormatPreservingProperties toProperties(String s)
+        throws IOException {
+        return toProperties(s, new FormatPreservingProperties());
+    }
+
+    protected FormatPreservingProperties toProperties(String s,
+        FormatPreservingProperties p) throws IOException {
+        Properties vanilla = new Properties();
+        vanilla.load(new StringBufferInputStream(s));
+
+        p.load(new StringBufferInputStream(s));
+        assertRoundTrip(s, p);
+
+        assertPropertiesSame(vanilla, p);
+
+        return p;
+    }
+
+    private void assertRoundTrip(String s, Properties p) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        p.store(out, null);
+        assertEquals(s, out.toString());
+
+        // also check serializable
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        new ObjectOutputStream(bout).writeObject(p);
+
+        try {
+            FormatPreservingProperties deserialized =
+                (FormatPreservingProperties) new ObjectInputStream
+                    (new ByteArrayInputStream(bout.toByteArray())).
+                    readObject();
+            assertEquals(p, deserialized);
+
+            out = new ByteArrayOutputStream();
+            deserialized.store(out, null);
+            assertEquals(s, out.toString());
+        } catch (ClassNotFoundException cnfe) {
+            fail(cnfe + "");
+        }
+    }
+
+    public static void assertEquals(String expected, String actual) {
+        if (expected == actual)
+            return;
+
+        if (expected == null || !expected.equals(actual))
+            fail("Expected <" + expected + "> but was <" + actual + ">");
+    }
+
+    private void assertPropertiesSame(Properties vanilla, Properties p) {
+        assertEquals(vanilla, p);
+    }
+
+    protected void assertProperties(String[][] strings, Properties p) {
+        for (int i = 0; i < strings.length; i++)
+            assertEquals(strings[i][1], p.get(strings[i][0]));
+
+        assertEquals(strings.length, p.size());
+    }
+}
diff --git a/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java b/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java
index 74857be..a396201 100644
--- a/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java
+++ b/openjpa-lib/src/test/java/org/apache/openjpa/lib/util/concurrent/TestNullSafeConcurrentHashMap.java
@@ -1,179 +1,179 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.util.concurrent;
-
-import java.io.IOException;
-import java.util.Set;
-import java.util.Collection;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Map.Entry;
-
-import org.apache.openjpa.lib.test.AbstractTestCase;
-
-public class TestNullSafeConcurrentHashMap extends AbstractTestCase {
-
-    private NullSafeConcurrentHashMap newMap() {
-        return new NullSafeConcurrentHashMap();
-    }
-
-    public void testRemoveRandomIsNotTotallyDeterministic() {
-        removeHelper(false);
-    }
-
-    public void testRandomIteratorIsNotTotallyDeterministic() {
-        removeHelper(true);
-    }
-
-    private void removeHelper(boolean iter) {
-        Map<String,Integer> removedCounts = new HashMap();
-        for (int i = 0; i < 1000; i++) {
-            NullSafeConcurrentHashMap m = new NullSafeConcurrentHashMap();
-            m.put("a", "A");
-            m.put("b", "B");
-            m.put("c", "C");
-            m.put("d", "D");
-            m.put("e", "E");
-            m.put("f", "F");
-            m.put("g", "G");
-
-            String removed;
-            if (iter) {
-                removed = (String) m.removeRandom().getKey();
-            } else {
-                removed = (String) ((Entry) m.randomEntryIterator().next())
-                    .getKey();
-                m.remove(removed);
-            }
-
-            Integer count = removedCounts.get(removed);
-            if (count == null)
-                removedCounts.put(removed, 1);
-            else
-                removedCounts.put(removed, count.intValue() + 1);
-        }
-
-        // assume that over 1000 runs, every element should be removed at
-        // least once, and no element should be removed more than 30% of
-        // the time
-        assertEquals(7, removedCounts.size());
-        for (Entry<String,Integer> entry : removedCounts.entrySet()) {
-            if (entry.getValue() == 0)
-                fail("element " + entry.getKey() + " was never removed");
-            if (entry.getValue() > 500)
-                fail("element " + entry.getKey() + " was removed "
-                    + entry.getValue() + " times; this is greater than the "
-                    + "threshold of 500.");
-        }
-    }
-
-    public void testNullKeys() throws ClassNotFoundException, IOException {
-        helper(null, "value 0", "value 1", "value 2");
-    }
-
-    private void helper(Object key, Object value0,
-        Object value1, Object value2)
-        throws IOException, ClassNotFoundException {
-
-        NullSafeConcurrentHashMap m = newMap();
-
-        // initial put
-        m.put(key, value0);
-
-        // get etc.
-        assertEquals(value0, m.get(key));
-        assertTrue(m.containsKey(key));
-        assertTrue(m.containsValue(value0));
-
-        // keySet
-        Set keys = m.keySet();
-        assertTrue(keys.contains(key));
-        assertEquals(1, keys.size());
-        assertEquals(key, keys.iterator().next());
-
-        // entrySet
-        Set entries = m.entrySet();
-        Entry e = (Entry) entries.iterator().next();
-        assertEquals(key, e.getKey());
-        assertEquals(value0, e.getValue());
-
-        // values
-        Collection values = m.values();
-        assertEquals(1, values.size());
-        assertEquals(value0, values.iterator().next());
-
-        // serializability
-        assertEquals(m, roundtrip(m, true));
-
-        // put
-        assertEquals(value0, m.put(key, value1));
-
-        // remove
-        assertEquals(value1, m.put(key, value1));
-        assertEquals(value1, m.remove(key));
-        m.put(key, value1);
-
-        // ConcurrentMap stuff
-        assertFalse(m.remove("invalid key", value0));
-        assertTrue(m.remove(key, value1));
-        assertNull(m.putIfAbsent(key, value0)); // null == prev unset
-
-        // value0 might be null; can't disambiguate from above in OpenJPA
-        // interpretation
-        assertEquals(value0, m.putIfAbsent(key, "invalid value"));
-
-        // replace
-        assertEquals(value0, m.replace(key, value1));
-        assertTrue(m.replace(key, value1, value2));
-
-        // putAll. Note that ConcurrentHashMap happens to delegate to put()
-        // from within putAll() calls. This test should help ensure that we
-        // find out if that changes.
-        m = newMap();
-        Map putAllArg = new HashMap();
-        putAllArg.put(key, value0);
-        putAllArg.put("another key", value1);
-        m.putAll(putAllArg);
-        assertEquals(value0, m.get(key));
-        assertEquals(value1, m.get("another key"));
-    }
-
-    public void testNullValues() throws ClassNotFoundException, IOException {
-        nullValsHelper("foo");
-    }
-
-    private void nullValsHelper(Object key)
-        throws IOException, ClassNotFoundException {
-        helper(key, null, null, null);
-        helper(key, "bar", "baz", "quux");
-
-        helper(key, "bar", "baz", null);
-        helper(key, null, "baz", "quux");
-        helper(key, "bar", null, "quux");
-
-        helper(key, "bar", null, null);
-        helper(key, null, "baz", null);
-        helper(key, null, null, "quux");
-    }
-
-    public void testNullKeysAndValues()
-        throws ClassNotFoundException, IOException {
-        nullValsHelper(null);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.util.concurrent;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.Collection;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+import org.apache.openjpa.lib.test.AbstractTestCase;
+
+public class TestNullSafeConcurrentHashMap extends AbstractTestCase {
+
+    private NullSafeConcurrentHashMap newMap() {
+        return new NullSafeConcurrentHashMap();
+    }
+
+    public void testRemoveRandomIsNotTotallyDeterministic() {
+        removeHelper(false);
+    }
+
+    public void testRandomIteratorIsNotTotallyDeterministic() {
+        removeHelper(true);
+    }
+
+    private void removeHelper(boolean iter) {
+        Map<String,Integer> removedCounts = new HashMap();
+        for (int i = 0; i < 1000; i++) {
+            NullSafeConcurrentHashMap m = new NullSafeConcurrentHashMap();
+            m.put("a", "A");
+            m.put("b", "B");
+            m.put("c", "C");
+            m.put("d", "D");
+            m.put("e", "E");
+            m.put("f", "F");
+            m.put("g", "G");
+
+            String removed;
+            if (iter) {
+                removed = (String) m.removeRandom().getKey();
+            } else {
+                removed = (String) ((Entry) m.randomEntryIterator().next())
+                    .getKey();
+                m.remove(removed);
+            }
+
+            Integer count = removedCounts.get(removed);
+            if (count == null)
+                removedCounts.put(removed, 1);
+            else
+                removedCounts.put(removed, count.intValue() + 1);
+        }
+
+        // assume that over 1000 runs, every element should be removed at
+        // least once, and no element should be removed more than 30% of
+        // the time
+        assertEquals(7, removedCounts.size());
+        for (Entry<String,Integer> entry : removedCounts.entrySet()) {
+            if (entry.getValue() == 0)
+                fail("element " + entry.getKey() + " was never removed");
+            if (entry.getValue() > 500)
+                fail("element " + entry.getKey() + " was removed "
+                    + entry.getValue() + " times; this is greater than the "
+                    + "threshold of 500.");
+        }
+    }
+
+    public void testNullKeys() throws ClassNotFoundException, IOException {
+        helper(null, "value 0", "value 1", "value 2");
+    }
+
+    private void helper(Object key, Object value0,
+        Object value1, Object value2)
+        throws IOException, ClassNotFoundException {
+
+        NullSafeConcurrentHashMap m = newMap();
+
+        // initial put
+        m.put(key, value0);
+
+        // get etc.
+        assertEquals(value0, m.get(key));
+        assertTrue(m.containsKey(key));
+        assertTrue(m.containsValue(value0));
+
+        // keySet
+        Set keys = m.keySet();
+        assertTrue(keys.contains(key));
+        assertEquals(1, keys.size());
+        assertEquals(key, keys.iterator().next());
+
+        // entrySet
+        Set entries = m.entrySet();
+        Entry e = (Entry) entries.iterator().next();
+        assertEquals(key, e.getKey());
+        assertEquals(value0, e.getValue());
+
+        // values
+        Collection values = m.values();
+        assertEquals(1, values.size());
+        assertEquals(value0, values.iterator().next());
+
+        // serializability
+        assertEquals(m, roundtrip(m, true));
+
+        // put
+        assertEquals(value0, m.put(key, value1));
+
+        // remove
+        assertEquals(value1, m.put(key, value1));
+        assertEquals(value1, m.remove(key));
+        m.put(key, value1);
+
+        // ConcurrentMap stuff
+        assertFalse(m.remove("invalid key", value0));
+        assertTrue(m.remove(key, value1));
+        assertNull(m.putIfAbsent(key, value0)); // null == prev unset
+
+        // value0 might be null; can't disambiguate from above in OpenJPA
+        // interpretation
+        assertEquals(value0, m.putIfAbsent(key, "invalid value"));
+
+        // replace
+        assertEquals(value0, m.replace(key, value1));
+        assertTrue(m.replace(key, value1, value2));
+
+        // putAll. Note that ConcurrentHashMap happens to delegate to put()
+        // from within putAll() calls. This test should help ensure that we
+        // find out if that changes.
+        m = newMap();
+        Map putAllArg = new HashMap();
+        putAllArg.put(key, value0);
+        putAllArg.put("another key", value1);
+        m.putAll(putAllArg);
+        assertEquals(value0, m.get(key));
+        assertEquals(value1, m.get("another key"));
+    }
+
+    public void testNullValues() throws ClassNotFoundException, IOException {
+        nullValsHelper("foo");
+    }
+
+    private void nullValsHelper(Object key)
+        throws IOException, ClassNotFoundException {
+        helper(key, null, null, null);
+        helper(key, "bar", "baz", "quux");
+
+        helper(key, "bar", "baz", null);
+        helper(key, null, "baz", "quux");
+        helper(key, "bar", null, "quux");
+
+        helper(key, "bar", null, null);
+        helper(key, null, "baz", null);
+        helper(key, null, null, "quux");
+    }
+
+    public void testNullKeysAndValues()
+        throws ClassNotFoundException, IOException {
+        nullValsHelper(null);
+    }
+}
diff --git a/openjpa-persistence-jdbc/pom.xml b/openjpa-persistence-jdbc/pom.xml
index 1d34e0b..2498608 100644
--- a/openjpa-persistence-jdbc/pom.xml
+++ b/openjpa-persistence-jdbc/pom.xml
@@ -31,7 +31,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <properties>
         <openjpa.loglevel>INFO</openjpa.loglevel>
@@ -44,6 +44,8 @@
         <dbcp.minIdle>2</dbcp.minIdle>
         <dbcp.maxWait>10000</dbcp.maxWait>
         <dbcp.args>MaxActive=${dbcp.maxActive},MaxIdle=${dbcp.maxIdle},MinIdle=${dbcp.minIdle},MaxWait=${dbcp.maxWait}</dbcp.args>
+        <derby.locks.waitTimeout>6</derby.locks.waitTimeout>        
+        <derby.locks.deadlockTimeout>5</derby.locks.deadlockTimeout>
     </properties>
     <profiles>
 
@@ -97,7 +99,7 @@
                 <dependency>
                     <groupId>mysql</groupId>
                     <artifactId>mysql-connector-java</artifactId>
-                    <version>5.1.5</version>
+                    <version>5.1.6</version>
                 </dependency>
             </dependencies>
             <properties>
@@ -449,7 +451,6 @@
                         <exclude>org/apache/openjpa/persistence/xml/TestPersistenceUnitWithoutXSD.java</exclude>
 
                         <!-- exclude new tests that aren't passing yet -->
-                        <exclude>org/apache/openjpa/persistence/jpql/clauses/TestEJBQueryInterface.java</exclude>
                         <exclude>org/apache/openjpa/persistence/kernel/TestInitialValueFetching.java</exclude>
                         <exclude>org/apache/openjpa/persistence/kernel/TestOpenResultsCommit.java</exclude>
                         <exclude>org/apache/openjpa/persistence/query/TestQuotedNumbersInFilters2.java</exclude>
@@ -616,6 +617,14 @@
                             <value>target/derby.log</value>
                         </property>
                         <property>
+                            <name>derby.locks.deadlockTimeout</name>
+                            <value>${derby.locks.deadlockTimeout}</value>
+                        </property>
+                        <property>
+                            <name>derby.locks.waitTimeout</name>
+                            <value>${derby.locks.waitTimeout}</value>
+                        </property>
+                        <property>
                             <name>openjpa.ConnectionProperties</name>
                             <value>DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}</value>
                         </property>
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java
index 30e9b5e..4f40d52 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Array, collection, or map element column.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface ElementColumn {
-
-    String name() default "";
-
-    boolean unique() default false;
-
-    boolean nullable() default true;
-
-    boolean insertable() default true;
-
-    boolean updatable() default true;
-
-    String columnDefinition() default "";
-
-    int length() default 255;
-
-    int precision() default 0; // decimal precision
-
-    int scale() default 0; // decimal scale
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Array, collection, or map element column.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementColumn {
+
+    String name() default "";
+
+    boolean unique() default false;
+
+    boolean nullable() default true;
+
+    boolean insertable() default true;
+
+    boolean updatable() default true;
+
+    String columnDefinition() default "";
+
+    int length() default 255;
+
+    int precision() default 0; // decimal precision
+
+    int scale() default 0; // decimal scale
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java
index 6a17e87..af682fb 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Allows the specification of multiple element columns for complex
- * mappings.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface ElementColumns {
-
-    ElementColumn[] value() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows the specification of multiple element columns for complex
+ * mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementColumns {
+
+    ElementColumn[] value() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java
index e2673df..a4c2062 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Embedded mapping information for an array, collection, or map
- * element.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface ElementEmbeddedMapping {
-
-    public static final String TRUE = "true";
-    public static final String FALSE = "false";
-
-    String nullIndicatorColumnName() default "";
-
-    String nullIndicatorAttributeName() default "";
-
-    XMappingOverride[] overrides() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Embedded mapping information for an array, collection, or map
+ * element.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementEmbeddedMapping {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    String nullIndicatorColumnName() default "";
+
+    String nullIndicatorAttributeName() default "";
+
+    XMappingOverride[] overrides() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java
index 04509ee..9dfb75c 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Array, collection, or map element mapping strategy.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface ElementStrategy {
-
-    String value() default "";
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Array, collection, or map element mapping strategy.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementStrategy {
+
+    String value() default "";
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java
index 1337aa1..8dbf223 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Marker interface specifying to use the expected class of the map key
- * relation as criteria in the join.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyClassCriteria {
-
-    boolean value() default true;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Marker interface specifying to use the expected class of the map key
+ * relation as criteria in the join.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyClassCriteria {
+
+    boolean value() default true;
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java
index 401a1f8..7046272 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Map key column.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyColumn {
-
-    String name() default "";
-
-    boolean unique() default false;
-
-    boolean nullable() default true;
-
-    boolean insertable() default true;
-
-    boolean updatable() default true;
-
-    String columnDefinition() default "";
-
-    int length() default 255;
-
-    int precision() default 0; // decimal precision
-
-    int scale() default 0; // decimal scale
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Map key column.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyColumn {
+
+    String name() default "";
+
+    boolean unique() default false;
+
+    boolean nullable() default true;
+
+    boolean insertable() default true;
+
+    boolean updatable() default true;
+
+    String columnDefinition() default "";
+
+    int length() default 255;
+
+    int precision() default 0; // decimal precision
+
+    int scale() default 0; // decimal scale
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java
index a5ee232..0505c59 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Allows the specification of multiple map key columns for complex
- * mappings.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyColumns {
-
-    KeyColumn[] value() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows the specification of multiple map key columns for complex
+ * mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyColumns {
+
+    KeyColumn[] value() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java
index 1061737..89472aa 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Embedded mapping information for a map key.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyEmbeddedMapping {
-
-    public static final String TRUE = "true";
-    public static final String FALSE = "false";
-
-    String nullIndicatorColumnName() default "";
-
-    String nullIndicatorAttributeName() default "";
-
-    XMappingOverride[] overrides() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Embedded mapping information for a map key.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyEmbeddedMapping {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    String nullIndicatorColumnName() default "";
+
+    String nullIndicatorAttributeName() default "";
+
+    XMappingOverride[] overrides() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java
index 3bd708e..dfc13a5 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Foreign key on map key columns.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyForeignKey {
-
-    String name() default "";
-
-    boolean enabled() default true;
-
-    boolean deferred() default false;
-
-    ForeignKeyAction deleteAction() default ForeignKeyAction.RESTRICT;
-
-    ForeignKeyAction updateAction() default ForeignKeyAction.RESTRICT;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Foreign key on map key columns.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyForeignKey {
+
+    String name() default "";
+
+    boolean enabled() default true;
+
+    boolean deferred() default false;
+
+    ForeignKeyAction deleteAction() default ForeignKeyAction.RESTRICT;
+
+    ForeignKeyAction updateAction() default ForeignKeyAction.RESTRICT;
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java
index d1b84d1..20d1709 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Index on map key columns.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyIndex {
-
-    String name() default "";
-
-    boolean enabled() default true;
-
-    boolean unique() default false;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Index on map key columns.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyIndex {
+
+    String name() default "";
+
+    boolean enabled() default true;
+
+    boolean unique() default false;
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java
index 3a28368..391b0af 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Map key join column.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyJoinColumn {
-
-    String name() default "";
-
-    String referencedColumnName() default "";
-
-    String referencedAttributeName() default "";
-
-    boolean unique() default false;
-
-    boolean nullable() default true;
-
-    boolean insertable() default true;
-
-    boolean updatable() default true;
-
-    String columnDefinition() default "";
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Map key join column.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyJoinColumn {
+
+    String name() default "";
+
+    String referencedColumnName() default "";
+
+    String referencedAttributeName() default "";
+
+    boolean unique() default false;
+
+    boolean nullable() default true;
+
+    boolean insertable() default true;
+
+    boolean updatable() default true;
+
+    String columnDefinition() default "";
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java
index c747074..8ff0946 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Allows the specification of multiple map key columns for compound
- * joins.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyJoinColumns {
-
-    KeyJoinColumn[] value() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows the specification of multiple map key columns for compound
+ * joins.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyJoinColumns {
+
+    KeyJoinColumn[] value() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java
index a1a1d00..05d6fcd 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Indicates that the annotated map's keys are not entirely polymorphic.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyNonpolymorphic {
-
-    NonpolymorphicType value() default NonpolymorphicType.EXACT;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Indicates that the annotated map's keys are not entirely polymorphic.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyNonpolymorphic {
+
+    NonpolymorphicType value() default NonpolymorphicType.EXACT;
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java
index ea17513..629247b 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Map key mapping strategy.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface KeyStrategy {
-
-    String value() default "";
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Map key mapping strategy.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyStrategy {
+
+    String value() default "";
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java
index 5a2907a..b7401d4 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Embedded mapping information.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ METHOD, FIELD })
-@Retention(RUNTIME)
-public @interface XEmbeddedMapping {
-
-    public static final String TRUE = "true";
-    public static final String FALSE = "false";
-
-    String nullIndicatorColumnName() default "";
-
-    String nullIndicatorAttributeName() default "";
-
-    XMappingOverride[] overrides() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Embedded mapping information.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface XEmbeddedMapping {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    String nullIndicatorColumnName() default "";
+
+    String nullIndicatorAttributeName() default "";
+
+    XMappingOverride[] overrides() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java
index f20bf6e..b083800 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.TYPE;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-import javax.persistence.Column;
-
-/**
- * <p>Allows override of complex embedded or superclass mappings.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ TYPE })
-@Retention(RUNTIME)
-public @interface XMappingOverride {
-
-    String name() default "";
-
-    Column[] columns() default {};
-
-    XJoinColumn[] joinColumns() default {};
-
-    ElementColumn[] elementColumns() default {};
-
-    ElementJoinColumn[] elementJoinColumns() default {};
-
-    KeyColumn[] keyColumns() default {};
-
-    KeyJoinColumn[] keyJoinColumns() default {};
-
-    ContainerTable containerTable() default @ContainerTable(specified = false);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.persistence.Column;
+
+/**
+ * <p>Allows override of complex embedded or superclass mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+public @interface XMappingOverride {
+
+    String name() default "";
+
+    Column[] columns() default {};
+
+    XJoinColumn[] joinColumns() default {};
+
+    ElementColumn[] elementColumns() default {};
+
+    ElementJoinColumn[] elementJoinColumns() default {};
+
+    KeyColumn[] keyColumns() default {};
+
+    KeyJoinColumn[] keyJoinColumns() default {};
+
+    ContainerTable containerTable() default @ContainerTable(specified = false);
+}
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java
index 6f4e9e1..a439e55 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import static java.lang.annotation.ElementType.TYPE;
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import java.lang.annotation.Target;
-
-/**
- * <p>Allows override of complex embedded or superclass mappings.</p>
- *
- * @author Abe White
- * @since 0.4.0, 1.1.0
- */
-@Target({ TYPE })
-@Retention(RUNTIME)
-public @interface XMappingOverrides {
-
-    XMappingOverride[] value() default {};
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows override of complex embedded or superclass mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+public @interface XMappingOverrides {
+
+    XMappingOverride[] value() default {};
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestBadJdbcUrl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestBadJdbcUrl.java
index b40f614..8a3b4a0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestBadJdbcUrl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestBadJdbcUrl.java
@@ -1,198 +1,198 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.conf;
-
-import java.util.Properties;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-import javax.persistence.PersistenceException;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Verifies appropriate exception is thrown when an incorrect protocol or
- * sub-protocol is specified in the JDBC URL. Per the JDBC specification, the
- * Driver should return a null connection upon getConnection() when a bad driver
- * is specified on the URL. OpenJPA must be able to handle this condition and
- * return an appropriate message.
- * 
- * OpenJPA JIRA: {@link http://issues.apache.org/jira/browse/OPENJPA-656}
- * 
- * @author Jeremy Bauer
- * @author Pinaki Poddar
- * 
- */
-public class TestBadJdbcUrl extends TestCase {
-	public static final String GOOD_URL = "jdbc:derby:target/database/openjpa-derby-database;create=true";
-	public static final String GOOD_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
-	public static final String GOOD_DATASOURCE = "org.apache.commons.dbcp.BasicDataSource";
-
-	public static final String BAD_DRIVER = "bad.driver";
-	public static final String BAD_URL_PROTOCOL = "bad.url.protocol";
-	public static final String BAD_URL_SUBPROTOCOL = "bad.url.sub.protocol";
-	public static final String BAD_CONN_PROPS = "connectionUrl=bad,connectionDriver=bad";
-
-	/*
-	 * Test specifying URL with bad protocol but a valid Driver.
-	 */
-	public void testBadUrlProtocolValueWithValidDriverClass() {
-		Properties p = new Properties();
-		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
-		p.put("openjpa.ConnectionURL", BAD_URL_PROTOCOL);
-		verifyConnectException(p, PersistenceException.class,
-				UserException.class, GOOD_DRIVER, BAD_URL_PROTOCOL);
-	}
-
-	/*
-	 * Test specifying URL with bad protocol but a valid DataSource.
-	 */
-	public void testBadUrlProtocolValueWithValidDataSource() {
-		Properties p = new Properties();
-		p.put("openjpa.ConnectionDriverName", GOOD_DATASOURCE);
-		p.put("openjpa.ConnectionURL", BAD_URL_PROTOCOL);
-		p.put("openjpa.ConnectionProperties", BAD_CONN_PROPS);
-		verifyConnectException(p, PersistenceException.class,
-				null, (String[])null);
-	}
-
-	/*
-	 * Test specifying URL with bad sub-protocol but a valid Driver.
-	 */
-	public void testBadUrlSubprotocolValueWithValidDriverClass() {
-		Properties p = new Properties();
-		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
-		p.put("openjpa.ConnectionURL", BAD_URL_SUBPROTOCOL);
-		verifyConnectException(p, PersistenceException.class,
-				UserException.class, GOOD_DRIVER, BAD_URL_SUBPROTOCOL);
-	}
-
-	/*
-	 * Test specifying URL with bad sub-protocol but a valid Driver.
-	 */
-	public void testBadUrlSubprotocolValueWithValidDataSource() {
-		Properties p = new Properties();
-		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
-		p.put("openjpa.ConnectionURL", BAD_URL_SUBPROTOCOL);
-		verifyConnectException(p, PersistenceException.class,
-				UserException.class, GOOD_DRIVER, BAD_URL_SUBPROTOCOL);
-	}
-
-	/*
-	 * Test specifying Valid URL with an invalid Driver.
-	 */
-	public void testValidUrlWithInvalidDriver() {
-		Properties p = new Properties();
-		p.put("openjpa.ConnectionDriverName", BAD_DRIVER);
-		p.put("openjpa.ConnectionURL", GOOD_URL);
-		verifyConnectException(p, PersistenceException.class,
-				UserException.class, GOOD_URL, BAD_DRIVER);
-	}
-
-	/**
-	 * Attempts to connect with given properties and analyze exception for the
-	 * existence of given target exception and error message strings.
-	 * 
-	 * @param props
-	 *            the properties to initialize the persistence unit
-	 * @param target
-	 *            the type expected exception to be raised.
-	 * @param nested
-	 *            the type expected nested exception. null implies not to look
-	 *            for any.
-	 * @param keys
-	 *            the strings that must occur in the exception message.
-	 */
-	private void verifyConnectException(Properties props, Class targetType,
-			Class nestedType, String... keys) {
-		EntityManagerFactory emf = null;
-		EntityManager em = null;
-		try {
-			emf = Persistence.createEntityManagerFactory("test", props);
-			em = emf.createEntityManager();
-			OpenJPAPersistence.cast(em).getConnection();
-			fail("Should have caught a " + targetType.getName());
-		} catch (Throwable t) {
-			assertException(t, targetType, nestedType);
-			assertMessage(t, keys);
-		} finally {
-			if (em != null)
-				em.close();
-			if (emf != null)
-				emf.close();
-		}
-	}
-
-	/**
-	 * Asserts that the given targetType is assignable from actual. Asserts that
-	 * the nestedType is a nested within the given actual Throwable
-	 * 
-	 * @param actual
-	 * @param targetType
-	 * @param nestedType
-	 */
-	void assertException(final Throwable actual, Class targetType,
-			Class nestedTargetType) {
-		if (targetType == null)
-			return;
-		assertNotNull(actual);
-		Class actualType = actual.getClass();
-		if (!targetType.isAssignableFrom(actualType)) {
-			actual.printStackTrace();
-			fail(targetType.getName() + " is not assignable from "
-					+ actualType.getName());
-		}
-
-		if (nestedTargetType != null) {
-			Throwable nested = actual.getCause();
-			Class nestedType = (nested == null) ? null : nested.getClass();
-			while (nestedType != null) {
-				if (nestedType.isAssignableFrom(nestedTargetType)) {
-					return;
-				} else {
-					Throwable next = nested.getCause();
-					if (next == null || next == nested)
-						break;
-					nestedType = next.getClass();
-					nested     = next;
-				}
-			}
-			actual.printStackTrace();
-			fail("No nested type " + nestedTargetType + " in " + actual);
-		}
-	}
-
-	/**
-	 * Assert that each of given keys are present in the message of the given
-	 * Throwable.
-	 */
-	void assertMessage(Throwable actual, String... keys) {
-		if (actual == null || keys == null)
-			return;
-		String message = actual.getMessage();
-		for (String key : keys) {
-			assertTrue(key + " is not in " + message, message.contains(key));
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.conf;
+
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.PersistenceException;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Verifies appropriate exception is thrown when an incorrect protocol or
+ * sub-protocol is specified in the JDBC URL. Per the JDBC specification, the
+ * Driver should return a null connection upon getConnection() when a bad driver
+ * is specified on the URL. OpenJPA must be able to handle this condition and
+ * return an appropriate message.
+ * 
+ * OpenJPA JIRA: {@link http://issues.apache.org/jira/browse/OPENJPA-656}
+ * 
+ * @author Jeremy Bauer
+ * @author Pinaki Poddar
+ * 
+ */
+public class TestBadJdbcUrl extends TestCase {
+	public static final String GOOD_URL = "jdbc:derby:target/database/openjpa-derby-database;create=true";
+	public static final String GOOD_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
+	public static final String GOOD_DATASOURCE = "org.apache.commons.dbcp.BasicDataSource";
+
+	public static final String BAD_DRIVER = "bad.driver";
+	public static final String BAD_URL_PROTOCOL = "bad.url.protocol";
+	public static final String BAD_URL_SUBPROTOCOL = "bad.url.sub.protocol";
+	public static final String BAD_CONN_PROPS = "connectionUrl=bad,connectionDriver=bad";
+
+	/*
+	 * Test specifying URL with bad protocol but a valid Driver.
+	 */
+	public void testBadUrlProtocolValueWithValidDriverClass() {
+		Properties p = new Properties();
+		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
+		p.put("openjpa.ConnectionURL", BAD_URL_PROTOCOL);
+		verifyConnectException(p, PersistenceException.class,
+				UserException.class, GOOD_DRIVER, BAD_URL_PROTOCOL);
+	}
+
+	/*
+	 * Test specifying URL with bad protocol but a valid DataSource.
+	 */
+	public void testBadUrlProtocolValueWithValidDataSource() {
+		Properties p = new Properties();
+		p.put("openjpa.ConnectionDriverName", GOOD_DATASOURCE);
+		p.put("openjpa.ConnectionURL", BAD_URL_PROTOCOL);
+		p.put("openjpa.ConnectionProperties", BAD_CONN_PROPS);
+		verifyConnectException(p, PersistenceException.class,
+				null, (String[])null);
+	}
+
+	/*
+	 * Test specifying URL with bad sub-protocol but a valid Driver.
+	 */
+	public void testBadUrlSubprotocolValueWithValidDriverClass() {
+		Properties p = new Properties();
+		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
+		p.put("openjpa.ConnectionURL", BAD_URL_SUBPROTOCOL);
+		verifyConnectException(p, PersistenceException.class,
+				UserException.class, GOOD_DRIVER, BAD_URL_SUBPROTOCOL);
+	}
+
+	/*
+	 * Test specifying URL with bad sub-protocol but a valid Driver.
+	 */
+	public void testBadUrlSubprotocolValueWithValidDataSource() {
+		Properties p = new Properties();
+		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
+		p.put("openjpa.ConnectionURL", BAD_URL_SUBPROTOCOL);
+		verifyConnectException(p, PersistenceException.class,
+				UserException.class, GOOD_DRIVER, BAD_URL_SUBPROTOCOL);
+	}
+
+	/*
+	 * Test specifying Valid URL with an invalid Driver.
+	 */
+	public void testValidUrlWithInvalidDriver() {
+		Properties p = new Properties();
+		p.put("openjpa.ConnectionDriverName", BAD_DRIVER);
+		p.put("openjpa.ConnectionURL", GOOD_URL);
+		verifyConnectException(p, PersistenceException.class,
+				UserException.class, GOOD_URL, BAD_DRIVER);
+	}
+
+	/**
+	 * Attempts to connect with given properties and analyze exception for the
+	 * existence of given target exception and error message strings.
+	 * 
+	 * @param props
+	 *            the properties to initialize the persistence unit
+	 * @param target
+	 *            the type expected exception to be raised.
+	 * @param nested
+	 *            the type expected nested exception. null implies not to look
+	 *            for any.
+	 * @param keys
+	 *            the strings that must occur in the exception message.
+	 */
+	private void verifyConnectException(Properties props, Class targetType,
+			Class nestedType, String... keys) {
+		EntityManagerFactory emf = null;
+		EntityManager em = null;
+		try {
+			emf = Persistence.createEntityManagerFactory("test", props);
+			em = emf.createEntityManager();
+			OpenJPAPersistence.cast(em).getConnection();
+			fail("Should have caught a " + targetType.getName());
+		} catch (Throwable t) {
+			assertException(t, targetType, nestedType);
+			assertMessage(t, keys);
+		} finally {
+			if (em != null)
+				em.close();
+			if (emf != null)
+				emf.close();
+		}
+	}
+
+	/**
+	 * Asserts that the given targetType is assignable from actual. Asserts that
+	 * the nestedType is a nested within the given actual Throwable
+	 * 
+	 * @param actual
+	 * @param targetType
+	 * @param nestedType
+	 */
+	void assertException(final Throwable actual, Class targetType,
+			Class nestedTargetType) {
+		if (targetType == null)
+			return;
+		assertNotNull(actual);
+		Class actualType = actual.getClass();
+		if (!targetType.isAssignableFrom(actualType)) {
+			actual.printStackTrace();
+			fail(targetType.getName() + " is not assignable from "
+					+ actualType.getName());
+		}
+
+		if (nestedTargetType != null) {
+			Throwable nested = actual.getCause();
+			Class nestedType = (nested == null) ? null : nested.getClass();
+			while (nestedType != null) {
+				if (nestedType.isAssignableFrom(nestedTargetType)) {
+					return;
+				} else {
+					Throwable next = nested.getCause();
+					if (next == null || next == nested)
+						break;
+					nestedType = next.getClass();
+					nested     = next;
+				}
+			}
+			actual.printStackTrace();
+			fail("No nested type " + nestedTargetType + " in " + actual);
+		}
+	}
+
+	/**
+	 * Assert that each of given keys are present in the message of the given
+	 * Throwable.
+	 */
+	void assertMessage(Throwable actual, String... keys) {
+		if (actual == null || keys == null)
+			return;
+		String message = actual.getMessage();
+		for (String key : keys) {
+			assertTrue(key + " is not in " + message, message.contains(key));
+		}
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshaller.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshaller.java
index d7a8611..7e31542 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshaller.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshaller.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import org.apache.openjpa.conf.CacheMarshaller.ValidationPolicy;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestCacheMarshaller
-    extends SingleEMFTestCase {
-
-    private CacheMarshaller cm;
-
-    public void setUp() {
-        setUp(new Object[] { "openjpa.CacheMarshallers",
-            "default(Id=" + getClass().getName() + ", ValidationPolicy="
-                + OpenJPAVersionAndConfigurationTypeValidationPolicy.class
-                    .getName()
-                + ", InputURL=file:target/" + getClass().getName() + ".ser"
-                + ", OutputFile=target/"
-                + getClass().getName() + ".ser)"
-        });
-        emf.createEntityManager().close();
-        cm = CacheMarshallersValue.getMarshallerById(emf.getConfiguration(),
-            getClass().getName());
-    }
-
-    public void testCacheMarshallerType() {
-        assertEquals(CacheMarshallerImpl.class, cm.getClass());
-    }
-
-    public void testConfiguration() {
-        assertEquals(getClass().getName(), cm.getId());
-    }
-
-    public void testValidation() {
-        ValidationPolicy vp = ((CacheMarshallerImpl) cm).getValidationPolicy();
-        assertEquals(OpenJPAVersionAndConfigurationTypeValidationPolicy.class,
-            vp.getClass());
-        Object[] cached = (Object[]) vp.getCacheableData(this);
-
-        assertEquals(3, cached.length);
-        assertEquals(OpenJPAVersion.VERSION_ID, cached[0]);
-        assertEquals(emf.getConfiguration().getClass().getName(), cached[1]);
-        assertEquals(this, cached[2]);
-
-        assertEquals(this, vp.getValidData(cached));
-    }
-
-    public void testRoundTrip() {
-        Object o = "foo";
-        cm.store(o);
-        assertEquals(o, cm.load());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import org.apache.openjpa.conf.CacheMarshaller.ValidationPolicy;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestCacheMarshaller
+    extends SingleEMFTestCase {
+
+    private CacheMarshaller cm;
+
+    public void setUp() {
+        setUp(new Object[] { "openjpa.CacheMarshallers",
+            "default(Id=" + getClass().getName() + ", ValidationPolicy="
+                + OpenJPAVersionAndConfigurationTypeValidationPolicy.class
+                    .getName()
+                + ", InputURL=file:target/" + getClass().getName() + ".ser"
+                + ", OutputFile=target/"
+                + getClass().getName() + ".ser)"
+        });
+        emf.createEntityManager().close();
+        cm = CacheMarshallersValue.getMarshallerById(emf.getConfiguration(),
+            getClass().getName());
+    }
+
+    public void testCacheMarshallerType() {
+        assertEquals(CacheMarshallerImpl.class, cm.getClass());
+    }
+
+    public void testConfiguration() {
+        assertEquals(getClass().getName(), cm.getId());
+    }
+
+    public void testValidation() {
+        ValidationPolicy vp = ((CacheMarshallerImpl) cm).getValidationPolicy();
+        assertEquals(OpenJPAVersionAndConfigurationTypeValidationPolicy.class,
+            vp.getClass());
+        Object[] cached = (Object[]) vp.getCacheableData(this);
+
+        assertEquals(3, cached.length);
+        assertEquals(OpenJPAVersion.VERSION_ID, cached[0]);
+        assertEquals(emf.getConfiguration().getClass().getName(), cached[1]);
+        assertEquals(this, cached[2]);
+
+        assertEquals(this, vp.getValidData(cached));
+    }
+
+    public void testRoundTrip() {
+        Object o = "foo";
+        cm.store(o);
+        assertEquals(o, cm.load());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshallerEndToEnd.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshallerEndToEnd.java
index 462bcd5..e8739b1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshallerEndToEnd.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestCacheMarshallerEndToEnd.java
@@ -1,171 +1,171 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.conf;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.query.NamedQueryEntity;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-import org.apache.openjpa.lib.log.Log;
-
-public class TestCacheMarshallerEndToEnd
-    extends PersistenceTestCase {
-
-    private static final Object[] STORE_PROPS = new Object[] {
-        "openjpa.CacheMarshallers",
-        "default(Id=" + MetaDataCacheMaintenance.class.getName()
-            + ", OutputFile=target/"
-                + MetaDataCacheMaintenance.class.getName() +".ser"
-            + ", ConsumeSerializationErrors=false"
-            + ", ValidationPolicy="
-            + OpenJPAVersionAndConfigurationTypeValidationPolicy.class.getName()
-            + ")",
-        "openjpa.QueryCompilationCache",
-        "java.util.concurrent.ConcurrentHashMap",
-        AllFieldTypes.class,
-        NamedQueryEntity.class,
-        CLEAR_TABLES
-    };
-
-    private static final Object[] LOAD_PROPS = new Object[] {
-        "openjpa.CacheMarshallers",
-        "default(Id=" + MetaDataCacheMaintenance.class.getName()
-            + ", InputURL=file:target/"
-                + MetaDataCacheMaintenance.class.getName() + ".ser"
-            + ", ConsumeSerializationErrors=false"
-            + ", ValidationPolicy="
-            + OpenJPAVersionAndConfigurationTypeValidationPolicy.class.getName()
-            + ")",
-        "openjpa.QueryCompilationCache",
-        "java.util.concurrent.ConcurrentHashMap",
-        AllFieldTypes.class,
-        NamedQueryEntity.class
-    };
-
-
-    public void testCacheMarshallerEndToEnd()
-        throws IOException {
-        OpenJPAEntityManagerFactorySPI emf = createEMF(STORE_PROPS);
-        CacheMarshallerImpl cm = (CacheMarshallerImpl)
-            CacheMarshallersValue.getMarshallerById(
-            emf.getConfiguration(), MetaDataCacheMaintenance.class.getName());
-        cm.getOutputFile().delete();
-        MetaDataCacheMaintenance maint = new MetaDataCacheMaintenance(
-            JPAFacadeHelper.toBrokerFactory(emf), false);
-        LogImpl log = new LogImpl();
-        maint.setLog(log);
-        maint.store();
-        assertContains(log.lines, "    " + AllFieldTypes.class.getName());
-        assertContains(log.lines, "    " + NamedQueryEntity.class.getName());
-        assertContains(log.lines, "    NamedQueryEntity.namedQuery");
-        emf.close();
-
-        emf = createEMF(LOAD_PROPS);
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(new NamedQueryEntity("foo"));
-        em.flush();
-        Query q = em.createNamedQuery("NamedQueryEntity.namedQuery");
-        assertEquals(1, q.getResultList().size());
-        em.getTransaction().rollback();
-        em.close();
-        emf.close();
-    }
-
-    private void assertContains(List<String> lines, String prefix) {
-        for (String line : lines)
-            if (line.startsWith(prefix))
-                return;
-        fail("should contain a line starting with " + prefix
-            + ": " + lines);
-    }
-
-    private class LogImpl implements Log {
-        private List<String> lines = new ArrayList<String>();
-
-        public boolean isTraceEnabled() {
-            return true;
-        }
-
-        public boolean isInfoEnabled() {
-            return true;
-        }
-
-        public boolean isWarnEnabled() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isErrorEnabled() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isFatalEnabled() {
-            throw new UnsupportedOperationException();
-        }
-
-        public void trace(Object o) {
-            lines.add(o.toString());
-        }
-
-        public void trace(Object o, Throwable t) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void info(Object o) {
-            lines.add(o.toString());
-        }
-
-        public void info(Object o, Throwable t) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void warn(Object o) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void warn(Object o, Throwable t) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void error(Object o) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void error(Object o, Throwable t) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void fatal(Object o) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void fatal(Object o, Throwable t) {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.conf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.query.NamedQueryEntity;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import org.apache.openjpa.lib.log.Log;
+
+public class TestCacheMarshallerEndToEnd
+    extends PersistenceTestCase {
+
+    private static final Object[] STORE_PROPS = new Object[] {
+        "openjpa.CacheMarshallers",
+        "default(Id=" + MetaDataCacheMaintenance.class.getName()
+            + ", OutputFile=target/"
+                + MetaDataCacheMaintenance.class.getName() +".ser"
+            + ", ConsumeSerializationErrors=false"
+            + ", ValidationPolicy="
+            + OpenJPAVersionAndConfigurationTypeValidationPolicy.class.getName()
+            + ")",
+        "openjpa.QueryCompilationCache",
+        "java.util.concurrent.ConcurrentHashMap",
+        AllFieldTypes.class,
+        NamedQueryEntity.class,
+        CLEAR_TABLES
+    };
+
+    private static final Object[] LOAD_PROPS = new Object[] {
+        "openjpa.CacheMarshallers",
+        "default(Id=" + MetaDataCacheMaintenance.class.getName()
+            + ", InputURL=file:target/"
+                + MetaDataCacheMaintenance.class.getName() + ".ser"
+            + ", ConsumeSerializationErrors=false"
+            + ", ValidationPolicy="
+            + OpenJPAVersionAndConfigurationTypeValidationPolicy.class.getName()
+            + ")",
+        "openjpa.QueryCompilationCache",
+        "java.util.concurrent.ConcurrentHashMap",
+        AllFieldTypes.class,
+        NamedQueryEntity.class
+    };
+
+
+    public void testCacheMarshallerEndToEnd()
+        throws IOException {
+        OpenJPAEntityManagerFactorySPI emf = createEMF(STORE_PROPS);
+        CacheMarshallerImpl cm = (CacheMarshallerImpl)
+            CacheMarshallersValue.getMarshallerById(
+            emf.getConfiguration(), MetaDataCacheMaintenance.class.getName());
+        cm.getOutputFile().delete();
+        MetaDataCacheMaintenance maint = new MetaDataCacheMaintenance(
+            JPAFacadeHelper.toBrokerFactory(emf), false);
+        LogImpl log = new LogImpl();
+        maint.setLog(log);
+        maint.store();
+        assertContains(log.lines, "    " + AllFieldTypes.class.getName());
+        assertContains(log.lines, "    " + NamedQueryEntity.class.getName());
+        assertContains(log.lines, "    NamedQueryEntity.namedQuery");
+        emf.close();
+
+        emf = createEMF(LOAD_PROPS);
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(new NamedQueryEntity("foo"));
+        em.flush();
+        Query q = em.createNamedQuery("NamedQueryEntity.namedQuery");
+        assertEquals(1, q.getResultList().size());
+        em.getTransaction().rollback();
+        em.close();
+        emf.close();
+    }
+
+    private void assertContains(List<String> lines, String prefix) {
+        for (String line : lines)
+            if (line.startsWith(prefix))
+                return;
+        fail("should contain a line starting with " + prefix
+            + ": " + lines);
+    }
+
+    private class LogImpl implements Log {
+        private List<String> lines = new ArrayList<String>();
+
+        public boolean isTraceEnabled() {
+            return true;
+        }
+
+        public boolean isInfoEnabled() {
+            return true;
+        }
+
+        public boolean isWarnEnabled() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean isErrorEnabled() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean isFatalEnabled() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void trace(Object o) {
+            lines.add(o.toString());
+        }
+
+        public void trace(Object o, Throwable t) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void info(Object o) {
+            lines.add(o.toString());
+        }
+
+        public void info(Object o, Throwable t) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void warn(Object o) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void warn(Object o, Throwable t) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void error(Object o) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void error(Object o, Throwable t) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void fatal(Object o) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void fatal(Object o, Throwable t) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestDynamicConfiguration.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestDynamicConfiguration.java
index e894964..c05392f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestDynamicConfiguration.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestDynamicConfiguration.java
@@ -1,136 +1,136 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.conf;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.lib.conf.Value;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.datacache.common.apps.PObject;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests dynamic modification of configuration property.
- * 
- * @author Pinaki Poddar
- *
- */
-public class TestDynamicConfiguration extends SingleEMFTestCase {
-
-	public void setUp() throws Exception {
-		super.setUp(PObject.class);
-	}
-	
-    public void testConfigurationIsEqualByValueAndHashCode() {
-		OpenJPAEntityManagerFactorySPI emf1 = createEMF();
-		assertNotNull(emf1);
-		OpenJPAConfiguration conf1 = emf1.getConfiguration();
-		
-		OpenJPAEntityManagerFactorySPI emf2 = createEMF();
-		assertNotNull(emf2);
-		OpenJPAConfiguration conf2 = emf2.getConfiguration();
-		
-		assertFalse(emf1==emf2);
-		assertFalse(emf1.equals(emf2));
-		assertFalse(conf1==conf2);
-		assertEquals(conf1, conf2);
-		assertEquals(conf1.hashCode(), conf2.hashCode());
-		assertEquals(conf1.toProperties(false), conf2.toProperties(false));
-	}
-	
-	public void testConfigurationIsReadOnlyAfterFirstConstruction() {
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		assertFalse(conf.isReadOnly());
-		emf.createEntityManager();
-		assertTrue(conf.isReadOnly());
-	}
-	
-	public void testNonDynamicValuesCanNotBeChanged() {
-		emf.createEntityManager();
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		
-		String oldValue = conf.getConnectionURL();
-		String newValue = "jdbc://mydb:8087/DBDoesNotExist";
-		try {
-			conf.setConnectionURL(newValue);
-			fail("Expected exception to modify configuration");
-		} catch (Exception ex) { // good
-			assertEquals(oldValue, conf.getConnectionURL());
-		}
-	}
-	
-	public void testDynamicValuesCanBeChanged() {
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		
-		int oldValue = conf.getLockTimeout();
-		int newValue = oldValue + 10;
-		
-		conf.setLockTimeout(newValue);
-		assertEquals(newValue, conf.getLockTimeout());
-	}
-
-	public void testDynamicValuesAreCorrectlySet() {
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		
-		Value lockTimeoutValue = conf.getValue("LockTimeout");
-		assertNotNull(lockTimeoutValue);
-		assertTrue(lockTimeoutValue.isDynamic());
-		
-		Value connectionURLValue = conf.getValue("ConnectionURL");
-		assertNotNull(connectionURLValue);
-		assertFalse(connectionURLValue.isDynamic());
-	}
-	
-	public void testDynamicChangeDoesNotChangeHashCode() {
-		OpenJPAConfiguration conf1 = emf.getConfiguration();
-		
-		int oldValue = conf1.getLockTimeout();
-		int newValue = oldValue+10;
-		int oldHash = conf1.hashCode();
-		conf1.setLockTimeout(newValue);
-		int newHash = conf1.hashCode();
-		
-		assertEquals(oldHash, newHash);
-	}
-	
-	public void testClassMetaDataRecognizesDataCacheTimeoutValueChange() {
-		OpenJPAConfiguration conf = emf.getConfiguration();
-		
-		// ensure that PObject is in metadata repository
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		PObject pc = new PObject();
-		em.persist(pc);
-		
-		int oldValue = conf.getDataCacheTimeout();
-		
-		ClassMetaData meta = conf.getMetaDataRepositoryInstance()
-			.getCachedMetaData(PObject.class);
-		assertNotNull(meta);
-		assertEquals(oldValue, meta.getDataCacheTimeout());
-		
-		int newValue = oldValue + 10;
-		conf.setDataCacheTimeout(newValue);
-		assertEquals(newValue, conf.getDataCacheTimeout());
-		assertEquals(newValue, meta.getDataCacheTimeout());
-		
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.conf;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.lib.conf.Value;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.datacache.common.apps.PObject;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests dynamic modification of configuration property.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestDynamicConfiguration extends SingleEMFTestCase {
+
+	public void setUp() throws Exception {
+		super.setUp(PObject.class);
+	}
+	
+    public void testConfigurationIsEqualByValueAndHashCode() {
+		OpenJPAEntityManagerFactorySPI emf1 = createEMF();
+		assertNotNull(emf1);
+		OpenJPAConfiguration conf1 = emf1.getConfiguration();
+		
+		OpenJPAEntityManagerFactorySPI emf2 = createEMF();
+		assertNotNull(emf2);
+		OpenJPAConfiguration conf2 = emf2.getConfiguration();
+		
+		assertFalse(emf1==emf2);
+		assertFalse(emf1.equals(emf2));
+		assertFalse(conf1==conf2);
+		assertEquals(conf1, conf2);
+		assertEquals(conf1.hashCode(), conf2.hashCode());
+		assertEquals(conf1.toProperties(false), conf2.toProperties(false));
+	}
+	
+	public void testConfigurationIsReadOnlyAfterFirstConstruction() {
+		OpenJPAConfiguration conf = emf.getConfiguration();
+		assertFalse(conf.isReadOnly());
+		emf.createEntityManager();
+		assertTrue(conf.isReadOnly());
+	}
+	
+	public void testNonDynamicValuesCanNotBeChanged() {
+		emf.createEntityManager();
+		OpenJPAConfiguration conf = emf.getConfiguration();
+		
+		String oldValue = conf.getConnectionURL();
+		String newValue = "jdbc://mydb:8087/DBDoesNotExist";
+		try {
+			conf.setConnectionURL(newValue);
+			fail("Expected exception to modify configuration");
+		} catch (Exception ex) { // good
+			assertEquals(oldValue, conf.getConnectionURL());
+		}
+	}
+	
+	public void testDynamicValuesCanBeChanged() {
+		OpenJPAConfiguration conf = emf.getConfiguration();
+		
+		int oldValue = conf.getLockTimeout();
+		int newValue = oldValue + 10;
+		
+		conf.setLockTimeout(newValue);
+		assertEquals(newValue, conf.getLockTimeout());
+	}
+
+	public void testDynamicValuesAreCorrectlySet() {
+		OpenJPAConfiguration conf = emf.getConfiguration();
+		
+		Value lockTimeoutValue = conf.getValue("LockTimeout");
+		assertNotNull(lockTimeoutValue);
+		assertTrue(lockTimeoutValue.isDynamic());
+		
+		Value connectionURLValue = conf.getValue("ConnectionURL");
+		assertNotNull(connectionURLValue);
+		assertFalse(connectionURLValue.isDynamic());
+	}
+	
+	public void testDynamicChangeDoesNotChangeHashCode() {
+		OpenJPAConfiguration conf1 = emf.getConfiguration();
+		
+		int oldValue = conf1.getLockTimeout();
+		int newValue = oldValue+10;
+		int oldHash = conf1.hashCode();
+		conf1.setLockTimeout(newValue);
+		int newHash = conf1.hashCode();
+		
+		assertEquals(oldHash, newHash);
+	}
+	
+	public void testClassMetaDataRecognizesDataCacheTimeoutValueChange() {
+		OpenJPAConfiguration conf = emf.getConfiguration();
+		
+		// ensure that PObject is in metadata repository
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		PObject pc = new PObject();
+		em.persist(pc);
+		
+		int oldValue = conf.getDataCacheTimeout();
+		
+		ClassMetaData meta = conf.getMetaDataRepositoryInstance()
+			.getCachedMetaData(PObject.class);
+		assertNotNull(meta);
+		assertEquals(oldValue, meta.getDataCacheTimeout());
+		
+		int newValue = oldValue + 10;
+		conf.setDataCacheTimeout(newValue);
+		assertEquals(newValue, conf.getDataCacheTimeout());
+		assertEquals(newValue, meta.getDataCacheTimeout());
+		
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java
index 028f34f..0b446c0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java
@@ -1,610 +1,610 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ByteArrayInputStream;
-import java.util.List;
-import java.util.Collections;
-import java.lang.reflect.Field;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.event.AbstractLifecycleListener;
-import org.apache.openjpa.event.LifecycleEvent;
-
-public abstract class AbstractUnenhancedClassTest
-    extends SingleEMFTestCase {
-
-    // ##### To do:
-    // - clearing in pnew property-access without redefinition
-    // - figure out how to auto-test the redefinition code, either in Java 5
-    //   or in Java 6
-    // - run CTS in the following combinations:
-    //   * Java 6
-    //   * Java 5 with javaagent
-    //   * Java 5 without javaagent
-
-    public void setUp() {
-        setUp(getUnenhancedClass(), getUnenhancedSubclass(), CLEAR_TABLES);
-        // trigger class redefinition
-        emf.createEntityManager().close();
-    }
-
-    protected abstract Class<? extends UnenhancedType> getUnenhancedClass();
-
-    protected abstract UnenhancedType newUnenhancedInstance();
-
-    protected abstract Class<? extends UnenhancedSubtype> getUnenhancedSubclass();
-
-    protected abstract UnenhancedSubtype newUnenhancedSubclassInstance();
-
-    private UnenhancedType newInstance(boolean sub) {
-        return sub ? newUnenhancedSubclassInstance()
-            : newUnenhancedInstance();
-    }
-
-    public void testMetaData() {
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
-            getUnenhancedClass());
-        assertEquals(ClassRedefiner.canRedefineClasses(),
-            meta.isIntercepting());
-    }
-
-    public void testImplHelperCalls() {
-        assertTrue(ImplHelper.isManagedType(null, getUnenhancedClass()));
-
-        UnenhancedType un = newUnenhancedInstance();
-        assertFalse(un instanceof PersistenceCapable);
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
-            emf.getConfiguration());
-        assertNotNull(pc);
-        assertTrue(ImplHelper.isManageable(un));
-    }
-
-    public void testBasicPersistenceCapableBehavior() {
-        UnenhancedType un = newUnenhancedInstance();
-        un.setStringField("bar");
-        PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
-            emf.getConfiguration());
-        assertFalse(pc.pcIsDeleted());
-        assertFalse(pc.pcIsDirty());
-        assertFalse(pc.pcIsNew());
-        assertFalse(pc.pcIsPersistent());
-        assertFalse(pc.pcIsTransactional());
-    }
-
-    public void testPCRegistry() {
-        assertTrue(PCRegistry.isRegistered(getUnenhancedClass()));
-        PersistenceCapable pc = PCRegistry.newInstance(
-            getUnenhancedClass(), null, false);
-        assertNotNull(pc);
-        assertEquals(pc.getClass(), PCRegistry.getPCType(getUnenhancedClass()));
-    }
-
-    public void testClearingOnSubtypeInstance() {
-        // the boolean at the end of newInstance will cause clear to be invoked
-        UnenhancedType un = (UnenhancedType)
-            PCRegistry.newInstance(getUnenhancedClass(), null, true);
-        assertEquals(null, un.getStringField());
-    }
-
-    public void testGetObjectIdOnOpenJPAType() {
-        getObjectIdHelper(true, false);
-    }
-
-    public void testGetObjectIdOnOpenJPATypeSubclass() {
-        getObjectIdHelper(false, false);
-    }
-
-    public void testGetObjectIdOnUserDefined() {
-        getObjectIdHelper(true, true);
-    }
-
-    public void testGetObjectIdOnUserDefinedSubclass() {
-        getObjectIdHelper(false, true);
-    }
-
-    private void getObjectIdHelper(boolean sub, boolean userDefined) {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        UnenhancedType un = newInstance(sub);
-        em.persist(un);
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-            un = em.find(getUnenhancedClass(), un.getId());
-        }
-
-        assertNotNull(em.getObjectId(un));
-    }
-
-    public void testOperationsOnUserDefined() {
-        opsHelper(false, true);
-    }
-
-    public void testSubclassOperationsOnUserDefined() {
-        opsHelper(true, true);
-    }
-
-    public void testOperationsOnOpenJPADefined() {
-        opsHelper(false, false);
-    }
-
-    public void testSubclassOperationsOnOpenJPADefined() {
-        opsHelper(true, false);
-    }
-
-    private void opsHelper(boolean sub, boolean userDefined) {
-        OpenJPAEntityManager em = null;
-        try {
-            UnenhancedType un = newInstance(sub);
-            em = emf.createEntityManager();
-
-            em.getTransaction().begin();
-            em.persist(un);
-            un.setStringField("bar");
-            assertEquals("bar", un.getStringField());
-            assertPersistenceContext(em, un, true, true, sub);
-            em.flush();
-            assertPersistenceContext(em, un, true, true, sub);
-            assertTrue(un.getId() != 0);
-            UnenhancedType un2 = em.find(getUnenhancedClass(), un.getId());
-            assertSame(un, un2);
-            em.getTransaction().commit();
-            assertPersistenceContext(em, un, false, false, sub);
-            un2 = em.find(getUnenhancedClass(), un.getId());
-            assertSame(un, un2);
-
-            if (!userDefined) {
-                em.close();
-                em = emf.createEntityManager();
-            }
-
-            un = em.find(getUnenhancedClass(), un.getId());
-            assertNotNull(un);
-            if (!userDefined)
-                assertTrue(un instanceof PersistenceCapable);
-            assertEquals("bar", un.getStringField());
-            em.getTransaction().begin();
-            un.setStringField("baz");
-            assertPersistenceContext(em, un, true, true, sub);
-            assertEquals("baz", un.getStringField());
-
-            if (sub)
-                ((UnenhancedSubtype) un).setIntField(17);
-
-            assertTrue(em.isDirty(un));
-            
-            em.getTransaction().commit();
-
-            // make sure that the values are still up-to-date after
-            // the commit happens
-            assertEquals("baz", un.getStringField());
-            
-            em.close();
-
-            em = emf.createEntityManager();
-            un = em.find(getUnenhancedClass(), un.getId());
-            assertNotNull(un);
-            assertTrue(un instanceof PersistenceCapable);
-            assertEquals("baz", un.getStringField());
-            if (sub)
-                assertEquals(17, ((UnenhancedSubtype) un).getIntField());
-            em.close();
-        } finally {
-            if (em != null && em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            if (em != null && em.isOpen())
-                em.close();
-        }
-    }
-
-    private void assertPersistenceContext(OpenJPAEntityManager em,
-        UnenhancedType un, boolean transactional, boolean dirty, boolean sub) {
-        assertEquals(transactional, em.getTransactionalObjects().contains(un));
-        assertEquals(dirty, em.getDirtyObjects().contains(un));
-        if (dirty) {
-            Class cls = sub ? getUnenhancedSubclass() : getUnenhancedClass();
-            assertTrue(em.getUpdatedClasses().contains(cls)
-                || em.getPersistedClasses().contains(cls));
-        }
-    }
-
-    public void testRelations() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        UnenhancedSubtype un = newUnenhancedSubclassInstance();
-        em.persist(un);
-        un.setStringField("aoeu");
-        UnenhancedSubtype related = newUnenhancedSubclassInstance();
-        un.setRelated(related);
-        related.setStringField("snth");
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        un = (UnenhancedSubtype) em.find(getUnenhancedClass(), un.getId());
-        assertEquals("aoeu", un.getStringField());
-        assertNotNull(un.getRelated());
-        assertEquals("snth", un.getRelated().getStringField());
-        em.close();
-    }
-
-    public void testEnhancer() throws IOException {
-        List<Class> subs =  ManagedClassSubclasser.prepareUnenhancedClasses(
-            emf.getConfiguration(),
-            Collections.singleton(getUnenhancedClass()), null);
-        Class sub = subs.get(0);
-        assertNotNull(sub);
-        assertEquals("org.apache.openjpa.enhance."
-            + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
-            sub.getName());
-        assertTrue(PersistenceCapable.class.isAssignableFrom(sub));
-        assertTrue(getUnenhancedClass().isAssignableFrom(sub));
-    }
-
-    public void testPCSubclassName() {
-        assertEquals("org.apache.openjpa.enhance."
-            + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
-            PCEnhancer.toPCSubclassName(getUnenhancedClass()));
-    }
-
-    public void testEvictionInUserCreatedInstance()
-        throws NoSuchFieldException, IllegalAccessException {
-        evictionHelper(true);
-    }
-
-    public void testEvictionInOpenJPACreatedInstance()
-        throws NoSuchFieldException, IllegalAccessException {
-        evictionHelper(false);
-    }
-
-    private void evictionHelper(boolean userDefined)
-        throws NoSuchFieldException, IllegalAccessException {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        UnenhancedType un = newUnenhancedInstance();
-        em.getTransaction().begin();
-        em.persist(un);
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-            un = em.find(getUnenhancedClass(), un.getId());
-            assertTrue(getUnenhancedClass() != un.getClass());
-        }
-
-        em.evict(un);
-        OpenJPAStateManager sm = (OpenJPAStateManager)
-            ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
-
-        // we only expect lazy loading to work when we can redefine classes
-        // or when accessing a property-access record that OpenJPA created.
-        if (ClassRedefiner.canRedefineClasses()
-            || (!userDefined && sm.getMetaData().getAccessType()
-                != ClassMetaData.ACCESS_FIELD)) {
-
-            assertFalse(sm.getLoaded()
-                .get(sm.getMetaData().getField("stringField").getIndex()));
-
-            // make sure that the value was cleared...
-            Field field = getUnenhancedClass().getDeclaredField(
-                isFieldAccessTest() ? "stringField" : "sf");
-            field.setAccessible(true);
-            assertEquals(null, field.get(un));
-
-            // ... and that it gets reloaded properly
-            assertEquals("foo", un.getStringField());
-            assertTrue(sm.getLoaded()
-                .get(sm.getMetaData().getField("stringField").getIndex()));
-        } else {
-            // unredefined properties with user-defined instance, or any
-            // unredefined field access
-            assertTrue(sm.getLoaded()
-                .get(sm.getMetaData().getField("stringField").getIndex()));
-
-            // make sure that the value was not cleared
-            Field field = getUnenhancedClass().getDeclaredField(
-                isFieldAccessTest() ? "stringField" : "sf");
-            field.setAccessible(true);
-            assertEquals("foo", field.get(un));
-        }
-
-        em.close();
-    }
-
-    protected abstract boolean isFieldAccessTest();
-
-    public void testLazyLoading()
-        throws NoSuchFieldException, IllegalAccessException {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        UnenhancedType un = newUnenhancedInstance();
-        em.getTransaction().begin();
-        em.persist(un);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        un = em.find(getUnenhancedClass(), un.getId());
-        assertTrue(getUnenhancedClass() != un.getClass());
-        OpenJPAStateManager sm = (OpenJPAStateManager)
-            ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
-
-        // we only expect lazy loading to work when we can redefine classes
-        // or when accessing a property-access record that OpenJPA created.
-        if (ClassRedefiner.canRedefineClasses()
-            || (sm.getMetaData().getAccessType() != ClassMetaData.ACCESS_FIELD))
-        {
-            assertFalse(sm.getLoaded()
-                .get(sm.getMetaData().getField("lazyField").getIndex()));
-
-            // make sure that the value was cleared
-            Field field = getUnenhancedClass().getDeclaredField("lazyField");
-            field.setAccessible(true);
-            assertEquals(null, field.get(un));
-        } else {
-            // unredefined field access
-            assertTrue(sm.getLoaded()
-                .get(sm.getMetaData().getField("lazyField").getIndex()));
-
-            // make sure that the value was loaded already
-            Field field = getUnenhancedClass().getDeclaredField("lazyField");
-            field.setAccessible(true);
-            assertEquals("lazy", field.get(un));
-        }
-
-        // make sure that the value is available, one way or another
-        assertEquals("lazy", un.getLazyField());
-        assertTrue(sm.getLoaded()
-            .get(sm.getMetaData().getField("lazyField").getIndex()));
-
-        em.close();
-    }
-
-    public void testSerializationOfUserDefinedInstance()
-        throws IOException, ClassNotFoundException {
-        serializationHelper(true, false);
-    }
-
-    public void testSerializationOfUserDefinedSubclassInstance()
-        throws IOException, ClassNotFoundException {
-        serializationHelper(true, true);
-    }
-
-    public void testSerializationOfOpenJPADefinedInstance()
-        throws IOException, ClassNotFoundException {
-        serializationHelper(false, false);
-    }
-
-    public void testSerializationOfOpenJPADefinedSubclassInstance()
-        throws IOException, ClassNotFoundException {
-        serializationHelper(false, true);
-    }
-
-    private void serializationHelper(boolean userDefined, boolean sub)
-        throws IOException, ClassNotFoundException {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        UnenhancedType un = newInstance(sub);
-        em.getTransaction().begin();
-        em.persist(un);
-
-        if (sub) {
-            UnenhancedType related = newInstance(false);
-            related.setStringField("related");
-            ((UnenhancedSubtype) un).setRelated(related);
-        }
-
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-        }
-
-        un = em.find(getUnenhancedClass(), un.getId());
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ObjectOutputStream oout = new ObjectOutputStream(out);
-        oout.writeObject(un);
-        oout.flush();
-        byte[] bytes = out.toByteArray();
-
-        ObjectInputStream oin = new ObjectInputStream(
-            new ByteArrayInputStream(bytes));
-        UnenhancedType deserialized = (UnenhancedType) oin.readObject();
-
-        copiedInstanceHelper(sub, em, un, deserialized, false);
-        em.close();
-    }
-
-    public void testCloningOfUserDefinedInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        cloneHelper(true, false);
-    }
-
-    public void testCloningOfUserDefinedSubclassInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        cloneHelper(true, true);
-    }
-
-    public void testCloningOfOpenJPADefinedInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        cloneHelper(false, false);
-    }
-
-    public void testCloningOfOpenJPADefinedSubclassInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        cloneHelper(false, true);
-    }
-
-    private void cloneHelper(boolean userDefined, boolean sub)
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        UnenhancedType un = newInstance(sub);
-        em.getTransaction().begin();
-        em.persist(un);
-
-        if (sub) {
-            UnenhancedType related = newInstance(false);
-            related.setStringField("related");
-            ((UnenhancedSubtype) un).setRelated(related);
-        }
-
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-        }
-
-        un = em.find(getUnenhancedClass(), un.getId());
-        UnenhancedType cloned = (UnenhancedType) un.clone();
-
-        copiedInstanceHelper(sub, em, un, cloned, true);
-        em.close();
-    }
-
-    private void copiedInstanceHelper(boolean sub, OpenJPAEntityManager em,
-        UnenhancedType un, UnenhancedType copy, boolean viaClone) {
-        assertNotSame(un, copy);
-        if (!viaClone)
-            assertEquals(sub ? getUnenhancedSubclass() : getUnenhancedClass(),
-                copy.getClass());
-        assertEquals(un.getId(), copy.getId());
-        assertEquals(un.getStringField(), copy.getStringField());
-        if (sub) {
-            assertEquals(
-                ((UnenhancedSubtype) un).getIntField(),
-                ((UnenhancedSubtype) copy).getIntField());
-            assertNotSame(
-                ((UnenhancedSubtype) un).getRelated(),
-                ((UnenhancedSubtype) copy).getRelated());
-            assertEquals(
-                ((UnenhancedSubtype) un).getRelated().getId(),
-                ((UnenhancedSubtype) copy).getRelated().getId());
-        }
-
-        assertFalse(em.isDetached(un));
-        assertTrue(em.isDetached(copy));
-
-        /*
-        ##### need to make detachment algorithm in ReflectingPC smarter
-        // ensure that remove() cannot be invoked on a detached instance
-        try {
-            em.getTransaction().begin();
-            em.remove(copy);
-            fail("remove() cannot be invoked on detached instance");
-        } catch (IllegalArgumentException e) {
-            em.getTransaction().rollback();
-        }
-        */
-
-        copy.setStringField("offline update");
-
-        em.getTransaction().begin();
-        assertSame(un, em.merge(copy));
-        assertTrue(em.isDirty(un));
-        assertEquals("offline update", un.getStringField());
-        em.getTransaction().commit();
-    }
-
-    public void testListenersOnUserDefinedInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        listenerHelper(true, false);
-    }
-
-    public void testListenersOnUserDefinedSubclassInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        listenerHelper(true, true);
-    }
-
-    public void testListenersOnOpenJPADefinedInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        listenerHelper(false, false);
-    }
-
-    public void testListenersOnOpenJPADefinedSubclassInstance()
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        listenerHelper(false, true);
-    }
-
-    private void listenerHelper(boolean userDefined, boolean sub)
-        throws IOException, ClassNotFoundException, CloneNotSupportedException {
-        ListenerImpl listener = new ListenerImpl();
-        emf.addLifecycleListener(listener, (Class[]) null);
-        OpenJPAEntityManager em = emf.createEntityManager();
-        UnenhancedType un = newInstance(sub);
-        em.getTransaction().begin();
-        em.persist(un);
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-        }
-
-        listener.invoked = false;
-
-        un = em.find(getUnenhancedClass(), un.getId());
-        em.getTransaction().begin();
-        un.setStringField("updated");
-        em.getTransaction().commit();
-        assertTrue(listener.invoked);
-        em.close();
-
-        assertEquals("updated", listener.stringField);
-    }
-
-    public void testGetMetaDataOfSubtype() {
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
-            getUnenhancedClass());
-        List<Class> subs =  ManagedClassSubclasser.prepareUnenhancedClasses(
-            emf.getConfiguration(),
-            Collections.singleton(getUnenhancedClass()), null);
-        assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
-
-        meta = JPAFacadeHelper.getMetaData(emf, getUnenhancedSubclass());
-        subs =  ManagedClassSubclasser.prepareUnenhancedClasses(
-            emf.getConfiguration(),
-            Collections.singleton(getUnenhancedSubclass()), null);
-        assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
-    }
-
-    private class ListenerImpl
-        extends AbstractLifecycleListener {
-
-        String stringField;
-        boolean invoked;
-
-        @Override
-        public void afterStore(LifecycleEvent event) {
-            invoked = true;
-            stringField = ((UnenhancedType) event.getSource()).getStringField();
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.Collections;
+import java.lang.reflect.Field;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.event.AbstractLifecycleListener;
+import org.apache.openjpa.event.LifecycleEvent;
+
+public abstract class AbstractUnenhancedClassTest
+    extends SingleEMFTestCase {
+
+    // ##### To do:
+    // - clearing in pnew property-access without redefinition
+    // - figure out how to auto-test the redefinition code, either in Java 5
+    //   or in Java 6
+    // - run CTS in the following combinations:
+    //   * Java 6
+    //   * Java 5 with javaagent
+    //   * Java 5 without javaagent
+
+    public void setUp() {
+        setUp(getUnenhancedClass(), getUnenhancedSubclass(), CLEAR_TABLES);
+        // trigger class redefinition
+        emf.createEntityManager().close();
+    }
+
+    protected abstract Class<? extends UnenhancedType> getUnenhancedClass();
+
+    protected abstract UnenhancedType newUnenhancedInstance();
+
+    protected abstract Class<? extends UnenhancedSubtype> getUnenhancedSubclass();
+
+    protected abstract UnenhancedSubtype newUnenhancedSubclassInstance();
+
+    private UnenhancedType newInstance(boolean sub) {
+        return sub ? newUnenhancedSubclassInstance()
+            : newUnenhancedInstance();
+    }
+
+    public void testMetaData() {
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
+            getUnenhancedClass());
+        assertEquals(ClassRedefiner.canRedefineClasses(),
+            meta.isIntercepting());
+    }
+
+    public void testImplHelperCalls() {
+        assertTrue(ImplHelper.isManagedType(null, getUnenhancedClass()));
+
+        UnenhancedType un = newUnenhancedInstance();
+        assertFalse(un instanceof PersistenceCapable);
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
+            emf.getConfiguration());
+        assertNotNull(pc);
+        assertTrue(ImplHelper.isManageable(un));
+    }
+
+    public void testBasicPersistenceCapableBehavior() {
+        UnenhancedType un = newUnenhancedInstance();
+        un.setStringField("bar");
+        PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
+            emf.getConfiguration());
+        assertFalse(pc.pcIsDeleted());
+        assertFalse(pc.pcIsDirty());
+        assertFalse(pc.pcIsNew());
+        assertFalse(pc.pcIsPersistent());
+        assertFalse(pc.pcIsTransactional());
+    }
+
+    public void testPCRegistry() {
+        assertTrue(PCRegistry.isRegistered(getUnenhancedClass()));
+        PersistenceCapable pc = PCRegistry.newInstance(
+            getUnenhancedClass(), null, false);
+        assertNotNull(pc);
+        assertEquals(pc.getClass(), PCRegistry.getPCType(getUnenhancedClass()));
+    }
+
+    public void testClearingOnSubtypeInstance() {
+        // the boolean at the end of newInstance will cause clear to be invoked
+        UnenhancedType un = (UnenhancedType)
+            PCRegistry.newInstance(getUnenhancedClass(), null, true);
+        assertEquals(null, un.getStringField());
+    }
+
+    public void testGetObjectIdOnOpenJPAType() {
+        getObjectIdHelper(true, false);
+    }
+
+    public void testGetObjectIdOnOpenJPATypeSubclass() {
+        getObjectIdHelper(false, false);
+    }
+
+    public void testGetObjectIdOnUserDefined() {
+        getObjectIdHelper(true, true);
+    }
+
+    public void testGetObjectIdOnUserDefinedSubclass() {
+        getObjectIdHelper(false, true);
+    }
+
+    private void getObjectIdHelper(boolean sub, boolean userDefined) {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        UnenhancedType un = newInstance(sub);
+        em.persist(un);
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+            un = em.find(getUnenhancedClass(), un.getId());
+        }
+
+        assertNotNull(em.getObjectId(un));
+    }
+
+    public void testOperationsOnUserDefined() {
+        opsHelper(false, true);
+    }
+
+    public void testSubclassOperationsOnUserDefined() {
+        opsHelper(true, true);
+    }
+
+    public void testOperationsOnOpenJPADefined() {
+        opsHelper(false, false);
+    }
+
+    public void testSubclassOperationsOnOpenJPADefined() {
+        opsHelper(true, false);
+    }
+
+    private void opsHelper(boolean sub, boolean userDefined) {
+        OpenJPAEntityManager em = null;
+        try {
+            UnenhancedType un = newInstance(sub);
+            em = emf.createEntityManager();
+
+            em.getTransaction().begin();
+            em.persist(un);
+            un.setStringField("bar");
+            assertEquals("bar", un.getStringField());
+            assertPersistenceContext(em, un, true, true, sub);
+            em.flush();
+            assertPersistenceContext(em, un, true, true, sub);
+            assertTrue(un.getId() != 0);
+            UnenhancedType un2 = em.find(getUnenhancedClass(), un.getId());
+            assertSame(un, un2);
+            em.getTransaction().commit();
+            assertPersistenceContext(em, un, false, false, sub);
+            un2 = em.find(getUnenhancedClass(), un.getId());
+            assertSame(un, un2);
+
+            if (!userDefined) {
+                em.close();
+                em = emf.createEntityManager();
+            }
+
+            un = em.find(getUnenhancedClass(), un.getId());
+            assertNotNull(un);
+            if (!userDefined)
+                assertTrue(un instanceof PersistenceCapable);
+            assertEquals("bar", un.getStringField());
+            em.getTransaction().begin();
+            un.setStringField("baz");
+            assertPersistenceContext(em, un, true, true, sub);
+            assertEquals("baz", un.getStringField());
+
+            if (sub)
+                ((UnenhancedSubtype) un).setIntField(17);
+
+            assertTrue(em.isDirty(un));
+            
+            em.getTransaction().commit();
+
+            // make sure that the values are still up-to-date after
+            // the commit happens
+            assertEquals("baz", un.getStringField());
+            
+            em.close();
+
+            em = emf.createEntityManager();
+            un = em.find(getUnenhancedClass(), un.getId());
+            assertNotNull(un);
+            assertTrue(un instanceof PersistenceCapable);
+            assertEquals("baz", un.getStringField());
+            if (sub)
+                assertEquals(17, ((UnenhancedSubtype) un).getIntField());
+            em.close();
+        } finally {
+            if (em != null && em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            if (em != null && em.isOpen())
+                em.close();
+        }
+    }
+
+    private void assertPersistenceContext(OpenJPAEntityManager em,
+        UnenhancedType un, boolean transactional, boolean dirty, boolean sub) {
+        assertEquals(transactional, em.getTransactionalObjects().contains(un));
+        assertEquals(dirty, em.getDirtyObjects().contains(un));
+        if (dirty) {
+            Class cls = sub ? getUnenhancedSubclass() : getUnenhancedClass();
+            assertTrue(em.getUpdatedClasses().contains(cls)
+                || em.getPersistedClasses().contains(cls));
+        }
+    }
+
+    public void testRelations() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        UnenhancedSubtype un = newUnenhancedSubclassInstance();
+        em.persist(un);
+        un.setStringField("aoeu");
+        UnenhancedSubtype related = newUnenhancedSubclassInstance();
+        un.setRelated(related);
+        related.setStringField("snth");
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        un = (UnenhancedSubtype) em.find(getUnenhancedClass(), un.getId());
+        assertEquals("aoeu", un.getStringField());
+        assertNotNull(un.getRelated());
+        assertEquals("snth", un.getRelated().getStringField());
+        em.close();
+    }
+
+    public void testEnhancer() throws IOException {
+        List<Class> subs =  ManagedClassSubclasser.prepareUnenhancedClasses(
+            emf.getConfiguration(),
+            Collections.singleton(getUnenhancedClass()), null);
+        Class sub = subs.get(0);
+        assertNotNull(sub);
+        assertEquals("org.apache.openjpa.enhance."
+            + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
+            sub.getName());
+        assertTrue(PersistenceCapable.class.isAssignableFrom(sub));
+        assertTrue(getUnenhancedClass().isAssignableFrom(sub));
+    }
+
+    public void testPCSubclassName() {
+        assertEquals("org.apache.openjpa.enhance."
+            + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
+            PCEnhancer.toPCSubclassName(getUnenhancedClass()));
+    }
+
+    public void testEvictionInUserCreatedInstance()
+        throws NoSuchFieldException, IllegalAccessException {
+        evictionHelper(true);
+    }
+
+    public void testEvictionInOpenJPACreatedInstance()
+        throws NoSuchFieldException, IllegalAccessException {
+        evictionHelper(false);
+    }
+
+    private void evictionHelper(boolean userDefined)
+        throws NoSuchFieldException, IllegalAccessException {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        UnenhancedType un = newUnenhancedInstance();
+        em.getTransaction().begin();
+        em.persist(un);
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+            un = em.find(getUnenhancedClass(), un.getId());
+            assertTrue(getUnenhancedClass() != un.getClass());
+        }
+
+        em.evict(un);
+        OpenJPAStateManager sm = (OpenJPAStateManager)
+            ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
+
+        // we only expect lazy loading to work when we can redefine classes
+        // or when accessing a property-access record that OpenJPA created.
+        if (ClassRedefiner.canRedefineClasses()
+            || (!userDefined && sm.getMetaData().getAccessType()
+                != ClassMetaData.ACCESS_FIELD)) {
+
+            assertFalse(sm.getLoaded()
+                .get(sm.getMetaData().getField("stringField").getIndex()));
+
+            // make sure that the value was cleared...
+            Field field = getUnenhancedClass().getDeclaredField(
+                isFieldAccessTest() ? "stringField" : "sf");
+            field.setAccessible(true);
+            assertEquals(null, field.get(un));
+
+            // ... and that it gets reloaded properly
+            assertEquals("foo", un.getStringField());
+            assertTrue(sm.getLoaded()
+                .get(sm.getMetaData().getField("stringField").getIndex()));
+        } else {
+            // unredefined properties with user-defined instance, or any
+            // unredefined field access
+            assertTrue(sm.getLoaded()
+                .get(sm.getMetaData().getField("stringField").getIndex()));
+
+            // make sure that the value was not cleared
+            Field field = getUnenhancedClass().getDeclaredField(
+                isFieldAccessTest() ? "stringField" : "sf");
+            field.setAccessible(true);
+            assertEquals("foo", field.get(un));
+        }
+
+        em.close();
+    }
+
+    protected abstract boolean isFieldAccessTest();
+
+    public void testLazyLoading()
+        throws NoSuchFieldException, IllegalAccessException {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        UnenhancedType un = newUnenhancedInstance();
+        em.getTransaction().begin();
+        em.persist(un);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        un = em.find(getUnenhancedClass(), un.getId());
+        assertTrue(getUnenhancedClass() != un.getClass());
+        OpenJPAStateManager sm = (OpenJPAStateManager)
+            ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
+
+        // we only expect lazy loading to work when we can redefine classes
+        // or when accessing a property-access record that OpenJPA created.
+        if (ClassRedefiner.canRedefineClasses()
+            || (sm.getMetaData().getAccessType() != ClassMetaData.ACCESS_FIELD))
+        {
+            assertFalse(sm.getLoaded()
+                .get(sm.getMetaData().getField("lazyField").getIndex()));
+
+            // make sure that the value was cleared
+            Field field = getUnenhancedClass().getDeclaredField("lazyField");
+            field.setAccessible(true);
+            assertEquals(null, field.get(un));
+        } else {
+            // unredefined field access
+            assertTrue(sm.getLoaded()
+                .get(sm.getMetaData().getField("lazyField").getIndex()));
+
+            // make sure that the value was loaded already
+            Field field = getUnenhancedClass().getDeclaredField("lazyField");
+            field.setAccessible(true);
+            assertEquals("lazy", field.get(un));
+        }
+
+        // make sure that the value is available, one way or another
+        assertEquals("lazy", un.getLazyField());
+        assertTrue(sm.getLoaded()
+            .get(sm.getMetaData().getField("lazyField").getIndex()));
+
+        em.close();
+    }
+
+    public void testSerializationOfUserDefinedInstance()
+        throws IOException, ClassNotFoundException {
+        serializationHelper(true, false);
+    }
+
+    public void testSerializationOfUserDefinedSubclassInstance()
+        throws IOException, ClassNotFoundException {
+        serializationHelper(true, true);
+    }
+
+    public void testSerializationOfOpenJPADefinedInstance()
+        throws IOException, ClassNotFoundException {
+        serializationHelper(false, false);
+    }
+
+    public void testSerializationOfOpenJPADefinedSubclassInstance()
+        throws IOException, ClassNotFoundException {
+        serializationHelper(false, true);
+    }
+
+    private void serializationHelper(boolean userDefined, boolean sub)
+        throws IOException, ClassNotFoundException {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        UnenhancedType un = newInstance(sub);
+        em.getTransaction().begin();
+        em.persist(un);
+
+        if (sub) {
+            UnenhancedType related = newInstance(false);
+            related.setStringField("related");
+            ((UnenhancedSubtype) un).setRelated(related);
+        }
+
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+        }
+
+        un = em.find(getUnenhancedClass(), un.getId());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oout = new ObjectOutputStream(out);
+        oout.writeObject(un);
+        oout.flush();
+        byte[] bytes = out.toByteArray();
+
+        ObjectInputStream oin = new ObjectInputStream(
+            new ByteArrayInputStream(bytes));
+        UnenhancedType deserialized = (UnenhancedType) oin.readObject();
+
+        copiedInstanceHelper(sub, em, un, deserialized, false);
+        em.close();
+    }
+
+    public void testCloningOfUserDefinedInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        cloneHelper(true, false);
+    }
+
+    public void testCloningOfUserDefinedSubclassInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        cloneHelper(true, true);
+    }
+
+    public void testCloningOfOpenJPADefinedInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        cloneHelper(false, false);
+    }
+
+    public void testCloningOfOpenJPADefinedSubclassInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        cloneHelper(false, true);
+    }
+
+    private void cloneHelper(boolean userDefined, boolean sub)
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        UnenhancedType un = newInstance(sub);
+        em.getTransaction().begin();
+        em.persist(un);
+
+        if (sub) {
+            UnenhancedType related = newInstance(false);
+            related.setStringField("related");
+            ((UnenhancedSubtype) un).setRelated(related);
+        }
+
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+        }
+
+        un = em.find(getUnenhancedClass(), un.getId());
+        UnenhancedType cloned = (UnenhancedType) un.clone();
+
+        copiedInstanceHelper(sub, em, un, cloned, true);
+        em.close();
+    }
+
+    private void copiedInstanceHelper(boolean sub, OpenJPAEntityManager em,
+        UnenhancedType un, UnenhancedType copy, boolean viaClone) {
+        assertNotSame(un, copy);
+        if (!viaClone)
+            assertEquals(sub ? getUnenhancedSubclass() : getUnenhancedClass(),
+                copy.getClass());
+        assertEquals(un.getId(), copy.getId());
+        assertEquals(un.getStringField(), copy.getStringField());
+        if (sub) {
+            assertEquals(
+                ((UnenhancedSubtype) un).getIntField(),
+                ((UnenhancedSubtype) copy).getIntField());
+            assertNotSame(
+                ((UnenhancedSubtype) un).getRelated(),
+                ((UnenhancedSubtype) copy).getRelated());
+            assertEquals(
+                ((UnenhancedSubtype) un).getRelated().getId(),
+                ((UnenhancedSubtype) copy).getRelated().getId());
+        }
+
+        assertFalse(em.isDetached(un));
+        assertTrue(em.isDetached(copy));
+
+        /*
+        ##### need to make detachment algorithm in ReflectingPC smarter
+        // ensure that remove() cannot be invoked on a detached instance
+        try {
+            em.getTransaction().begin();
+            em.remove(copy);
+            fail("remove() cannot be invoked on detached instance");
+        } catch (IllegalArgumentException e) {
+            em.getTransaction().rollback();
+        }
+        */
+
+        copy.setStringField("offline update");
+
+        em.getTransaction().begin();
+        assertSame(un, em.merge(copy));
+        assertTrue(em.isDirty(un));
+        assertEquals("offline update", un.getStringField());
+        em.getTransaction().commit();
+    }
+
+    public void testListenersOnUserDefinedInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        listenerHelper(true, false);
+    }
+
+    public void testListenersOnUserDefinedSubclassInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        listenerHelper(true, true);
+    }
+
+    public void testListenersOnOpenJPADefinedInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        listenerHelper(false, false);
+    }
+
+    public void testListenersOnOpenJPADefinedSubclassInstance()
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        listenerHelper(false, true);
+    }
+
+    private void listenerHelper(boolean userDefined, boolean sub)
+        throws IOException, ClassNotFoundException, CloneNotSupportedException {
+        ListenerImpl listener = new ListenerImpl();
+        emf.addLifecycleListener(listener, (Class[]) null);
+        OpenJPAEntityManager em = emf.createEntityManager();
+        UnenhancedType un = newInstance(sub);
+        em.getTransaction().begin();
+        em.persist(un);
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+        }
+
+        listener.invoked = false;
+
+        un = em.find(getUnenhancedClass(), un.getId());
+        em.getTransaction().begin();
+        un.setStringField("updated");
+        em.getTransaction().commit();
+        assertTrue(listener.invoked);
+        em.close();
+
+        assertEquals("updated", listener.stringField);
+    }
+
+    public void testGetMetaDataOfSubtype() {
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
+            getUnenhancedClass());
+        List<Class> subs =  ManagedClassSubclasser.prepareUnenhancedClasses(
+            emf.getConfiguration(),
+            Collections.singleton(getUnenhancedClass()), null);
+        assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
+
+        meta = JPAFacadeHelper.getMetaData(emf, getUnenhancedSubclass());
+        subs =  ManagedClassSubclasser.prepareUnenhancedClasses(
+            emf.getConfiguration(),
+            Collections.singleton(getUnenhancedSubclass()), null);
+        assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
+    }
+
+    private class ListenerImpl
+        extends AbstractLifecycleListener {
+
+        String stringField;
+        boolean invoked;
+
+        @Override
+        public void afterStore(LifecycleEvent event) {
+            invoked = true;
+            stringField = ((UnenhancedType) event.getSource()).getStringField();
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestDataCachingAndUnenhancedPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestDataCachingAndUnenhancedPropertyAccess.java
index 489d2a5..c3ab5d2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestDataCachingAndUnenhancedPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestDataCachingAndUnenhancedPropertyAccess.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestDataCachingAndUnenhancedPropertyAccess
-    extends SingleEMFTestCase {
-
-    @Override
-    public void setUp() {
-        setUp(UnenhancedIdentityIdPropertyAccess.class, CLEAR_TABLES,
-            "openjpa.DataCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm");
-    }
-
-    public void testSimpleDataCacheOperation() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(new UnenhancedIdentityIdPropertyAccess());
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testAccessIdBeforeCommit() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        UnenhancedIdentityIdPropertyAccess o =
-            new UnenhancedIdentityIdPropertyAccess();
-        em.persist(o);
-        em.getObjectId(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestDataCachingAndUnenhancedPropertyAccess
+    extends SingleEMFTestCase {
+
+    @Override
+    public void setUp() {
+        setUp(UnenhancedIdentityIdPropertyAccess.class, CLEAR_TABLES,
+            "openjpa.DataCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm");
+    }
+
+    public void testSimpleDataCacheOperation() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(new UnenhancedIdentityIdPropertyAccess());
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testAccessIdBeforeCommit() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        UnenhancedIdentityIdPropertyAccess o =
+            new UnenhancedIdentityIdPropertyAccess();
+        em.persist(o);
+        em.getObjectId(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementConfiguration.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementConfiguration.java
index 0737163..4348b23 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementConfiguration.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementConfiguration.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.util.ImplHelper;
-
-public class TestEnhancementConfiguration
-    extends SingleEMFTestCase {
-
-    public void testEnhancementConfiguration() {
-        try {
-            emf = createEMF(
-                "openjpa.RuntimeUnenhancedClasses", "unsupported",
-                UnenhancedFieldAccess.class, CLEAR_TABLES);
-            assertFalse(ImplHelper.isManagedType(emf.getConfiguration(),
-                UnenhancedFieldAccess.class));
-            emf.createEntityManager().close();
-            fail("should not be possible to fully-initialize a system " +
-                "that depends on unenhanced types but disables runtime" +
-                "redefinition.");
-        } catch (Exception e) {
-            assertTrue(e.getMessage().contains(
-                "This configuration disallows runtime optimization"));
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.util.ImplHelper;
+
+public class TestEnhancementConfiguration
+    extends SingleEMFTestCase {
+
+    public void testEnhancementConfiguration() {
+        try {
+            emf = createEMF(
+                "openjpa.RuntimeUnenhancedClasses", "unsupported",
+                UnenhancedFieldAccess.class, CLEAR_TABLES);
+            assertFalse(ImplHelper.isManagedType(emf.getConfiguration(),
+                UnenhancedFieldAccess.class));
+            emf.createEntityManager().close();
+            fail("should not be possible to fully-initialize a system " +
+                "that depends on unenhanced types but disables runtime" +
+                "redefinition.");
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains(
+                "This configuration disallows runtime optimization"));
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
index 10e7973..15392bf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
@@ -1,151 +1,151 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.IOException;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.lib.util.BytecodeWriter;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-import serp.bytecode.BCClass;
-import serp.bytecode.Project;
-
-public class TestEnhancementWithMultiplePUs
-    extends PersistenceTestCase {
-
-    public void testExplicitEnhancementWithClassNotInFirstPU()
-        throws ClassNotFoundException {
-        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
-        Configurations.populateConfiguration(conf, new Options());
-        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
-        ClassLoader loader = (ClassLoader) AccessController
-            .doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
-                getClass().getClassLoader()));
-        Project project = new Project();
-
-        String className =
-            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance";
-        BCClass bc = assertNotPC(loader, project, className);
-
-        PCEnhancer enhancer = new PCEnhancer(conf, bc, repos, loader);
-
-        assertEquals(PCEnhancer.ENHANCE_PC, enhancer.run());
-        assertTrue(Arrays.asList(bc.getInterfaceNames()).contains(
-            PersistenceCapable.class.getName()));
-    }
-
-    private BCClass assertNotPC(ClassLoader loader, Project project,
-        String className) {
-        BCClass bc = project.loadClass(className, loader);
-        assertFalse(className + " must not be enhanced already; it was.",
-            Arrays.asList(bc.getInterfaceNames()).contains(
-                PersistenceCapable.class.getName()));
-        return bc;
-    }
-
-    public void testEnhancementOfSecondPUWithClassNotInFirstPU()
-        throws IOException {
-        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
-        Options opts = new Options();
-        opts.setProperty("p",
-            "META-INF/persistence.xml#second-persistence-unit");
-        Configurations.populateConfiguration(conf, opts);
-        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
-        ClassLoader loader = (ClassLoader) AccessController
-            .doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
-                getClass().getClassLoader()));
-        Project project = new Project();
-
-        // make sure that the class is not already enhanced for some reason
-        String className =
-            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance";
-        BCClass bc = assertNotPC(loader, project, className);
-
-        // build up a writer that just stores to a list so that we don't
-        // mutate the disk.
-        final List<String> written = new ArrayList<String>();
-        BytecodeWriter writer = new BytecodeWriter() {
-
-            public void write(BCClass type) throws IOException {
-                assertTrue(Arrays.asList(type.getInterfaceNames()).contains(
-                    PersistenceCapable.class.getName()));
-                written.add(type.getName());
-            }
-        };
-
-        PCEnhancer.run(conf, null, new PCEnhancer.Flags(), repos, writer,
-            loader);
-
-        // ensure that we don't attempt to process classes listed in other PUs
-        assertEquals(1, written.size());
-
-        // ensure that we do process the classes listed in the PU
-        assertTrue(written.contains(className));
-    }
-
-    public void testEnhancementOfAllPUsWithinAResource()
-        throws IOException {
-        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
-        Options opts = new Options();
-        opts.setProperty("p", "META-INF/persistence.xml");
-        Configurations.populateConfiguration(conf, opts);
-        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
-        ClassLoader loader = (ClassLoader) AccessController
-            .doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
-                getClass().getClassLoader()));
-        Project project = new Project();
-
-        // make sure that the classes is not already enhanced for some reason
-        assertNotPC(loader, project,
-            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance");
-        assertNotPC(loader, project,
-            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance2");
-
-        // build up a writer that just stores to a list so that we don't
-        // mutate the disk.
-        final List<String> written = new ArrayList<String>();
-        BytecodeWriter writer = new BytecodeWriter() {
-
-            public void write(BCClass type) throws IOException {
-                assertTrue(Arrays.asList(type.getInterfaceNames()).contains(
-                    PersistenceCapable.class.getName()));
-                written.add(type.getName());
-            }
-        };
-
-        opts = new Options();
-        opts.put(PCEnhancer.class.getName() + "#bytecodeWriter", writer);
-        PCEnhancer.run(null, opts);
-
-        // ensure that we do process the classes listed in the PUs
-        assertTrue(written.contains(
-            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance"));
-        assertTrue(written.contains(
-            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance2"));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.util.BytecodeWriter;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import serp.bytecode.BCClass;
+import serp.bytecode.Project;
+
+public class TestEnhancementWithMultiplePUs
+    extends PersistenceTestCase {
+
+    public void testExplicitEnhancementWithClassNotInFirstPU()
+        throws ClassNotFoundException {
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
+        Configurations.populateConfiguration(conf, new Options());
+        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
+        ClassLoader loader = (ClassLoader) AccessController
+            .doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
+                getClass().getClassLoader()));
+        Project project = new Project();
+
+        String className =
+            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance";
+        BCClass bc = assertNotPC(loader, project, className);
+
+        PCEnhancer enhancer = new PCEnhancer(conf, bc, repos, loader);
+
+        assertEquals(PCEnhancer.ENHANCE_PC, enhancer.run());
+        assertTrue(Arrays.asList(bc.getInterfaceNames()).contains(
+            PersistenceCapable.class.getName()));
+    }
+
+    private BCClass assertNotPC(ClassLoader loader, Project project,
+        String className) {
+        BCClass bc = project.loadClass(className, loader);
+        assertFalse(className + " must not be enhanced already; it was.",
+            Arrays.asList(bc.getInterfaceNames()).contains(
+                PersistenceCapable.class.getName()));
+        return bc;
+    }
+
+    public void testEnhancementOfSecondPUWithClassNotInFirstPU()
+        throws IOException {
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
+        Options opts = new Options();
+        opts.setProperty("p",
+            "META-INF/persistence.xml#second-persistence-unit");
+        Configurations.populateConfiguration(conf, opts);
+        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
+        ClassLoader loader = (ClassLoader) AccessController
+            .doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
+                getClass().getClassLoader()));
+        Project project = new Project();
+
+        // make sure that the class is not already enhanced for some reason
+        String className =
+            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance";
+        BCClass bc = assertNotPC(loader, project, className);
+
+        // build up a writer that just stores to a list so that we don't
+        // mutate the disk.
+        final List<String> written = new ArrayList<String>();
+        BytecodeWriter writer = new BytecodeWriter() {
+
+            public void write(BCClass type) throws IOException {
+                assertTrue(Arrays.asList(type.getInterfaceNames()).contains(
+                    PersistenceCapable.class.getName()));
+                written.add(type.getName());
+            }
+        };
+
+        PCEnhancer.run(conf, null, new PCEnhancer.Flags(), repos, writer,
+            loader);
+
+        // ensure that we don't attempt to process classes listed in other PUs
+        assertEquals(1, written.size());
+
+        // ensure that we do process the classes listed in the PU
+        assertTrue(written.contains(className));
+    }
+
+    public void testEnhancementOfAllPUsWithinAResource()
+        throws IOException {
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
+        Options opts = new Options();
+        opts.setProperty("p", "META-INF/persistence.xml");
+        Configurations.populateConfiguration(conf, opts);
+        MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
+        ClassLoader loader = (ClassLoader) AccessController
+            .doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
+                getClass().getClassLoader()));
+        Project project = new Project();
+
+        // make sure that the classes is not already enhanced for some reason
+        assertNotPC(loader, project,
+            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance");
+        assertNotPC(loader, project,
+            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance2");
+
+        // build up a writer that just stores to a list so that we don't
+        // mutate the disk.
+        final List<String> written = new ArrayList<String>();
+        BytecodeWriter writer = new BytecodeWriter() {
+
+            public void write(BCClass type) throws IOException {
+                assertTrue(Arrays.asList(type.getInterfaceNames()).contains(
+                    PersistenceCapable.class.getName()));
+                written.add(type.getName());
+            }
+        };
+
+        opts = new Options();
+        opts.put(PCEnhancer.class.getName() + "#bytecodeWriter", writer);
+        PCEnhancer.run(null, opts);
+
+        // ensure that we do process the classes listed in the PUs
+        assertTrue(written.contains(
+            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance"));
+        assertTrue(written.contains(
+            "org.apache.openjpa.enhance.UnenhancedBootstrapInstance2"));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestPCEnhancerFindField.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestPCEnhancerFindField.java
index d3b8e3e..4407738 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestPCEnhancerFindField.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestPCEnhancerFindField.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import junit.framework.TestCase;
-import serp.bytecode.BCClass;
-import serp.bytecode.BCField;
-import serp.bytecode.BCMethod;
-import serp.bytecode.Project;
-
-public class TestPCEnhancerFindField
-    extends TestCase {
-
-    private String field;
-
-    public String myMethod() {
-        if (Math.abs(1) == 1)
-            return field;
-        else
-            return field;
-    }
-
-    public void testPCEnhancerFindField() {
-        Project proj = new Project();
-        BCClass bc = proj.loadClass(getClass());
-        BCMethod meth = bc.getMethods("myMethod")[0];
-        BCField field = PCEnhancer.getReturnedField(meth);
-        assertEquals("field", field.getName());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import junit.framework.TestCase;
+import serp.bytecode.BCClass;
+import serp.bytecode.BCField;
+import serp.bytecode.BCMethod;
+import serp.bytecode.Project;
+
+public class TestPCEnhancerFindField
+    extends TestCase {
+
+    private String field;
+
+    public String myMethod() {
+        if (Math.abs(1) == 1)
+            return field;
+        else
+            return field;
+    }
+
+    public void testPCEnhancerFindField() {
+        Project proj = new Project();
+        BCClass bc = proj.loadClass(getClass());
+        BCMethod meth = bc.getMethods("myMethod")[0];
+        BCField field = PCEnhancer.getReturnedField(meth);
+        assertEquals("field", field.getName());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java
index 02cb60b..1dd81d1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestRelationToUnlistedClass
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(UnenhancedUnlistedReferer.class, CLEAR_TABLES);
-    }
-
-    public void testRelationToUnlistedClass() {
-        try {
-            emf.createEntityManager().close();
-            fail("should not be able to initialize system");
-        } catch (Exception e) {
-            assertTrue(e.getMessage().startsWith(
-                "The following classes were not specified"));
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestRelationToUnlistedClass
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(UnenhancedUnlistedReferer.class, CLEAR_TABLES);
+    }
+
+    public void testRelationToUnlistedClass() {
+        try {
+            emf.createEntityManager().close();
+            fail("should not be able to initialize system");
+        } catch (Exception e) {
+            assertTrue(e.getMessage().startsWith(
+                "The following classes were not specified"));
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSimpleUnenhancedQuery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSimpleUnenhancedQuery.java
index c44a564..ed60af8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSimpleUnenhancedQuery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSimpleUnenhancedQuery.java
@@ -1,49 +1,49 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * A simple query fails with unenhanced (or runtime enhanced classes)
- * as originally reported in 
- * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-659">OPENJPA-659</A>.
- * The original issue reports the failure in a Spring-Tomcat-Weaver settings
- * with embedded instances but even the following test shows the same failure 
- * in a simpler settings.
- *  
- * @author Pinaki Poddar
- *
- */
-public class TestSimpleUnenhancedQuery extends SingleEMFTestCase {
-	public void setUp() throws Exception {
-		setUp(CLEAR_TABLES, UnenhancedPObject.class);
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		em.persist(new UnenhancedPObject());
-		em.getTransaction().commit();
-	}
-	
-	public void testExtentQuery() {
-		EntityManager em = emf.createEntityManager();
-		assertFalse(em.createQuery("SELECT p FROM UnenhancedPObject p")
-				.getResultList().isEmpty());
-	}
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * A simple query fails with unenhanced (or runtime enhanced classes)
+ * as originally reported in 
+ * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-659">OPENJPA-659</A>.
+ * The original issue reports the failure in a Spring-Tomcat-Weaver settings
+ * with embedded instances but even the following test shows the same failure 
+ * in a simpler settings.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+public class TestSimpleUnenhancedQuery extends SingleEMFTestCase {
+	public void setUp() throws Exception {
+		setUp(CLEAR_TABLES, UnenhancedPObject.class);
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		em.persist(new UnenhancedPObject());
+		em.getTransaction().commit();
+	}
+	
+	public void testExtentQuery() {
+		EntityManager em = emf.createEntityManager();
+		assertFalse(em.createQuery("SELECT p FROM UnenhancedPObject p")
+				.getResultList().isEmpty());
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPK.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPK.java
index 797db35..36f3949 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPK.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPK.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestUnenhancedCompoundPK
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(UnenhancedCompoundPKFieldAccess.class,
-            UnenhancedCompoundPKPropertyAccess.class, CLEAR_TABLES);
-    }
-
-    public void testCompoundPKFieldAccessUserDefined() {
-        UnenhancedCompoundPKFieldAccess un
-            = new UnenhancedCompoundPKFieldAccess(17, 31);
-        UnenhancedCompoundPKFieldAccess.PK oid
-            = new UnenhancedCompoundPKFieldAccess.PK(17, 31);
-        compoundPKHelper(un, oid, true);
-    }
-
-    public void testCompoundPKFieldAccessOpenJPADefined() {
-        UnenhancedCompoundPKFieldAccess un
-            = new UnenhancedCompoundPKFieldAccess(17, 31);
-        UnenhancedCompoundPKFieldAccess.PK oid
-            = new UnenhancedCompoundPKFieldAccess.PK(17, 31);
-        compoundPKHelper(un, oid, false);
-    }
-
-    public void testCompoundPKPropertyAccessUserDefined() {
-        UnenhancedCompoundPKPropertyAccess un
-            = new UnenhancedCompoundPKPropertyAccess(17, 31);
-        UnenhancedCompoundPKPropertyAccess.PK oid
-            = new UnenhancedCompoundPKPropertyAccess.PK(17, 31);
-        compoundPKHelper(un, oid, true);
-    }
-
-    public void testCompoundPKPropertyAccessOpenJPADefined() {
-        UnenhancedCompoundPKPropertyAccess un
-            = new UnenhancedCompoundPKPropertyAccess(17, 31);
-        UnenhancedCompoundPKPropertyAccess.PK oid
-            = new UnenhancedCompoundPKPropertyAccess.PK(17, 31);
-        compoundPKHelper(un, oid, false);
-    }
-
-    private void compoundPKHelper(Object o, Object oid, boolean userDefined) {
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-        }
-
-        em.find(o.getClass(), oid);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestUnenhancedCompoundPK
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(UnenhancedCompoundPKFieldAccess.class,
+            UnenhancedCompoundPKPropertyAccess.class, CLEAR_TABLES);
+    }
+
+    public void testCompoundPKFieldAccessUserDefined() {
+        UnenhancedCompoundPKFieldAccess un
+            = new UnenhancedCompoundPKFieldAccess(17, 31);
+        UnenhancedCompoundPKFieldAccess.PK oid
+            = new UnenhancedCompoundPKFieldAccess.PK(17, 31);
+        compoundPKHelper(un, oid, true);
+    }
+
+    public void testCompoundPKFieldAccessOpenJPADefined() {
+        UnenhancedCompoundPKFieldAccess un
+            = new UnenhancedCompoundPKFieldAccess(17, 31);
+        UnenhancedCompoundPKFieldAccess.PK oid
+            = new UnenhancedCompoundPKFieldAccess.PK(17, 31);
+        compoundPKHelper(un, oid, false);
+    }
+
+    public void testCompoundPKPropertyAccessUserDefined() {
+        UnenhancedCompoundPKPropertyAccess un
+            = new UnenhancedCompoundPKPropertyAccess(17, 31);
+        UnenhancedCompoundPKPropertyAccess.PK oid
+            = new UnenhancedCompoundPKPropertyAccess.PK(17, 31);
+        compoundPKHelper(un, oid, true);
+    }
+
+    public void testCompoundPKPropertyAccessOpenJPADefined() {
+        UnenhancedCompoundPKPropertyAccess un
+            = new UnenhancedCompoundPKPropertyAccess(17, 31);
+        UnenhancedCompoundPKPropertyAccess.PK oid
+            = new UnenhancedCompoundPKPropertyAccess.PK(17, 31);
+        compoundPKHelper(un, oid, false);
+    }
+
+    private void compoundPKHelper(Object o, Object oid, boolean userDefined) {
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+        }
+
+        em.find(o.getClass(), oid);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPKSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPKSubclass.java
index bbfe16e..866bbc5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPKSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedCompoundPKSubclass.java
@@ -1,57 +1,57 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestUnenhancedCompoundPKSubclass extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(UnenhancedCompoundPKFieldAccessSuperclass.class,
-            UnenhancedCompoundPKFieldAccessSubclass.class, CLEAR_TABLES);
-    }
-
-    public void testCompoundPKFieldAccessUserDefined() {
-        UnenhancedCompoundPKFieldAccessSuperclass un =
-            new UnenhancedCompoundPKFieldAccessSubclass(17, 31);
-        UnenhancedCompoundPKFieldAccessSuperclass.PK oid =
-            new UnenhancedCompoundPKFieldAccessSuperclass.PK(17, 31);
-        compoundPKHelper(un, oid, true);
-    }
-
-    public void testCompoundPKFieldAccessOpenJPADefined() {
-        UnenhancedCompoundPKFieldAccessSuperclass un =
-            new UnenhancedCompoundPKFieldAccessSubclass(17, 31);
-        UnenhancedCompoundPKFieldAccessSuperclass.PK oid =
-            new UnenhancedCompoundPKFieldAccessSuperclass.PK(17, 31);
-        compoundPKHelper(un, oid, false);
-    }
-
-    private void compoundPKHelper(Object o, Object oid, boolean userDefined) {
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-
-        if (!userDefined) {
-            em.close();
-            em = emf.createEntityManager();
-        }
-
-        em.find(o.getClass(), oid);
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestUnenhancedCompoundPKSubclass extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(UnenhancedCompoundPKFieldAccessSuperclass.class,
+            UnenhancedCompoundPKFieldAccessSubclass.class, CLEAR_TABLES);
+    }
+
+    public void testCompoundPKFieldAccessUserDefined() {
+        UnenhancedCompoundPKFieldAccessSuperclass un =
+            new UnenhancedCompoundPKFieldAccessSubclass(17, 31);
+        UnenhancedCompoundPKFieldAccessSuperclass.PK oid =
+            new UnenhancedCompoundPKFieldAccessSuperclass.PK(17, 31);
+        compoundPKHelper(un, oid, true);
+    }
+
+    public void testCompoundPKFieldAccessOpenJPADefined() {
+        UnenhancedCompoundPKFieldAccessSuperclass un =
+            new UnenhancedCompoundPKFieldAccessSubclass(17, 31);
+        UnenhancedCompoundPKFieldAccessSuperclass.PK oid =
+            new UnenhancedCompoundPKFieldAccessSuperclass.PK(17, 31);
+        compoundPKHelper(un, oid, false);
+    }
+
+    private void compoundPKHelper(Object o, Object oid, boolean userDefined) {
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+
+        if (!userDefined) {
+            em.close();
+            em = emf.createEntityManager();
+        }
+
+        em.find(o.getClass(), oid);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccess.java
index b3a2b25..1e69bf9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccess.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-public class TestUnenhancedFieldAccess
-    extends AbstractUnenhancedClassTest {
-
-    protected Class<? extends UnenhancedType> getUnenhancedClass() {
-        return UnenhancedFieldAccess.class;
-    }
-
-    protected UnenhancedType newUnenhancedInstance() {
-        return new UnenhancedFieldAccess();
-    }
-
-    protected Class<? extends UnenhancedSubtype> getUnenhancedSubclass() {
-        return UnenhancedFieldAccessSubclass.class;
-    }
-
-    protected UnenhancedSubtype newUnenhancedSubclassInstance() {
-        return new UnenhancedFieldAccessSubclass();
-    }
-
-    protected boolean isFieldAccessTest() {
-        return true;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+public class TestUnenhancedFieldAccess
+    extends AbstractUnenhancedClassTest {
+
+    protected Class<? extends UnenhancedType> getUnenhancedClass() {
+        return UnenhancedFieldAccess.class;
+    }
+
+    protected UnenhancedType newUnenhancedInstance() {
+        return new UnenhancedFieldAccess();
+    }
+
+    protected Class<? extends UnenhancedSubtype> getUnenhancedSubclass() {
+        return UnenhancedFieldAccessSubclass.class;
+    }
+
+    protected UnenhancedSubtype newUnenhancedSubclassInstance() {
+        return new UnenhancedFieldAccessSubclass();
+    }
+
+    protected boolean isFieldAccessTest() {
+        return true;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccessPrimitiveWrapper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccessPrimitiveWrapper.java
index 616f34b..01b3294 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccessPrimitiveWrapper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedFieldAccessPrimitiveWrapper.java
@@ -1,42 +1,42 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-public class TestUnenhancedFieldAccessPrimitiveWrapper
-    extends AbstractUnenhancedClassTest {
-
-    protected Class<? extends UnenhancedType> getUnenhancedClass() {
-        return UnenhancedFieldAccessPrimitiveWrapper.class;
-    }
-
-    protected UnenhancedType newUnenhancedInstance() {
-        return new UnenhancedFieldAccessPrimitiveWrapper();
-    }
-
-    protected Class<? extends UnenhancedSubtype> getUnenhancedSubclass() {
-        return UnenhancedFieldAccessPrimitiveWrapperSubclass.class;
-    }
-
-    protected UnenhancedSubtype newUnenhancedSubclassInstance() {
-        return new UnenhancedFieldAccessPrimitiveWrapperSubclass();
-    }
-
-    protected boolean isFieldAccessTest() {
-        return true;
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+public class TestUnenhancedFieldAccessPrimitiveWrapper
+    extends AbstractUnenhancedClassTest {
+
+    protected Class<? extends UnenhancedType> getUnenhancedClass() {
+        return UnenhancedFieldAccessPrimitiveWrapper.class;
+    }
+
+    protected UnenhancedType newUnenhancedInstance() {
+        return new UnenhancedFieldAccessPrimitiveWrapper();
+    }
+
+    protected Class<? extends UnenhancedSubtype> getUnenhancedSubclass() {
+        return UnenhancedFieldAccessPrimitiveWrapperSubclass.class;
+    }
+
+    protected UnenhancedSubtype newUnenhancedSubclassInstance() {
+        return new UnenhancedFieldAccessPrimitiveWrapperSubclass();
+    }
+
+    protected boolean isFieldAccessTest() {
+        return true;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedOneToMany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedOneToMany.java
index 9db55d1..116ed50 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedOneToMany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedOneToMany.java
@@ -1,118 +1,118 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.lang.reflect.Proxy;
-import java.util.Collection;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestUnenhancedOneToMany extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(UnenhancedOne.class, UnenhancedMany.class, CLEAR_TABLES);
-    }
-
-    public void testOneToMany() throws Exception {
-        assertFalse(PersistenceCapable.class.isAssignableFrom(
-            UnenhancedOne.class));
-        assertFalse(PersistenceCapable.class.isAssignableFrom(
-            UnenhancedMany.class));
-
-        em.getTransaction().begin();
-
-        UnenhancedOne one = new UnenhancedOne(1000);
-
-        UnenhancedMany manyA = new UnenhancedMany(1);
-        one.getMany().add(manyA);
-        manyA.setOne(one);
-
-        UnenhancedMany manyB = new UnenhancedMany(2);
-        one.getMany().add(manyB);
-        manyB.setOne(one);
-
-        UnenhancedMany manyC = new UnenhancedMany(3);
-        one.getMany().add(manyC);
-        manyC.setOne(one);
-
-        // em should not know about our entities
-        assertFalse(em.contains(one));
-        assertFalse(em.contains(manyA));
-        assertFalse(em.contains(manyB));
-        assertFalse(em.contains(manyC));
-
-        // persist the entity
-        em.persist(one);
-        em.persist(manyA);
-        em.persist(manyB);
-        em.persist(manyC);
-        em.flush();
-
-        // em should now be aware of our entity
-        assertTrue(em.contains(one));
-        assertTrue(em.contains(manyA));
-        assertTrue(em.contains(manyB));
-        assertTrue(em.contains(manyC));
-
-        em.getTransaction().commit();
-
-        // recreate entity manager to avoid caching
-        one = null;
-        manyA = null;
-        manyB = null;
-        manyC = null;
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        // reload one
-        one = em.find(UnenhancedOne.class, 1000);
-        assertNotNull("one is null", one);
-
-        // verify one.getMany(); ensure that it's a dynamic proxy before
-        // it is accessed
-        assertTrue(Proxy.isProxyClass(one.many.getClass()));
-        assertNotNull("one.getMany() is null", one.getMany());
-        Collection<UnenhancedMany> many = one.getMany();
-        assertEquals(3, many.size());
-
-        // reload the many
-        manyA = em.find(UnenhancedMany.class, 1);
-        assertNotNull("manyA is null", manyA);
-        manyB = em.find(UnenhancedMany.class, 2);
-        assertNotNull("manyB is null", manyA);
-        manyC = em.find(UnenhancedMany.class, 3);
-        assertNotNull("manyc is null", manyA);
-
-        // verify many.getOne()
-        assertNotNull("manyA.getOne() is null", manyA.getOne());
-        assertEquals(one, manyA.getOne());
-        assertNotNull("manyB.getOne() is null", manyB.getOne());
-        assertEquals(one, manyB.getOne());
-        assertNotNull("manyC.getOne() is null", manyC.getOne());
-        assertEquals(one, manyC.getOne());
-
-        // verify collection contains each many
-        assertTrue(many.contains(manyA));
-        assertTrue(many.contains(manyB));
-        assertTrue(many.contains(manyC));
-
-        em.getTransaction().commit();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.lang.reflect.Proxy;
+import java.util.Collection;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestUnenhancedOneToMany extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(UnenhancedOne.class, UnenhancedMany.class, CLEAR_TABLES);
+    }
+
+    public void testOneToMany() throws Exception {
+        assertFalse(PersistenceCapable.class.isAssignableFrom(
+            UnenhancedOne.class));
+        assertFalse(PersistenceCapable.class.isAssignableFrom(
+            UnenhancedMany.class));
+
+        em.getTransaction().begin();
+
+        UnenhancedOne one = new UnenhancedOne(1000);
+
+        UnenhancedMany manyA = new UnenhancedMany(1);
+        one.getMany().add(manyA);
+        manyA.setOne(one);
+
+        UnenhancedMany manyB = new UnenhancedMany(2);
+        one.getMany().add(manyB);
+        manyB.setOne(one);
+
+        UnenhancedMany manyC = new UnenhancedMany(3);
+        one.getMany().add(manyC);
+        manyC.setOne(one);
+
+        // em should not know about our entities
+        assertFalse(em.contains(one));
+        assertFalse(em.contains(manyA));
+        assertFalse(em.contains(manyB));
+        assertFalse(em.contains(manyC));
+
+        // persist the entity
+        em.persist(one);
+        em.persist(manyA);
+        em.persist(manyB);
+        em.persist(manyC);
+        em.flush();
+
+        // em should now be aware of our entity
+        assertTrue(em.contains(one));
+        assertTrue(em.contains(manyA));
+        assertTrue(em.contains(manyB));
+        assertTrue(em.contains(manyC));
+
+        em.getTransaction().commit();
+
+        // recreate entity manager to avoid caching
+        one = null;
+        manyA = null;
+        manyB = null;
+        manyC = null;
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        // reload one
+        one = em.find(UnenhancedOne.class, 1000);
+        assertNotNull("one is null", one);
+
+        // verify one.getMany(); ensure that it's a dynamic proxy before
+        // it is accessed
+        assertTrue(Proxy.isProxyClass(one.many.getClass()));
+        assertNotNull("one.getMany() is null", one.getMany());
+        Collection<UnenhancedMany> many = one.getMany();
+        assertEquals(3, many.size());
+
+        // reload the many
+        manyA = em.find(UnenhancedMany.class, 1);
+        assertNotNull("manyA is null", manyA);
+        manyB = em.find(UnenhancedMany.class, 2);
+        assertNotNull("manyB is null", manyA);
+        manyC = em.find(UnenhancedMany.class, 3);
+        assertNotNull("manyc is null", manyA);
+
+        // verify many.getOne()
+        assertNotNull("manyA.getOne() is null", manyA.getOne());
+        assertEquals(one, manyA.getOne());
+        assertNotNull("manyB.getOne() is null", manyB.getOne());
+        assertEquals(one, manyB.getOne());
+        assertNotNull("manyC.getOne() is null", manyC.getOne());
+        assertEquals(one, manyC.getOne());
+
+        // verify collection contains each many
+        assertTrue(many.contains(manyA));
+        assertTrue(many.contains(manyB));
+        assertTrue(many.contains(manyC));
+
+        em.getTransaction().commit();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedPropertyAccess.java
index d8618d1..638018e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestUnenhancedPropertyAccess.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-public class TestUnenhancedPropertyAccess
-    extends AbstractUnenhancedClassTest {
-
-    protected Class<? extends UnenhancedType> getUnenhancedClass() {
-        return UnenhancedPropertyAccess.class;
-    }
-
-    protected UnenhancedType newUnenhancedInstance() {
-        return new UnenhancedPropertyAccess();
-    }
-
-    protected Class<? extends UnenhancedSubtype> getUnenhancedSubclass() {
-        return UnenhancedPropertyAccessSubclass.class;
-    }
-
-    protected UnenhancedSubtype newUnenhancedSubclassInstance() {
-        return new UnenhancedPropertyAccessSubclass();
-    }
-
-    protected boolean isFieldAccessTest() {
-        return false;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+public class TestUnenhancedPropertyAccess
+    extends AbstractUnenhancedClassTest {
+
+    protected Class<? extends UnenhancedType> getUnenhancedClass() {
+        return UnenhancedPropertyAccess.class;
+    }
+
+    protected UnenhancedType newUnenhancedInstance() {
+        return new UnenhancedPropertyAccess();
+    }
+
+    protected Class<? extends UnenhancedSubtype> getUnenhancedSubclass() {
+        return UnenhancedPropertyAccessSubclass.class;
+    }
+
+    protected UnenhancedSubtype newUnenhancedSubclassInstance() {
+        return new UnenhancedPropertyAccessSubclass();
+    }
+
+    protected boolean isFieldAccessTest() {
+        return false;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance.java
index 95a0e4a..130d788 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class UnenhancedBootstrapInstance {
-    @Id
-    private int id;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class UnenhancedBootstrapInstance {
+    @Id
+    private int id;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance2.java
index 3db77b8..287c5e3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedBootstrapInstance2.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class UnenhancedBootstrapInstance2 {
-    @Id
-    private int id;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class UnenhancedBootstrapInstance2 {
+    @Id
+    private int id;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccess.java
index 35d23c2..33298a5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccess.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.IdClass;
-import javax.persistence.Id;
-
-import org.apache.openjpa.enhance.UnenhancedCompoundPKFieldAccess.PK;
-
-@Entity
-@IdClass(PK.class)
-public class UnenhancedCompoundPKFieldAccess {
-
-    @Id private int id0;
-    @Id private int id1;
-
-    protected UnenhancedCompoundPKFieldAccess() {
-    }
-
-    public UnenhancedCompoundPKFieldAccess(
-        int i0, int i1) {
-        id0 = i0;
-        id1 = i1;
-    }
-
-    public static class PK {
-        static {
-            // register persistent class in JVM
-            try {
-                Class.forName(UnenhancedCompoundPKFieldAccess.class.getName());
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-
-        public int id0;
-        public int id1;
-
-        public PK() {
-        }
-
-        public PK(int i0, int i1) {
-            id0 = i0;
-            id1 = i1;
-        }
-
-        public String toString() {
-            return String.valueOf(id0)
-                + "::" + String.valueOf(id1);
-        }
-
-        public int hashCode() {
-            int rs = 17;
-            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
-            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
-            return rs;
-        }
-
-        public boolean equals(Object obj) {
-            if(this == obj)
-                return true;
-            if(obj == null || obj.getClass() != getClass())
-                return false;
-
-            PK other = (PK) obj;
-            return (id0 == other.id0)
-                && (id1 == other.id1);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.IdClass;
+import javax.persistence.Id;
+
+import org.apache.openjpa.enhance.UnenhancedCompoundPKFieldAccess.PK;
+
+@Entity
+@IdClass(PK.class)
+public class UnenhancedCompoundPKFieldAccess {
+
+    @Id private int id0;
+    @Id private int id1;
+
+    protected UnenhancedCompoundPKFieldAccess() {
+    }
+
+    public UnenhancedCompoundPKFieldAccess(
+        int i0, int i1) {
+        id0 = i0;
+        id1 = i1;
+    }
+
+    public static class PK {
+        static {
+            // register persistent class in JVM
+            try {
+                Class.forName(UnenhancedCompoundPKFieldAccess.class.getName());
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        public int id0;
+        public int id1;
+
+        public PK() {
+        }
+
+        public PK(int i0, int i1) {
+            id0 = i0;
+            id1 = i1;
+        }
+
+        public String toString() {
+            return String.valueOf(id0)
+                + "::" + String.valueOf(id1);
+        }
+
+        public int hashCode() {
+            int rs = 17;
+            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
+            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
+            return rs;
+        }
+
+        public boolean equals(Object obj) {
+            if(this == obj)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+
+            PK other = (PK) obj;
+            return (id0 == other.id0)
+                && (id1 == other.id1);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSubclass.java
index d1b007f..f79a4c9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSubclass.java
@@ -1,34 +1,34 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.IdClass;
-
-@Entity
-@IdClass(UnenhancedCompoundPKFieldAccessSubclass.PK.class)
-public class UnenhancedCompoundPKFieldAccessSubclass
-    extends UnenhancedCompoundPKFieldAccessSuperclass {
-
-    public UnenhancedCompoundPKFieldAccessSubclass() {
-    }
-
-    public UnenhancedCompoundPKFieldAccessSubclass(int i0, int i1) {
-        super(i0, i1);
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.IdClass;
+
+@Entity
+@IdClass(UnenhancedCompoundPKFieldAccessSubclass.PK.class)
+public class UnenhancedCompoundPKFieldAccessSubclass
+    extends UnenhancedCompoundPKFieldAccessSuperclass {
+
+    public UnenhancedCompoundPKFieldAccessSubclass() {
+    }
+
+    public UnenhancedCompoundPKFieldAccessSubclass(int i0, int i1) {
+        super(i0, i1);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSuperclass.java
index a791c05..0b10141 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSuperclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKFieldAccessSuperclass.java
@@ -1,88 +1,88 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.MappedSuperclass;
-
-@MappedSuperclass
-@IdClass(UnenhancedCompoundPKFieldAccessSuperclass.PK.class)
-public class UnenhancedCompoundPKFieldAccessSuperclass {
-
-    @Id
-    private int id0;
-    @Id
-    private int id1;
-
-    protected UnenhancedCompoundPKFieldAccessSuperclass() {
-    }
-
-    public UnenhancedCompoundPKFieldAccessSuperclass(int i0, int i1) {
-        id0 = i0;
-        id1 = i1;
-    }
-
-    public static class PK {
-
-        static {
-            // register persistent class in JVM
-            try {
-                Class.forName(
-                    UnenhancedCompoundPKFieldAccessSuperclass.class.getName());
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-
-        public int id0;
-        public int id1;
-
-        public PK() {
-        }
-
-        public PK(int i0, int i1) {
-            id0 = i0;
-            id1 = i1;
-        }
-
-        public String toString() {
-            return String.valueOf(id0)
-                + "::" + String.valueOf(id1);
-        }
-
-        public int hashCode() {
-            int rs = 17;
-            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
-            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
-            return rs;
-        }
-
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (obj == null || obj.getClass() != getClass())
-                return false;
-
-            UnenhancedCompoundPKFieldAccessSuperclass.PK other =
-                (UnenhancedCompoundPKFieldAccessSuperclass.PK) obj;
-            return (id0 == other.id0)
-                && (id1 == other.id1);
-        }
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.MappedSuperclass;
+
+@MappedSuperclass
+@IdClass(UnenhancedCompoundPKFieldAccessSuperclass.PK.class)
+public class UnenhancedCompoundPKFieldAccessSuperclass {
+
+    @Id
+    private int id0;
+    @Id
+    private int id1;
+
+    protected UnenhancedCompoundPKFieldAccessSuperclass() {
+    }
+
+    public UnenhancedCompoundPKFieldAccessSuperclass(int i0, int i1) {
+        id0 = i0;
+        id1 = i1;
+    }
+
+    public static class PK {
+
+        static {
+            // register persistent class in JVM
+            try {
+                Class.forName(
+                    UnenhancedCompoundPKFieldAccessSuperclass.class.getName());
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        public int id0;
+        public int id1;
+
+        public PK() {
+        }
+
+        public PK(int i0, int i1) {
+            id0 = i0;
+            id1 = i1;
+        }
+
+        public String toString() {
+            return String.valueOf(id0)
+                + "::" + String.valueOf(id1);
+        }
+
+        public int hashCode() {
+            int rs = 17;
+            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
+            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
+            return rs;
+        }
+
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null || obj.getClass() != getClass())
+                return false;
+
+            UnenhancedCompoundPKFieldAccessSuperclass.PK other =
+                (UnenhancedCompoundPKFieldAccessSuperclass.PK) obj;
+            return (id0 == other.id0)
+                && (id1 == other.id1);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKPropertyAccess.java
index e69da15..03e3391 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedCompoundPKPropertyAccess.java
@@ -1,122 +1,122 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.IdClass;
-import javax.persistence.Id;
-
-import org.apache.openjpa.enhance.UnenhancedCompoundPKPropertyAccess.PK;
-
-@Entity
-@IdClass(PK.class)
-public class UnenhancedCompoundPKPropertyAccess {
-
-    private int id0;
-    private int id1;
-
-    protected UnenhancedCompoundPKPropertyAccess() {
-    }
-
-    public UnenhancedCompoundPKPropertyAccess(
-        int i0, int i1) {
-        id0 = i0;
-        id1 = i1;
-    }
-
-    @Id
-    public int getId0() {
-        return id0;
-    }
-
-    public void setId0(int id0) {
-        this.id0 = id0;
-    }
-
-    @Id
-    public int getId1() {
-        return id1;
-    }
-
-    public void setId1(int id1) {
-        this.id1 = id1;
-    }
-
-    public static class PK {
-        static {
-            // register persistent class in JVM
-            try {
-                Class.forName(
-                    UnenhancedCompoundPKPropertyAccess.class.getName());
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-
-        public int id0;
-        public int id1;
-
-        public PK() {
-        }
-
-        public PK(int i0, int i1) {
-            id0 = i0;
-            id1 = i1;
-        }
-
-        public int getId0() {
-            return id0;
-        }
-
-        public void setId0(int id0) {
-            this.id0 = id0;
-        }
-
-        public int getId1() {
-            return id1;
-        }
-
-        public void setId1(int id1) {
-            this.id1 = id1;
-        }
-
-        public String toString() {
-            return String.valueOf(id0)
-                + "::" + String.valueOf(id1);
-        }
-
-        public int hashCode() {
-            int rs = 17;
-            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
-            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
-            return rs;
-        }
-
-        public boolean equals(Object obj) {
-            if(this == obj)
-                return true;
-            if(obj == null || obj.getClass() != getClass())
-                return false;
-
-            PK other = (PK) obj;
-            return (id0 == other.id0)
-                && (id1 == other.id1);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.IdClass;
+import javax.persistence.Id;
+
+import org.apache.openjpa.enhance.UnenhancedCompoundPKPropertyAccess.PK;
+
+@Entity
+@IdClass(PK.class)
+public class UnenhancedCompoundPKPropertyAccess {
+
+    private int id0;
+    private int id1;
+
+    protected UnenhancedCompoundPKPropertyAccess() {
+    }
+
+    public UnenhancedCompoundPKPropertyAccess(
+        int i0, int i1) {
+        id0 = i0;
+        id1 = i1;
+    }
+
+    @Id
+    public int getId0() {
+        return id0;
+    }
+
+    public void setId0(int id0) {
+        this.id0 = id0;
+    }
+
+    @Id
+    public int getId1() {
+        return id1;
+    }
+
+    public void setId1(int id1) {
+        this.id1 = id1;
+    }
+
+    public static class PK {
+        static {
+            // register persistent class in JVM
+            try {
+                Class.forName(
+                    UnenhancedCompoundPKPropertyAccess.class.getName());
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        public int id0;
+        public int id1;
+
+        public PK() {
+        }
+
+        public PK(int i0, int i1) {
+            id0 = i0;
+            id1 = i1;
+        }
+
+        public int getId0() {
+            return id0;
+        }
+
+        public void setId0(int id0) {
+            this.id0 = id0;
+        }
+
+        public int getId1() {
+            return id1;
+        }
+
+        public void setId1(int id1) {
+            this.id1 = id1;
+        }
+
+        public String toString() {
+            return String.valueOf(id0)
+                + "::" + String.valueOf(id1);
+        }
+
+        public int hashCode() {
+            int rs = 17;
+            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
+            rs = rs * 37 + (int) (id0 ^ (id1 >>> 32));
+            return rs;
+        }
+
+        public boolean equals(Object obj) {
+            if(this == obj)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+
+            PK other = (PK) obj;
+            return (id0 == other.id0)
+                && (id1 == other.id1);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccess.java
index a8894f6..acfbaa2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccess.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-import javax.persistence.Version;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
-import javax.persistence.Basic;
-import javax.persistence.FetchType;
-
-import org.apache.openjpa.persistence.DetachedState;
-
-@Entity
-@Table(name="UN_FIELD")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class UnenhancedFieldAccess
-    implements UnenhancedType, Serializable, Cloneable {
-    
-    @Id @GeneratedValue private int id;
-    @Version public int version;
-    protected String stringField = "foo";
-
-    @Basic(fetch = FetchType.LAZY)
-    private String lazyField = "lazy";
-
-    public int getId() {
-        return id;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public String getLazyField() {
-        return lazyField;
-    }
-
-    public boolean equals(Object o) {
-        if (o == this)
-            return true;
-        if (o == null)
-            return false;
-        if (!getClass().isAssignableFrom(o.getClass()))
-            return false;
-
-        return id == ((UnenhancedFieldAccess) o).id;
-    }
-
-    public int hashCode() {
-        return id;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Version;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Basic;
+import javax.persistence.FetchType;
+
+import org.apache.openjpa.persistence.DetachedState;
+
+@Entity
+@Table(name="UN_FIELD")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class UnenhancedFieldAccess
+    implements UnenhancedType, Serializable, Cloneable {
+    
+    @Id @GeneratedValue private int id;
+    @Version public int version;
+    protected String stringField = "foo";
+
+    @Basic(fetch = FetchType.LAZY)
+    private String lazyField = "lazy";
+
+    public int getId() {
+        return id;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public String getLazyField() {
+        return lazyField;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (!getClass().isAssignableFrom(o.getClass()))
+            return false;
+
+        return id == ((UnenhancedFieldAccess) o).id;
+    }
+
+    public int hashCode() {
+        return id;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapper.java
index d7d799f..31c009a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapper.java
@@ -1,81 +1,81 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name = "UN_FIELD_WRAP")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class UnenhancedFieldAccessPrimitiveWrapper
-    implements UnenhancedType, Serializable, Cloneable {
-
-    @Id
-    @GeneratedValue
-    private Integer id;
-    @Version
-    public int version;
-    protected String stringField = "foo";
-
-    @Basic(fetch = FetchType.LAZY)
-    private String lazyField = "lazy";
-
-    public int getId() {
-        return id == null ? -1 : id;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public String getLazyField() {
-        return lazyField;
-    }
-
-    public boolean equals(Object o) {
-        if (o == this)
-            return true;
-        if (o == null)
-            return false;
-        if (!getClass().isAssignableFrom(o.getClass()))
-            return false;
-
-        return id == ((UnenhancedFieldAccessPrimitiveWrapper) o).id;
-    }
-
-    public int hashCode() {
-        return id == null ? 0 : id;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "UN_FIELD_WRAP")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class UnenhancedFieldAccessPrimitiveWrapper
+    implements UnenhancedType, Serializable, Cloneable {
+
+    @Id
+    @GeneratedValue
+    private Integer id;
+    @Version
+    public int version;
+    protected String stringField = "foo";
+
+    @Basic(fetch = FetchType.LAZY)
+    private String lazyField = "lazy";
+
+    public int getId() {
+        return id == null ? -1 : id;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public String getLazyField() {
+        return lazyField;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (!getClass().isAssignableFrom(o.getClass()))
+            return false;
+
+        return id == ((UnenhancedFieldAccessPrimitiveWrapper) o).id;
+    }
+
+    public int hashCode() {
+        return id == null ? 0 : id;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapperSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapperSubclass.java
index f5125fc..d8780d0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapperSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessPrimitiveWrapperSubclass.java
@@ -1,55 +1,55 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-
-@Entity
-public class UnenhancedFieldAccessPrimitiveWrapperSubclass
-    extends UnenhancedFieldAccessPrimitiveWrapper
-    implements UnenhancedSubtype {
-
-    @OneToOne(cascade = CascadeType.ALL)
-    private UnenhancedFieldAccessPrimitiveWrapper related;
-    private int intField;
-
-    public UnenhancedType getRelated() {
-        return related;
-    }
-
-    public void setRelated(UnenhancedType related) {
-        this.related = (UnenhancedFieldAccessPrimitiveWrapper) related;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        UnenhancedFieldAccessPrimitiveWrapperSubclass un =
-            (UnenhancedFieldAccessPrimitiveWrapperSubclass) super.clone();
-        un.setRelated((UnenhancedType) getRelated().clone());
-        return un;
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+
+@Entity
+public class UnenhancedFieldAccessPrimitiveWrapperSubclass
+    extends UnenhancedFieldAccessPrimitiveWrapper
+    implements UnenhancedSubtype {
+
+    @OneToOne(cascade = CascadeType.ALL)
+    private UnenhancedFieldAccessPrimitiveWrapper related;
+    private int intField;
+
+    public UnenhancedType getRelated() {
+        return related;
+    }
+
+    public void setRelated(UnenhancedType related) {
+        this.related = (UnenhancedFieldAccessPrimitiveWrapper) related;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        UnenhancedFieldAccessPrimitiveWrapperSubclass un =
+            (UnenhancedFieldAccessPrimitiveWrapperSubclass) super.clone();
+        un.setRelated((UnenhancedType) getRelated().clone());
+        return un;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessSubclass.java
index 26e8ee3..ac928a6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedFieldAccessSubclass.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.OneToOne;
-import javax.persistence.Entity;
-import javax.persistence.CascadeType;
-
-@Entity
-public class UnenhancedFieldAccessSubclass
-    extends UnenhancedFieldAccess 
-    implements UnenhancedSubtype {
-
-    @OneToOne(cascade = CascadeType.ALL)
-    private UnenhancedFieldAccess related;
-    private int intField;
-
-    public UnenhancedType getRelated() {
-        return related;
-    }
-
-    public void setRelated(UnenhancedType related) {
-        this.related = (UnenhancedFieldAccess) related;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        UnenhancedFieldAccessSubclass un =
-            (UnenhancedFieldAccessSubclass) super.clone();
-        un.setRelated((UnenhancedType) getRelated().clone());
-        return un;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.OneToOne;
+import javax.persistence.Entity;
+import javax.persistence.CascadeType;
+
+@Entity
+public class UnenhancedFieldAccessSubclass
+    extends UnenhancedFieldAccess 
+    implements UnenhancedSubtype {
+
+    @OneToOne(cascade = CascadeType.ALL)
+    private UnenhancedFieldAccess related;
+    private int intField;
+
+    public UnenhancedType getRelated() {
+        return related;
+    }
+
+    public void setRelated(UnenhancedType related) {
+        this.related = (UnenhancedFieldAccess) related;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        UnenhancedFieldAccessSubclass un =
+            (UnenhancedFieldAccessSubclass) super.clone();
+        un.setRelated((UnenhancedType) getRelated().clone());
+        return un;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedIdentityIdPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedIdentityIdPropertyAccess.java
index c1088af..1044e0f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedIdentityIdPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedIdentityIdPropertyAccess.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.PrePersist;
-
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-@Entity
-public class UnenhancedIdentityIdPropertyAccess {
-
-    private int id;
-    private String stringField;
-
-    public UnenhancedIdentityIdPropertyAccess() {
-    }
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PrePersist;
+
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+@Entity
+public class UnenhancedIdentityIdPropertyAccess {
+
+    private int id;
+    private String stringField;
+
+    public UnenhancedIdentityIdPropertyAccess() {
+    }
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedMany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedMany.java
index 9b2b052..f034ac9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedMany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedMany.java
@@ -1,69 +1,69 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import java.io.Serializable;
-
-@Entity
-public class UnenhancedMany implements Serializable, Cloneable {
-    private static final long serialVersionUID = 4041356744771116705L;
-
-    @Id
-    private int id;
-
-    @ManyToOne
-    private UnenhancedOne one;
-
-    public UnenhancedMany() {
-    }
-
-    public UnenhancedMany(int id) {
-        this.id = id;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public UnenhancedOne getOne() {
-        return one;
-    }
-
-    public void setOne(UnenhancedOne one) {
-        this.one = one;
-    }
-
-    public boolean equals(Object o) {
-        if (o == this) return true;
-        if (o == null) return false;
-        if (!getClass().isAssignableFrom(o.getClass())) return false;
-
-        return id == ((UnenhancedMany) o).id;
-    }
-
-    public int hashCode() {
-        return id;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import java.io.Serializable;
+
+@Entity
+public class UnenhancedMany implements Serializable, Cloneable {
+    private static final long serialVersionUID = 4041356744771116705L;
+
+    @Id
+    private int id;
+
+    @ManyToOne
+    private UnenhancedOne one;
+
+    public UnenhancedMany() {
+    }
+
+    public UnenhancedMany(int id) {
+        this.id = id;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public UnenhancedOne getOne() {
+        return one;
+    }
+
+    public void setOne(UnenhancedOne one) {
+        this.one = one;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (o == null) return false;
+        if (!getClass().isAssignableFrom(o.getClass())) return false;
+
+        return id == ((UnenhancedMany) o).id;
+    }
+
+    public int hashCode() {
+        return id;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedOne.java
index a964445..a8bdbce 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedOne.java
@@ -1,67 +1,67 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-
-@Entity
-public class UnenhancedOne implements Serializable, Cloneable {
-    private static final long serialVersionUID = -5834998517804641711L;
-
-    @Id
-    private int id;
-
-    @OneToMany
-    Collection<UnenhancedMany> many = new HashSet<UnenhancedMany>();
-
-    public UnenhancedOne() {
-    }
-
-    public UnenhancedOne(int id) {
-        this.id = id;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public Collection<UnenhancedMany> getMany() {
-        return many;
-    }
-
-    public boolean equals(Object o) {
-        if (o == this) return true;
-        if (o == null) return false;
-        if (!getClass().isAssignableFrom(o.getClass())) return false;
-
-        return id == ((UnenhancedOne) o).id;
-    }
-
-    public int hashCode() {
-        return id;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+
+@Entity
+public class UnenhancedOne implements Serializable, Cloneable {
+    private static final long serialVersionUID = -5834998517804641711L;
+
+    @Id
+    private int id;
+
+    @OneToMany
+    Collection<UnenhancedMany> many = new HashSet<UnenhancedMany>();
+
+    public UnenhancedOne() {
+    }
+
+    public UnenhancedOne(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public Collection<UnenhancedMany> getMany() {
+        return many;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (o == null) return false;
+        if (!getClass().isAssignableFrom(o.getClass())) return false;
+
+        return id == ((UnenhancedOne) o).id;
+    }
+
+    public int hashCode() {
+        return id;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPObject.java
index 4812fbf..027e973 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPObject.java
@@ -1,25 +1,25 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-
-@Entity
-public class UnenhancedPObject {
-
-}
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+
+@Entity
+public class UnenhancedPObject {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccess.java
index dc0de4b..22efc08 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccess.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-import javax.persistence.Version;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Basic;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
-import javax.persistence.FetchType;
-
-@Entity
-@Table(name="UN_PROP")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class UnenhancedPropertyAccess
-    implements UnenhancedType, Serializable, Cloneable {
-
-    private int id;
-    private int version;
-    private String sf = "foo";
-    private String lazyField = "lazy";
-
-    @Id @GeneratedValue
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    @Version
-    protected int getVersion() {
-        return version;
-    }
-
-    protected void setVersion(int v) {
-        version = v;
-    }
-
-    @Basic
-    public String getStringField() {
-        return sf;
-    }
-
-    public void setStringField(String s) {
-        sf = s;
-    }
-
-    @Basic(fetch = FetchType.LAZY)
-    public String getLazyField() {
-        return lazyField;
-    }
-
-    public void setLazyField(String s) {
-        lazyField = s;
-    }
-
-    public boolean equals(Object o) {
-        if (o == this)
-            return true;
-        if (o == null)
-            return false;
-        if (!getClass().isAssignableFrom(o.getClass()))
-            return false;
-
-        return getId() == ((UnenhancedPropertyAccess) o).getId();
-    }
-
-    public int hashCode() {
-        return getId();
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Version;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Basic;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.FetchType;
+
+@Entity
+@Table(name="UN_PROP")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class UnenhancedPropertyAccess
+    implements UnenhancedType, Serializable, Cloneable {
+
+    private int id;
+    private int version;
+    private String sf = "foo";
+    private String lazyField = "lazy";
+
+    @Id @GeneratedValue
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    @Version
+    protected int getVersion() {
+        return version;
+    }
+
+    protected void setVersion(int v) {
+        version = v;
+    }
+
+    @Basic
+    public String getStringField() {
+        return sf;
+    }
+
+    public void setStringField(String s) {
+        sf = s;
+    }
+
+    @Basic(fetch = FetchType.LAZY)
+    public String getLazyField() {
+        return lazyField;
+    }
+
+    public void setLazyField(String s) {
+        lazyField = s;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (!getClass().isAssignableFrom(o.getClass()))
+            return false;
+
+        return getId() == ((UnenhancedPropertyAccess) o).getId();
+    }
+
+    public int hashCode() {
+        return getId();
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccessSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccessSubclass.java
index 72b464b..de4cfa3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccessSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedPropertyAccessSubclass.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.OneToOne;
-import javax.persistence.Transient;
-import javax.persistence.Entity;
-import javax.persistence.CascadeType;
-
-import org.apache.openjpa.persistence.Type;
-
-@Entity
-public class UnenhancedPropertyAccessSubclass
-    extends UnenhancedPropertyAccess
-    implements UnenhancedSubtype {
-
-    private UnenhancedPropertyAccess related;
-    private int intField;
-
-    @OneToOne(cascade = CascadeType.ALL)
-    @Type(UnenhancedPropertyAccess.class)
-    public UnenhancedType getRelated() {
-        return related;
-    }
-
-    public void setRelated(UnenhancedType related) {
-        this.related = (UnenhancedPropertyAccess) related;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        UnenhancedPropertyAccessSubclass un =
-            (UnenhancedPropertyAccessSubclass) super.clone();
-        un.setRelated((UnenhancedType) getRelated().clone());
-        return un;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.OneToOne;
+import javax.persistence.Transient;
+import javax.persistence.Entity;
+import javax.persistence.CascadeType;
+
+import org.apache.openjpa.persistence.Type;
+
+@Entity
+public class UnenhancedPropertyAccessSubclass
+    extends UnenhancedPropertyAccess
+    implements UnenhancedSubtype {
+
+    private UnenhancedPropertyAccess related;
+    private int intField;
+
+    @OneToOne(cascade = CascadeType.ALL)
+    @Type(UnenhancedPropertyAccess.class)
+    public UnenhancedType getRelated() {
+        return related;
+    }
+
+    public void setRelated(UnenhancedType related) {
+        this.related = (UnenhancedPropertyAccess) related;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public Object clone() throws CloneNotSupportedException {
+        UnenhancedPropertyAccessSubclass un =
+            (UnenhancedPropertyAccessSubclass) super.clone();
+        un.setRelated((UnenhancedType) getRelated().clone());
+        return un;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedSubtype.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedSubtype.java
index 4530db7..79331c7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedSubtype.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedSubtype.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-public interface UnenhancedSubtype
-    extends UnenhancedType {
-
-    UnenhancedType getRelated();
-
-    void setRelated(UnenhancedType related);
-
-    void setIntField(int i);
-
-    int getIntField();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+public interface UnenhancedSubtype
+    extends UnenhancedType {
+
+    UnenhancedType getRelated();
+
+    void setRelated(UnenhancedType related);
+
+    void setIntField(int i);
+
+    int getIntField();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedType.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedType.java
index 707eb31..ef19b8f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedType.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedType.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-/**
- * Used in {@link AbstractUnenhancedClassTest}
- */
-public interface UnenhancedType {
-
-    int getId();
-
-    void setStringField(String s);
-    String getStringField();
-
-    String getLazyField();
-
-    Object clone() throws CloneNotSupportedException;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+/**
+ * Used in {@link AbstractUnenhancedClassTest}
+ */
+public interface UnenhancedType {
+
+    int getId();
+
+    void setStringField(String s);
+    String getStringField();
+
+    String getLazyField();
+
+    Object clone() throws CloneNotSupportedException;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java
index 5ae5e07..5bca64e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class UnenhancedUnlistedClass {
-    @Id
-    private int id;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class UnenhancedUnlistedClass {
+    @Id
+    private int id;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java
index e520fe5..b44ff2f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.enhance;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-
-@Entity
-public class UnenhancedUnlistedReferer {
-    @Id
-    private int id;
-
-    @OneToOne
-    private UnenhancedUnlistedClass other;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+
+@Entity
+public class UnenhancedUnlistedReferer {
+    @Id
+    private int id;
+
+    @OneToOne
+    private UnenhancedUnlistedClass other;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestLifecycleListener.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestLifecycleListener.java
index ece282a..26f6841 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestLifecycleListener.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestLifecycleListener.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-
-public class TestLifecycleListener
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AllFieldTypes.class, CLEAR_TABLES);
-    }
-
-    public void testMutationsInLifecycleListener() {
-        emf.addLifecycleListener(new AbstractLifecycleListener() {
-            @Override
-            public void beforePersist(LifecycleEvent event) {
-                ((AllFieldTypes) event.getSource()).setLongField(17);
-            }
-        }, (Class[]) null);
-
-        AllFieldTypes aft = new AllFieldTypes();
-        aft.setStringField("foo");
-        aft.setIntField(5);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(aft);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        aft = (AllFieldTypes) em.createQuery("select o from AllFieldTypes o")
-            .getSingleResult();
-        // is changed in the listener impl
-        assertEquals(17, aft.getLongField());
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+public class TestLifecycleListener
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AllFieldTypes.class, CLEAR_TABLES);
+    }
+
+    public void testMutationsInLifecycleListener() {
+        emf.addLifecycleListener(new AbstractLifecycleListener() {
+            @Override
+            public void beforePersist(LifecycleEvent event) {
+                ((AllFieldTypes) event.getSource()).setLongField(17);
+            }
+        }, (Class[]) null);
+
+        AllFieldTypes aft = new AllFieldTypes();
+        aft.setStringField("foo");
+        aft.setIntField(5);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(aft);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        aft = (AllFieldTypes) em.createQuery("select o from AllFieldTypes o")
+            .getSingleResult();
+        // is changed in the listener impl
+        assertEquals(17, aft.getLongField());
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestSJVMRemoteCommitProvider.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestSJVMRemoteCommitProvider.java
index 3c9c0c5..d9172f2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestSJVMRemoteCommitProvider.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/event/TestSJVMRemoteCommitProvider.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.event;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Collections;
-import javax.persistence.Persistence;
-
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-public class TestSJVMRemoteCommitProvider
-    extends PersistenceTestCase {
-
-    private OpenJPAEntityManagerFactorySPI emf1;
-    private OpenJPAEntityManagerFactorySPI emf2;
-    private ListenerImpl listen1;
-    private ListenerImpl listen2;
-
-    public void setUp() {
-        Map sjvm1 = new HashMap();
-        sjvm1.put("openjpa.RemoteCommitProvider", "sjvm");
-        // set this to differentiate emf1 from the other emf below
-        sjvm1.put("openjpa.DetachState", "true");
-        emf1 = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
-            Persistence.createEntityManagerFactory("test", sjvm1));
-        emf1.getConfiguration().getRemoteCommitEventManager().addListener(
-            listen1 = new ListenerImpl());
-
-        Map sjvm2 = new HashMap();
-        sjvm2.put("openjpa.RemoteCommitProvider", "sjvm");
-        sjvm2.put("openjpa.DetachState", "false"); // differentiate from above
-        emf2 = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
-            Persistence.createEntityManagerFactory("test", sjvm2));
-        emf2.getConfiguration().getRemoteCommitEventManager().addListener(
-            listen2 = new ListenerImpl());
-    }
-
-    public void testSJVMRemoteCommitProvider() {
-        assertNotSame(JPAFacadeHelper.toBrokerFactory(emf1),
-            JPAFacadeHelper.toBrokerFactory(emf2));
-        
-        emf1.getConfiguration().getRemoteCommitEventManager()
-            .getRemoteCommitProvider().broadcast(
-                new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS,
-                    Collections.EMPTY_SET,
-                    Collections.EMPTY_SET,
-                    Collections.EMPTY_SET,
-                    Collections.EMPTY_SET));
-
-        assertEquals(0, listen1.eventCount);
-        assertEquals(1, listen2.eventCount);
-    }
-
-    private class ListenerImpl
-        implements RemoteCommitListener {
-
-        private int eventCount;
-
-        public void afterCommit(RemoteCommitEvent event) {
-            eventCount++;
-        }
-
-        public void close() {
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.event;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Collections;
+import javax.persistence.Persistence;
+
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+public class TestSJVMRemoteCommitProvider
+    extends PersistenceTestCase {
+
+    private OpenJPAEntityManagerFactorySPI emf1;
+    private OpenJPAEntityManagerFactorySPI emf2;
+    private ListenerImpl listen1;
+    private ListenerImpl listen2;
+
+    public void setUp() {
+        Map sjvm1 = new HashMap();
+        sjvm1.put("openjpa.RemoteCommitProvider", "sjvm");
+        // set this to differentiate emf1 from the other emf below
+        sjvm1.put("openjpa.DetachState", "true");
+        emf1 = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
+            Persistence.createEntityManagerFactory("test", sjvm1));
+        emf1.getConfiguration().getRemoteCommitEventManager().addListener(
+            listen1 = new ListenerImpl());
+
+        Map sjvm2 = new HashMap();
+        sjvm2.put("openjpa.RemoteCommitProvider", "sjvm");
+        sjvm2.put("openjpa.DetachState", "false"); // differentiate from above
+        emf2 = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
+            Persistence.createEntityManagerFactory("test", sjvm2));
+        emf2.getConfiguration().getRemoteCommitEventManager().addListener(
+            listen2 = new ListenerImpl());
+    }
+
+    public void testSJVMRemoteCommitProvider() {
+        assertNotSame(JPAFacadeHelper.toBrokerFactory(emf1),
+            JPAFacadeHelper.toBrokerFactory(emf2));
+        
+        emf1.getConfiguration().getRemoteCommitEventManager()
+            .getRemoteCommitProvider().broadcast(
+                new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS,
+                    Collections.EMPTY_SET,
+                    Collections.EMPTY_SET,
+                    Collections.EMPTY_SET,
+                    Collections.EMPTY_SET));
+
+        assertEquals(0, listen1.eventCount);
+        assertEquals(1, listen2.eventCount);
+    }
+
+    private class ListenerImpl
+        implements RemoteCommitListener {
+
+        private int eventCount;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            eventCount++;
+        }
+
+        public void close() {
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityA.java
index 5003166..77ed718 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityA.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.OneToOne;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-
-@Entity
-public class EntityA {
-
-    @Id
-    @Column(name = "entitya_id", nullable = false)
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Integer id;
-
-    private String name;
-
-    @OneToOne(cascade = CascadeType.ALL, optional = false)
-    @JoinColumn(name = "entityb_id", referencedColumnName = "entityb_id",
-        nullable = false)
-    @ForeignKey
-    private EntityB entityB;
-
-    @Version
-    private Integer optLock;
-
-    public EntityA() {
-    }
-
-    public void setId(Integer id) {
-        this.id = id;
-    }
-
-    public Integer getId() {
-        return id;
-    }
-
-    public EntityB getEntityB() {
-        return this.entityB;
-    }
-
-    public void setEntityB(EntityB entityB) {
-        this.entityB = entityB;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+
+@Entity
+public class EntityA {
+
+    @Id
+    @Column(name = "entitya_id", nullable = false)
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String name;
+
+    @OneToOne(cascade = CascadeType.ALL, optional = false)
+    @JoinColumn(name = "entityb_id", referencedColumnName = "entityb_id",
+        nullable = false)
+    @ForeignKey
+    private EntityB entityB;
+
+    @Version
+    private Integer optLock;
+
+    public EntityA() {
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public EntityB getEntityB() {
+        return this.entityB;
+    }
+
+    public void setEntityB(EntityB entityB) {
+        this.entityB = entityB;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityB.java
index a4087f2..0c9f869 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityB.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.OneToOne;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-
-@Entity
-public class EntityB {
-
-    @Id
-    @Column(name = "entityb_id", nullable = false)
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Integer id;
-
-    private String name;
-
-    @OneToOne(cascade = CascadeType.ALL, optional = false)
-    @JoinColumn(name = "entityc_id", referencedColumnName = "entityc_id",
-        nullable = false)
-    @ForeignKey
-    private EntityC entityC;
-
-    @Version
-    private Integer optLock;
-
-    public EntityB() {
-    }
-
-    public void setId(Integer id) {
-        this.id = id;
-    }
-
-    public Integer getId() {
-        return id;
-    }
-
-    public EntityC getEntityC() {
-        return this.entityC;
-    }
-
-    public void setEntityC(EntityC entityC) {
-        this.entityC = entityC;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+
+@Entity
+public class EntityB {
+
+    @Id
+    @Column(name = "entityb_id", nullable = false)
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String name;
+
+    @OneToOne(cascade = CascadeType.ALL, optional = false)
+    @JoinColumn(name = "entityc_id", referencedColumnName = "entityc_id",
+        nullable = false)
+    @ForeignKey
+    private EntityC entityC;
+
+    @Version
+    private Integer optLock;
+
+    public EntityB() {
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public EntityC getEntityC() {
+        return this.entityC;
+    }
+
+    public void setEntityC(EntityC entityC) {
+        this.entityC = entityC;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityC.java
index 03c85b4..36e7328 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityC.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.OneToOne;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.Dependent;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-
-@Entity
-public class EntityC {
-
-    @Id
-    @Column(name = "entityc_id", nullable = false)
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Integer id;
-
-    private String name;
-
-    @OneToOne(cascade = CascadeType.ALL, optional = false)
-    @JoinColumn(name = "entityd_id", referencedColumnName = "entityd_id",
-        nullable = false)
-    @ForeignKey
-    @Dependent
-    private EntityD entityD;
-
-    @Version
-    private Integer optLock;
-
-    public EntityC() {
-    }
-
-    public void setId(Integer id) {
-        this.id = id;
-    }
-
-    public Integer getId() {
-        return id;
-    }
-
-    public EntityD getEntityD() {
-        return this.entityD;
-    }
-
-    public void setEntityD(EntityD entityD) {
-        this.entityD = entityD;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.Dependent;
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+
+@Entity
+public class EntityC {
+
+    @Id
+    @Column(name = "entityc_id", nullable = false)
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String name;
+
+    @OneToOne(cascade = CascadeType.ALL, optional = false)
+    @JoinColumn(name = "entityd_id", referencedColumnName = "entityd_id",
+        nullable = false)
+    @ForeignKey
+    @Dependent
+    private EntityD entityD;
+
+    @Version
+    private Integer optLock;
+
+    public EntityC() {
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public EntityD getEntityD() {
+        return this.entityD;
+    }
+
+    public void setEntityD(EntityD entityD) {
+        this.entityD = entityD;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityD.java
index d321dd2..7239aac 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityD.java
@@ -1,90 +1,90 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Version;
-import javax.persistence.OneToOne;
-import javax.persistence.JoinColumn;
-
-@Entity
-public class EntityD {
-
-    @Id
-    @Column(name = "entityd_id", nullable = false)
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Integer id;
-
-    private String name;
-
-    @OneToOne
-    @JoinColumn(name = "entitya_id", referencedColumnName = "entitya_id")
-    @ForeignKey
-    private EntityA entityA;
-    
-    @OneToOne
-    @JoinColumn(name = "entityb_id", referencedColumnName = "entityb_id")
-    @ForeignKey
-    private EntityB entityB;
-    
-    @Version
-    private Integer optLock;
-
-    public EntityD() {
-    }
-
-    public void setId(Integer id) {
-        this.id = id;
-    }
-
-    public Integer getId() {
-        return id;
-    }
-
-    public EntityA getEntityA() {
-        return this.entityA;
-    }
-
-    public void setEntityA(EntityA entityA) {
-        this.entityA = entityA;
-    }
-
-    public EntityB getEntityB() {
-        return entityB;
-    }
-
-    public void setEntityB(EntityB entityB) {
-        this.entityB = entityB;
-    }
-    
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Version;
+import javax.persistence.OneToOne;
+import javax.persistence.JoinColumn;
+
+@Entity
+public class EntityD {
+
+    @Id
+    @Column(name = "entityd_id", nullable = false)
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String name;
+
+    @OneToOne
+    @JoinColumn(name = "entitya_id", referencedColumnName = "entitya_id")
+    @ForeignKey
+    private EntityA entityA;
+    
+    @OneToOne
+    @JoinColumn(name = "entityb_id", referencedColumnName = "entityb_id")
+    @ForeignKey
+    private EntityB entityB;
+    
+    @Version
+    private Integer optLock;
+
+    public EntityD() {
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public EntityA getEntityA() {
+        return this.entityA;
+    }
+
+    public void setEntityA(EntityA entityA) {
+        this.entityA = entityA;
+    }
+
+    public EntityB getEntityB() {
+        return entityB;
+    }
+
+    public void setEntityB(EntityB entityB) {
+        this.entityB = entityB;
+    }
+    
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityF.java
index 72d589f..7888c89 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityF.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-import java.util.List;
-
-import javax.persistence.*;
-
-@Entity
-public class EntityF  {
-	@Id private int id;
-
-	@OneToMany(cascade=CascadeType.ALL, mappedBy="entityF")
-	private List<EntityG> listG;
-	
-	public List<EntityG> getListG() {
-		return listG;
-	}
-	public void setListG(List<EntityG> listG) {
-		this.listG = listG;
-	}
-	public int getId() {
-		return id;
-	}
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+public class EntityF  {
+	@Id private int id;
+
+	@OneToMany(cascade=CascadeType.ALL, mappedBy="entityF")
+	private List<EntityG> listG;
+	
+	public List<EntityG> getListG() {
+		return listG;
+	}
+	public void setListG(List<EntityG> listG) {
+		this.listG = listG;
+	}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityG.java
index c547dd0..38750bf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/EntityG.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
-
-@Entity
-public class EntityG  {
-	@Id private int id;
-
-	@ForeignKey(deleteAction=ForeignKeyAction.CASCADE)
-	@ManyToOne (cascade=CascadeType.MERGE)	
-	private EntityF entityF;
-	
-	public EntityF getEntityF() {
-		return entityF;
-	}
-	public void setEntityF(EntityF entityF) {
-		this.entityF = entityF;
-	}
-	public int getId() {
-		return id;
-	}
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+
+@Entity
+public class EntityG  {
+	@Id private int id;
+
+	@ForeignKey(deleteAction=ForeignKeyAction.CASCADE)
+	@ManyToOne (cascade=CascadeType.MERGE)	
+	private EntityF entityF;
+	
+	public EntityF getEntityF() {
+		return entityF;
+	}
+	public void setEntityF(EntityF entityF) {
+		this.entityF = entityF;
+	}
+	public int getId() {
+		return id;
+	}
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestNoForeignKeyViolation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestNoForeignKeyViolation.java
index 5dfc8c3..2b24115 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestNoForeignKeyViolation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestNoForeignKeyViolation.java
@@ -1,211 +1,211 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.jdbc.kernel;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test that sql statements get flushed in an order which does not violate
- * non-nullable foreign key constraints on inserts and deletes.
- *
- * @author Reece Garrett
- */
-public class TestNoForeignKeyViolation
-    extends SingleEMFTestCase {
-
-    private EntityA entityA;
-    private EntityB entityB;
-    private EntityC entityC;
-    private EntityD entityD;
-
-    public void setUp() {
-        setUp(EntityA.class, EntityB.class, EntityC.class, EntityD.class, 
-              EntityE.class, EntityF.class, EntityG.class);
-
-        createTestData();
-    }
-
-    private void createTestData() {
-        entityA = new EntityA();
-        entityB = new EntityB();
-        entityC = new EntityC();
-        entityD = new EntityD();
-        entityA.setName("entityA");
-        entityB.setName("entityB");
-        entityC.setName("entityC");
-        entityD.setName("entityD");
-        entityA.setEntityB(entityB);
-        entityB.setEntityC(entityC);
-        entityC.setEntityD(entityD);
-    }
-
-    public void testSqlOrder() {
-        EntityManager em = emf.createEntityManager();
-        try {
-            em.getTransaction().begin();
-            em.persist(entityA);
-            em.getTransaction().commit();
-
-            EntityD newEntityD = new EntityD();
-            newEntityD.setName("newEntityD");
-            entityC.setEntityD(newEntityD);
-
-            em.getTransaction().begin();
-            em.merge(entityC);
-            em.getTransaction().commit();
-
-            EntityC newEntityC = new EntityC();
-            newEntityC.setName("newEntityC");
-            newEntityD = new EntityD();
-            newEntityD.setName("newNewEntityD");
-            newEntityC.setEntityD(newEntityD);
-            entityB.setEntityC(newEntityC);
-
-            em.getTransaction().begin();
-            em.merge(entityB);
-            em.getTransaction().commit();
-        }
-        finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            em.close();
-        }
-    }
-    
-    public void testSimpleCycle() {
-        EntityManager em = emf.createEntityManager();
-        try {
-            em.getTransaction().begin();
-            entityD.setEntityA(entityA);
-            em.persist(entityA);
-            em.getTransaction().commit();
-        }
-        finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            em.close();
-        }
-    }
-    
-    public void testComplexCycle() {
-        EntityManager em = emf.createEntityManager();
-        try {
-            EntityE entityE = new EntityE();
-            entityE.setName("entityE");
-            entityE.setEntityB(entityB);
-
-            em.getTransaction().begin();
-            em.persist(entityE);
-            entityD.setEntityA(entityA);
-            em.persist(entityA);
-            em.getTransaction().commit();
-            
-            em.getTransaction().begin();
-            em.remove(entityE);
-            em.remove(entityA);
-            em.getTransaction().commit();
-        }
-        finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            em.close();
-        }
-    }
-
-    public void testComplexTwoCycles() {
-        EntityManager em = emf.createEntityManager();
-        try {
-            EntityE entityE = new EntityE();
-            entityE.setName("entityE");
-            entityE.setEntityB(entityB);
-
-            em.getTransaction().begin();
-            em.persist(entityE);
-            entityD.setEntityA(entityA);
-            entityD.setEntityB(entityB);
-            em.persist(entityA);
-            em.getTransaction().commit();
-            
-            em.getTransaction().begin();
-            em.remove(entityE);
-            em.remove(entityA);
-            em.getTransaction().commit();
-        }
-        finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            em.close();
-        }
-    }
-    
-    public void testForeignKeyCascade() {
-        EntityManager em = emf.createEntityManager();
-        try {
-            EntityF f = new EntityF();
-            f.setId(1);
-
-            List<EntityG> listG = new ArrayList<EntityG>();
-            EntityG g1 = new EntityG();
-            g1.setId(1);
-            listG.add(g1);
-            g1.setEntityF(f);
-            
-            EntityG g2 = new EntityG();
-            g2.setId(2);
-            listG.add(g2);
-            g2.setEntityF(f);
-
-            EntityG g3 = new EntityG();
-            g3.setId(3);
-            listG.add(g3);
-            g3.setEntityF(f);
-
-            EntityG g4 = new EntityG();
-            g4.setId(4);
-            listG.add(g4);
-            g4.setEntityF(f);
-            
-            f.setListG(listG);
-            em.getTransaction().begin();
-            em.persist(f);
-            em.persist(g1);
-            em.persist(g2);
-            em.persist(g3);
-            em.persist(g4);
-            em.getTransaction().commit();
-
-            em.getTransaction().begin();
-            em.remove(f);
-            em.getTransaction().commit();
-        }
-        catch (Exception e) {
-            fail("Fail to delete EntityF");
-        }
-        finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            em.close();
-        }
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test that sql statements get flushed in an order which does not violate
+ * non-nullable foreign key constraints on inserts and deletes.
+ *
+ * @author Reece Garrett
+ */
+public class TestNoForeignKeyViolation
+    extends SingleEMFTestCase {
+
+    private EntityA entityA;
+    private EntityB entityB;
+    private EntityC entityC;
+    private EntityD entityD;
+
+    public void setUp() {
+        setUp(EntityA.class, EntityB.class, EntityC.class, EntityD.class, 
+              EntityE.class, EntityF.class, EntityG.class);
+
+        createTestData();
+    }
+
+    private void createTestData() {
+        entityA = new EntityA();
+        entityB = new EntityB();
+        entityC = new EntityC();
+        entityD = new EntityD();
+        entityA.setName("entityA");
+        entityB.setName("entityB");
+        entityC.setName("entityC");
+        entityD.setName("entityD");
+        entityA.setEntityB(entityB);
+        entityB.setEntityC(entityC);
+        entityC.setEntityD(entityD);
+    }
+
+    public void testSqlOrder() {
+        EntityManager em = emf.createEntityManager();
+        try {
+            em.getTransaction().begin();
+            em.persist(entityA);
+            em.getTransaction().commit();
+
+            EntityD newEntityD = new EntityD();
+            newEntityD.setName("newEntityD");
+            entityC.setEntityD(newEntityD);
+
+            em.getTransaction().begin();
+            em.merge(entityC);
+            em.getTransaction().commit();
+
+            EntityC newEntityC = new EntityC();
+            newEntityC.setName("newEntityC");
+            newEntityD = new EntityD();
+            newEntityD.setName("newNewEntityD");
+            newEntityC.setEntityD(newEntityD);
+            entityB.setEntityC(newEntityC);
+
+            em.getTransaction().begin();
+            em.merge(entityB);
+            em.getTransaction().commit();
+        }
+        finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+    
+    public void testSimpleCycle() {
+        EntityManager em = emf.createEntityManager();
+        try {
+            em.getTransaction().begin();
+            entityD.setEntityA(entityA);
+            em.persist(entityA);
+            em.getTransaction().commit();
+        }
+        finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+    
+    public void testComplexCycle() {
+        EntityManager em = emf.createEntityManager();
+        try {
+            EntityE entityE = new EntityE();
+            entityE.setName("entityE");
+            entityE.setEntityB(entityB);
+
+            em.getTransaction().begin();
+            em.persist(entityE);
+            entityD.setEntityA(entityA);
+            em.persist(entityA);
+            em.getTransaction().commit();
+            
+            em.getTransaction().begin();
+            em.remove(entityE);
+            em.remove(entityA);
+            em.getTransaction().commit();
+        }
+        finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testComplexTwoCycles() {
+        EntityManager em = emf.createEntityManager();
+        try {
+            EntityE entityE = new EntityE();
+            entityE.setName("entityE");
+            entityE.setEntityB(entityB);
+
+            em.getTransaction().begin();
+            em.persist(entityE);
+            entityD.setEntityA(entityA);
+            entityD.setEntityB(entityB);
+            em.persist(entityA);
+            em.getTransaction().commit();
+            
+            em.getTransaction().begin();
+            em.remove(entityE);
+            em.remove(entityA);
+            em.getTransaction().commit();
+        }
+        finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+    
+    public void testForeignKeyCascade() {
+        EntityManager em = emf.createEntityManager();
+        try {
+            EntityF f = new EntityF();
+            f.setId(1);
+
+            List<EntityG> listG = new ArrayList<EntityG>();
+            EntityG g1 = new EntityG();
+            g1.setId(1);
+            listG.add(g1);
+            g1.setEntityF(f);
+            
+            EntityG g2 = new EntityG();
+            g2.setId(2);
+            listG.add(g2);
+            g2.setEntityF(f);
+
+            EntityG g3 = new EntityG();
+            g3.setId(3);
+            listG.add(g3);
+            g3.setEntityF(f);
+
+            EntityG g4 = new EntityG();
+            g4.setId(4);
+            listG.add(g4);
+            g4.setEntityF(f);
+            
+            f.setListG(listG);
+            em.getTransaction().begin();
+            em.persist(f);
+            em.persist(g1);
+            em.persist(g2);
+            em.persist(g3);
+            em.persist(g4);
+            em.getTransaction().commit();
+
+            em.getTransaction().begin();
+            em.remove(f);
+            em.getTransaction().commit();
+        }
+        catch (Exception e) {
+            fail("Fail to delete EntityF");
+        }
+        finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/AbstractLobTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/AbstractLobTest.java
index 0745dfd..01cab7f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/AbstractLobTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/AbstractLobTest.java
@@ -1,286 +1,286 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.IOException;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.datacache.DataCachePCData;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.jdbc.sql.MySQLDictionary;
-import org.apache.openjpa.jdbc.sql.OracleDictionary;
-import org.apache.openjpa.jdbc.sql.PostgresDictionary;
-import org.apache.openjpa.jdbc.sql.SQLServerDictionary;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * This abstract class defines all the tests for LOBS.
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-public abstract class AbstractLobTest extends SingleEMFTestCase {
-
-    public void setUp() throws Exception {
-        super.setUp(getLobEntityClass(), CLEAR_TABLES,
-            "openjpa.DataCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm");
-    }
-
-    public boolean isDatabaseSupported() {
-        DBDictionary dict = ((JDBCConfiguration) emf.getConfiguration())
-            .getDBDictionaryInstance();
-        if (dict instanceof MySQLDictionary ||
-            dict instanceof SQLServerDictionary ||
-            dict instanceof OracleDictionary ||
-            dict instanceof PostgresDictionary) {
-            return true;
-        }
-        return false;
-    }
-
-    public void insert(LobEntity le) {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(le);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testInsert() {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity("oOOOOOo", 1));
-    }
-
-    public void testInsertAndSelect() throws IOException {
-        if (!isDatabaseSupported()) return;
-        String s = "oooOOOooo";
-        insert(newLobEntity(s, 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        Query query = em.createQuery(getSelectQuery());
-        LobEntity entity = (LobEntity) query.getSingleResult();
-        assertNotNull(entity.getStream());
-        assertEquals(s, getStreamContentAsString(entity.getStream()));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testInsertNull() {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity(null, 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity le = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertNull(le.getStream());
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testUpdate() throws IOException {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity("oOOOOOo", 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        String string = "iIIIIIi";
-        changeStream(entity, string);
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertEquals(string, getStreamContentAsString(entity.getStream()));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testUpdateWithNull() {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity("oOOOOOo", 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        entity.setStream(null);
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertNull(entity.getStream());
-        em.getTransaction().commit();
-        em.close();
-    }
-    
-    public void testUpdateANullObjectWithoutNull() throws IOException {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity(null, 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        String string = "iIIIIIi";
-        changeStream(entity, string);
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertEquals(string, getStreamContentAsString(entity.getStream()));
-        em.getTransaction().commit();
-        em.close();
-    }
-    
-    public void testDelete() {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity("oOOOOOo", 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        em.remove(entity);
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Query q = em.createQuery(getSelectQuery());
-        assertEquals(0, q.getResultList().size());
-        em.getTransaction().commit();
-        em.close();
-    }
-    
-    public void testLifeCycleInsertFlushModify() {
-        if (!isDatabaseSupported()) return;
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity le = newLobEntity("oOOOOOo", 1);
-        em.persist(le);
-        em.flush();
-        changeStream(le, "iIIIIIi");
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testLifeCycleLoadFlushModifyFlush() {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity("oOOOOOo", 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        em.flush();
-        changeStream(entity, "iIIIIIi");
-        em.flush();
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testReadingMultipleTimesWithASingleConnection()
-        throws IOException {
-        if (!isDatabaseSupported()) return;
-        insert(newLobEntity("oOOOOOo", 1));
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity le = (LobEntity) em.find(getLobEntityClass(), 1);
-        String string = "iIIIIIi";
-        changeStream(le, string);
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        le = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertNotNull(le.getStream());
-        LobEntity entity = newLobEntity("oOOOOOo", 2);
-        em.persist(entity);
-        assertEquals(string, getStreamContentAsString(le.getStream()));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testDataCache() {
-        if (!isDatabaseSupported()) return;
-        OpenJPAEntityManager em = emf.createEntityManager();
-
-        em.getTransaction().begin();
-        LobEntity le = newLobEntity("oOOOOOo", 1);
-        em.persist(le);
-        em.getTransaction().commit();
-        OpenJPAConfiguration conf = emf.getConfiguration();
-        Object o = em.getObjectId(le);
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(le);
-        Object objectId = JPAFacadeHelper.toOpenJPAObjectId(meta, o);
-        DataCachePCData pcd =
-            conf.getDataCacheManagerInstance()
-                .getSystemDataCache().get(objectId);
-        assertFalse(pcd.isLoaded(meta.getField("stream").getIndex()));
-        em.close();
-    }
-
-    public void testSetResetAndFlush() throws IOException {
-        if (!isDatabaseSupported()) return;
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity le = newLobEntity("oOOOOOo", 1);
-        em.persist(le);
-        changeStream(le, "iIIIIIi");
-        em.flush();
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertEquals("iIIIIIi", getStreamContentAsString(entity.getStream()));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testSetFlushAndReset() throws IOException {
-        if (!isDatabaseSupported()) return;
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        LobEntity le = newLobEntity("oOOOOOo", 1);
-        em.persist(le);
-        em.flush();
-        changeStream(le, "iIIIIIi");
-        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
-        assertEquals("iIIIIIi", getStreamContentAsString(entity.getStream()));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    protected abstract Class getLobEntityClass();
-
-    protected abstract String getStreamContentAsString(Object o)
-        throws IOException;
-
-    protected abstract LobEntity newLobEntity(String s, int id);
-
-    protected abstract LobEntity newLobEntityForLoadContent(String s, int id);
-
-    protected abstract String getSelectQuery();
-
-    protected abstract void changeStream(LobEntity le, String s);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.IOException;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.datacache.DataCachePCData;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.MySQLDictionary;
+import org.apache.openjpa.jdbc.sql.OracleDictionary;
+import org.apache.openjpa.jdbc.sql.PostgresDictionary;
+import org.apache.openjpa.jdbc.sql.SQLServerDictionary;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * This abstract class defines all the tests for LOBS.
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+public abstract class AbstractLobTest extends SingleEMFTestCase {
+
+    public void setUp() throws Exception {
+        super.setUp(getLobEntityClass(), CLEAR_TABLES,
+            "openjpa.DataCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm");
+    }
+
+    public boolean isDatabaseSupported() {
+        DBDictionary dict = ((JDBCConfiguration) emf.getConfiguration())
+            .getDBDictionaryInstance();
+        if (dict instanceof MySQLDictionary ||
+            dict instanceof SQLServerDictionary ||
+            dict instanceof OracleDictionary ||
+            dict instanceof PostgresDictionary) {
+            return true;
+        }
+        return false;
+    }
+
+    public void insert(LobEntity le) {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(le);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testInsert() {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity("oOOOOOo", 1));
+    }
+
+    public void testInsertAndSelect() throws IOException {
+        if (!isDatabaseSupported()) return;
+        String s = "oooOOOooo";
+        insert(newLobEntity(s, 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        Query query = em.createQuery(getSelectQuery());
+        LobEntity entity = (LobEntity) query.getSingleResult();
+        assertNotNull(entity.getStream());
+        assertEquals(s, getStreamContentAsString(entity.getStream()));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testInsertNull() {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity(null, 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity le = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertNull(le.getStream());
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testUpdate() throws IOException {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity("oOOOOOo", 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        String string = "iIIIIIi";
+        changeStream(entity, string);
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertEquals(string, getStreamContentAsString(entity.getStream()));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testUpdateWithNull() {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity("oOOOOOo", 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        entity.setStream(null);
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertNull(entity.getStream());
+        em.getTransaction().commit();
+        em.close();
+    }
+    
+    public void testUpdateANullObjectWithoutNull() throws IOException {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity(null, 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        String string = "iIIIIIi";
+        changeStream(entity, string);
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertEquals(string, getStreamContentAsString(entity.getStream()));
+        em.getTransaction().commit();
+        em.close();
+    }
+    
+    public void testDelete() {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity("oOOOOOo", 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        em.remove(entity);
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query q = em.createQuery(getSelectQuery());
+        assertEquals(0, q.getResultList().size());
+        em.getTransaction().commit();
+        em.close();
+    }
+    
+    public void testLifeCycleInsertFlushModify() {
+        if (!isDatabaseSupported()) return;
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity le = newLobEntity("oOOOOOo", 1);
+        em.persist(le);
+        em.flush();
+        changeStream(le, "iIIIIIi");
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testLifeCycleLoadFlushModifyFlush() {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity("oOOOOOo", 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        em.flush();
+        changeStream(entity, "iIIIIIi");
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testReadingMultipleTimesWithASingleConnection()
+        throws IOException {
+        if (!isDatabaseSupported()) return;
+        insert(newLobEntity("oOOOOOo", 1));
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity le = (LobEntity) em.find(getLobEntityClass(), 1);
+        String string = "iIIIIIi";
+        changeStream(le, string);
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        le = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertNotNull(le.getStream());
+        LobEntity entity = newLobEntity("oOOOOOo", 2);
+        em.persist(entity);
+        assertEquals(string, getStreamContentAsString(le.getStream()));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testDataCache() {
+        if (!isDatabaseSupported()) return;
+        OpenJPAEntityManager em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        LobEntity le = newLobEntity("oOOOOOo", 1);
+        em.persist(le);
+        em.getTransaction().commit();
+        OpenJPAConfiguration conf = emf.getConfiguration();
+        Object o = em.getObjectId(le);
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(le);
+        Object objectId = JPAFacadeHelper.toOpenJPAObjectId(meta, o);
+        DataCachePCData pcd =
+            conf.getDataCacheManagerInstance()
+                .getSystemDataCache().get(objectId);
+        assertFalse(pcd.isLoaded(meta.getField("stream").getIndex()));
+        em.close();
+    }
+
+    public void testSetResetAndFlush() throws IOException {
+        if (!isDatabaseSupported()) return;
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity le = newLobEntity("oOOOOOo", 1);
+        em.persist(le);
+        changeStream(le, "iIIIIIi");
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertEquals("iIIIIIi", getStreamContentAsString(entity.getStream()));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testSetFlushAndReset() throws IOException {
+        if (!isDatabaseSupported()) return;
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        LobEntity le = newLobEntity("oOOOOOo", 1);
+        em.persist(le);
+        em.flush();
+        changeStream(le, "iIIIIIi");
+        LobEntity entity = (LobEntity) em.find(getLobEntityClass(), 1);
+        assertEquals("iIIIIIi", getStreamContentAsString(entity.getStream()));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    protected abstract Class getLobEntityClass();
+
+    protected abstract String getStreamContentAsString(Object o)
+        throws IOException;
+
+    protected abstract LobEntity newLobEntity(String s, int id);
+
+    protected abstract LobEntity newLobEntityForLoadContent(String s, int id);
+
+    protected abstract String getSelectQuery();
+
+    protected abstract void changeStream(LobEntity le, String s);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobEntity.java
index 5321f90..a546d39 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobEntity.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.InputStream;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.Persistent;
-
-/**
- * An entity with an InputStream.
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-@Entity
-public class InputStreamLobEntity implements LobEntity {
-
-    @Id
-    private int id;
-
-    @Persistent
-    private InputStream stream;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public Object getStream() {
-        return stream;
-    }
-
-    public void setStream(Object o) {
-        stream = (InputStream) o;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.InputStream;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.Persistent;
+
+/**
+ * An entity with an InputStream.
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+@Entity
+public class InputStreamLobEntity implements LobEntity {
+
+    @Id
+    private int id;
+
+    @Persistent
+    private InputStream stream;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public Object getStream() {
+        return stream;
+    }
+
+    public void setStream(Object o) {
+        stream = (InputStream) o;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobTest.java
index 3f91be6..486f23f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamLobTest.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Defines all the abstract methods from AbstractLobTest to tests the
- * the LOB support with an InputStream.
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-public class InputStreamLobTest extends AbstractLobTest {
-
-    protected LobEntity newLobEntity(String s, int id) {
-        InputStreamLobEntity isle = new InputStreamLobEntity();
-        isle.setId(id);
-        if (s != null) {
-            isle.setStream(new ByteArrayInputStream(s.getBytes()));
-        } else {
-            isle.setStream(null);
-        }
-        return isle;
-    }
-
-    protected LobEntity newLobEntityForLoadContent(String s, int id) {
-        InputStreamLobEntity isle = new InputStreamLobEntity();
-        isle.setId(id);
-        isle.setStream(new InputStreamWrapper(s));
-        return isle;
-    }
-
-    protected Class getLobEntityClass() {
-        return InputStreamLobEntity.class;
-    }
-
-    protected String getSelectQuery() {
-        return "SELECT o FROM InputStreamLobEntity o";
-    }
-
-    protected String getStreamContentAsString(Object o) throws IOException {
-        InputStream is = (InputStream) o;
-        String content = "";
-        byte[] bs = new byte[4];
-        int read = -1;
-        do {
-            read = is.read(bs);
-            if (read == -1) {
-                return content;
-            }
-            content = content + (new String(bs)).substring(0, read);
-        } while (true);
-    }
-
-    protected void changeStream(LobEntity le, String s) {
-        le.setStream(new ByteArrayInputStream(s.getBytes()));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Defines all the abstract methods from AbstractLobTest to tests the
+ * the LOB support with an InputStream.
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+public class InputStreamLobTest extends AbstractLobTest {
+
+    protected LobEntity newLobEntity(String s, int id) {
+        InputStreamLobEntity isle = new InputStreamLobEntity();
+        isle.setId(id);
+        if (s != null) {
+            isle.setStream(new ByteArrayInputStream(s.getBytes()));
+        } else {
+            isle.setStream(null);
+        }
+        return isle;
+    }
+
+    protected LobEntity newLobEntityForLoadContent(String s, int id) {
+        InputStreamLobEntity isle = new InputStreamLobEntity();
+        isle.setId(id);
+        isle.setStream(new InputStreamWrapper(s));
+        return isle;
+    }
+
+    protected Class getLobEntityClass() {
+        return InputStreamLobEntity.class;
+    }
+
+    protected String getSelectQuery() {
+        return "SELECT o FROM InputStreamLobEntity o";
+    }
+
+    protected String getStreamContentAsString(Object o) throws IOException {
+        InputStream is = (InputStream) o;
+        String content = "";
+        byte[] bs = new byte[4];
+        int read = -1;
+        do {
+            read = is.read(bs);
+            if (read == -1) {
+                return content;
+            }
+            content = content + (new String(bs)).substring(0, read);
+        } while (true);
+    }
+
+    protected void changeStream(LobEntity le, String s) {
+        le.setStream(new ByteArrayInputStream(s.getBytes()));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamWrapper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamWrapper.java
index c728ddb..8cd9dd9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamWrapper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/InputStreamWrapper.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class is used to kwon where the content of the InputStream is load.
- * If the content is load out of the flush then throws a
- * UnsupportedOperationException
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-public class InputStreamWrapper extends InputStream {
-
-    private InputStream is;
-
-    public InputStreamWrapper(String s) {
-        this.is = new ByteArrayInputStream(s.getBytes());
-    }
-
-    public int read() throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    public int available() throws IOException {
-        return is.available();
-    }
-
-    public void close() throws IOException {
-        is.close();
-    }
-
-    public int read(byte[] b, int off, int len) throws IOException {
-        StackTraceElement[] ste = Thread.currentThread().getStackTrace();
-        for (StackTraceElement element : ste) {
-            if ("flush".equals(element.getMethodName())) {
-                return is.read(b, off, len);
-            }
-        }
-        throw new UnsupportedOperationException();
-    }
-
-    public int read(byte[] b) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This class is used to kwon where the content of the InputStream is load.
+ * If the content is load out of the flush then throws a
+ * UnsupportedOperationException
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+public class InputStreamWrapper extends InputStream {
+
+    private InputStream is;
+
+    public InputStreamWrapper(String s) {
+        this.is = new ByteArrayInputStream(s.getBytes());
+    }
+
+    public int read() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    public int available() throws IOException {
+        return is.available();
+    }
+
+    public void close() throws IOException {
+        is.close();
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        StackTraceElement[] ste = Thread.currentThread().getStackTrace();
+        for (StackTraceElement element : ste) {
+            if ("flush".equals(element.getMethodName())) {
+                return is.read(b, off, len);
+            }
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    public int read(byte[] b) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/LobEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/LobEntity.java
index 0ffb1df..57e9838 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/LobEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/LobEntity.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-package org.apache.openjpa.jdbc.meta.strats;
-
-/**
- * Defines the methods for the entities
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-public interface LobEntity {
-
-    public void setStream(Object o);
-
-    public void setId(int id);
-
-    public Object getStream();
-
-    public int getId();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.jdbc.meta.strats;
+
+/**
+ * Defines the methods for the entities
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+public interface LobEntity {
+
+    public void setStream(Object o);
+
+    public void setId(int id);
+
+    public Object getStream();
+
+    public int getId();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobEntity.java
index 64adc29..769b541 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobEntity.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.Reader;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.Persistent;
-
-/**
- * An entity with a Reader field.
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-@Entity
-public class ReaderLobEntity implements LobEntity {
-
-    @Id
-    private int id;
-
-    @Persistent
-    private Reader stream;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public Object getStream() {
-        return stream;
-    }
-
-    public void setStream(Object o) {
-        this.stream = (Reader) o;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.Reader;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.Persistent;
+
+/**
+ * An entity with a Reader field.
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+@Entity
+public class ReaderLobEntity implements LobEntity {
+
+    @Id
+    private int id;
+
+    @Persistent
+    private Reader stream;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public Object getStream() {
+        return stream;
+    }
+
+    public void setStream(Object o) {
+        this.stream = (Reader) o;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobTest.java
index d2097ed..61a9ee6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderLobTest.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.CharArrayReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * Defines all the abstract methods from AbstractLobTest to tests the
- * the LOB support with a Reader.
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-public class ReaderLobTest extends AbstractLobTest {
-
-    protected LobEntity newLobEntity(String s, int id) {
-        ReaderLobEntity rle = new ReaderLobEntity();
-        rle.setId(id);
-        if (s != null) {
-            rle.setStream(new CharArrayReader(s.toCharArray()));
-        } else {
-            rle.setStream(null);
-        }
-        return rle;
-    }
-
-    protected LobEntity newLobEntityForLoadContent(String s, int id) {
-        ReaderLobEntity rle = new ReaderLobEntity();
-        rle.setId(id);
-        rle.setStream(new ReaderWrapper(s));
-        return rle;
-    }
-
-    protected Class getLobEntityClass() {
-        return ReaderLobEntity.class;
-    }
-
-    protected String getSelectQuery() {
-        return "SELECT o FROM ReaderLobEntity o";
-    }
-
-    protected String getStreamContentAsString(Object o) throws IOException {
-        Reader r = (Reader) o;
-        String content = "";
-        char[] cs = new char[4];
-        int read = -1;
-        do {
-            read = r.read(cs);
-            if (read == -1) {
-                return content;
-            }
-            content = content + (new String(cs)).substring(0, read);
-        } while (true);
-    }
-
-    protected void changeStream(LobEntity le, String s) {
-        le.setStream(new CharArrayReader(s.toCharArray()));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * Defines all the abstract methods from AbstractLobTest to tests the
+ * the LOB support with a Reader.
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+public class ReaderLobTest extends AbstractLobTest {
+
+    protected LobEntity newLobEntity(String s, int id) {
+        ReaderLobEntity rle = new ReaderLobEntity();
+        rle.setId(id);
+        if (s != null) {
+            rle.setStream(new CharArrayReader(s.toCharArray()));
+        } else {
+            rle.setStream(null);
+        }
+        return rle;
+    }
+
+    protected LobEntity newLobEntityForLoadContent(String s, int id) {
+        ReaderLobEntity rle = new ReaderLobEntity();
+        rle.setId(id);
+        rle.setStream(new ReaderWrapper(s));
+        return rle;
+    }
+
+    protected Class getLobEntityClass() {
+        return ReaderLobEntity.class;
+    }
+
+    protected String getSelectQuery() {
+        return "SELECT o FROM ReaderLobEntity o";
+    }
+
+    protected String getStreamContentAsString(Object o) throws IOException {
+        Reader r = (Reader) o;
+        String content = "";
+        char[] cs = new char[4];
+        int read = -1;
+        do {
+            read = r.read(cs);
+            if (read == -1) {
+                return content;
+            }
+            content = content + (new String(cs)).substring(0, read);
+        } while (true);
+    }
+
+    protected void changeStream(LobEntity le, String s) {
+        le.setStream(new CharArrayReader(s.toCharArray()));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderWrapper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderWrapper.java
index 334d02f..e77c4bf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderWrapper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/meta/strats/ReaderWrapper.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.jdbc.meta.strats;
-
-import java.io.CharArrayReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * This class is used to kwon where the content of the Reader is load.
- * If the content is load out of the flush then throws a
- * UnsupportedOperationException
- *
- * @author Ignacio Andreu
- * @since 1.1.0
- */
-
-public class ReaderWrapper extends Reader {
-
-    private Reader reader;
-
-    public ReaderWrapper(String s) {
-        this.reader = new CharArrayReader(s.toCharArray());
-    }
-
-    public void close() throws IOException {
-        reader.close();
-    }
-
-    public int read(char[] cbuf, int off, int len) throws IOException {
-        StackTraceElement[] ste = Thread.currentThread().getStackTrace();
-        for (StackTraceElement element : ste) {
-            if ("flush".equals(element.getMethodName())) {
-                return reader.read(cbuf, off, len);
-            }
-        }
-        throw new UnsupportedOperationException();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This class is used to kwon where the content of the Reader is load.
+ * If the content is load out of the flush then throws a
+ * UnsupportedOperationException
+ *
+ * @author Ignacio Andreu
+ * @since 1.1.0
+ */
+
+public class ReaderWrapper extends Reader {
+
+    private Reader reader;
+
+    public ReaderWrapper(String s) {
+        this.reader = new CharArrayReader(s.toCharArray());
+    }
+
+    public void close() throws IOException {
+        reader.close();
+    }
+
+    public int read(char[] cbuf, int off, int len) throws IOException {
+        StackTraceElement[] ste = Thread.currentThread().getStackTrace();
+        for (StackTraceElement element : ste) {
+            if ("flush".equals(element.getMethodName())) {
+                return reader.read(cbuf, off, len);
+            }
+        }
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java
index 7d8d44b..ff3e7a7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java
@@ -1,446 +1,446 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.event.AbstractLifecycleListener;
-import org.apache.openjpa.event.AbstractTransactionListener;
-import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.event.TransactionEvent;
-import org.apache.openjpa.persistence.InvalidStateException;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
-import org.apache.openjpa.persistence.jdbc.JoinSyntax;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/*
- * To test:
- *  - managed transactions
- *  - converting non-enhanced classes to enhanced subclasses
- *    (maybe an ugly ThreadLocal, maybe through PCData?)
- */
-public abstract class AbstractBrokerSerializationTest<T>
-    extends SingleEMFTestCase {
-
-    private static LifeListener deserializedLifeListener;
-    private static int testGlobalRefreshCount = 0;
-
-    private static TxListener deserializedTxListener;
-    private static int testGlobalBeginCount = 0;
-
-
-    private Object id;
-
-    public void setUp() {
-        testGlobalRefreshCount = 0;
-        deserializedLifeListener = null;
-        testGlobalBeginCount = 0;
-        deserializedTxListener = null;
-
-        setUp(getManagedType(), getSecondaryType(), CLEAR_TABLES,
-            "openjpa.EntityManagerFactoryPool", "true");
-        
-        T e = newManagedInstance();
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(e);
-        em.getTransaction().commit();
-        id = em.getObjectId(e);
-        em.close();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-        testGlobalRefreshCount = 0;
-        deserializedLifeListener = null;
-        testGlobalBeginCount = 0;
-        deserializedTxListener = null;
-    }
-
-    public void testEmptyBrokerSerialization() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
-
-        assertTrue(em != em2);
-        assertTrue(
-            JPAFacadeHelper.toBroker(em) != JPAFacadeHelper.toBroker(em2));
-        assertSame(em.getEntityManagerFactory(), em2.getEntityManagerFactory());
-
-        assertSame(em2, JPAFacadeHelper.toBroker(em2)
-            .getUserObject(JPAFacadeHelper.EM_KEY));
-
-        em.close();
-        assertTrue(em2.isOpen());
-        em2.close();
-    }
-
-    public void testNontransactionalBrokerSerialization() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        T e = em.find(getManagedType(), id);
-        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
-
-        assertFalse(em2.getTransaction().isActive());
-
-        assertFalse(em2.contains(e));
-        assertEquals(1*graphSize(), em2.getManagedObjects().size());
-        T e2 = em2.find(getManagedType(), id);
-        assertEquals(em.getObjectId(e), em2.getObjectId(e2));
-
-        em.close();
-        em2.close();
-    }
-
-    public void testUnflushedOptimisticTxBrokerSerialization() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        T e = em.find(getManagedType(), id);
-        OpenJPAEntityManager em2 = null;
-        OpenJPAEntityManager em3 = null;
-        try {
-            em.getTransaction().begin();
-            modifyInstance(e);
-            T newe = newManagedInstance();
-            em.persist(newe);
-            em2 = deserializeEM(serialize(em));
-
-            assertTrue(em2.getTransaction().isActive());
-
-            assertFalse(em2.contains(e));
-            T e2 = em2.find(getManagedType(), id);
-            assertEquals(em.getObjectId(e), em2.getObjectId(e2));
-
-            assertEquals("modified", getModifiedValue(e2));
-
-            em.getTransaction().rollback();
-            assertTrue(em2.getTransaction().isActive());
-            em2.getTransaction().commit();
-
-            em3 = emf.createEntityManager();
-            T e3 = em3.find(getManagedType(), id);
-            assertEquals(getModifiedValue(e2), getModifiedValue(e3));
-            assertTrue(1 < ((Number) em3.createQuery("select count(o) from "
-                + getManagedType().getName() + " o").getSingleResult())
-                .intValue());
-        } finally {
-            close(em);
-            close(em2);
-            close(em3);
-        }
-    }
-
-    public void testFlushedOptimisticTxBrokerSerialization() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        T e = em.find(getManagedType(), id);
-        em.getTransaction().begin();
-        modifyInstance(e);
-        em.flush();
-        try {
-            serialize(em);
-        } catch (InvalidStateException ise) {
-            // expected
-            assertTrue(ise.getMessage().contains("flushed"));
-        } finally {
-            em.getTransaction().rollback();
-            em.close();
-        }
-    }
-
-    public void testConnectedOptimisticTxBrokerSerialization() {
-        Map m = new HashMap();
-        m.put("openjpa.ConnectionRetainMode", "always");
-        OpenJPAEntityManager em = emf.createEntityManager(m);
-        try {
-            serialize(em);
-        } catch (InvalidStateException ise) {
-            // expected
-            assertTrue(ise.getMessage().contains("connected"));
-        } finally {
-            em.close();
-        }
-    }
-
-    public void testEmptyPessimisticTxBrokerSerialization() {
-        Map m = new HashMap();
-        m.put("openjpa.Optimistic", "false");
-        OpenJPAEntityManager em = emf.createEntityManager(m);
-        em.getTransaction().begin();
-        try {
-            serialize(em);
-            fail("should not be able to serialize");
-        } catch (InvalidStateException ise) {
-            // expected
-            assertTrue(ise.getMessage().contains("datastore (pessimistic)"));
-        } finally {
-            em.getTransaction().rollback();
-            em.close();
-        }
-    }
-
-    public void testNonEmptyPessimisticTxBrokerSerialization() {
-        Map m = new HashMap();
-        m.put("openjpa.Optimistic", "false");
-        OpenJPAEntityManager em = emf.createEntityManager(m);
-        T e = em.find(getManagedType(), id);
-        em.getTransaction().begin();
-        try {
-            serialize(em);
-            fail("should not be able to serialize");
-        } catch (InvalidStateException ise) {
-            // expected
-            assertTrue(ise.getMessage().contains("datastore (pessimistic)"));
-        } finally {
-            em.getTransaction().rollback();
-            em.close();
-        }
-    }
-
-    public void testFetchConfigurationMutations() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        JDBCFetchPlan plan = (JDBCFetchPlan) em.getFetchPlan();
-
-        assertNotEquals(17, plan.getLockTimeout());
-        assertNotEquals(JoinSyntax.TRADITIONAL, plan.getJoinSyntax());
-
-        plan.setLockTimeout(17);
-        plan.setJoinSyntax(JoinSyntax.TRADITIONAL);
-
-        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
-        JDBCFetchPlan plan2 = (JDBCFetchPlan) em2.getFetchPlan();
-        assertEquals(17, plan2.getLockTimeout());
-        assertEquals(JoinSyntax.TRADITIONAL, plan2.getJoinSyntax());
-    }
-
-    public void testInMemorySavepointsWithNewInstances() {
-        emf.close();
-        OpenJPAEntityManagerFactory emf = createEMF(
-            getManagedType(), getSecondaryType(),
-            "openjpa.EntityManagerFactoryPool", "true",
-            "openjpa.SavepointManager", "in-mem");
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAEntityManager em2 = null;
-        try {
-            em.getTransaction().begin();
-            T t = newManagedInstance();
-            Object orig = getModifiedValue(t);
-            em.persist(t);
-            Object id = em.getObjectId(t);
-            em.setSavepoint("foo");
-            modifyInstance(t);
-            assertNotEquals(orig, getModifiedValue(t));
-
-            em2 = deserializeEM(serialize(em));
-            T t2 = em2.find(getManagedType(), id);
-            assertNotEquals(orig, getModifiedValue(t2));
-
-            em.rollbackToSavepoint("foo");
-            assertEquals(orig, getModifiedValue(t));
-
-            em2.rollbackToSavepoint("foo");
-            assertEquals(orig, getModifiedValue(t2));
-        } finally {
-            close(em);
-            close(em2);
-        }
-    }
-
-    public void testInMemorySavepointsWithModifiedInstances() {
-        emf.close();
-        OpenJPAEntityManagerFactory emf = createEMF(
-            getManagedType(), getSecondaryType(),
-            "openjpa.EntityManagerFactoryPool", "true",
-            "openjpa.SavepointManager", "in-mem");
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAEntityManager em2 = null;
-        try {
-            em.getTransaction().begin();
-            T t = em.find(getManagedType(), id);
-            Object orig = getModifiedValue(t);
-            em.setSavepoint("foo");
-            modifyInstance(t);
-            assertNotEquals(orig, getModifiedValue(t));
-
-            em2 = deserializeEM(serialize(em));
-            T t2 = em2.find(getManagedType(), id);
-            assertNotEquals(orig, getModifiedValue(t2));
-
-            em.rollbackToSavepoint("foo");
-            assertEquals(orig, getModifiedValue(t));
-
-            em2.rollbackToSavepoint("foo");
-            assertEquals(orig, getModifiedValue(t2));
-        } finally {
-            close(em);
-            close(em2);
-        }
-    }
-
-    public void testEventManagers() {
-        TxListener txListener = new TxListener();
-        emf.addTransactionListener(txListener);
-        LifeListener lifeListener = new LifeListener();
-        emf.addLifecycleListener(lifeListener, null);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        T t = em.find(getManagedType(), id);
-        assertEquals(0, lifeListener.refreshCount);
-        em.refresh(t);
-        assertEquals(1*graphSize(), lifeListener.refreshCount);
-        em.getTransaction().begin();
-        em.getTransaction().commit();
-        em.getTransaction().begin();
-        em.getTransaction().commit();
-        assertEquals(2, txListener.beginCount);
-
-        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
-        assertNotNull(deserializedLifeListener);
-        assertEquals(1* graphSize(),
-            deserializedLifeListener.refreshCount);
-        assertNotSame(lifeListener, deserializedLifeListener);
-        T t2 = em2.find(getManagedType(), id);
-        em2.refresh(t2);
-        assertEquals(2* graphSize(),
-            deserializedLifeListener.refreshCount);
-
-        // if this is 3*refreshMultiplier(), that means that there are
-        // extra registered listeners
-        assertEquals(2* graphSize(), testGlobalRefreshCount);
-
-
-        assertNotNull(deserializedTxListener);
-        assertEquals(2, deserializedTxListener.beginCount);
-        assertNotSame(txListener, deserializedTxListener);
-        em2.getTransaction().begin();
-        em2.getTransaction().rollback();
-        assertEquals(3, deserializedTxListener.beginCount);
-
-        // if this is 4, that means that there are extra registered listeners
-        assertEquals(3, testGlobalBeginCount);
-    }
-
-    byte[] serialize(Object o) {
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(o);
-            oos.flush();
-            return baos.toByteArray();
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe);
-        }
-    }
-
-    OpenJPAEntityManager deserializeEM(byte[] bytes) {
-        return (OpenJPAEntityManager) deserialize(bytes);
-    }
-
-    private Object deserialize(byte[] bytes) {
-        try {
-            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-            ObjectInputStream ois = new ObjectInputStream(bais);
-            return ois.readObject();
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe);
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    void close(EntityManager em) {
-        if (em != null && em.isOpen() && em.getTransaction().isActive())
-            em.getTransaction().rollback();
-        if (em != null && em.isOpen())
-            em.close();
-    }
-
-    protected abstract Class<T> getManagedType();
-
-    protected abstract T newManagedInstance();
-
-    protected abstract void modifyInstance(T t);
-
-    protected abstract Object getModifiedValue(T t);
-
-    /**
-     * The number of instances in the graph created
-     * by {@link #newManagedInstance()} of type T.
-     */
-    protected int graphSize() {
-        return 1;
-    }
-
-    /**
-     * An additional type that must be available in this PC. May be null.
-     */
-    protected Class getSecondaryType() {
-        return null;
-    }
-
-    private static class TxListener
-        extends AbstractTransactionListener
-        implements Serializable {
-
-        private int beginCount = 0;
-
-        public TxListener() {
-
-        }
-
-        @Override
-        public void afterBegin(TransactionEvent event) {
-            beginCount++;
-            testGlobalBeginCount++;
-        }
-
-        private void readObject(ObjectInputStream in)
-            throws ClassNotFoundException, IOException {
-            in.defaultReadObject();
-            deserializedTxListener = this;
-        }
-    }
-
-    private static class LifeListener
-        extends AbstractLifecycleListener
-        implements Serializable {
-
-        private int refreshCount = 0;
-
-        @Override
-        public void afterRefresh(LifecycleEvent event) {
-            refreshCount++;
-            testGlobalRefreshCount++;
-        }
-
-        private void readObject(ObjectInputStream in)
-            throws ClassNotFoundException, IOException {
-            in.defaultReadObject();
-            deserializedLifeListener = this;
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.event.AbstractLifecycleListener;
+import org.apache.openjpa.event.AbstractTransactionListener;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.persistence.InvalidStateException;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
+import org.apache.openjpa.persistence.jdbc.JoinSyntax;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/*
+ * To test:
+ *  - managed transactions
+ *  - converting non-enhanced classes to enhanced subclasses
+ *    (maybe an ugly ThreadLocal, maybe through PCData?)
+ */
+public abstract class AbstractBrokerSerializationTest<T>
+    extends SingleEMFTestCase {
+
+    private static LifeListener deserializedLifeListener;
+    private static int testGlobalRefreshCount = 0;
+
+    private static TxListener deserializedTxListener;
+    private static int testGlobalBeginCount = 0;
+
+
+    private Object id;
+
+    public void setUp() {
+        testGlobalRefreshCount = 0;
+        deserializedLifeListener = null;
+        testGlobalBeginCount = 0;
+        deserializedTxListener = null;
+
+        setUp(getManagedType(), getSecondaryType(), CLEAR_TABLES,
+            "openjpa.EntityManagerFactoryPool", "true");
+        
+        T e = newManagedInstance();
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(e);
+        em.getTransaction().commit();
+        id = em.getObjectId(e);
+        em.close();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        testGlobalRefreshCount = 0;
+        deserializedLifeListener = null;
+        testGlobalBeginCount = 0;
+        deserializedTxListener = null;
+    }
+
+    public void testEmptyBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+
+        assertTrue(em != em2);
+        assertTrue(
+            JPAFacadeHelper.toBroker(em) != JPAFacadeHelper.toBroker(em2));
+        assertSame(em.getEntityManagerFactory(), em2.getEntityManagerFactory());
+
+        assertSame(em2, JPAFacadeHelper.toBroker(em2)
+            .getUserObject(JPAFacadeHelper.EM_KEY));
+
+        em.close();
+        assertTrue(em2.isOpen());
+        em2.close();
+    }
+
+    public void testNontransactionalBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T e = em.find(getManagedType(), id);
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+
+        assertFalse(em2.getTransaction().isActive());
+
+        assertFalse(em2.contains(e));
+        assertEquals(1*graphSize(), em2.getManagedObjects().size());
+        T e2 = em2.find(getManagedType(), id);
+        assertEquals(em.getObjectId(e), em2.getObjectId(e2));
+
+        em.close();
+        em2.close();
+    }
+
+    public void testUnflushedOptimisticTxBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T e = em.find(getManagedType(), id);
+        OpenJPAEntityManager em2 = null;
+        OpenJPAEntityManager em3 = null;
+        try {
+            em.getTransaction().begin();
+            modifyInstance(e);
+            T newe = newManagedInstance();
+            em.persist(newe);
+            em2 = deserializeEM(serialize(em));
+
+            assertTrue(em2.getTransaction().isActive());
+
+            assertFalse(em2.contains(e));
+            T e2 = em2.find(getManagedType(), id);
+            assertEquals(em.getObjectId(e), em2.getObjectId(e2));
+
+            assertEquals("modified", getModifiedValue(e2));
+
+            em.getTransaction().rollback();
+            assertTrue(em2.getTransaction().isActive());
+            em2.getTransaction().commit();
+
+            em3 = emf.createEntityManager();
+            T e3 = em3.find(getManagedType(), id);
+            assertEquals(getModifiedValue(e2), getModifiedValue(e3));
+            assertTrue(1 < ((Number) em3.createQuery("select count(o) from "
+                + getManagedType().getName() + " o").getSingleResult())
+                .intValue());
+        } finally {
+            close(em);
+            close(em2);
+            close(em3);
+        }
+    }
+
+    public void testFlushedOptimisticTxBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T e = em.find(getManagedType(), id);
+        em.getTransaction().begin();
+        modifyInstance(e);
+        em.flush();
+        try {
+            serialize(em);
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("flushed"));
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testConnectedOptimisticTxBrokerSerialization() {
+        Map m = new HashMap();
+        m.put("openjpa.ConnectionRetainMode", "always");
+        OpenJPAEntityManager em = emf.createEntityManager(m);
+        try {
+            serialize(em);
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("connected"));
+        } finally {
+            em.close();
+        }
+    }
+
+    public void testEmptyPessimisticTxBrokerSerialization() {
+        Map m = new HashMap();
+        m.put("openjpa.Optimistic", "false");
+        OpenJPAEntityManager em = emf.createEntityManager(m);
+        em.getTransaction().begin();
+        try {
+            serialize(em);
+            fail("should not be able to serialize");
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("datastore (pessimistic)"));
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testNonEmptyPessimisticTxBrokerSerialization() {
+        Map m = new HashMap();
+        m.put("openjpa.Optimistic", "false");
+        OpenJPAEntityManager em = emf.createEntityManager(m);
+        T e = em.find(getManagedType(), id);
+        em.getTransaction().begin();
+        try {
+            serialize(em);
+            fail("should not be able to serialize");
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("datastore (pessimistic)"));
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testFetchConfigurationMutations() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        JDBCFetchPlan plan = (JDBCFetchPlan) em.getFetchPlan();
+
+        assertNotEquals(17, plan.getLockTimeout());
+        assertNotEquals(JoinSyntax.TRADITIONAL, plan.getJoinSyntax());
+
+        plan.setLockTimeout(17);
+        plan.setJoinSyntax(JoinSyntax.TRADITIONAL);
+
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+        JDBCFetchPlan plan2 = (JDBCFetchPlan) em2.getFetchPlan();
+        assertEquals(17, plan2.getLockTimeout());
+        assertEquals(JoinSyntax.TRADITIONAL, plan2.getJoinSyntax());
+    }
+
+    public void testInMemorySavepointsWithNewInstances() {
+        emf.close();
+        OpenJPAEntityManagerFactory emf = createEMF(
+            getManagedType(), getSecondaryType(),
+            "openjpa.EntityManagerFactoryPool", "true",
+            "openjpa.SavepointManager", "in-mem");
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        try {
+            em.getTransaction().begin();
+            T t = newManagedInstance();
+            Object orig = getModifiedValue(t);
+            em.persist(t);
+            Object id = em.getObjectId(t);
+            em.setSavepoint("foo");
+            modifyInstance(t);
+            assertNotEquals(orig, getModifiedValue(t));
+
+            em2 = deserializeEM(serialize(em));
+            T t2 = em2.find(getManagedType(), id);
+            assertNotEquals(orig, getModifiedValue(t2));
+
+            em.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t));
+
+            em2.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t2));
+        } finally {
+            close(em);
+            close(em2);
+        }
+    }
+
+    public void testInMemorySavepointsWithModifiedInstances() {
+        emf.close();
+        OpenJPAEntityManagerFactory emf = createEMF(
+            getManagedType(), getSecondaryType(),
+            "openjpa.EntityManagerFactoryPool", "true",
+            "openjpa.SavepointManager", "in-mem");
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        try {
+            em.getTransaction().begin();
+            T t = em.find(getManagedType(), id);
+            Object orig = getModifiedValue(t);
+            em.setSavepoint("foo");
+            modifyInstance(t);
+            assertNotEquals(orig, getModifiedValue(t));
+
+            em2 = deserializeEM(serialize(em));
+            T t2 = em2.find(getManagedType(), id);
+            assertNotEquals(orig, getModifiedValue(t2));
+
+            em.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t));
+
+            em2.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t2));
+        } finally {
+            close(em);
+            close(em2);
+        }
+    }
+
+    public void testEventManagers() {
+        TxListener txListener = new TxListener();
+        emf.addTransactionListener(txListener);
+        LifeListener lifeListener = new LifeListener();
+        emf.addLifecycleListener(lifeListener, null);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T t = em.find(getManagedType(), id);
+        assertEquals(0, lifeListener.refreshCount);
+        em.refresh(t);
+        assertEquals(1*graphSize(), lifeListener.refreshCount);
+        em.getTransaction().begin();
+        em.getTransaction().commit();
+        em.getTransaction().begin();
+        em.getTransaction().commit();
+        assertEquals(2, txListener.beginCount);
+
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+        assertNotNull(deserializedLifeListener);
+        assertEquals(1* graphSize(),
+            deserializedLifeListener.refreshCount);
+        assertNotSame(lifeListener, deserializedLifeListener);
+        T t2 = em2.find(getManagedType(), id);
+        em2.refresh(t2);
+        assertEquals(2* graphSize(),
+            deserializedLifeListener.refreshCount);
+
+        // if this is 3*refreshMultiplier(), that means that there are
+        // extra registered listeners
+        assertEquals(2* graphSize(), testGlobalRefreshCount);
+
+
+        assertNotNull(deserializedTxListener);
+        assertEquals(2, deserializedTxListener.beginCount);
+        assertNotSame(txListener, deserializedTxListener);
+        em2.getTransaction().begin();
+        em2.getTransaction().rollback();
+        assertEquals(3, deserializedTxListener.beginCount);
+
+        // if this is 4, that means that there are extra registered listeners
+        assertEquals(3, testGlobalBeginCount);
+    }
+
+    byte[] serialize(Object o) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(o);
+            oos.flush();
+            return baos.toByteArray();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    OpenJPAEntityManager deserializeEM(byte[] bytes) {
+        return (OpenJPAEntityManager) deserialize(bytes);
+    }
+
+    private Object deserialize(byte[] bytes) {
+        try {
+            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return ois.readObject();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    void close(EntityManager em) {
+        if (em != null && em.isOpen() && em.getTransaction().isActive())
+            em.getTransaction().rollback();
+        if (em != null && em.isOpen())
+            em.close();
+    }
+
+    protected abstract Class<T> getManagedType();
+
+    protected abstract T newManagedInstance();
+
+    protected abstract void modifyInstance(T t);
+
+    protected abstract Object getModifiedValue(T t);
+
+    /**
+     * The number of instances in the graph created
+     * by {@link #newManagedInstance()} of type T.
+     */
+    protected int graphSize() {
+        return 1;
+    }
+
+    /**
+     * An additional type that must be available in this PC. May be null.
+     */
+    protected Class getSecondaryType() {
+        return null;
+    }
+
+    private static class TxListener
+        extends AbstractTransactionListener
+        implements Serializable {
+
+        private int beginCount = 0;
+
+        public TxListener() {
+
+        }
+
+        @Override
+        public void afterBegin(TransactionEvent event) {
+            beginCount++;
+            testGlobalBeginCount++;
+        }
+
+        private void readObject(ObjectInputStream in)
+            throws ClassNotFoundException, IOException {
+            in.defaultReadObject();
+            deserializedTxListener = this;
+        }
+    }
+
+    private static class LifeListener
+        extends AbstractLifecycleListener
+        implements Serializable {
+
+        private int refreshCount = 0;
+
+        @Override
+        public void afterRefresh(LifecycleEvent event) {
+            refreshCount++;
+            testGlobalRefreshCount++;
+        }
+
+        private void readObject(ObjectInputStream in)
+            throws ClassNotFoundException, IOException {
+            in.defaultReadObject();
+            deserializedLifeListener = this;
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java
index f8f0a81..e5b9204 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.UnenhancedSubtype;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.util.ImplHelper;
-
-public abstract class AbstractUnenhancedRelationBrokerSerializationTest<T>
-    extends AbstractBrokerSerializationTest<T> {
-
-    public void testNewUnenhancedSMsRegisteredGlobally() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAEntityManager em2 = null;
-        try {
-            em.getTransaction().begin();
-            UnenhancedSubtype newe = (UnenhancedSubtype) newManagedInstance();
-            em.persist(newe);
-            em2 = deserializeEM(serialize(em));
-
-            for (Object o : em2.getManagedObjects()) {
-                assertFalse(o instanceof PersistenceCapable);
-                assertNotNull(ImplHelper.toPersistenceCapable(o,
-                    emf.getConfiguration()));
-                if (o instanceof UnenhancedSubtype)
-                    assertNotNull(ImplHelper.toPersistenceCapable(
-                        ((UnenhancedSubtype) o).getRelated(),
-                            emf.getConfiguration()));
-            }
-        } finally {
-            close(em);
-            close(em2);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.UnenhancedSubtype;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.util.ImplHelper;
+
+public abstract class AbstractUnenhancedRelationBrokerSerializationTest<T>
+    extends AbstractBrokerSerializationTest<T> {
+
+    public void testNewUnenhancedSMsRegisteredGlobally() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        try {
+            em.getTransaction().begin();
+            UnenhancedSubtype newe = (UnenhancedSubtype) newManagedInstance();
+            em.persist(newe);
+            em2 = deserializeEM(serialize(em));
+
+            for (Object o : em2.getManagedObjects()) {
+                assertFalse(o instanceof PersistenceCapable);
+                assertNotNull(ImplHelper.toPersistenceCapable(o,
+                    emf.getConfiguration()));
+                if (o instanceof UnenhancedSubtype)
+                    assertNotNull(ImplHelper.toPersistenceCapable(
+                        ((UnenhancedSubtype) o).getRelated(),
+                            emf.getConfiguration()));
+            }
+        } finally {
+            close(em);
+            close(em2);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryEventManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryEventManager.java
index 2f39285..f240d27 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryEventManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryEventManager.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import javax.persistence.Persistence;
-
-import junit.framework.TestCase;
-import org.apache.openjpa.event.BrokerFactoryListener;
-import org.apache.openjpa.event.BrokerFactoryEvent;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public class TestBrokerFactoryEventManager
-    extends TestCase {
-
-    public void testCreateEvent() {
-        OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
-            OpenJPAPersistence.cast(
-                Persistence.createEntityManagerFactory("test"));
-        ListenerImpl listener = new ListenerImpl();
-        emf.getConfiguration().getBrokerFactoryEventManager()
-            .addListener(listener);
-        emf.createEntityManager().close();
-        assertTrue(listener.createEventReceived);
-        emf.close();
-    }
-
-    private class ListenerImpl implements BrokerFactoryListener {
-
-        boolean createEventReceived = false;
-
-        public void eventFired(BrokerFactoryEvent event) {
-            if (event.getEventType()
-                == BrokerFactoryEvent.BROKER_FACTORY_CREATED)
-                createEventReceived = true;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import javax.persistence.Persistence;
+
+import junit.framework.TestCase;
+import org.apache.openjpa.event.BrokerFactoryListener;
+import org.apache.openjpa.event.BrokerFactoryEvent;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestBrokerFactoryEventManager
+    extends TestCase {
+
+    public void testCreateEvent() {
+        OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
+            OpenJPAPersistence.cast(
+                Persistence.createEntityManagerFactory("test"));
+        ListenerImpl listener = new ListenerImpl();
+        emf.getConfiguration().getBrokerFactoryEventManager()
+            .addListener(listener);
+        emf.createEntityManager().close();
+        assertTrue(listener.createEventReceived);
+        emf.close();
+    }
+
+    private class ListenerImpl implements BrokerFactoryListener {
+
+        boolean createEventReceived = false;
+
+        public void eventFired(BrokerFactoryEvent event) {
+            if (event.getEventType()
+                == BrokerFactoryEvent.BROKER_FACTORY_CREATED)
+                createEventReceived = true;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java
index 3f24bda..63dc881 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.event.AbstractLifecycleListener;
-import org.apache.openjpa.event.AbstractTransactionListener;
-import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.event.TransactionEvent;
-
-public class TestBrokerFactoryListenerRegistry
-    extends SingleEMFTestCase {
-
-    private int persistCount = 0;
-    private int beginCount = 0;
-
-    @Override
-    public void setUp() {
-        super.setUp(AllFieldTypes.class);
-    }
-
-    @Override
-    protected OpenJPAEntityManagerFactorySPI createEMF(Object... props) {
-        OpenJPAEntityManagerFactorySPI emf = super.createEMF(props);
-        emf.addLifecycleListener(new AbstractLifecycleListener() {
-            @Override
-            public void beforePersist(LifecycleEvent event) {
-                persistCount++;
-            }
-        }, null);
-        emf.addTransactionListener(new AbstractTransactionListener() {
-            @Override
-            public void afterBegin(TransactionEvent event) {
-                beginCount++;
-            }
-        });
-        return emf;
-    }
-
-    public void testLifecycleListenerRegistry() {
-        beginCount = 0;
-        persistCount = 0;
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        try {
-            em.persist(new AllFieldTypes());
-            em.flush();
-            assertEquals(1, beginCount);
-            assertEquals(1, persistCount);
-        } finally {
-            em.getTransaction().rollback();
-            em.close();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.event.AbstractLifecycleListener;
+import org.apache.openjpa.event.AbstractTransactionListener;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.TransactionEvent;
+
+public class TestBrokerFactoryListenerRegistry
+    extends SingleEMFTestCase {
+
+    private int persistCount = 0;
+    private int beginCount = 0;
+
+    @Override
+    public void setUp() {
+        super.setUp(AllFieldTypes.class);
+    }
+
+    @Override
+    protected OpenJPAEntityManagerFactorySPI createEMF(Object... props) {
+        OpenJPAEntityManagerFactorySPI emf = super.createEMF(props);
+        emf.addLifecycleListener(new AbstractLifecycleListener() {
+            @Override
+            public void beforePersist(LifecycleEvent event) {
+                persistCount++;
+            }
+        }, null);
+        emf.addTransactionListener(new AbstractTransactionListener() {
+            @Override
+            public void afterBegin(TransactionEvent event) {
+                beginCount++;
+            }
+        });
+        return emf;
+    }
+
+    public void testLifecycleListenerRegistry() {
+        beginCount = 0;
+        persistCount = 0;
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        try {
+            em.persist(new AllFieldTypes());
+            em.flush();
+            assertEquals(1, beginCount);
+            assertEquals(1, persistCount);
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestDynamicClassRegistration.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestDynamicClassRegistration.java
index 91541a0..6fa77b9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestDynamicClassRegistration.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestDynamicClassRegistration.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import java.util.List;
-import java.util.Collections;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.UnenhancedFieldAccess;
-import org.apache.openjpa.enhance.ManagedClassSubclasser;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.query.SimpleEntity;
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-
-public class TestDynamicClassRegistration
-    extends PersistenceTestCase {
-
-    private OpenJPAEntityManagerFactorySPI emf;
-
-    public void setUp() throws Exception {
-        super.setUp();
-
-        emf = createNamedEMF("empty-pu");
-    }
-
-    public void testEnhancedDynamicClassRegistration()
-        throws ClassNotFoundException {
-        assertTrue(
-            PersistenceCapable.class.isAssignableFrom(SimpleEntity.class));
-
-        // trigger class initialization. We could just do 'new SimpleEntity()'.
-        Class.forName(SimpleEntity.class.getName(), true,
-            getClass().getClassLoader());
-
-        ClassMetaData meta =
-            JPAFacadeHelper.getMetaData(emf, SimpleEntity.class);
-        assertNotNull(meta);
-        EntityManager em = emf.createEntityManager();
-        javax.persistence.Query q = em.createQuery("select o from simple o");
-        em.close();
-    }
-
-    public void testUnenhancedDynamicClassRegistration() {
-        assertFalse(PersistenceCapable.class.isAssignableFrom(
-            UnenhancedFieldAccess.class));
-
-        // trigger class initialization
-        ManagedClassSubclasser.prepareUnenhancedClasses(
-            emf.getConfiguration(),
-            Collections.singleton(UnenhancedFieldAccess.class),
-            null);
-
-        ClassMetaData meta =
-            JPAFacadeHelper.getMetaData(emf, UnenhancedFieldAccess.class);
-        assertNotNull(meta);
-        EntityManager em = emf.createEntityManager();
-        javax.persistence.Query q = em.createQuery(
-            "select o from UnenhancedFieldAccess o");
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import java.util.List;
+import java.util.Collections;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.UnenhancedFieldAccess;
+import org.apache.openjpa.enhance.ManagedClassSubclasser;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.query.SimpleEntity;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+
+public class TestDynamicClassRegistration
+    extends PersistenceTestCase {
+
+    private OpenJPAEntityManagerFactorySPI emf;
+
+    public void setUp() throws Exception {
+        super.setUp();
+
+        emf = createNamedEMF("empty-pu");
+    }
+
+    public void testEnhancedDynamicClassRegistration()
+        throws ClassNotFoundException {
+        assertTrue(
+            PersistenceCapable.class.isAssignableFrom(SimpleEntity.class));
+
+        // trigger class initialization. We could just do 'new SimpleEntity()'.
+        Class.forName(SimpleEntity.class.getName(), true,
+            getClass().getClassLoader());
+
+        ClassMetaData meta =
+            JPAFacadeHelper.getMetaData(emf, SimpleEntity.class);
+        assertNotNull(meta);
+        EntityManager em = emf.createEntityManager();
+        javax.persistence.Query q = em.createQuery("select o from simple o");
+        em.close();
+    }
+
+    public void testUnenhancedDynamicClassRegistration() {
+        assertFalse(PersistenceCapable.class.isAssignableFrom(
+            UnenhancedFieldAccess.class));
+
+        // trigger class initialization
+        ManagedClassSubclasser.prepareUnenhancedClasses(
+            emf.getConfiguration(),
+            Collections.singleton(UnenhancedFieldAccess.class),
+            null);
+
+        ClassMetaData meta =
+            JPAFacadeHelper.getMetaData(emf, UnenhancedFieldAccess.class);
+        assertNotNull(meta);
+        EntityManager em = emf.createEntityManager();
+        javax.persistence.Query q = em.createQuery(
+            "select o from UnenhancedFieldAccess o");
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java
index ceb8f25..f712505 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.persistence.query.SimpleEntity;
-
-public class TestEnhancedInstanceBrokerSerialization
-    extends AbstractBrokerSerializationTest<SimpleEntity> {
-
-    @Override
-    public void setUp() {
-        assertTrue(
-            PersistenceCapable.class.isAssignableFrom(SimpleEntity.class));
-        super.setUp();
-    }
-
-    protected Class<SimpleEntity> getManagedType() {
-        return SimpleEntity.class;
-    }
-
-    protected SimpleEntity newManagedInstance() {
-        SimpleEntity e = new SimpleEntity();
-        e.setName("foo");
-        e.setValue("bar");
-        return e;
-    }
-
-    protected void modifyInstance(SimpleEntity e) {
-        e.setValue("modified");
-    }
-
-    protected Object getModifiedValue(SimpleEntity e) {
-        return e.getValue();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.query.SimpleEntity;
+
+public class TestEnhancedInstanceBrokerSerialization
+    extends AbstractBrokerSerializationTest<SimpleEntity> {
+
+    @Override
+    public void setUp() {
+        assertTrue(
+            PersistenceCapable.class.isAssignableFrom(SimpleEntity.class));
+        super.setUp();
+    }
+
+    protected Class<SimpleEntity> getManagedType() {
+        return SimpleEntity.class;
+    }
+
+    protected SimpleEntity newManagedInstance() {
+        SimpleEntity e = new SimpleEntity();
+        e.setName("foo");
+        e.setValue("bar");
+        return e;
+    }
+
+    protected void modifyInstance(SimpleEntity e) {
+        e.setValue("modified");
+    }
+
+    protected Object getModifiedValue(SimpleEntity e) {
+        return e.getValue();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java
index f61a62c..562ed6a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestEntityManagerFactoryPool
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp("openjpa.EntityManagerFactoryPool", Boolean.TRUE);
-
-        emf.createEntityManager().close();
-    }
-
-    public void testBrokerFactoryPoolHit() {
-        Map m = new HashMap();
-        // also tests string values for the property
-        m.put("openjpa.EntityManagerFactoryPool", "True");
-        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
-            "test", m);
-        assertSame(this.emf, emf);
-    }
-
-    public void testBrokerFactoryPoolMiss() {
-        Map m = new HashMap();
-        m.put("openjpa.EntityManagerFactoryPool", Boolean.TRUE);
-        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
-            "second-persistence-unit", m);
-        assertNotSame(this.emf, emf);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestEntityManagerFactoryPool
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp("openjpa.EntityManagerFactoryPool", Boolean.TRUE);
+
+        emf.createEntityManager().close();
+    }
+
+    public void testBrokerFactoryPoolHit() {
+        Map m = new HashMap();
+        // also tests string values for the property
+        m.put("openjpa.EntityManagerFactoryPool", "True");
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+            "test", m);
+        assertSame(this.emf, emf);
+    }
+
+    public void testBrokerFactoryPoolMiss() {
+        Map m = new HashMap();
+        m.put("openjpa.EntityManagerFactoryPool", Boolean.TRUE);
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+            "second-persistence-unit", m);
+        assertNotSame(this.emf, emf);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java
index 4fc26d4..8a17714 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.persistence.query.ManyOneEntity;
-
-public class TestInstanceGraphBrokerSerialization
-    extends AbstractBrokerSerializationTest<ManyOneEntity> {
-
-    protected Class<ManyOneEntity> getManagedType() {
-        return ManyOneEntity.class;
-    }
-
-    protected ManyOneEntity newManagedInstance() {
-        ManyOneEntity e = new ManyOneEntity();
-        e.setName("foo");
-        ManyOneEntity rel = new ManyOneEntity();
-        rel.setName("bar");
-        e.setRel(rel);
-        return e;
-    }
-
-    protected void modifyInstance(ManyOneEntity e) {
-        e.getRel().setName("modified");
-    }
-
-    protected Object getModifiedValue(ManyOneEntity e) {
-        return e.getRel().getName();
-    }
-
-    @Override
-    protected int graphSize() {
-        return 2;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.persistence.query.ManyOneEntity;
+
+public class TestInstanceGraphBrokerSerialization
+    extends AbstractBrokerSerializationTest<ManyOneEntity> {
+
+    protected Class<ManyOneEntity> getManagedType() {
+        return ManyOneEntity.class;
+    }
+
+    protected ManyOneEntity newManagedInstance() {
+        ManyOneEntity e = new ManyOneEntity();
+        e.setName("foo");
+        ManyOneEntity rel = new ManyOneEntity();
+        rel.setName("bar");
+        e.setRel(rel);
+        return e;
+    }
+
+    protected void modifyInstance(ManyOneEntity e) {
+        e.getRel().setName("modified");
+    }
+
+    protected Object getModifiedValue(ManyOneEntity e) {
+        return e.getRel().getName();
+    }
+
+    @Override
+    protected int graphSize() {
+        return 2;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java
index 1918545..0ecf316 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.enhance.UnenhancedFieldAccess;
-
-public class TestUnenhancedFieldAccessInstanceBrokerSerialization
-    extends AbstractBrokerSerializationTest<UnenhancedFieldAccess> {
-
-    protected Class<UnenhancedFieldAccess> getManagedType() {
-        return UnenhancedFieldAccess.class;
-    }
-
-    protected UnenhancedFieldAccess newManagedInstance() {
-        UnenhancedFieldAccess e = new UnenhancedFieldAccess();
-        e.setStringField("foo");
-        return e;
-    }
-
-    protected void modifyInstance(UnenhancedFieldAccess e) {
-        e.setStringField("modified");
-    }
-
-    protected Object getModifiedValue(UnenhancedFieldAccess e) {
-        return e.getStringField();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedFieldAccess;
+
+public class TestUnenhancedFieldAccessInstanceBrokerSerialization
+    extends AbstractBrokerSerializationTest<UnenhancedFieldAccess> {
+
+    protected Class<UnenhancedFieldAccess> getManagedType() {
+        return UnenhancedFieldAccess.class;
+    }
+
+    protected UnenhancedFieldAccess newManagedInstance() {
+        UnenhancedFieldAccess e = new UnenhancedFieldAccess();
+        e.setStringField("foo");
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedFieldAccess e) {
+        e.setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedFieldAccess e) {
+        return e.getStringField();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java
index 02ac209..511e32b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java
@@ -1,57 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.enhance.UnenhancedFieldAccess;
-import org.apache.openjpa.enhance.UnenhancedFieldAccessSubclass;
-
-public class TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization
-    extends AbstractUnenhancedRelationBrokerSerializationTest
-        <UnenhancedFieldAccessSubclass> {
-
-    protected Class getSecondaryType() {
-        return UnenhancedFieldAccess.class;
-    }
-
-    protected Class<UnenhancedFieldAccessSubclass> getManagedType() {
-        return UnenhancedFieldAccessSubclass.class;
-    }
-
-    protected UnenhancedFieldAccessSubclass newManagedInstance() {
-        UnenhancedFieldAccessSubclass e = new UnenhancedFieldAccessSubclass();
-        e.setStringField("foo");
-        UnenhancedFieldAccess related = new UnenhancedFieldAccess();
-        related.setStringField("bar");
-        e.setRelated(related);
-        return e;
-    }
-
-    protected void modifyInstance(UnenhancedFieldAccessSubclass e) {
-        e.getRelated().setStringField("modified");
-    }
-
-    protected Object getModifiedValue(UnenhancedFieldAccessSubclass e) {
-        return e.getRelated().getStringField();
-    }
-
-    @Override
-    protected int graphSize() {
-        return 2;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedFieldAccess;
+import org.apache.openjpa.enhance.UnenhancedFieldAccessSubclass;
+
+public class TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization
+    extends AbstractUnenhancedRelationBrokerSerializationTest
+        <UnenhancedFieldAccessSubclass> {
+
+    protected Class getSecondaryType() {
+        return UnenhancedFieldAccess.class;
+    }
+
+    protected Class<UnenhancedFieldAccessSubclass> getManagedType() {
+        return UnenhancedFieldAccessSubclass.class;
+    }
+
+    protected UnenhancedFieldAccessSubclass newManagedInstance() {
+        UnenhancedFieldAccessSubclass e = new UnenhancedFieldAccessSubclass();
+        e.setStringField("foo");
+        UnenhancedFieldAccess related = new UnenhancedFieldAccess();
+        related.setStringField("bar");
+        e.setRelated(related);
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedFieldAccessSubclass e) {
+        e.getRelated().setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedFieldAccessSubclass e) {
+        return e.getRelated().getStringField();
+    }
+
+    @Override
+    protected int graphSize() {
+        return 2;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java
index 3c49949..7104450 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
-
-public class TestUnenhancedPropertyAccessInstanceBrokerSerialization
-    extends AbstractBrokerSerializationTest<UnenhancedPropertyAccess> {
-
-    protected Class<UnenhancedPropertyAccess> getManagedType() {
-        return UnenhancedPropertyAccess.class;
-    }
-
-    protected UnenhancedPropertyAccess newManagedInstance() {
-        UnenhancedPropertyAccess e = new UnenhancedPropertyAccess();
-        e.setStringField("foo");
-        return e;
-    }
-
-    protected void modifyInstance(UnenhancedPropertyAccess e) {
-        e.setStringField("modified");
-    }
-
-    protected Object getModifiedValue(UnenhancedPropertyAccess e) {
-        return e.getStringField();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
+
+public class TestUnenhancedPropertyAccessInstanceBrokerSerialization
+    extends AbstractBrokerSerializationTest<UnenhancedPropertyAccess> {
+
+    protected Class<UnenhancedPropertyAccess> getManagedType() {
+        return UnenhancedPropertyAccess.class;
+    }
+
+    protected UnenhancedPropertyAccess newManagedInstance() {
+        UnenhancedPropertyAccess e = new UnenhancedPropertyAccess();
+        e.setStringField("foo");
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedPropertyAccess e) {
+        e.setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedPropertyAccess e) {
+        return e.getStringField();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java
index 3f533f7..4499cfa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.kernel;
-
-import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
-import org.apache.openjpa.enhance.UnenhancedPropertyAccessSubclass;
-
-public class TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization
-    extends AbstractUnenhancedRelationBrokerSerializationTest
-        <UnenhancedPropertyAccessSubclass> {
-
-    protected Class getSecondaryType() {
-        return UnenhancedPropertyAccess.class;
-    }
-
-    protected Class<UnenhancedPropertyAccessSubclass> getManagedType() {
-        return UnenhancedPropertyAccessSubclass.class;
-    }
-
-    protected UnenhancedPropertyAccessSubclass newManagedInstance() {
-        UnenhancedPropertyAccessSubclass e =
-            new UnenhancedPropertyAccessSubclass();
-        e.setStringField("foo");
-        UnenhancedPropertyAccess related = new UnenhancedPropertyAccess();
-        related.setStringField("bar");
-        e.setRelated(related);
-        return e;
-    }
-
-    protected void modifyInstance(UnenhancedPropertyAccessSubclass e) {
-        e.getRelated().setStringField("modified");
-    }
-
-    protected Object getModifiedValue(UnenhancedPropertyAccessSubclass e) {
-        return e.getRelated().getStringField();
-    }
-
-    @Override
-    protected int graphSize() {
-        return 2;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
+import org.apache.openjpa.enhance.UnenhancedPropertyAccessSubclass;
+
+public class TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization
+    extends AbstractUnenhancedRelationBrokerSerializationTest
+        <UnenhancedPropertyAccessSubclass> {
+
+    protected Class getSecondaryType() {
+        return UnenhancedPropertyAccess.class;
+    }
+
+    protected Class<UnenhancedPropertyAccessSubclass> getManagedType() {
+        return UnenhancedPropertyAccessSubclass.class;
+    }
+
+    protected UnenhancedPropertyAccessSubclass newManagedInstance() {
+        UnenhancedPropertyAccessSubclass e =
+            new UnenhancedPropertyAccessSubclass();
+        e.setStringField("foo");
+        UnenhancedPropertyAccess related = new UnenhancedPropertyAccess();
+        related.setStringField("bar");
+        e.setRelated(related);
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedPropertyAccessSubclass e) {
+        e.getRelated().setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedPropertyAccessSubclass e) {
+        return e.getRelated().getStringField();
+    }
+
+    @Override
+    protected int graphSize() {
+        return 2;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestAnchorParsing.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestAnchorParsing.java
index 0b97ff2..61f740e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestAnchorParsing.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestAnchorParsing.java
@@ -1,155 +1,155 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.lib.conf;
-
-import java.util.List;
-import java.util.MissingResourceException;
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-
-import junit.framework.TestCase;
-import org.apache.openjpa.lib.util.Options;
-
-public class TestAnchorParsing extends TestCase {
-
-    public void testFQAnchor() {
-        String fqLoc = "META-INF/persistence.xml#test";
-        Options opts = new Options();
-        opts.setProperty("p", fqLoc);
-        List locs =
-            Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
-        assertNotNull(locs);
-        assertEquals(1, locs.size());
-        assertEquals(fqLoc, locs.get(0));
-    }
-
-    public void testNoResource() {
-        allHelper(null);
-    }
-
-    public void testNoAnchor() {
-        allHelper("META-INF/persistence.xml");
-    }
-
-    private void allHelper(String resource) {
-        Options opts = new Options();
-        if (resource != null)
-            opts.setProperty("p", resource);
-        List locs =
-            Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
-        assertNotNull(locs);
-        // approximate so that if someone adds more units, this doesn't break
-        assertTrue(locs.size() >= 4);
-        assertTrue(locs.contains("META-INF/persistence.xml#test"));
-        assertTrue(locs.contains(
-            "META-INF/persistence.xml#second-persistence-unit"));
-        assertTrue(locs.contains(
-            "META-INF/persistence.xml#third-persistence-unit"));
-        assertTrue(locs.contains("META-INF/persistence.xml#invalid"));
-    }
-
-    public void testProductDerivationsLoadResource() {
-        ProductDerivations.load(
-            "org/apache/openjpa/lib/conf/product-derivations-load.xml",
-            "foo", null);
-
-        ProductDerivations.load(
-            "org/apache/openjpa/lib/conf/product-derivations-load.xml",
-            null, null);
-
-        try {
-            ProductDerivations.load(
-                "org/apache/openjpa/lib/conf/product-derivations-load.xml",
-                "nonexistant", null);
-            fail("pu 'nonexistant' does not exist");
-        } catch (MissingResourceException mre) {
-            // expected
-        }
-
-        try {
-            ProductDerivations.load(
-                "org/apache/openjpa/lib/conf/product-derivations-load.xml",
-                "", null);
-            fail("pu '' does not exist");
-        } catch (MissingResourceException mre) {
-            // expected
-        }
-    }
-
-    public void testNonexistantResourceLoad() {
-        try {
-            ProductDerivations.load("nonexistant-resource", null, null);
-            fail("resource 'nonexistant-resource' should not exist");
-        } catch (MissingResourceException e) {
-            // expected
-        }
-    }
-
-    public void testProductDerivationsLoadFile() throws IOException {
-        File validFile = resourceToTemporaryFile(
-            "org/apache/openjpa/lib/conf/product-derivations-load.xml");
-
-        ProductDerivations.load(validFile, "foo", null);
-
-        ProductDerivations.load(validFile, null, null);
-
-        try {
-            ProductDerivations.load(validFile, "nonexistant", null);
-            fail("pu 'nonexistant' does not exist");
-        } catch (MissingResourceException mre) {
-            // expected
-        }
-
-        try {
-            ProductDerivations.load(validFile, "", null);
-            fail("pu '' does not exist");
-        } catch (MissingResourceException mre) {
-            // expected
-        }
-    }
-
-    public void testNonexistantFileLoad() {
-        File f = new File("this-should-not-exist");
-        assertFalse(f.exists());
-        try {
-            ProductDerivations.load(f, null, null);
-            fail(f.getName() + " does not exist");
-        } catch (MissingResourceException e) {
-            // expected
-        }
-    }
-
-    private File resourceToTemporaryFile(String s) throws IOException {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(s);
-        File f = File.createTempFile("TestAnchorParsing", ".xml");
-        OutputStream out = new FileOutputStream(f);
-        byte[] bytes = new byte[1024];
-        while (true) {
-            int count = in.read(bytes);
-            if (count < 0)
-                break;
-            out.write(bytes, 0, count);
-        }
-        f.deleteOnExit();
-        return f;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.conf;
+
+import java.util.List;
+import java.util.MissingResourceException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+import org.apache.openjpa.lib.util.Options;
+
+public class TestAnchorParsing extends TestCase {
+
+    public void testFQAnchor() {
+        String fqLoc = "META-INF/persistence.xml#test";
+        Options opts = new Options();
+        opts.setProperty("p", fqLoc);
+        List locs =
+            Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
+        assertNotNull(locs);
+        assertEquals(1, locs.size());
+        assertEquals(fqLoc, locs.get(0));
+    }
+
+    public void testNoResource() {
+        allHelper(null);
+    }
+
+    public void testNoAnchor() {
+        allHelper("META-INF/persistence.xml");
+    }
+
+    private void allHelper(String resource) {
+        Options opts = new Options();
+        if (resource != null)
+            opts.setProperty("p", resource);
+        List locs =
+            Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
+        assertNotNull(locs);
+        // approximate so that if someone adds more units, this doesn't break
+        assertTrue(locs.size() >= 4);
+        assertTrue(locs.contains("META-INF/persistence.xml#test"));
+        assertTrue(locs.contains(
+            "META-INF/persistence.xml#second-persistence-unit"));
+        assertTrue(locs.contains(
+            "META-INF/persistence.xml#third-persistence-unit"));
+        assertTrue(locs.contains("META-INF/persistence.xml#invalid"));
+    }
+
+    public void testProductDerivationsLoadResource() {
+        ProductDerivations.load(
+            "org/apache/openjpa/lib/conf/product-derivations-load.xml",
+            "foo", null);
+
+        ProductDerivations.load(
+            "org/apache/openjpa/lib/conf/product-derivations-load.xml",
+            null, null);
+
+        try {
+            ProductDerivations.load(
+                "org/apache/openjpa/lib/conf/product-derivations-load.xml",
+                "nonexistant", null);
+            fail("pu 'nonexistant' does not exist");
+        } catch (MissingResourceException mre) {
+            // expected
+        }
+
+        try {
+            ProductDerivations.load(
+                "org/apache/openjpa/lib/conf/product-derivations-load.xml",
+                "", null);
+            fail("pu '' does not exist");
+        } catch (MissingResourceException mre) {
+            // expected
+        }
+    }
+
+    public void testNonexistantResourceLoad() {
+        try {
+            ProductDerivations.load("nonexistant-resource", null, null);
+            fail("resource 'nonexistant-resource' should not exist");
+        } catch (MissingResourceException e) {
+            // expected
+        }
+    }
+
+    public void testProductDerivationsLoadFile() throws IOException {
+        File validFile = resourceToTemporaryFile(
+            "org/apache/openjpa/lib/conf/product-derivations-load.xml");
+
+        ProductDerivations.load(validFile, "foo", null);
+
+        ProductDerivations.load(validFile, null, null);
+
+        try {
+            ProductDerivations.load(validFile, "nonexistant", null);
+            fail("pu 'nonexistant' does not exist");
+        } catch (MissingResourceException mre) {
+            // expected
+        }
+
+        try {
+            ProductDerivations.load(validFile, "", null);
+            fail("pu '' does not exist");
+        } catch (MissingResourceException mre) {
+            // expected
+        }
+    }
+
+    public void testNonexistantFileLoad() {
+        File f = new File("this-should-not-exist");
+        assertFalse(f.exists());
+        try {
+            ProductDerivations.load(f, null, null);
+            fail(f.getName() + " does not exist");
+        } catch (MissingResourceException e) {
+            // expected
+        }
+    }
+
+    private File resourceToTemporaryFile(String s) throws IOException {
+        InputStream in = getClass().getClassLoader().getResourceAsStream(s);
+        File f = File.createTempFile("TestAnchorParsing", ".xml");
+        OutputStream out = new FileOutputStream(f);
+        byte[] bytes = new byte[1024];
+        while (true) {
+            int count = in.read(bytes);
+            if (count < 0)
+                break;
+            out.write(bytes, 0, count);
+        }
+        f.deleteOnExit();
+        return f;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/A.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/A.java
index 2062d3f..f6b9a37 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/A.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/A.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-@Entity
-@Table(name="meta_A")
-public class A extends AbstractThing {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="meta_A")
+public class A extends AbstractThing {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/AbstractThing.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/AbstractThing.java
index 7fb7037..6c680f3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/AbstractThing.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/AbstractThing.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import javax.persistence.MappedSuperclass;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Column;
-
-@MappedSuperclass
-public class AbstractThing {
-
-    private String id;
-
-    @Id
-    @GeneratedValue(generator = "uuid-hex")
-    @Column(columnDefinition = "char(32)")
-    public String getId() {
-        return id;
-    }
-
-    protected void setId(final String id) {
-        this.id = id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Column;
+
+@MappedSuperclass
+public class AbstractThing {
+
+    private String id;
+
+    @Id
+    @GeneratedValue(generator = "uuid-hex")
+    @Column(columnDefinition = "char(32)")
+    public String getId() {
+        return id;
+    }
+
+    protected void setId(final String id) {
+        this.id = id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Artist.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Artist.java
index 32c0937..ff573ef 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Artist.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Artist.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import javax.persistence.Entity;
-
-@Entity
-public class Artist
-    extends Person {
-
-    /**
-     * Default constructor required for enhancement.
-     */
-    public Artist() {
-        super();
-    }
-
-    /**
-     * The public constructor constructs with a name.
-     *
-     * @param name the name of the artist.
-     */
-    public Artist(String name) {
-        super(name);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import javax.persistence.Entity;
+
+@Entity
+public class Artist
+    extends Person {
+
+    /**
+     * Default constructor required for enhancement.
+     */
+    public Artist() {
+        super();
+    }
+
+    /**
+     * The public constructor constructs with a name.
+     *
+     * @param name the name of the artist.
+     */
+    public Artist(String name) {
+        super(name);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/B.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/B.java
index e89ba24..8beb7ab 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/B.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/B.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import java.util.Set;
-import javax.persistence.Entity;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-
-import org.apache.openjpa.meta.C;
-
-@Entity
-@Table(name="meta_B")
-public class B extends AbstractThing {
-    private Set<C> cs;
-    private Set<A> as;
-
-    @OneToMany
-    public Set<C> getCs() {
-        return cs;
-    }
-
-    public void setCs(Set<C> cs) {
-        this.cs = cs;
-    }
-
-    @OneToMany
-    public Set<A> getAs() {
-        return as;
-    }
-
-    public void setAs(Set<A> as) {
-        this.as = as;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import java.util.Set;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.apache.openjpa.meta.C;
+
+@Entity
+@Table(name="meta_B")
+public class B extends AbstractThing {
+    private Set<C> cs;
+    private Set<A> as;
+
+    @OneToMany
+    public Set<C> getCs() {
+        return cs;
+    }
+
+    public void setCs(Set<C> cs) {
+        this.cs = cs;
+    }
+
+    @OneToMany
+    public Set<A> getAs() {
+        return as;
+    }
+
+    public void setAs(Set<A> as) {
+        this.as = as;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/C.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/C.java
index 83f99aa..08c5920 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/C.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/C.java
@@ -1,103 +1,103 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import javax.persistence.Entity;
-import javax.persistence.IdClass;
-import javax.persistence.ManyToOne;
-import javax.persistence.Column;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.openjpa.meta.C.Identity;
-
-@Entity
-@IdClass(Identity.class)
-@Table(name="meta_C")
-public class C {
-    private A a;
-    private B b;
-    private long num;
-
-    @ManyToOne(optional = false)
-    @Column(nullable = false)
-    public A getA() {
-        return a;
-    }
-
-    public void setA(A a) {
-        this.a = a;
-    }
-
-    @Id
-    @ManyToOne(optional = false)
-    @Column(nullable = false)
-    public B getB() {
-        return b;
-    }
-
-    public void setB(B b) {
-        this.b = b;
-    }
-
-    @Id
-    public long getNum() {
-        return num;
-    }
-
-    public void setNum(long num) {
-        this.num = num;
-    }
-
-    public static class Identity {
-        private String b;
-        private long num;
-
-        @Override
-        public int hashCode() {
-            return b.hashCode() * 17 + (int) num;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            return obj != null && (obj instanceof Identity)
-                && b.equals(((Identity) obj).b) && num == ((Identity) obj).num;
-        }
-
-        public String getB() {
-            return b;
-        }
-
-        public void setB(B b) {
-            this.b = b.getId();
-        }
-
-        public void setB(String b) {
-            this.b = b;
-        }
-
-        public long getNum() {
-            return num;
-        }
-
-        public void setNum(long num) {
-            this.num = num;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import javax.persistence.Entity;
+import javax.persistence.IdClass;
+import javax.persistence.ManyToOne;
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.openjpa.meta.C.Identity;
+
+@Entity
+@IdClass(Identity.class)
+@Table(name="meta_C")
+public class C {
+    private A a;
+    private B b;
+    private long num;
+
+    @ManyToOne(optional = false)
+    @Column(nullable = false)
+    public A getA() {
+        return a;
+    }
+
+    public void setA(A a) {
+        this.a = a;
+    }
+
+    @Id
+    @ManyToOne(optional = false)
+    @Column(nullable = false)
+    public B getB() {
+        return b;
+    }
+
+    public void setB(B b) {
+        this.b = b;
+    }
+
+    @Id
+    public long getNum() {
+        return num;
+    }
+
+    public void setNum(long num) {
+        this.num = num;
+    }
+
+    public static class Identity {
+        private String b;
+        private long num;
+
+        @Override
+        public int hashCode() {
+            return b.hashCode() * 17 + (int) num;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj != null && (obj instanceof Identity)
+                && b.equals(((Identity) obj).b) && num == ((Identity) obj).num;
+        }
+
+        public String getB() {
+            return b;
+        }
+
+        public void setB(B b) {
+            this.b = b.getId();
+        }
+
+        public void setB(String b) {
+            this.b = b;
+        }
+
+        public long getNum() {
+            return num;
+        }
+
+        public void setNum(long num) {
+            this.num = num;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Item.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Item.java
index e7e0450..e1c413c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Item.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Item.java
@@ -1,110 +1,110 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import java.io.Serializable;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-
-@Entity
-public class Item implements Serializable {
-
-    @Id
-    @GeneratedValue
-    private int id;
-
-    private String title;
-
-    @ManyToOne(cascade = CascadeType.PERSIST)
-    private Artist artist;
-
-    /**
-     * A no-arg constructor is required for enhancement.
-     */
-    protected Item() {
-        super();
-    }
-
-    /**
-     * The public constructor constructs with a title.
-     *
-     * @param title the title of the item.
-     */
-    public Item(String title) {
-        super();
-        this.title = title;
-    }
-
-    /**
-     * Gets the unique identifier of this receiver. There is no corresponding
-     * <code>setId()</code> method as the identifier value is generated by the
-     * Persistence Provider Runtime.
-     *
-     * @return unique identifier of this instance.
-     */
-    public int getId() {
-        return id;
-    }
-
-    /**
-     * Gets the title of this item.
-     *
-     * @return return the tile of the item.
-     */
-    public String getTitle() {
-        return title;
-    }
-
-    /**
-     * Sets the title of this receiver.
-     *
-     * @param title must not be null or empty.
-     */
-    public void setTitle(String title) {
-        if (title == null || title.trim().length() == 0)
-            throw new IllegalArgumentException(
-                "null or empty title not allowed");
-        this.title = title;
-    }
-
-    /**
-     * Gets the artist who created this item. This is an example of
-     * unidirectional single-valued relationship.
-     *
-     * @return the artist who created this item.
-     */
-    public Artist getArtist() {
-        return artist;
-    }
-
-    /**
-     * Sets the artist who created this Item.
-     *
-     * @param artist must not be null.
-     */
-    public void setArtist(Artist artist) {
-        if (artist == null)
-            throw new IllegalArgumentException("null Artist for " + this);
-
-        this.artist = artist;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import java.io.Serializable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class Item implements Serializable {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    private String title;
+
+    @ManyToOne(cascade = CascadeType.PERSIST)
+    private Artist artist;
+
+    /**
+     * A no-arg constructor is required for enhancement.
+     */
+    protected Item() {
+        super();
+    }
+
+    /**
+     * The public constructor constructs with a title.
+     *
+     * @param title the title of the item.
+     */
+    public Item(String title) {
+        super();
+        this.title = title;
+    }
+
+    /**
+     * Gets the unique identifier of this receiver. There is no corresponding
+     * <code>setId()</code> method as the identifier value is generated by the
+     * Persistence Provider Runtime.
+     *
+     * @return unique identifier of this instance.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Gets the title of this item.
+     *
+     * @return return the tile of the item.
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Sets the title of this receiver.
+     *
+     * @param title must not be null or empty.
+     */
+    public void setTitle(String title) {
+        if (title == null || title.trim().length() == 0)
+            throw new IllegalArgumentException(
+                "null or empty title not allowed");
+        this.title = title;
+    }
+
+    /**
+     * Gets the artist who created this item. This is an example of
+     * unidirectional single-valued relationship.
+     *
+     * @return the artist who created this item.
+     */
+    public Artist getArtist() {
+        return artist;
+    }
+
+    /**
+     * Sets the artist who created this Item.
+     *
+     * @param artist must not be null.
+     */
+    public void setArtist(Artist artist) {
+        if (artist == null)
+            throw new IllegalArgumentException("null Artist for " + this);
+
+        this.artist = artist;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Painter.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Painter.java
index e85c46b..6326fb1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Painter.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Painter.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import javax.persistence.Entity;
-
-@Entity
-public class Painter extends Artist {
-
-    public Painter() {
-        super();
-    }
-
-    public Painter(String name) {
-        super(name);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import javax.persistence.Entity;
+
+@Entity
+public class Painter extends Artist {
+
+    public Painter() {
+        super();
+    }
+
+    public Painter(String name) {
+        super(name);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Person.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Person.java
index 49e99f8..fe7f17e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Person.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/Person.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import java.io.Serializable;
-import java.util.Collection;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-
-@Entity
-public class Person implements Serializable {
-
-    @Id
-    private String name;
-
-    @OneToMany
-    private Collection<Painter> paitersForPortrait;
-
-    /**
-     * default constructor required by enhancement.
-     */
-    protected Person() {
-
-    }
-
-    /**
-     * The public constructor constructs with a name.
-     *
-     * @param name the name of the person.
-     */
-
-    public Person(String name) {
-        this.name = name;
-    }
-
-    /**
-     * Gets the name of this person. This is the unique identifier.
-     *
-     * @return return the name of this person.
-     */
-    public String getName() {
-
-        return name;
-    }
-
-    public void setName(String name) {
-        if (name == null || name.trim().length() == 0)
-            throw new IllegalArgumentException(
-                "null or empty name not allowed");
-        this.name = name;
-    }
-
-    public Collection<Painter> getPainters() {
-
-        return paitersForPortrait;
-    }
-
-    public void setPainters(Collection<Painter> p) {
-        this.paitersForPortrait = p;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import java.io.Serializable;
+import java.util.Collection;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+@Entity
+public class Person implements Serializable {
+
+    @Id
+    private String name;
+
+    @OneToMany
+    private Collection<Painter> paitersForPortrait;
+
+    /**
+     * default constructor required by enhancement.
+     */
+    protected Person() {
+
+    }
+
+    /**
+     * The public constructor constructs with a name.
+     *
+     * @param name the name of the person.
+     */
+
+    public Person(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets the name of this person. This is the unique identifier.
+     *
+     * @return return the name of this person.
+     */
+    public String getName() {
+
+        return name;
+    }
+
+    public void setName(String name) {
+        if (name == null || name.trim().length() == 0)
+            throw new IllegalArgumentException(
+                "null or empty name not allowed");
+        this.name = name;
+    }
+
+    public Collection<Painter> getPainters() {
+
+        return paitersForPortrait;
+    }
+
+    public void setPainters(Collection<Painter> p) {
+        this.paitersForPortrait = p;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestGetMetaData.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestGetMetaData.java
index 9439385..29ef0d0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestGetMetaData.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestGetMetaData.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestGetMetaData extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(Item.class, Person.class, Artist.class, Painter.class,
-            CLEAR_TABLES);
-    }
-
-    public void testGetMetaData() {
-        assertNotNull(JPAFacadeHelper.getMetaData(emf, Item.class));
-        assertNotNull(JPAFacadeHelper.getMetaData(emf, Person.class));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestGetMetaData extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Item.class, Person.class, Artist.class, Painter.class,
+            CLEAR_TABLES);
+    }
+
+    public void testGetMetaData() {
+        assertNotNull(JPAFacadeHelper.getMetaData(emf, Item.class));
+        assertNotNull(JPAFacadeHelper.getMetaData(emf, Person.class));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java
index c93377f..b78fe8d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.meta;
-
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-public class TestMetaDataInheritanceComparator extends PersistenceTestCase {
-
-    public void testInheritanceComparatorWithBase() {
-        inheritanceComparatorHelper(true);
-    }
-
-    private void inheritanceComparatorHelper(boolean base) {
-        InheritanceComparator comp = new InheritanceComparator();
-        if (base)
-            comp.setBase(AbstractThing.class);
-
-        assertEquals(-1, comp.compare(A.class, B.class));
-        assertEquals(-1, comp.compare(B.class, C.class));
-        assertTrue(comp.compare(A.class, C.class) < 0);
-
-        assertEquals(-1, comp.compare(AbstractThing.class, A.class));
-        assertEquals(-1, comp.compare(AbstractThing.class, B.class));
-        assertTrue(comp.compare(AbstractThing.class, C.class) < 0);
-    }
-
-    public void testMetaDataInheritanceComparatorWithBase() {
-        metaDataInheritanceComparatorHelper(true);
-    }
-
-    private void metaDataInheritanceComparatorHelper(boolean base) {
-        InheritanceComparator comp = new MetaDataInheritanceComparator();
-        if (base)
-            comp.setBase(AbstractThing.class);
-
-        EntityManagerFactory emf = createEMF(A.class, B.class, C.class,
-            AbstractThing.class);
-
-        ClassMetaData a = JPAFacadeHelper.getMetaData(emf, A.class);
-        ClassMetaData b = JPAFacadeHelper.getMetaData(emf, B.class);
-        ClassMetaData c = JPAFacadeHelper.getMetaData(emf, C.class);
-        ClassMetaData at = JPAFacadeHelper.getMetaData(emf,
-            AbstractThing.class);
-
-        emf.close();
-
-        assertEquals(-1, comp.compare(a, b));
-        assertEquals(-1, comp.compare(b, c));
-        assertTrue(comp.compare(a, c) < 0);
-
-        assertEquals(1, comp.compare(b, a));
-        assertEquals(1, comp.compare(c, b));
-        assertTrue(comp.compare(c, a) > 0);
-
-        assertEquals(-1, comp.compare(at, a));
-        assertEquals(-1, comp.compare(at, b));
-        assertEquals(-1, comp.compare(at, c));
-    }
-
-    public void testEndToEnd() {
-        // make sure we can get things fully instantiated
-        EntityManagerFactory emf = createEMF(A.class, B.class, C.class,
-            AbstractThing.class);
-        emf.createEntityManager().close();
-        emf.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+public class TestMetaDataInheritanceComparator extends PersistenceTestCase {
+
+    public void testInheritanceComparatorWithBase() {
+        inheritanceComparatorHelper(true);
+    }
+
+    private void inheritanceComparatorHelper(boolean base) {
+        InheritanceComparator comp = new InheritanceComparator();
+        if (base)
+            comp.setBase(AbstractThing.class);
+
+        assertEquals(-1, comp.compare(A.class, B.class));
+        assertEquals(-1, comp.compare(B.class, C.class));
+        assertTrue(comp.compare(A.class, C.class) < 0);
+
+        assertEquals(-1, comp.compare(AbstractThing.class, A.class));
+        assertEquals(-1, comp.compare(AbstractThing.class, B.class));
+        assertTrue(comp.compare(AbstractThing.class, C.class) < 0);
+    }
+
+    public void testMetaDataInheritanceComparatorWithBase() {
+        metaDataInheritanceComparatorHelper(true);
+    }
+
+    private void metaDataInheritanceComparatorHelper(boolean base) {
+        InheritanceComparator comp = new MetaDataInheritanceComparator();
+        if (base)
+            comp.setBase(AbstractThing.class);
+
+        EntityManagerFactory emf = createEMF(A.class, B.class, C.class,
+            AbstractThing.class);
+
+        ClassMetaData a = JPAFacadeHelper.getMetaData(emf, A.class);
+        ClassMetaData b = JPAFacadeHelper.getMetaData(emf, B.class);
+        ClassMetaData c = JPAFacadeHelper.getMetaData(emf, C.class);
+        ClassMetaData at = JPAFacadeHelper.getMetaData(emf,
+            AbstractThing.class);
+
+        emf.close();
+
+        assertEquals(-1, comp.compare(a, b));
+        assertEquals(-1, comp.compare(b, c));
+        assertTrue(comp.compare(a, c) < 0);
+
+        assertEquals(1, comp.compare(b, a));
+        assertEquals(1, comp.compare(c, b));
+        assertTrue(comp.compare(c, a) > 0);
+
+        assertEquals(-1, comp.compare(at, a));
+        assertEquals(-1, comp.compare(at, b));
+        assertEquals(-1, comp.compare(at, c));
+    }
+
+    public void testEndToEnd() {
+        // make sure we can get things fully instantiated
+        EntityManagerFactory emf = createEMF(A.class, B.class, C.class,
+            AbstractThing.class);
+        emf.createEntityManager().close();
+        emf.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/AnnotationTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/AnnotationTestCase.java
index 991b68e..9f39748 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/AnnotationTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/AnnotationTestCase.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.annotations;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public abstract class AnnotationTestCase extends AbstractTestCase {
-
-    public AnnotationTestCase(String name, String s) {
-        super(name, s);
-    }
-
-    @Override
-    protected String computePersistenceXmlResource(String s) {
-        if (s.startsWith("annotation"))
-            return "org/apache/openjpa/persistence/annotations/common/apps/" +
-                "annotApp/annotype/META-INF/persistence.xml";
-        else if (s.startsWith("dd"))
-            return "org/apache/openjpa/persistence/annotations/common/apps/" +
-                "annotApp/ddtype/META-INF/persistence.xml";
-        else
-            return super.computePersistenceXmlResource(s);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public abstract class AnnotationTestCase extends AbstractTestCase {
+
+    public AnnotationTestCase(String name, String s) {
+        super(name, s);
+    }
+
+    @Override
+    protected String computePersistenceXmlResource(String s) {
+        if (s.startsWith("annotation"))
+            return "org/apache/openjpa/persistence/annotations/common/apps/" +
+                "annotApp/annotype/META-INF/persistence.xml";
+        else if (s.startsWith("dd"))
+            return "org/apache/openjpa/persistence/annotations/common/apps/" +
+                "annotApp/ddtype/META-INF/persistence.xml";
+        else
+            return super.computePersistenceXmlResource(s);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAdvAnnot.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAdvAnnot.java
index 1c4e622..f757ff8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAdvAnnot.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAdvAnnot.java
@@ -1,133 +1,133 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import junit.framework.*;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestAdvAnnot extends AnnotationTestCase
-{
-	public TestAdvAnnot(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-	public void setUp()
-	{
-		deleteAll(Schedule.class);
-		deleteAll(FlightSchedule.class);
-
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		for(int i = 0; i<5; i++)
-		{
-			Calendar cal = Calendar.getInstance();
-			Date date = new Date(01012006l);
-			Date edate = new Date(10031980l);
-			String name = "AmericaWest"+i;
-			String schedname = "Schedule"+i;
-			FlightSchedule sched = new FlightSchedule(schedname, cal, date, edate, name);
-
-			em.persist(sched);
-
-
-		}
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testTimeTemporalAnnot()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-
-		String query = "SELECT d.startDate FROM FlightSchedule d WHERE d.name = :name";
-
-		Date obj = (Date) em.createQuery(query)
-		              .setParameter("name", "Schedule3")
-		              .getSingleResult();
-
-		assertNotNull(obj);
-		assertTrue(obj instanceof Date);
-
-		endEm(em);
-	}
-
-	public void testCalendarTemporalAnnot()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		String query = "SELECT d FROM FlightSchedule d";
-
-		List list = em.createQuery(query).getResultList();
-		assertNotNull(list);
-		assertEquals(5, list.size());
-		/*
-		String query = "SELECT d.dob FROM FlightSchedule d WHERE d.name = :name";
-
-		List list = em.createQuery(query)
-		              .setParameter("name", "Schedule3")
-		              .getResultList();
-
-		assertNotNull(list);
-		assertTrue(list.get(0) instanceof Calendar);*/
-
-		endEm(em);
-	}
-
-	public void testUniqueConstraintAnnot()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		String query = "Update FlightSchedule f SET f.planeName = :plane WHERE f.name = :sname";
-		int upd = 0;
-
-		try
-		{
-			upd = em.createQuery(query)
-            .setParameter("plane", "AmericaWest3")
-            .setParameter("sname", "Schedule2")
-            .executeUpdate();
-
-			fail("Violated unique constraint rule...@Unique Constraint annotation needs to be supported");
-		}
-		catch(Exception e)
-		{
-			//suppose to throw exception based on the unique constraint rule
-		}
-
-		assertNotNull(upd);
-		assertEquals(0, upd);
-
-		endTx(em);
-		endEm(em);
-	}
-
-
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import junit.framework.*;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestAdvAnnot extends AnnotationTestCase
+{
+	public TestAdvAnnot(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+	public void setUp()
+	{
+		deleteAll(Schedule.class);
+		deleteAll(FlightSchedule.class);
+
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		for(int i = 0; i<5; i++)
+		{
+			Calendar cal = Calendar.getInstance();
+			Date date = new Date(01012006l);
+			Date edate = new Date(10031980l);
+			String name = "AmericaWest"+i;
+			String schedname = "Schedule"+i;
+			FlightSchedule sched = new FlightSchedule(schedname, cal, date, edate, name);
+
+			em.persist(sched);
+
+
+		}
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testTimeTemporalAnnot()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+
+		String query = "SELECT d.startDate FROM FlightSchedule d WHERE d.name = :name";
+
+		Date obj = (Date) em.createQuery(query)
+		              .setParameter("name", "Schedule3")
+		              .getSingleResult();
+
+		assertNotNull(obj);
+		assertTrue(obj instanceof Date);
+
+		endEm(em);
+	}
+
+	public void testCalendarTemporalAnnot()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		String query = "SELECT d FROM FlightSchedule d";
+
+		List list = em.createQuery(query).getResultList();
+		assertNotNull(list);
+		assertEquals(5, list.size());
+		/*
+		String query = "SELECT d.dob FROM FlightSchedule d WHERE d.name = :name";
+
+		List list = em.createQuery(query)
+		              .setParameter("name", "Schedule3")
+		              .getResultList();
+
+		assertNotNull(list);
+		assertTrue(list.get(0) instanceof Calendar);*/
+
+		endEm(em);
+	}
+
+	public void testUniqueConstraintAnnot()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		String query = "Update FlightSchedule f SET f.planeName = :plane WHERE f.name = :sname";
+		int upd = 0;
+
+		try
+		{
+			upd = em.createQuery(query)
+            .setParameter("plane", "AmericaWest3")
+            .setParameter("sname", "Schedule2")
+            .executeUpdate();
+
+			fail("Violated unique constraint rule...@Unique Constraint annotation needs to be supported");
+		}
+		catch(Exception e)
+		{
+			//suppose to throw exception based on the unique constraint rule
+		}
+
+		assertNotNull(upd);
+		assertEquals(0, upd);
+
+		endTx(em);
+		endEm(em);
+	}
+
+
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAnnotationBasics.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAnnotationBasics.java
index 3637bf1..024f593 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAnnotationBasics.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestAnnotationBasics.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-
-public class TestAnnotationBasics extends AnnotationTestCase {
-
-	public TestAnnotationBasics(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void testSingleFieldIdentity()
-    {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(em, Entity1.class);
-        assertTrue("Entity1 should use application identity",
-            ClassMetaData.ID_APPLICATION == meta.getIdentityType());
-        assertTrue("Entity1 should use single-field identity",
-            meta.isOpenJPAIdentity());
-    }
-/*
-    public void testVersionField() {
-        ClassMapping mapping = (ClassMapping) getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(Entity1.class,
-            null, true);
-        FieldMapping fm = mapping.getFieldMapping("versionField");
-        assertTrue(fm.isVersion());
-        String col = mapping.getVersion().getColumns()[0].getName();
-        assertTrue(col, "VERSIONFIELD".equalsIgnoreCase(col));
-    }
-*/}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+
+public class TestAnnotationBasics extends AnnotationTestCase {
+
+	public TestAnnotationBasics(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void testSingleFieldIdentity()
+    {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(em, Entity1.class);
+        assertTrue("Entity1 should use application identity",
+            ClassMetaData.ID_APPLICATION == meta.getIdentityType());
+        assertTrue("Entity1 should use single-field identity",
+            meta.isOpenJPAIdentity());
+    }
+/*
+    public void testVersionField() {
+        ClassMapping mapping = (ClassMapping) getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(Entity1.class,
+            null, true);
+        FieldMapping fm = mapping.getFieldMapping("versionField");
+        assertTrue(fm.isVersion());
+        String col = mapping.getVersion().getColumns()[0].getName();
+        assertTrue(col, "VERSIONFIELD".equalsIgnoreCase(col));
+    }
+*/}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestDDCallbackMethods.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestDDCallbackMethods.java
index cd40573..41acca6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestDDCallbackMethods.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestDDCallbackMethods.java
@@ -1,266 +1,266 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.util.List;
-
-import junit.framework.*;
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestDDCallbackMethods extends AnnotationTestCase
-{
-
-	public TestDDCallbackMethods(String name)
-	{
-		super(name, "ddcactusapp");
-	}
-
-	public void setUp()
-	{
-		deleteAll(LifeCycleDDEntity.class);
-		deleteAll(LifeCycleDDEntity2.class);
-		CallbackStorage.clearStore();
-	}
-
-	public void testDDPrpPop()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity lcd = new LifeCycleDDEntity("afam", "okeke");
-
-		em.persist(lcd);
-		CallbackStorage store = CallbackStorage.getInstance();
-
-		assertNotNull(store.getClist());
-		assertEquals(2, store.getClist().size());
-		assertEquals("def-prepersist", store.getClist().get(0));
-		assertEquals("def-postpersist", store.getClist().get(1));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testDDPrrPor()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity lcd = new LifeCycleDDEntity("john", "rash");
-
-		em.persist(lcd);
-		int id = lcd.getId();
-
-		lcd = em.find(LifeCycleDDEntity.class, id);
-
-		assertNotNull(lcd);
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.clearStore();
-
-		em.remove(lcd);
-
-		assertNotNull(store.getClist());
-		assertEquals(2, store.getClist().size());
-		assertEquals("def-preremove", store.getClist().get(0));
-		assertEquals("def-postremove", store.getClist().get(1) );
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testDDPouPru()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity lcd = new LifeCycleDDEntity("Don", "Shiddle");
-
-		em.persist(lcd);
-		int id = lcd.getId();
-
-		CallbackStorage.clearStore();
-
-		String query = "Update LifeCycleDDEntity e SET e.name = 'Joseph' WHERE e.id = :id";
-
-		int result = em.createQuery(query)
-		               .setParameter("id", id)
-		               .executeUpdate();
-
-		List store = CallbackStorage.getInstance().getClist();
-
-		assertNotNull(result);
-		assertEquals(1, result);
-		assertNotNull(store);
-		assertEquals(2, store.size());
-		assertEquals("def-preupdate", store.get(0));
-		assertEquals("def-postupdate", store.get(1));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testDDPol()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity lcd = new LifeCycleDDEntity("Julie", "Jolie");
-
-		em.persist(lcd);
-		int id = lcd.getId();
-
-        CallbackStorage.clearStore();
-
-		endTx(em);
-
-		startTx(em);
-		CallbackStorage.clearStore();
-
-		assertTrue(CallbackStorage.getInstance().getClist().isEmpty());
-
-		lcd = em.find(LifeCycleDDEntity.class, id);
-		em.refresh(lcd);
-
-		assertNotNull(lcd);
-		assertNotNull(CallbackStorage.getInstance().getClist());
-		assertEquals(2, CallbackStorage.getInstance().getClist().size());
-		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(0));
-		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(1));
-
-		endTx(em);
-		endEm(em);
-
-	}
-
-	/**  DEFAULT LISTENER DD TESTING **/
-
-	public void testDefaultPrePostPersistListener()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity2 lc = new LifeCycleDDEntity2("Bill", "Clinton");
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.clearStore();
-
-		em.persist(lc);
-
-		assertEquals(4, store.getClist().size());
-		assertEquals("def-prepersist", store.getClist().get(0));
-		assertEquals("verifyprp", store.getClist().get(1));
-		assertEquals("def-postpersist", store.getClist().get(2));
-		assertEquals("verifypop", store.getClist().get(3));
-
-		endTx(em);
-		endEm(em);
-	}
-
-    //FIX-ME Default-Entity-listener Impl. is over firing
-	public void testDefaultPrePostUpdateListener()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity2 emp = new LifeCycleDDEntity2("lincoln", "Abraham");
-
-		em.persist(emp);
-
-		int id = emp.getId();
-
-		CallbackStorage.clearStore();
-
-		String query = "Update LifeCycleDDEntity2 e SET e.name = 'Joseph' WHERE e.id = :id";
-
-		int result = em.createQuery(query)
-		               .setParameter("id", id)
-		               .executeUpdate();
-
-		List store = CallbackStorage.getInstance().getClist();
-
-		assertNotNull(result);
-		assertEquals(1, result);
-		assertNotNull(store);
-		assertEquals(2, store.size());
-		assertEquals("def-preupdate", store.get(0));
-		assertEquals("def-postupdate", store.get(1));
-//		assertEquals("def-postupdate", store.get(2));
-//		assertEquals("def-postupdate", store.get(3));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	//FIX-ME Default-Entity-listener Impl. is over firing
-	public void testDefaultPostLoadListener()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity2 emp = new LifeCycleDDEntity2("Thomas", "Jefferson");
-
-		em.persist(emp);
-		int id = emp.getId();
-		CallbackStorage.clearStore();
-
-		endTx(em);
-
-		startTx(em);
-		CallbackStorage.clearStore();
-
-		assertTrue("not empty...", CallbackStorage.isEmpty());
-
-		emp = em.find(LifeCycleDDEntity2.class, id);
-		em.refresh(emp);
-
-		assertNotNull(emp);
-		assertNotNull(CallbackStorage.getInstance().getClist());
-		assertEquals(2, CallbackStorage.getInstance().getClist().size());
-		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(0));
-		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(1));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testSubClassOverrideSuperCallbacksInh()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		LifeCycleDDEntity2 emp = new LifeCycleDDEntity2("Thomas", "Jefferson");
-
-		em.persist(emp);
-
-		assertNotNull(emp);
-		assertNotNull(CallbackStorage.getInstance().getClist());
-		assertEquals(4, CallbackStorage.getInstance().getClist().size());
-		assertEquals("def-prepersist", CallbackStorage.getInstance().getClist().get(0));
-		assertEquals("verifyprp", CallbackStorage.getInstance().getClist().get(1));
-		assertEquals("def-postpersist", CallbackStorage.getInstance().getClist().get(2));
-		assertEquals("verifypop", CallbackStorage.getInstance().getClist().get(3));
-
-		endTx(em);
-		endEm(em);
-	}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.util.List;
+
+import junit.framework.*;
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestDDCallbackMethods extends AnnotationTestCase
+{
+
+	public TestDDCallbackMethods(String name)
+	{
+		super(name, "ddcactusapp");
+	}
+
+	public void setUp()
+	{
+		deleteAll(LifeCycleDDEntity.class);
+		deleteAll(LifeCycleDDEntity2.class);
+		CallbackStorage.clearStore();
+	}
+
+	public void testDDPrpPop()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity lcd = new LifeCycleDDEntity("afam", "okeke");
+
+		em.persist(lcd);
+		CallbackStorage store = CallbackStorage.getInstance();
+
+		assertNotNull(store.getClist());
+		assertEquals(2, store.getClist().size());
+		assertEquals("def-prepersist", store.getClist().get(0));
+		assertEquals("def-postpersist", store.getClist().get(1));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testDDPrrPor()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity lcd = new LifeCycleDDEntity("john", "rash");
+
+		em.persist(lcd);
+		int id = lcd.getId();
+
+		lcd = em.find(LifeCycleDDEntity.class, id);
+
+		assertNotNull(lcd);
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.clearStore();
+
+		em.remove(lcd);
+
+		assertNotNull(store.getClist());
+		assertEquals(2, store.getClist().size());
+		assertEquals("def-preremove", store.getClist().get(0));
+		assertEquals("def-postremove", store.getClist().get(1) );
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testDDPouPru()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity lcd = new LifeCycleDDEntity("Don", "Shiddle");
+
+		em.persist(lcd);
+		int id = lcd.getId();
+
+		CallbackStorage.clearStore();
+
+		String query = "Update LifeCycleDDEntity e SET e.name = 'Joseph' WHERE e.id = :id";
+
+		int result = em.createQuery(query)
+		               .setParameter("id", id)
+		               .executeUpdate();
+
+		List store = CallbackStorage.getInstance().getClist();
+
+		assertNotNull(result);
+		assertEquals(1, result);
+		assertNotNull(store);
+		assertEquals(2, store.size());
+		assertEquals("def-preupdate", store.get(0));
+		assertEquals("def-postupdate", store.get(1));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testDDPol()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity lcd = new LifeCycleDDEntity("Julie", "Jolie");
+
+		em.persist(lcd);
+		int id = lcd.getId();
+
+        CallbackStorage.clearStore();
+
+		endTx(em);
+
+		startTx(em);
+		CallbackStorage.clearStore();
+
+		assertTrue(CallbackStorage.getInstance().getClist().isEmpty());
+
+		lcd = em.find(LifeCycleDDEntity.class, id);
+		em.refresh(lcd);
+
+		assertNotNull(lcd);
+		assertNotNull(CallbackStorage.getInstance().getClist());
+		assertEquals(2, CallbackStorage.getInstance().getClist().size());
+		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(0));
+		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(1));
+
+		endTx(em);
+		endEm(em);
+
+	}
+
+	/**  DEFAULT LISTENER DD TESTING **/
+
+	public void testDefaultPrePostPersistListener()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity2 lc = new LifeCycleDDEntity2("Bill", "Clinton");
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.clearStore();
+
+		em.persist(lc);
+
+		assertEquals(4, store.getClist().size());
+		assertEquals("def-prepersist", store.getClist().get(0));
+		assertEquals("verifyprp", store.getClist().get(1));
+		assertEquals("def-postpersist", store.getClist().get(2));
+		assertEquals("verifypop", store.getClist().get(3));
+
+		endTx(em);
+		endEm(em);
+	}
+
+    //FIX-ME Default-Entity-listener Impl. is over firing
+	public void testDefaultPrePostUpdateListener()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity2 emp = new LifeCycleDDEntity2("lincoln", "Abraham");
+
+		em.persist(emp);
+
+		int id = emp.getId();
+
+		CallbackStorage.clearStore();
+
+		String query = "Update LifeCycleDDEntity2 e SET e.name = 'Joseph' WHERE e.id = :id";
+
+		int result = em.createQuery(query)
+		               .setParameter("id", id)
+		               .executeUpdate();
+
+		List store = CallbackStorage.getInstance().getClist();
+
+		assertNotNull(result);
+		assertEquals(1, result);
+		assertNotNull(store);
+		assertEquals(2, store.size());
+		assertEquals("def-preupdate", store.get(0));
+		assertEquals("def-postupdate", store.get(1));
+//		assertEquals("def-postupdate", store.get(2));
+//		assertEquals("def-postupdate", store.get(3));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	//FIX-ME Default-Entity-listener Impl. is over firing
+	public void testDefaultPostLoadListener()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity2 emp = new LifeCycleDDEntity2("Thomas", "Jefferson");
+
+		em.persist(emp);
+		int id = emp.getId();
+		CallbackStorage.clearStore();
+
+		endTx(em);
+
+		startTx(em);
+		CallbackStorage.clearStore();
+
+		assertTrue("not empty...", CallbackStorage.isEmpty());
+
+		emp = em.find(LifeCycleDDEntity2.class, id);
+		em.refresh(emp);
+
+		assertNotNull(emp);
+		assertNotNull(CallbackStorage.getInstance().getClist());
+		assertEquals(2, CallbackStorage.getInstance().getClist().size());
+		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(0));
+		assertEquals("def-postload", CallbackStorage.getInstance().getClist().get(1));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testSubClassOverrideSuperCallbacksInh()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		LifeCycleDDEntity2 emp = new LifeCycleDDEntity2("Thomas", "Jefferson");
+
+		em.persist(emp);
+
+		assertNotNull(emp);
+		assertNotNull(CallbackStorage.getInstance().getClist());
+		assertEquals(4, CallbackStorage.getInstance().getClist().size());
+		assertEquals("def-prepersist", CallbackStorage.getInstance().getClist().get(0));
+		assertEquals("verifyprp", CallbackStorage.getInstance().getClist().get(1));
+		assertEquals("def-postpersist", CallbackStorage.getInstance().getClist().get(2));
+		assertEquals("verifypop", CallbackStorage.getInstance().getClist().get(3));
+
+		endTx(em);
+		endEm(em);
+	}
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEJBEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEJBEmbedded.java
index f8e181e..98b6176 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEJBEmbedded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEJBEmbedded.java
@@ -1,140 +1,140 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.sql.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.meta.strats.*;
-import org.apache.openjpa.jdbc.sql.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-//import kodo.persistence.test.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-import junit.framework.*;
-
-/**
- * Test for embedded
- *
- * @author Steve Kim
- */
-public class TestEJBEmbedded extends AnnotationTestCase
-{
-
-	public TestEJBEmbedded(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    private static final String CLOB;
-
-    static {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < 1000; i++)
-            buf.append('a');
-        CLOB = buf.toString();
-    }
-
-    public void setUp()
-    {
-        deleteAll (EmbedOwner.class);
-    }
-
-    public void testEmbedded()
-    {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        EmbedOwner owner = new EmbedOwner();
-        owner.setBasic("foo");
-        EmbedValue embed = new EmbedValue();
-        embed.setClob(CLOB);
-        embed.setBasic("bar");
-        embed.setBlob("foobar".getBytes());
-        embed.setOwner(owner);
-        owner.setEmbed(embed);
-        em.persist(owner);
-        int pk = owner.getPk();
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        owner = em.find(EmbedOwner.class, pk);
-        assertEquals("foo", owner.getBasic());
-        embed = owner.getEmbed();
-        assertNotNull(embed);
-        assertEquals(CLOB, embed.getClob());
-        assertEquals("bar", embed.getBasic());
-        assertEquals("foobar", new String(embed.getBlob()));
-        assertEquals(owner, embed.getOwner());
-        endEm(em);
-    }
-
-    public void testNull() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        EmbedOwner owner = new EmbedOwner();
-        owner.setBasic("foo");
-        em.persist(owner);
-        int pk = owner.getPk();
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        owner = em.find(EmbedOwner.class, pk);
-        assertEquals("foo", owner.getBasic());
-        EmbedValue embed = owner.getEmbed();
-        assertNotNull(embed);
-        assertNull(embed.getClob());
-        assertNull(embed.getBasic());
-        assertNull(embed.getBlob());
-        startTx(em);
-    }
-
-//    public void testMappingTransferAndOverride() {
-//        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-//        ClassMapping cls = conf.getMappingRepositoryInstance().getMapping
-//            (EmbedOwner.class, null, true);
-//        assertEquals("OWN_BASIC", cls.getFieldMapping("basic").
-//            getColumns()[0].getName());
-//        ClassMapping embed = cls.getFieldMapping("embed").currentEntityManager()beddedMapping();
-//        assertEquals("EMB_BLOB", embed.getFieldMapping("blob").
-//            getColumns()[0].getName());
-//        assertEquals("OVER_BASIC", embed.getFieldMapping("basic").
-//            getColumns()[0].getName());
-//        assertEquals("OVER_OWNER", embed.getFieldMapping("owner").
-//            getColumns()[0].getName());
-//
-//        FieldMapping fm = embed.getFieldMapping("clob");
-//        DBDictionary dict = conf.getDBDictionaryInstance();
-//        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
-//            if (dict.maxEmbeddedClobSize > 0)
-//                assertTrue(fm.getStrategy() instanceof
-//                    MaxEmbeddedClobFieldStrategy);
-//            else
-//                assertTrue(fm.getHandler() instanceof ClobValueHandler);
-//        } else
-//            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
-//    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.sql.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.jdbc.sql.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+//import kodo.persistence.test.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+import junit.framework.*;
+
+/**
+ * Test for embedded
+ *
+ * @author Steve Kim
+ */
+public class TestEJBEmbedded extends AnnotationTestCase
+{
+
+	public TestEJBEmbedded(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    private static final String CLOB;
+
+    static {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < 1000; i++)
+            buf.append('a');
+        CLOB = buf.toString();
+    }
+
+    public void setUp()
+    {
+        deleteAll (EmbedOwner.class);
+    }
+
+    public void testEmbedded()
+    {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        EmbedOwner owner = new EmbedOwner();
+        owner.setBasic("foo");
+        EmbedValue embed = new EmbedValue();
+        embed.setClob(CLOB);
+        embed.setBasic("bar");
+        embed.setBlob("foobar".getBytes());
+        embed.setOwner(owner);
+        owner.setEmbed(embed);
+        em.persist(owner);
+        int pk = owner.getPk();
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        owner = em.find(EmbedOwner.class, pk);
+        assertEquals("foo", owner.getBasic());
+        embed = owner.getEmbed();
+        assertNotNull(embed);
+        assertEquals(CLOB, embed.getClob());
+        assertEquals("bar", embed.getBasic());
+        assertEquals("foobar", new String(embed.getBlob()));
+        assertEquals(owner, embed.getOwner());
+        endEm(em);
+    }
+
+    public void testNull() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        EmbedOwner owner = new EmbedOwner();
+        owner.setBasic("foo");
+        em.persist(owner);
+        int pk = owner.getPk();
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        owner = em.find(EmbedOwner.class, pk);
+        assertEquals("foo", owner.getBasic());
+        EmbedValue embed = owner.getEmbed();
+        assertNotNull(embed);
+        assertNull(embed.getClob());
+        assertNull(embed.getBasic());
+        assertNull(embed.getBlob());
+        startTx(em);
+    }
+
+//    public void testMappingTransferAndOverride() {
+//        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+//        ClassMapping cls = conf.getMappingRepositoryInstance().getMapping
+//            (EmbedOwner.class, null, true);
+//        assertEquals("OWN_BASIC", cls.getFieldMapping("basic").
+//            getColumns()[0].getName());
+//        ClassMapping embed = cls.getFieldMapping("embed").currentEntityManager()beddedMapping();
+//        assertEquals("EMB_BLOB", embed.getFieldMapping("blob").
+//            getColumns()[0].getName());
+//        assertEquals("OVER_BASIC", embed.getFieldMapping("basic").
+//            getColumns()[0].getName());
+//        assertEquals("OVER_OWNER", embed.getFieldMapping("owner").
+//            getColumns()[0].getName());
+//
+//        FieldMapping fm = embed.getFieldMapping("clob");
+//        DBDictionary dict = conf.getDBDictionaryInstance();
+//        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
+//            if (dict.maxEmbeddedClobSize > 0)
+//                assertTrue(fm.getStrategy() instanceof
+//                    MaxEmbeddedClobFieldStrategy);
+//            else
+//                assertTrue(fm.getHandler() instanceof ClobValueHandler);
+//        } else
+//            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
+//    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddableSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddableSuperclass.java
index de56598..a373c89 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddableSuperclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddableSuperclass.java
@@ -1,140 +1,140 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.sql.*;
-
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.meta.strats.*;
-import org.apache.openjpa.jdbc.sql.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-import junit.framework.*;
-
-/**
- * <p>Test embeddable superclasses.</p>
- *
- * @author Abe White
- */
-public class TestEmbeddableSuperclass extends AnnotationTestCase
-{
-
-	public TestEmbeddableSuperclass(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp() {
-        deleteAll(EmbeddableSuperSub.class);
-    }
-
-    /*public void testSuperclassEmbeddedOnly() {
-        ClassMapping cls = ((JDBCConfiguration) getConfiguration()).
-            getMappingRepositoryInstance().getMapping(EmbeddableSuper.class,
-            null, true);
-        assertTrue(cls.isEmbeddedOnly());
-        assertEquals(NoneClassStrategy.getInstance(), cls.getStrategy());
-    }
-
-    public void testSubclassMappingDefaultsAndOverrides() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        assertTrue(!cls.isEmbeddedOnly());
-        assertTrue(cls.getStrategy() instanceof FullClassStrategy);
-        assertEquals(ClassMapping.ID_APPLICATION, cls.getIdentityType());
-        assertTrue(cls.isOpenJPAIdentity());
-
-        FieldMapping fm = cls.getFieldMapping("pk");
-        assertTrue(fm.isPrimaryKey());
-        assertEquals(ValueStrategies.SEQUENCE, fm.getValueStrategy());
-        assertEquals("ID", fm.getColumns()[0].getName());
-
-        assertNull(cls.getField("trans"));
-
-        fm = cls.getFieldMapping("clob");
-        assertEquals("CC", fm.getColumns()[0].getName());
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
-            if (dict.maxEmbeddedClobSize > 0)
-                assertTrue(fm.getStrategy() instanceof
-                    MaxEmbeddedClobFieldStrategy);
-            else
-                assertTrue(fm.getHandler() instanceof ClobValueHandler);
-        } else
-            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
-    }
-
-    public void testSubclassDiscriminatorMapping() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        assertEquals("DISC", cls.getDiscriminator().getColumns()[0].
-            getName());
-    }
-
-    public void testVersionOverrideMapping() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        assertEquals("VERSVAL", cls.getVersion().getColumns()[0].getName());
-    }
-
-    public void testRelationMappings() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        FieldMapping fm = cls.getFieldMapping("sub");
-        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
-
-        fm = cls.getFieldMapping("sup");
-        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
-    }
-*/
-    public void testPersistAndFind() {
-        EmbeddableSuperSub parent = new EmbeddableSuperSub();
-        parent.setClob("parent");
-        EmbeddableSuperSub sub = new EmbeddableSuperSub();
-        sub.setClob("sub");
-        EmbeddableSuperSub sup = new EmbeddableSuperSub();
-        sup.setClob("sup");
-        parent.setSub(sub);
-        parent.setSup(sup);
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        em.persistAll(parent, sub, sup);
-        endTx(em);
-        long pk = parent.getPK();
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        parent = em.find(EmbeddableSuperSub.class, pk);
-        assertEquals("parent", parent.getClob());
-        assertEquals("sub", parent.getSub().getClob());
-        assertEquals("sup", parent.getSup().getClob());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.sql.*;
+
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.jdbc.sql.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+import junit.framework.*;
+
+/**
+ * <p>Test embeddable superclasses.</p>
+ *
+ * @author Abe White
+ */
+public class TestEmbeddableSuperclass extends AnnotationTestCase
+{
+
+	public TestEmbeddableSuperclass(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp() {
+        deleteAll(EmbeddableSuperSub.class);
+    }
+
+    /*public void testSuperclassEmbeddedOnly() {
+        ClassMapping cls = ((JDBCConfiguration) getConfiguration()).
+            getMappingRepositoryInstance().getMapping(EmbeddableSuper.class,
+            null, true);
+        assertTrue(cls.isEmbeddedOnly());
+        assertEquals(NoneClassStrategy.getInstance(), cls.getStrategy());
+    }
+
+    public void testSubclassMappingDefaultsAndOverrides() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        assertTrue(!cls.isEmbeddedOnly());
+        assertTrue(cls.getStrategy() instanceof FullClassStrategy);
+        assertEquals(ClassMapping.ID_APPLICATION, cls.getIdentityType());
+        assertTrue(cls.isOpenJPAIdentity());
+
+        FieldMapping fm = cls.getFieldMapping("pk");
+        assertTrue(fm.isPrimaryKey());
+        assertEquals(ValueStrategies.SEQUENCE, fm.getValueStrategy());
+        assertEquals("ID", fm.getColumns()[0].getName());
+
+        assertNull(cls.getField("trans"));
+
+        fm = cls.getFieldMapping("clob");
+        assertEquals("CC", fm.getColumns()[0].getName());
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
+            if (dict.maxEmbeddedClobSize > 0)
+                assertTrue(fm.getStrategy() instanceof
+                    MaxEmbeddedClobFieldStrategy);
+            else
+                assertTrue(fm.getHandler() instanceof ClobValueHandler);
+        } else
+            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
+    }
+
+    public void testSubclassDiscriminatorMapping() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        assertEquals("DISC", cls.getDiscriminator().getColumns()[0].
+            getName());
+    }
+
+    public void testVersionOverrideMapping() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        assertEquals("VERSVAL", cls.getVersion().getColumns()[0].getName());
+    }
+
+    public void testRelationMappings() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        FieldMapping fm = cls.getFieldMapping("sub");
+        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
+
+        fm = cls.getFieldMapping("sup");
+        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
+    }
+*/
+    public void testPersistAndFind() {
+        EmbeddableSuperSub parent = new EmbeddableSuperSub();
+        parent.setClob("parent");
+        EmbeddableSuperSub sub = new EmbeddableSuperSub();
+        sub.setClob("sub");
+        EmbeddableSuperSub sup = new EmbeddableSuperSub();
+        sup.setClob("sup");
+        parent.setSub(sub);
+        parent.setSup(sup);
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persistAll(parent, sub, sup);
+        endTx(em);
+        long pk = parent.getPK();
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        parent = em.find(EmbeddableSuperSub.class, pk);
+        assertEquals("parent", parent.getClob());
+        assertEquals("sub", parent.getSub().getClob());
+        assertEquals("sup", parent.getSup().getClob());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddedId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddedId.java
index 62a2f4f..2f2fd08 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddedId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEmbeddedId.java
@@ -1,264 +1,264 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.enhance.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-/**
- * <p>Test embedded id classes.</p>
- *
- * @author Abe White
- */
-public class TestEmbeddedId extends AnnotationTestCase
-{
-
-	public TestEmbeddedId(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    EmbeddedIdClass _oid;
-    EmbeddedIdClass _roid;
-
-    public void setUp() {
-        deleteAll(EmbeddedIdEntity.class);
-
-        _oid = new EmbeddedIdClass();
-        _oid.setPk1(1);
-        _oid.setPk2(2);
-
-        EmbeddedIdEntity e = new EmbeddedIdEntity();
-        e.setId(_oid);
-        e.setValue("e");
-
-        _roid = new EmbeddedIdClass();
-        _roid.setPk1(2);
-        _roid.setPk2(3);
-
-        EmbeddedIdEntity rel = new EmbeddedIdEntity();
-        rel.setId(_roid);
-        rel.setValue("r");
-        e.setRelation(rel);
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        em.persistAll(e, rel);
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testGetObjectId() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
-        assertNotNull(e);
-        assertEquals("e", e.getValue());
-        assertNull(e.getMappingOverrideRelation());
-        assertNotNull(e.getRelation());
-        assertEquals("r", e.getRelation().getValue());
-
-        assertEquals(_oid, em.getObjectId(e));
-        assertEquals(_roid, em.getObjectId(e.getRelation()));
-        assertEquals(_oid, e.getId());
-        assertEquals(_roid, e.getRelation().getId());
-        assertNull(((PersistenceCapable) e.getId()).pcGetGenericContext());
-        endEm(em);
-    }
-
-    public void testMutateEmbeddedIdFieldValueOfNew() {
-        EmbeddedIdEntity e1 = new EmbeddedIdEntity();
-        e1.setValue("e1");
-        EmbeddedIdEntity e2 = new EmbeddedIdEntity();
-        e2.setValue("e2");
-        
-        e2.setId(new EmbeddedIdClass());
-        //Comment this since pk3 is auto-generated and assigning
-        //it explicitly causes a rollback
-        //e2.getId().setPk3(99); // prevent assign on access
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        //em.persistAll(e1, e2);
-
-         EmbeddedIdClass oid = new EmbeddedIdClass();
-        oid.setPk1(4);
-        oid.setPk2(5);
-        //Comment this since pk3 is auto-generated and assigning
-        //it explicitly causes a rollback
-        //oid.setPk3(6);
-        e1.setId(oid);
-        e2.getId().setPk1(6);
-        e2.getId().setPk2(7);
-        em.persistAll(e1, e2);
-
-        endTx(em);
-
-        EmbeddedIdClass oid1 = e1.getId();
-        EmbeddedIdClass oid2 = e2.getId();
-        assertEquals(oid1, em.getObjectId(e1));
-        assertEquals(oid2, em.getObjectId(e2));
-        assertEquals(4, oid1.getPk1());
-        assertEquals(5, oid1.getPk2());
-        assertEquals(6, oid2.getPk1());
-        assertEquals(7, oid2.getPk2());
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        e1 = em.find(EmbeddedIdEntity.class, oid1);
-        e2 = em.find(EmbeddedIdEntity.class, oid2);
-        assertEquals(oid1, em.getObjectId(e1));
-        assertEquals(oid2, em.getObjectId(e2));
-        assertEquals(oid1, e1.getId());
-        assertEquals(oid2, e2.getId());
-        endEm(em);
-    }
-
-    public void testMutateEmbeddedIdFieldValueOfExisting() 
-    {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
-        e.setValue("changed");
-        try {
-            e.getId().setPk1(9);
-            endTx(em);
-            fail("Committed with changed oid field.");
-        } catch (RuntimeException re) {
-            if (isActiveTx(em))
-            	rollbackTx(em);
-        }
-        catch (Exception exc)
-        {
-            if (isActiveTx(em))
-            	rollbackTx(em);
-        }
-        endEm(em);
-    }
-
-    public void testDetachAttach() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
-        e.getRelation();
-        endEm(em);
-
-        e.setValue("echanged");
-        e.getRelation().setValue("rchanged");
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        EmbeddedIdEntity me = (EmbeddedIdEntity) em.mergeAll(e,
-            e.getRelation())[0];
-        assertTrue(me != e);
-        assertNotNull(me.getRelation());
-        assertTrue(me.getRelation() != e.getRelation());
-        assertEquals("echanged", me.getValue());
-        assertEquals("rchanged", me.getRelation().getValue());
-        assertEquals(_oid, me.getId());
-        assertEquals(_oid, em.getObjectId(me));
-        assertEquals(_roid, me.getRelation().getId());
-        assertEquals(_roid, em.getObjectId(me.getRelation()));
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testQuery() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        Query q = em.createQuery("select e from EmbeddedIdEntity e "
-            + "where e.id.pk1 = 1");
-        EmbeddedIdEntity e = (EmbeddedIdEntity) q.getSingleResult();
-        assertEquals(_oid, e.getId());
-        assertEquals("e", e.getValue());
-
-        q = em.createQuery("select e.id.pk2 from EmbeddedIdEntity e "
-            + "where e.id.pk1 = 1");
-        assertEquals(new Long(_oid.getPk2()), q.getSingleResult());
-
-        q = em.createQuery("select e.id from EmbeddedIdEntity e "
-            + "where e.id.pk1 = 1");
-        assertEquals(_oid, q.getSingleResult());
-        endEm(em);
-    }
-
-    public void testAutoAssigned() {
-        // begin with null id object
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        EmbeddedIdEntity e = new EmbeddedIdEntity();
-        em.persist(e);
-        EmbeddedIdClass oid = e.getId();
-        assertNotNull(oid);
-        assertTrue(oid.getPk3() != 0);
-        assertEquals(oid, em.getObjectId(e));
-        endTx(em);
-        assertEquals(oid, em.getObjectId(e));
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        e = em.find(EmbeddedIdEntity.class, oid);
-        assertEquals(oid, em.getObjectId(e));
-        endEm(em);
-
-        // begin with non-null id object
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        e = new EmbeddedIdEntity();
-        oid = new EmbeddedIdClass();
-        oid.setPk1(4);
-        oid.setPk2(5);
-        e.setId(oid);
-        em.persist(e);
-        oid = e.getId();
-        assertEquals(4, oid.getPk1());
-        assertEquals(5, oid.getPk2());
-        assertTrue(oid.getPk3() != 0);
-        assertEquals(oid, em.getObjectId(e));
-        endTx(em);
-        assertEquals(oid, em.getObjectId(e));
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        e = em.find(EmbeddedIdEntity.class, oid);
-        assertEquals(oid, em.getObjectId(e));
-        endEm(em);
-
-        // flush before accessing id field
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        e = new EmbeddedIdEntity();
-        em.persist(e);
-        endTx(em);
-        oid = e.getId();
-        assertTrue(oid.getPk3() != 0);
-        assertEquals(oid, em.getObjectId(e));
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        e = em.find(EmbeddedIdEntity.class, oid);
-        assertEquals(oid, em.getObjectId(e));
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.enhance.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+/**
+ * <p>Test embedded id classes.</p>
+ *
+ * @author Abe White
+ */
+public class TestEmbeddedId extends AnnotationTestCase
+{
+
+	public TestEmbeddedId(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    EmbeddedIdClass _oid;
+    EmbeddedIdClass _roid;
+
+    public void setUp() {
+        deleteAll(EmbeddedIdEntity.class);
+
+        _oid = new EmbeddedIdClass();
+        _oid.setPk1(1);
+        _oid.setPk2(2);
+
+        EmbeddedIdEntity e = new EmbeddedIdEntity();
+        e.setId(_oid);
+        e.setValue("e");
+
+        _roid = new EmbeddedIdClass();
+        _roid.setPk1(2);
+        _roid.setPk2(3);
+
+        EmbeddedIdEntity rel = new EmbeddedIdEntity();
+        rel.setId(_roid);
+        rel.setValue("r");
+        e.setRelation(rel);
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persistAll(e, rel);
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testGetObjectId() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
+        assertNotNull(e);
+        assertEquals("e", e.getValue());
+        assertNull(e.getMappingOverrideRelation());
+        assertNotNull(e.getRelation());
+        assertEquals("r", e.getRelation().getValue());
+
+        assertEquals(_oid, em.getObjectId(e));
+        assertEquals(_roid, em.getObjectId(e.getRelation()));
+        assertEquals(_oid, e.getId());
+        assertEquals(_roid, e.getRelation().getId());
+        assertNull(((PersistenceCapable) e.getId()).pcGetGenericContext());
+        endEm(em);
+    }
+
+    public void testMutateEmbeddedIdFieldValueOfNew() {
+        EmbeddedIdEntity e1 = new EmbeddedIdEntity();
+        e1.setValue("e1");
+        EmbeddedIdEntity e2 = new EmbeddedIdEntity();
+        e2.setValue("e2");
+        
+        e2.setId(new EmbeddedIdClass());
+        //Comment this since pk3 is auto-generated and assigning
+        //it explicitly causes a rollback
+        //e2.getId().setPk3(99); // prevent assign on access
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        //em.persistAll(e1, e2);
+
+         EmbeddedIdClass oid = new EmbeddedIdClass();
+        oid.setPk1(4);
+        oid.setPk2(5);
+        //Comment this since pk3 is auto-generated and assigning
+        //it explicitly causes a rollback
+        //oid.setPk3(6);
+        e1.setId(oid);
+        e2.getId().setPk1(6);
+        e2.getId().setPk2(7);
+        em.persistAll(e1, e2);
+
+        endTx(em);
+
+        EmbeddedIdClass oid1 = e1.getId();
+        EmbeddedIdClass oid2 = e2.getId();
+        assertEquals(oid1, em.getObjectId(e1));
+        assertEquals(oid2, em.getObjectId(e2));
+        assertEquals(4, oid1.getPk1());
+        assertEquals(5, oid1.getPk2());
+        assertEquals(6, oid2.getPk1());
+        assertEquals(7, oid2.getPk2());
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        e1 = em.find(EmbeddedIdEntity.class, oid1);
+        e2 = em.find(EmbeddedIdEntity.class, oid2);
+        assertEquals(oid1, em.getObjectId(e1));
+        assertEquals(oid2, em.getObjectId(e2));
+        assertEquals(oid1, e1.getId());
+        assertEquals(oid2, e2.getId());
+        endEm(em);
+    }
+
+    public void testMutateEmbeddedIdFieldValueOfExisting() 
+    {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
+        e.setValue("changed");
+        try {
+            e.getId().setPk1(9);
+            endTx(em);
+            fail("Committed with changed oid field.");
+        } catch (RuntimeException re) {
+            if (isActiveTx(em))
+            	rollbackTx(em);
+        }
+        catch (Exception exc)
+        {
+            if (isActiveTx(em))
+            	rollbackTx(em);
+        }
+        endEm(em);
+    }
+
+    public void testDetachAttach() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
+        e.getRelation();
+        endEm(em);
+
+        e.setValue("echanged");
+        e.getRelation().setValue("rchanged");
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        EmbeddedIdEntity me = (EmbeddedIdEntity) em.mergeAll(e,
+            e.getRelation())[0];
+        assertTrue(me != e);
+        assertNotNull(me.getRelation());
+        assertTrue(me.getRelation() != e.getRelation());
+        assertEquals("echanged", me.getValue());
+        assertEquals("rchanged", me.getRelation().getValue());
+        assertEquals(_oid, me.getId());
+        assertEquals(_oid, em.getObjectId(me));
+        assertEquals(_roid, me.getRelation().getId());
+        assertEquals(_roid, em.getObjectId(me.getRelation()));
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testQuery() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        Query q = em.createQuery("select e from EmbeddedIdEntity e "
+            + "where e.id.pk1 = 1");
+        EmbeddedIdEntity e = (EmbeddedIdEntity) q.getSingleResult();
+        assertEquals(_oid, e.getId());
+        assertEquals("e", e.getValue());
+
+        q = em.createQuery("select e.id.pk2 from EmbeddedIdEntity e "
+            + "where e.id.pk1 = 1");
+        assertEquals(new Long(_oid.getPk2()), q.getSingleResult());
+
+        q = em.createQuery("select e.id from EmbeddedIdEntity e "
+            + "where e.id.pk1 = 1");
+        assertEquals(_oid, q.getSingleResult());
+        endEm(em);
+    }
+
+    public void testAutoAssigned() {
+        // begin with null id object
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        EmbeddedIdEntity e = new EmbeddedIdEntity();
+        em.persist(e);
+        EmbeddedIdClass oid = e.getId();
+        assertNotNull(oid);
+        assertTrue(oid.getPk3() != 0);
+        assertEquals(oid, em.getObjectId(e));
+        endTx(em);
+        assertEquals(oid, em.getObjectId(e));
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        e = em.find(EmbeddedIdEntity.class, oid);
+        assertEquals(oid, em.getObjectId(e));
+        endEm(em);
+
+        // begin with non-null id object
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        e = new EmbeddedIdEntity();
+        oid = new EmbeddedIdClass();
+        oid.setPk1(4);
+        oid.setPk2(5);
+        e.setId(oid);
+        em.persist(e);
+        oid = e.getId();
+        assertEquals(4, oid.getPk1());
+        assertEquals(5, oid.getPk2());
+        assertTrue(oid.getPk3() != 0);
+        assertEquals(oid, em.getObjectId(e));
+        endTx(em);
+        assertEquals(oid, em.getObjectId(e));
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        e = em.find(EmbeddedIdEntity.class, oid);
+        assertEquals(oid, em.getObjectId(e));
+        endEm(em);
+
+        // flush before accessing id field
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        e = new EmbeddedIdEntity();
+        em.persist(e);
+        endTx(em);
+        oid = e.getId();
+        assertTrue(oid.getPk3() != 0);
+        assertEquals(oid, em.getObjectId(e));
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        e = em.find(EmbeddedIdEntity.class, oid);
+        assertEquals(oid, em.getObjectId(e));
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityListenerAnnot.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityListenerAnnot.java
index 0c153a0..6ee4ae1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityListenerAnnot.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityListenerAnnot.java
@@ -1,265 +1,265 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.util.List;
-
-import javax.persistence.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestEntityListenerAnnot extends AnnotationTestCase
-{
-
-	public TestEntityListenerAnnot(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-	public void setUp()
-	{
-		deleteAll(Employee.class);
-		deleteAll(ContractEmployee.class);
-		CallbackStorage.clearStore();
-	}
-
-	public void testPrePersist()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-
-		ContractEmployee cemp = new ContractEmployee(21, "afam", 25, 5);
-
-		em.persist(cemp);
-		CallbackStorage store = CallbackStorage.getInstance();
-
-		assertNotNull(store.getClist());
-		assertEquals("@pre/post persist callback is over/under-firing", 2, store.getClist().size());
-		assertEquals("longnamevalidatorprr", store.getClist().get(0));
-		assertEquals("contractemployee", store.getClist().get(1));
-
-		endEm(em);
-	}
-
-	public void testPostPersist()
-	{
-		OpenJPAEntityManager em = null;	
-	  try{	
-		em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		Employee emp = new Employee(1, "john");
-
-		em.persist(emp);
-		CallbackStorage store = CallbackStorage.getInstance();
-
-		assertNotNull(store.getClist());
-		assertEquals("@pre/post persist callback is over/under-firing", 4, store.getClist().size());
-		assertEquals("namevalidator", store.getClist().get(0));
-		assertEquals("longnamevalidatorprr", store.getClist().get(1));
-		assertEquals("employeepop", store.getClist().get(2));
-		assertEquals("We expected 'gen#" +  emp.getCheck() + " : " + emp.getCheck() + "'. However, we got '" + store.getClist().get(3) + "'", "gen#"+emp.getCheck(), store.getClist().get(3));
-	  }
-      finally {
-		endTx(em);
-		endEm(em);
-      }
-	}
-
-	public void testPre_PostRemove()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		Employee emp = new Employee(8, "Jonathan");
-		em.persist(emp);
-
-		endTx(em);
-		endEm(em);
-		//--------------------------------------------------------------
-		em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		emp = em.find(Employee.class, 8);
-
-		CallbackStorage.clearStore(); //clear the store
-		assertTrue(CallbackStorage.isEmpty());
-
-		em.remove(emp);
-
-		assertTrue(!CallbackStorage.isEmpty());
-		assertEquals("callback is under/over-firing...", 2, CallbackStorage.size());
-		assertEquals("namevalidatorprr", CallbackStorage.getInstance().getClist().get(0));
-		assertEquals("namevalidatorpor", CallbackStorage.getInstance().getClist().get(1));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testPreUpdate()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		Employee emp = new Employee(5, "Abraham");
-		em.persist(emp);
-
-		CallbackStorage.clearStore();
-
-		String query = "Update Employee e SET e.name = 'Joseph' WHERE e.id = :id";
-
-		int result = em.createQuery(query)
-		               .setParameter("id", 5)
-		               .executeUpdate();
-
-		List store = CallbackStorage.getInstance().getClist();
-
-		assertNotNull(result);
-		assertEquals(1, result);
-		assertNotNull(store);
-		assertEquals(3, store.size());
-		assertEquals("namevalidatorpou", store.get(0));
-		assertEquals("longnamevalidatorpou", store.get(1));
-		assertEquals("employeepou", store.get(2));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testPreUpdate2()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		Employee emp = new Employee(5, "Abraham");
-		em.persist(emp);
-
-		CallbackStorage.clearStore();
-		endTx(em);
-
-		startTx(em);
-		emp = em.find(Employee.class, 5);
-
-		CallbackStorage.clearStore();
-		assertEquals("Abraham", emp.getName());
-
-		emp.setName("Abrahamovich");
-		em.flush();
-
-		List store = CallbackStorage.getInstance().getClist();
-
-		assertNotNull(store);
-		assertEquals("update callback is either underfiring or overfiring...", 3, store.size());
-		assertEquals("namevalidatorpou", store.get(0));
-		assertEquals("longnamevalidatorpou", store.get(1));
-		assertEquals("employeepou", store.get(2));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testPostLoad()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		Employee emp = new Employee(6, "Jefferson");
-
-		em.persist(emp);
-		CallbackStorage.clearStore();
-
-		endTx(em);
-
-		startTx(em);
-		CallbackStorage.clearStore();
-
-		assertTrue(CallbackStorage.getInstance().getClist().isEmpty());
-
-		emp = em.find(Employee.class, 6);
-		em.refresh(emp);
-
-		assertNotNull(emp);
-		assertNotNull(CallbackStorage.getInstance().getClist());
-		assertEquals("PostLoad is overfiring...not accurate", 2, CallbackStorage.getInstance().getClist().size());
-		assertEquals("employeepol", CallbackStorage.getInstance().getClist().get(0));
-		assertEquals("employeepol", CallbackStorage.getInstance().getClist().get(1));
-
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testGenPriKeyAvailInPostPersist()
-	{
-		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-
-		assertNotNull(em);
-
-		Employee emp = new Employee(7, "Maxwell");
-
-		assertEquals(0, emp.getCheck());
-
-		em.persist(emp);
-		int check = emp.getCheck();
-
-		assertNotNull(check);
-		assertTrue(CallbackStorage.getInstance().getClist().contains("gen#"+check));
-
-		endTx(em);
-		endEm(em);
-	}
-	/*Fix Me: aokeke - should fail when persisting with invalid id*/
-//	public void testExceptionCauseTxRollback2()
-//	{
-//		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-//		startTx(em);
-//		
-//		Employee emp = new Employee(-1, "failure");
-//		
-//		try
-//		{
-//			//persisting an entity with an invalid id throws an exception
-//			em.persist(emp);
-//			endTx(em);
-//			fail("Should have failed..persisting an entity with invalid id");
-//		}
-//		catch(RuntimeException e)
-//		{			
-//			assertFalse(em.isPersistent(emp));
-//			assertTrue("transaction was not marked for rollback", em.getRollbackOnly());
-//			e.printStackTrace();
-//			if(em.getRollbackOnly() == true)
-//				endEm(em);
-//		}
-//		catch(Exception e)
-//		{
-//			assertFalse(em.isPersistent(emp));
-//			assertTrue("transaction was not marked for rollback", em.getRollbackOnly());
-//			e.printStackTrace();
-//			if(em.getRollbackOnly() == true)
-//				endEm(em);
-//		}
-//		
-//		if(em.isActive())
-//			endEm(em);
-//	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.util.List;
+
+import javax.persistence.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestEntityListenerAnnot extends AnnotationTestCase
+{
+
+	public TestEntityListenerAnnot(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+	public void setUp()
+	{
+		deleteAll(Employee.class);
+		deleteAll(ContractEmployee.class);
+		CallbackStorage.clearStore();
+	}
+
+	public void testPrePersist()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+
+		ContractEmployee cemp = new ContractEmployee(21, "afam", 25, 5);
+
+		em.persist(cemp);
+		CallbackStorage store = CallbackStorage.getInstance();
+
+		assertNotNull(store.getClist());
+		assertEquals("@pre/post persist callback is over/under-firing", 2, store.getClist().size());
+		assertEquals("longnamevalidatorprr", store.getClist().get(0));
+		assertEquals("contractemployee", store.getClist().get(1));
+
+		endEm(em);
+	}
+
+	public void testPostPersist()
+	{
+		OpenJPAEntityManager em = null;	
+	  try{	
+		em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		Employee emp = new Employee(1, "john");
+
+		em.persist(emp);
+		CallbackStorage store = CallbackStorage.getInstance();
+
+		assertNotNull(store.getClist());
+		assertEquals("@pre/post persist callback is over/under-firing", 4, store.getClist().size());
+		assertEquals("namevalidator", store.getClist().get(0));
+		assertEquals("longnamevalidatorprr", store.getClist().get(1));
+		assertEquals("employeepop", store.getClist().get(2));
+		assertEquals("We expected 'gen#" +  emp.getCheck() + " : " + emp.getCheck() + "'. However, we got '" + store.getClist().get(3) + "'", "gen#"+emp.getCheck(), store.getClist().get(3));
+	  }
+      finally {
+		endTx(em);
+		endEm(em);
+      }
+	}
+
+	public void testPre_PostRemove()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		Employee emp = new Employee(8, "Jonathan");
+		em.persist(emp);
+
+		endTx(em);
+		endEm(em);
+		//--------------------------------------------------------------
+		em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		emp = em.find(Employee.class, 8);
+
+		CallbackStorage.clearStore(); //clear the store
+		assertTrue(CallbackStorage.isEmpty());
+
+		em.remove(emp);
+
+		assertTrue(!CallbackStorage.isEmpty());
+		assertEquals("callback is under/over-firing...", 2, CallbackStorage.size());
+		assertEquals("namevalidatorprr", CallbackStorage.getInstance().getClist().get(0));
+		assertEquals("namevalidatorpor", CallbackStorage.getInstance().getClist().get(1));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testPreUpdate()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		Employee emp = new Employee(5, "Abraham");
+		em.persist(emp);
+
+		CallbackStorage.clearStore();
+
+		String query = "Update Employee e SET e.name = 'Joseph' WHERE e.id = :id";
+
+		int result = em.createQuery(query)
+		               .setParameter("id", 5)
+		               .executeUpdate();
+
+		List store = CallbackStorage.getInstance().getClist();
+
+		assertNotNull(result);
+		assertEquals(1, result);
+		assertNotNull(store);
+		assertEquals(3, store.size());
+		assertEquals("namevalidatorpou", store.get(0));
+		assertEquals("longnamevalidatorpou", store.get(1));
+		assertEquals("employeepou", store.get(2));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testPreUpdate2()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		Employee emp = new Employee(5, "Abraham");
+		em.persist(emp);
+
+		CallbackStorage.clearStore();
+		endTx(em);
+
+		startTx(em);
+		emp = em.find(Employee.class, 5);
+
+		CallbackStorage.clearStore();
+		assertEquals("Abraham", emp.getName());
+
+		emp.setName("Abrahamovich");
+		em.flush();
+
+		List store = CallbackStorage.getInstance().getClist();
+
+		assertNotNull(store);
+		assertEquals("update callback is either underfiring or overfiring...", 3, store.size());
+		assertEquals("namevalidatorpou", store.get(0));
+		assertEquals("longnamevalidatorpou", store.get(1));
+		assertEquals("employeepou", store.get(2));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testPostLoad()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		Employee emp = new Employee(6, "Jefferson");
+
+		em.persist(emp);
+		CallbackStorage.clearStore();
+
+		endTx(em);
+
+		startTx(em);
+		CallbackStorage.clearStore();
+
+		assertTrue(CallbackStorage.getInstance().getClist().isEmpty());
+
+		emp = em.find(Employee.class, 6);
+		em.refresh(emp);
+
+		assertNotNull(emp);
+		assertNotNull(CallbackStorage.getInstance().getClist());
+		assertEquals("PostLoad is overfiring...not accurate", 2, CallbackStorage.getInstance().getClist().size());
+		assertEquals("employeepol", CallbackStorage.getInstance().getClist().get(0));
+		assertEquals("employeepol", CallbackStorage.getInstance().getClist().get(1));
+
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testGenPriKeyAvailInPostPersist()
+	{
+		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+
+		assertNotNull(em);
+
+		Employee emp = new Employee(7, "Maxwell");
+
+		assertEquals(0, emp.getCheck());
+
+		em.persist(emp);
+		int check = emp.getCheck();
+
+		assertNotNull(check);
+		assertTrue(CallbackStorage.getInstance().getClist().contains("gen#"+check));
+
+		endTx(em);
+		endEm(em);
+	}
+	/*Fix Me: aokeke - should fail when persisting with invalid id*/
+//	public void testExceptionCauseTxRollback2()
+//	{
+//		OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+//		startTx(em);
+//		
+//		Employee emp = new Employee(-1, "failure");
+//		
+//		try
+//		{
+//			//persisting an entity with an invalid id throws an exception
+//			em.persist(emp);
+//			endTx(em);
+//			fail("Should have failed..persisting an entity with invalid id");
+//		}
+//		catch(RuntimeException e)
+//		{			
+//			assertFalse(em.isPersistent(emp));
+//			assertTrue("transaction was not marked for rollback", em.getRollbackOnly());
+//			e.printStackTrace();
+//			if(em.getRollbackOnly() == true)
+//				endEm(em);
+//		}
+//		catch(Exception e)
+//		{
+//			assertFalse(em.isPersistent(emp));
+//			assertTrue("transaction was not marked for rollback", em.getRollbackOnly());
+//			e.printStackTrace();
+//			if(em.getRollbackOnly() == true)
+//				endEm(em);
+//		}
+//		
+//		if(em.isActive())
+//			endEm(em);
+//	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityOrderBy.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityOrderBy.java
index 9ff69c1..b22458c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityOrderBy.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEntityOrderBy.java
@@ -1,116 +1,116 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.util.*;
-
-import org.apache.openjpa.conf.*;
-import org.apache.openjpa.meta.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-import junit.framework.*;
-
-/**
- * <p>Test @OrderBy annotation support.</p>
- *
- * @author Abe White
- */
-public class TestEntityOrderBy extends AnnotationTestCase
-{
-
-	public TestEntityOrderBy(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-//    private ClassMetaData _meta;
-
-    public void setUp()
-    {
-//        _meta = ((OpenJPAConfiguration) getConfiguration()).
-//            getMetaDataRepositoryInstance().getMetaData(OrderByEntity.class,
-//            null, true);
-    }
-
- /*   public void testEmptyOrderBy() {
-        String dec = Order.ELEMENT + " asc";
-        assertEquals(dec, _meta.getField("strings").getOrderDeclaration());
-        assertEquals(dec, _meta.getField("pkRels").getOrderDeclaration());
-    }
-
-    public void testSpecifiedOrderBy() {
-        assertEquals("string desc", _meta.getField("stringRels").
-            getOrderDeclaration());
-    }
-*/
-    public void testUse() {
-        // note: functionality thoroughly tested in kodo.meta.TestOrderBy;
-        // this is just a sanity check on JPA use
-        deleteAll(OrderByEntity.class);
-
-        OrderByEntity pc = new OrderByEntity();
-        pc.setId(1L);
-        pc.getStrings().add("2");
-        pc.getStrings().add("1");
-        pc.getStrings().add("3");
-
-        OrderByEntity rel1 = new OrderByEntity();
-        rel1.setId(102L);
-        rel1.setString("2");
-        OrderByEntity rel2 = new OrderByEntity();
-        rel2.setId(101L);
-        rel2.setString("1");
-        OrderByEntity rel3 = new OrderByEntity();
-        rel3.setId(103L);
-        rel3.setString("3");
-        pc.getPKRels().add(rel1);
-        pc.getPKRels().add(rel2);
-        pc.getPKRels().add(rel3);
-        pc.getStringRels().add(rel1);
-        pc.getStringRels().add(rel2);
-        pc.getStringRels().add(rel3);
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        em.persistAll(pc, rel1, rel2, rel3);
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(OrderByEntity.class, 1L);
-        List<String> strings = pc.getStrings();
-        assertEquals("1", strings.get(0));
-        assertEquals("2", strings.get(1));
-        assertEquals("3", strings.get(2));
-
-        List<OrderByEntity> pkRels = pc.getPKRels();
-        assertEquals(101L, pkRels.get(0).getId());
-        assertEquals(102L, pkRels.get(1).getId());
-        assertEquals(103L, pkRels.get(2).getId());
-
-        List<OrderByEntity> stringRels = pc.getStringRels();
-        assertEquals("3", stringRels.get(0).getString());
-        assertEquals("2", stringRels.get(1).getString());
-        assertEquals("1", stringRels.get(2).getString());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.util.*;
+
+import org.apache.openjpa.conf.*;
+import org.apache.openjpa.meta.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+import junit.framework.*;
+
+/**
+ * <p>Test @OrderBy annotation support.</p>
+ *
+ * @author Abe White
+ */
+public class TestEntityOrderBy extends AnnotationTestCase
+{
+
+	public TestEntityOrderBy(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+//    private ClassMetaData _meta;
+
+    public void setUp()
+    {
+//        _meta = ((OpenJPAConfiguration) getConfiguration()).
+//            getMetaDataRepositoryInstance().getMetaData(OrderByEntity.class,
+//            null, true);
+    }
+
+ /*   public void testEmptyOrderBy() {
+        String dec = Order.ELEMENT + " asc";
+        assertEquals(dec, _meta.getField("strings").getOrderDeclaration());
+        assertEquals(dec, _meta.getField("pkRels").getOrderDeclaration());
+    }
+
+    public void testSpecifiedOrderBy() {
+        assertEquals("string desc", _meta.getField("stringRels").
+            getOrderDeclaration());
+    }
+*/
+    public void testUse() {
+        // note: functionality thoroughly tested in kodo.meta.TestOrderBy;
+        // this is just a sanity check on JPA use
+        deleteAll(OrderByEntity.class);
+
+        OrderByEntity pc = new OrderByEntity();
+        pc.setId(1L);
+        pc.getStrings().add("2");
+        pc.getStrings().add("1");
+        pc.getStrings().add("3");
+
+        OrderByEntity rel1 = new OrderByEntity();
+        rel1.setId(102L);
+        rel1.setString("2");
+        OrderByEntity rel2 = new OrderByEntity();
+        rel2.setId(101L);
+        rel2.setString("1");
+        OrderByEntity rel3 = new OrderByEntity();
+        rel3.setId(103L);
+        rel3.setString("3");
+        pc.getPKRels().add(rel1);
+        pc.getPKRels().add(rel2);
+        pc.getPKRels().add(rel3);
+        pc.getStringRels().add(rel1);
+        pc.getStringRels().add(rel2);
+        pc.getStringRels().add(rel3);
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persistAll(pc, rel1, rel2, rel3);
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(OrderByEntity.class, 1L);
+        List<String> strings = pc.getStrings();
+        assertEquals("1", strings.get(0));
+        assertEquals("2", strings.get(1));
+        assertEquals("3", strings.get(2));
+
+        List<OrderByEntity> pkRels = pc.getPKRels();
+        assertEquals(101L, pkRels.get(0).getId());
+        assertEquals(102L, pkRels.get(1).getId());
+        assertEquals(103L, pkRels.get(2).getId());
+
+        List<OrderByEntity> stringRels = pc.getStringRels();
+        assertEquals("3", stringRels.get(0).getString());
+        assertEquals("2", stringRels.get(1).getString());
+        assertEquals("1", stringRels.get(2).getString());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEnumerated.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEnumerated.java
index 77e6907..0ca620f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEnumerated.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestEnumerated.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import org.apache.openjpa.persistence.*;
-import java.util.List;
-import javax.persistence.*;
-import junit.framework.*;
-import org.apache.openjpa.persistence.common.utils.*;
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-
-
-
-
-
-/**
- * Test enums and the @Enumerated annotation.
- *
- * @author Abe White
- */
-public class TestEnumerated extends AnnotationTestCase
-{
-
-	public TestEnumerated(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp() {
-        deleteAll(AnnoTest1.class);
-    }
-
-   /** public void testMapping() {
-        ClassMapping cls = (ClassMapping) getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(AnnoTest1.class,
-            null, true);
-        FieldMapping fm = cls.getDeclaredFieldMapping("enumeration");
-        assertNotNull(fm);
-        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
-        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
-        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
-
-        fm = cls.getDeclaredFieldMapping("ordinalEnumeration");
-        assertNotNull(fm);
-        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
-        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
-        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
-
-        fm = cls.getDeclaredFieldMapping("stringEnumeration");
-        assertNotNull(fm);
-        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
-        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
-        assertEquals(JavaTypes.STRING, fm.getColumns()[0].getJavaType());
-    }*/
-
-    public void testBehavior() 
-    {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();        
-        startTx(em);
-        
-        AnnoTest1 pc = new AnnoTest1(1);
-        assertNotNull("pc is null", pc);
-        assertNotNull("InheritanceType.TABLE_PER_CLASS is null", InheritanceType.TABLE_PER_CLASS);
-        assertNotNull("InheritanceType.JOINED is null", InheritanceType.JOINED);
-        pc.setEnumeration(InheritanceType.TABLE_PER_CLASS);
-        pc.setOrdinalEnumeration(InheritanceType.TABLE_PER_CLASS);
-        pc.setStringEnumeration(InheritanceType.JOINED);
-        em.persist(pc);
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        OpenJPAQuery q = em.createQuery("SELECT o FROM AnnoTest1 o"); 
-        assertEquals(1, q.getResultList().size());
-        
-//        AnnoTest1 pc2 = em.find(AnnoTest1.class, new Long(1));
-        AnnoTest1 pc2 = (AnnoTest1) q.getSingleResult();
-        assertNotNull("pc2 is null", pc2);
-        assertEquals(InheritanceType.TABLE_PER_CLASS, pc2.getEnumeration());
-        assertEquals(InheritanceType.TABLE_PER_CLASS, pc2.getOrdinalEnumeration());
-        assertEquals(InheritanceType.JOINED,  pc2.getStringEnumeration());
-        startTx(em);
-        pc2.setEnumeration(InheritanceType.JOINED);
-        pc2.setOrdinalEnumeration(InheritanceType.JOINED);
-        pc2.setStringEnumeration(InheritanceType.TABLE_PER_CLASS);
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-//        pc2 = em.find(AnnoTest1.class, new Long(1));
-        q = em.createQuery("SELECT o FROM AnnoTest1 o"); 
-        pc2 = (AnnoTest1) q.getSingleResult();
-        assertEquals(InheritanceType.JOINED, pc2.getEnumeration());
-        assertEquals(InheritanceType.JOINED, pc2.getOrdinalEnumeration());
-        assertEquals(InheritanceType.TABLE_PER_CLASS, pc2.getStringEnumeration());
-        endEm(em);
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import org.apache.openjpa.persistence.*;
+import java.util.List;
+import javax.persistence.*;
+import junit.framework.*;
+import org.apache.openjpa.persistence.common.utils.*;
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+
+
+
+
+
+/**
+ * Test enums and the @Enumerated annotation.
+ *
+ * @author Abe White
+ */
+public class TestEnumerated extends AnnotationTestCase
+{
+
+	public TestEnumerated(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp() {
+        deleteAll(AnnoTest1.class);
+    }
+
+   /** public void testMapping() {
+        ClassMapping cls = (ClassMapping) getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(AnnoTest1.class,
+            null, true);
+        FieldMapping fm = cls.getDeclaredFieldMapping("enumeration");
+        assertNotNull(fm);
+        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
+        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
+        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
+
+        fm = cls.getDeclaredFieldMapping("ordinalEnumeration");
+        assertNotNull(fm);
+        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
+        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
+        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
+
+        fm = cls.getDeclaredFieldMapping("stringEnumeration");
+        assertNotNull(fm);
+        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
+        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
+        assertEquals(JavaTypes.STRING, fm.getColumns()[0].getJavaType());
+    }*/
+
+    public void testBehavior() 
+    {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();        
+        startTx(em);
+        
+        AnnoTest1 pc = new AnnoTest1(1);
+        assertNotNull("pc is null", pc);
+        assertNotNull("InheritanceType.TABLE_PER_CLASS is null", InheritanceType.TABLE_PER_CLASS);
+        assertNotNull("InheritanceType.JOINED is null", InheritanceType.JOINED);
+        pc.setEnumeration(InheritanceType.TABLE_PER_CLASS);
+        pc.setOrdinalEnumeration(InheritanceType.TABLE_PER_CLASS);
+        pc.setStringEnumeration(InheritanceType.JOINED);
+        em.persist(pc);
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        OpenJPAQuery q = em.createQuery("SELECT o FROM AnnoTest1 o"); 
+        assertEquals(1, q.getResultList().size());
+        
+//        AnnoTest1 pc2 = em.find(AnnoTest1.class, new Long(1));
+        AnnoTest1 pc2 = (AnnoTest1) q.getSingleResult();
+        assertNotNull("pc2 is null", pc2);
+        assertEquals(InheritanceType.TABLE_PER_CLASS, pc2.getEnumeration());
+        assertEquals(InheritanceType.TABLE_PER_CLASS, pc2.getOrdinalEnumeration());
+        assertEquals(InheritanceType.JOINED,  pc2.getStringEnumeration());
+        startTx(em);
+        pc2.setEnumeration(InheritanceType.JOINED);
+        pc2.setOrdinalEnumeration(InheritanceType.JOINED);
+        pc2.setStringEnumeration(InheritanceType.TABLE_PER_CLASS);
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+//        pc2 = em.find(AnnoTest1.class, new Long(1));
+        q = em.createQuery("SELECT o FROM AnnoTest1 o"); 
+        pc2 = (AnnoTest1) q.getSingleResult();
+        assertEquals(InheritanceType.JOINED, pc2.getEnumeration());
+        assertEquals(InheritanceType.JOINED, pc2.getOrdinalEnumeration());
+        assertEquals(InheritanceType.TABLE_PER_CLASS, pc2.getStringEnumeration());
+        endEm(em);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestFlatInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestFlatInheritance.java
index e92f4a4..d8c70b9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestFlatInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestFlatInheritance.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-/**
- * Test for InheritanceType.SINGLE_TABLE
- *
- * @author Steve Kim
- */
-public class TestFlatInheritance extends AnnotationTestCase
-{
-
-	public TestFlatInheritance(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp()
-    {
-        deleteAll(Flat1.class);
-    }
-
-    public void testInheritance() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        Flat1 pc = new Flat1(1);
-        Flat2 pc2 = new Flat2(2);
-        pc.setBasic(10);
-        pc2.setBasic(20);
-        pc2.setBasic2("DOG");
-        em.persist(pc);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(Flat1.class, 1);
-        assertEquals(10, pc.getBasic());
-        pc = em.find(Flat1.class, 2);
-        assertEquals(Flat2.class, pc.getClass());
-        assertEquals(20, pc.getBasic());
-        assertEquals("DOG", ((Flat2) pc).getBasic2());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+/**
+ * Test for InheritanceType.SINGLE_TABLE
+ *
+ * @author Steve Kim
+ */
+public class TestFlatInheritance extends AnnotationTestCase
+{
+
+	public TestFlatInheritance(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp()
+    {
+        deleteAll(Flat1.class);
+    }
+
+    public void testInheritance() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        Flat1 pc = new Flat1(1);
+        Flat2 pc2 = new Flat2(2);
+        pc.setBasic(10);
+        pc2.setBasic(20);
+        pc2.setBasic2("DOG");
+        em.persist(pc);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(Flat1.class, 1);
+        assertEquals(10, pc.getBasic());
+        pc = em.find(Flat1.class, 2);
+        assertEquals(Flat2.class, pc.getClass());
+        assertEquals(20, pc.getBasic());
+        assertEquals("DOG", ((Flat2) pc).getBasic2());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestGenerators.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestGenerators.java
index d6ed63c..300e6fb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestGenerators.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestGenerators.java
@@ -1,103 +1,103 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-import junit.framework.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * Test for generators
- *
- * @author Steve Kim
- */
-public class TestGenerators extends AnnotationTestCase
-{
-
-	public TestGenerators(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp()
-        throws Exception {
-        deleteAll(Generator.class);
-    }
-
-    public void testGet() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        Generator g = new Generator();
-        g.setPk(5);
-        em.persist(g);
-        assertPks(g);
-        endTx(em);
-        endEm(em);
-        assertNew();
-    }
-
-    public void testFlush() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        Generator g = new Generator();
-        g.setPk(5);
-        em.persist(g);
-        em.flush();
-        assertPks(g);
-        endTx(em);
-        endEm(em);
-        assertNew();
-    }
-
-    public void testCommit() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        Generator g = new Generator();
-        g.setPk(5);
-        em.persist(g);
-        endTx(em);
-        endEm(em);
-        assertNew();
-    }
-
-    private void assertNew() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        Query q = em.createQuery("select g from Generator g where "
-            + "g.stringField = 'foo'");
-        for (Object o : q.getResultList())
-            assertPks((Generator) o);
-        endEm(em);
-    }
-
-    private void assertPks(Generator g) {
-        assertNotEquals(0, g.getPk());
-        assertNotNull(g.getPk2());
-       // assertNotEquals(new Integer(0), g);
-        assertNotEquals(0, g.getPk3());
-    }
-
-    private boolean assertNotEquals(long n, long num)
-    {
-    	return(n != num);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+import junit.framework.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * Test for generators
+ *
+ * @author Steve Kim
+ */
+public class TestGenerators extends AnnotationTestCase
+{
+
+	public TestGenerators(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp()
+        throws Exception {
+        deleteAll(Generator.class);
+    }
+
+    public void testGet() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        Generator g = new Generator();
+        g.setPk(5);
+        em.persist(g);
+        assertPks(g);
+        endTx(em);
+        endEm(em);
+        assertNew();
+    }
+
+    public void testFlush() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        Generator g = new Generator();
+        g.setPk(5);
+        em.persist(g);
+        em.flush();
+        assertPks(g);
+        endTx(em);
+        endEm(em);
+        assertNew();
+    }
+
+    public void testCommit() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        Generator g = new Generator();
+        g.setPk(5);
+        em.persist(g);
+        endTx(em);
+        endEm(em);
+        assertNew();
+    }
+
+    private void assertNew() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        Query q = em.createQuery("select g from Generator g where "
+            + "g.stringField = 'foo'");
+        for (Object o : q.getResultList())
+            assertPks((Generator) o);
+        endEm(em);
+    }
+
+    private void assertPks(Generator g) {
+        assertNotEquals(0, g.getPk());
+        assertNotNull(g.getPk2());
+       // assertNotEquals(new Integer(0), g);
+        assertNotEquals(0, g.getPk3());
+    }
+
+    private boolean assertNotEquals(long n, long num)
+    {
+    	return(n != num);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestJoinedInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestJoinedInheritance.java
index f19cf13..0462985 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestJoinedInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestJoinedInheritance.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-import junit.framework.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-/**
- * Test for InheritanceType.JOINED
- *
- * @author Steve Kim
- */
-public class TestJoinedInheritance extends AnnotationTestCase
-{
-
-	public TestJoinedInheritance(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp()
-    {
-        new AnnoTest1();
-        new AnnoTest2();
-        new AnnoTest3();
-
-        deleteAll(AnnoTest1.class);
-        deleteAll(AnnoTest2.class);
-    }
-
-    public void testInheritance() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest3 pc = new AnnoTest3();
-        pc.setPk(new Long(1));
-        pc.setBasic(10);
-        pc.setBasic2(20);
-        em.persist(pc);
-
-        AnnoTest2 pc2 = new AnnoTest2();
-        pc2.setPk1(2);
-        pc2.setPk2("bar");
-        pc2.setInverseOneOne(pc);
-        pc.setSubOneOne(pc2);
-        em.persist(pc2);
-
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc2 = em.find(AnnoTest2.class, new AnnoTest2.Oid(2, "bar"));
-        pc = (AnnoTest3) pc2.getInverseOneOne();
-        assertEquals(pc.getInverseOwnerOneOne(), pc2);
-        assertEquals(10, pc.getBasic());
-        assertEquals(20, pc.getBasic2());
-        assertEquals(pc2, pc.getSubOneOne());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+import junit.framework.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+/**
+ * Test for InheritanceType.JOINED
+ *
+ * @author Steve Kim
+ */
+public class TestJoinedInheritance extends AnnotationTestCase
+{
+
+	public TestJoinedInheritance(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp()
+    {
+        new AnnoTest1();
+        new AnnoTest2();
+        new AnnoTest3();
+
+        deleteAll(AnnoTest1.class);
+        deleteAll(AnnoTest2.class);
+    }
+
+    public void testInheritance() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest3 pc = new AnnoTest3();
+        pc.setPk(new Long(1));
+        pc.setBasic(10);
+        pc.setBasic2(20);
+        em.persist(pc);
+
+        AnnoTest2 pc2 = new AnnoTest2();
+        pc2.setPk1(2);
+        pc2.setPk2("bar");
+        pc2.setInverseOneOne(pc);
+        pc.setSubOneOne(pc2);
+        em.persist(pc2);
+
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc2 = em.find(AnnoTest2.class, new AnnoTest2.Oid(2, "bar"));
+        pc = (AnnoTest3) pc2.getInverseOneOne();
+        assertEquals(pc.getInverseOwnerOneOne(), pc2);
+        assertEquals(10, pc.getBasic());
+        assertEquals(20, pc.getBasic2());
+        assertEquals(pc2, pc.getSubOneOne());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestManyToMany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestManyToMany.java
index 6a3d90f..5bad087 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestManyToMany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestManyToMany.java
@@ -1,123 +1,123 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.util.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * Test for m-m
- *
- * @author Steve Kim
- */
-public class TestManyToMany extends AnnotationTestCase
-{
-	public TestManyToMany(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp() {
-        deleteAll(AnnoTest1.class);
-        deleteAll(AnnoTest2.class);
-    }
-
-    public void testManyToMany() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        long lid = 4;
-        AnnoTest1 pc = new AnnoTest1(lid);
-        em.persist(pc);
-        AnnoTest2 pc2;
-        for (int i = 0; i < 3; i++) {
-            pc2 = new AnnoTest2(5 + i, "foo" + i);
-            pc.getManyMany().add(pc2);
-            em.persist(pc2);
-        }
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(lid));
-        Set<AnnoTest2> many = pc.getManyMany();
-        assertEquals(3, many.size());
-        for (AnnoTest2 manyPc2 : many) {
-            switch ((int) manyPc2.getPk1()) {
-                case 5:
-                    assertEquals("foo0", manyPc2.getPk2());
-                    break;
-                case 6:
-                    assertEquals("foo1", manyPc2.getPk2());
-                    break;
-                case 7:
-                    assertEquals("foo2", manyPc2.getPk2());
-                    break;
-                default:
-                    fail("bad pk:" + manyPc2.getPk1());
-            }
-        }
-        endEm(em);
-    }
-
-    public void testInverseOwnerManyToMany() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        long lid = 4;
-        AnnoTest1 pc = new AnnoTest1(lid);
-        em.persist(pc);
-        AnnoTest2 pc2;
-        for (int i = 0; i < 3; i++) {
-            pc2 = new AnnoTest2(5 + i, "foo" + i);
-            pc2.getManyMany().add(pc);
-            em.persist(pc2);
-        }
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(lid));
-        Set<AnnoTest2> many = pc.getInverseOwnerManyMany();
-        assertEquals(3, many.size());
-        for (AnnoTest2 manyPc2 : many) {
-            assertTrue(manyPc2.getManyMany().contains(pc));
-            switch ((int) manyPc2.getPk1()) {
-                case 5:
-                    assertEquals("foo0", manyPc2.getPk2());
-                    break;
-                case 6:
-                    assertEquals("foo1", manyPc2.getPk2());
-                    break;
-                case 7:
-                    assertEquals("foo2", manyPc2.getPk2());
-                    break;
-                default:
-                    fail("bad pk:" + manyPc2.getPk1());
-            }
-        }
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * Test for m-m
+ *
+ * @author Steve Kim
+ */
+public class TestManyToMany extends AnnotationTestCase
+{
+	public TestManyToMany(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp() {
+        deleteAll(AnnoTest1.class);
+        deleteAll(AnnoTest2.class);
+    }
+
+    public void testManyToMany() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        long lid = 4;
+        AnnoTest1 pc = new AnnoTest1(lid);
+        em.persist(pc);
+        AnnoTest2 pc2;
+        for (int i = 0; i < 3; i++) {
+            pc2 = new AnnoTest2(5 + i, "foo" + i);
+            pc.getManyMany().add(pc2);
+            em.persist(pc2);
+        }
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(lid));
+        Set<AnnoTest2> many = pc.getManyMany();
+        assertEquals(3, many.size());
+        for (AnnoTest2 manyPc2 : many) {
+            switch ((int) manyPc2.getPk1()) {
+                case 5:
+                    assertEquals("foo0", manyPc2.getPk2());
+                    break;
+                case 6:
+                    assertEquals("foo1", manyPc2.getPk2());
+                    break;
+                case 7:
+                    assertEquals("foo2", manyPc2.getPk2());
+                    break;
+                default:
+                    fail("bad pk:" + manyPc2.getPk1());
+            }
+        }
+        endEm(em);
+    }
+
+    public void testInverseOwnerManyToMany() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        long lid = 4;
+        AnnoTest1 pc = new AnnoTest1(lid);
+        em.persist(pc);
+        AnnoTest2 pc2;
+        for (int i = 0; i < 3; i++) {
+            pc2 = new AnnoTest2(5 + i, "foo" + i);
+            pc2.getManyMany().add(pc);
+            em.persist(pc2);
+        }
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(lid));
+        Set<AnnoTest2> many = pc.getInverseOwnerManyMany();
+        assertEquals(3, many.size());
+        for (AnnoTest2 manyPc2 : many) {
+            assertTrue(manyPc2.getManyMany().contains(pc));
+            switch ((int) manyPc2.getPk1()) {
+                case 5:
+                    assertEquals("foo0", manyPc2.getPk2());
+                    break;
+                case 6:
+                    assertEquals("foo1", manyPc2.getPk2());
+                    break;
+                case 7:
+                    assertEquals("foo2", manyPc2.getPk2());
+                    break;
+                default:
+                    fail("bad pk:" + manyPc2.getPk1());
+            }
+        }
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestMapKey.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestMapKey.java
index 19bd764..4f551bf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestMapKey.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestMapKey.java
@@ -1,131 +1,131 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.meta.strats.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-
-
-/**
- * <p>Test the use of the {@link MapKey} annotation.  Note that we have
- * more thorough Kodo core tests for the mappings themselves.  See
- * {@link kodo.jdbc.meta.TestMappedByKeyMaps}.
- *
- * @author Abe White
- */
-public class TestMapKey extends AnnotationTestCase
-{
-
-	public TestMapKey(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    //private ClassMapping _mapping;
-
-    public void setUp()
-    {
-        deleteAll(Flat1.class);
-        deleteAll(AnnoTest2.class);
-        deleteAll(AnnoTest1.class);
-//        _mapping = ((JDBCConfiguration) getConfiguration()).
-//            getMappingRepositoryInstance().getMapping(AnnoTest1.class,
-//            null, true);
-    }
-
-   /** public void testDefaultMapKeyMapping() {
-        FieldMapping fm = _mapping.getFieldMapping("defaultMapKey");
-        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
-        assertEquals("pk", fm.getKey().getValueMappedBy());
-        assertEquals(_mapping.getRepository().getMetaData(Flat1.class, null,
-            true).getField("pk"), fm.getKey().getValueMappedByMetaData());
-    }
-
-    public void testNamedMapKeyMapping() {
-        FieldMapping fm = _mapping.getFieldMapping("namedMapKey");
-        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
-        assertEquals("basic", fm.getKey().getValueMappedBy());
-        assertEquals(_mapping.getRepository().getMetaData(Flat1.class, null,
-            true).getField("basic"), fm.getKey().getValueMappedByMetaData());
-    }
-
-    public void testInverseOwnerMapKeyMapping() {
-        FieldMapping fm = _mapping.getFieldMapping("inverseOwnerMapKey");
-        assertTrue(fm.getStrategy() instanceof
-            RelationMapInverseKeyFieldStrategy);
-        assertEquals("basic", fm.getKey().getValueMappedBy());
-        assertEquals(_mapping.getRepository().getMetaData(AnnoTest2.class,
-            null, true).getField("basic"), fm.getKey().
-            getValueMappedByMetaData());
-    }**/
-
-    public void testInsertAndRetrieve()
-    {
-
-        Flat1 f1 = new Flat1(1);
-        f1.setBasic(100);
-        Flat1 f2 = new Flat1(2);
-        f2.setBasic(200);
-        AnnoTest2 a1 = new AnnoTest2(1L, "1");
-        a1.setBasic("100");
-        AnnoTest2 a2 = new AnnoTest2(2L, "2");
-        a2.setBasic("200");
-
-        AnnoTest1 pc = new AnnoTest1(1L);
-        pc.getDefaultMapKey().put(f1.getPk(), f1);
-        pc.getDefaultMapKey().put(f2.getPk(), f2);
-        pc.getNamedMapKey().put(f1.getBasic(), f1);
-        pc.getNamedMapKey().put(f2.getBasic(), f2);
-        pc.getInverseOwnerMapKey().put(a1.getBasic(), a1);
-        pc.getInverseOwnerMapKey().put(a2.getBasic(), a2);
-        a1.setOneManyOwner(pc);
-        a2.setOneManyOwner(pc);
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-       startTx(em);
-        em.persistAll(new Object[]{ pc, f1, f2, a1, a2 });
-       endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        assertEquals(2, pc.getDefaultMapKey().size());
-        assertEquals(1, pc.getDefaultMapKey().get(1).getPk());
-        assertEquals(2, pc.getDefaultMapKey().get(2).getPk());
-        assertEquals(2, pc.getNamedMapKey().size());
-        assertEquals(100, pc.getNamedMapKey().get(100).getBasic());
-        assertEquals(200, pc.getNamedMapKey().get(200).getBasic());
-        assertEquals(2, pc.getInverseOwnerMapKey().size());
-        assertEquals("100", pc.getInverseOwnerMapKey().get("100").
-            getBasic());
-        assertEquals("200", pc.getInverseOwnerMapKey().get("200").
-            getBasic());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+
+
+/**
+ * <p>Test the use of the {@link MapKey} annotation.  Note that we have
+ * more thorough Kodo core tests for the mappings themselves.  See
+ * {@link kodo.jdbc.meta.TestMappedByKeyMaps}.
+ *
+ * @author Abe White
+ */
+public class TestMapKey extends AnnotationTestCase
+{
+
+	public TestMapKey(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    //private ClassMapping _mapping;
+
+    public void setUp()
+    {
+        deleteAll(Flat1.class);
+        deleteAll(AnnoTest2.class);
+        deleteAll(AnnoTest1.class);
+//        _mapping = ((JDBCConfiguration) getConfiguration()).
+//            getMappingRepositoryInstance().getMapping(AnnoTest1.class,
+//            null, true);
+    }
+
+   /** public void testDefaultMapKeyMapping() {
+        FieldMapping fm = _mapping.getFieldMapping("defaultMapKey");
+        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
+        assertEquals("pk", fm.getKey().getValueMappedBy());
+        assertEquals(_mapping.getRepository().getMetaData(Flat1.class, null,
+            true).getField("pk"), fm.getKey().getValueMappedByMetaData());
+    }
+
+    public void testNamedMapKeyMapping() {
+        FieldMapping fm = _mapping.getFieldMapping("namedMapKey");
+        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
+        assertEquals("basic", fm.getKey().getValueMappedBy());
+        assertEquals(_mapping.getRepository().getMetaData(Flat1.class, null,
+            true).getField("basic"), fm.getKey().getValueMappedByMetaData());
+    }
+
+    public void testInverseOwnerMapKeyMapping() {
+        FieldMapping fm = _mapping.getFieldMapping("inverseOwnerMapKey");
+        assertTrue(fm.getStrategy() instanceof
+            RelationMapInverseKeyFieldStrategy);
+        assertEquals("basic", fm.getKey().getValueMappedBy());
+        assertEquals(_mapping.getRepository().getMetaData(AnnoTest2.class,
+            null, true).getField("basic"), fm.getKey().
+            getValueMappedByMetaData());
+    }**/
+
+    public void testInsertAndRetrieve()
+    {
+
+        Flat1 f1 = new Flat1(1);
+        f1.setBasic(100);
+        Flat1 f2 = new Flat1(2);
+        f2.setBasic(200);
+        AnnoTest2 a1 = new AnnoTest2(1L, "1");
+        a1.setBasic("100");
+        AnnoTest2 a2 = new AnnoTest2(2L, "2");
+        a2.setBasic("200");
+
+        AnnoTest1 pc = new AnnoTest1(1L);
+        pc.getDefaultMapKey().put(f1.getPk(), f1);
+        pc.getDefaultMapKey().put(f2.getPk(), f2);
+        pc.getNamedMapKey().put(f1.getBasic(), f1);
+        pc.getNamedMapKey().put(f2.getBasic(), f2);
+        pc.getInverseOwnerMapKey().put(a1.getBasic(), a1);
+        pc.getInverseOwnerMapKey().put(a2.getBasic(), a2);
+        a1.setOneManyOwner(pc);
+        a2.setOneManyOwner(pc);
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+       startTx(em);
+        em.persistAll(new Object[]{ pc, f1, f2, a1, a2 });
+       endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        assertEquals(2, pc.getDefaultMapKey().size());
+        assertEquals(1, pc.getDefaultMapKey().get(1).getPk());
+        assertEquals(2, pc.getDefaultMapKey().get(2).getPk());
+        assertEquals(2, pc.getNamedMapKey().size());
+        assertEquals(100, pc.getNamedMapKey().get(100).getBasic());
+        assertEquals(200, pc.getNamedMapKey().get(200).getBasic());
+        assertEquals(2, pc.getInverseOwnerMapKey().size());
+        assertEquals("100", pc.getInverseOwnerMapKey().get("100").
+            getBasic());
+        assertEquals("200", pc.getInverseOwnerMapKey().get("200").
+            getBasic());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToMany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToMany.java
index 0bee57f..13174c1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToMany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToMany.java
@@ -1,113 +1,113 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-
-
-/**
- * Test for 1-m
- *
- * @author Steve Kim
- */
-public class TestOneToMany extends AnnotationTestCase
-{
-	public TestOneToMany(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp() {
-        deleteAll(AnnoTest1.class);
-        deleteAll(AnnoTest2.class);
-    }
-
-    public void testOneToMany() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        pc.getOneMany().add(new AnnoTest2(15, "foo"));
-        pc.getOneMany().add(new AnnoTest2(20, "foobar"));
-        em.persist(pc);
-        em.persistAll(pc.getOneMany());
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        Collection<AnnoTest2> many = pc.getOneMany();
-        assertEquals(2, many.size());
-        for (AnnoTest2 pc2 : many) {
-            switch ((int) pc2.getPk1()) {
-                case 15:
-                    assertEquals("foo", pc2.getPk2());
-                    break;
-                case 20:
-                    assertEquals("foobar", pc2.getPk2());
-                    break;
-                default:
-                    fail("unknown element:" + pc2.getPk1());
-            }
-        }
-        endEm(em);
-    }
-
-    public void testInverseOwnerOneToMany() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc.getInverseOwnerOneMany().add(pc2);
-        pc2.setOneManyOwner(pc);
-        pc2 = new AnnoTest2(20, "foobar");
-        pc.getInverseOwnerOneMany().add(pc2);
-        pc2.setOneManyOwner(pc);
-        em.persist(pc);
-        em.persistAll(pc.getInverseOwnerOneMany());
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager)currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        Collection<AnnoTest2> many = pc.getInverseOwnerOneMany();
-        assertEquals(2, many.size());
-        for (AnnoTest2 pc3 : many) {
-            assertEquals(pc, pc3.getOneManyOwner());
-            switch ((int) pc3.getPk1()) {
-                case 15:
-                    assertEquals("foo", pc3.getPk2());
-                    break;
-                case 20:
-                    assertEquals("foobar", pc3.getPk2());
-                    break;
-                default:
-                    fail("unknown element:" + pc3.getPk1());
-            }
-        }
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+
+
+/**
+ * Test for 1-m
+ *
+ * @author Steve Kim
+ */
+public class TestOneToMany extends AnnotationTestCase
+{
+	public TestOneToMany(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp() {
+        deleteAll(AnnoTest1.class);
+        deleteAll(AnnoTest2.class);
+    }
+
+    public void testOneToMany() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        pc.getOneMany().add(new AnnoTest2(15, "foo"));
+        pc.getOneMany().add(new AnnoTest2(20, "foobar"));
+        em.persist(pc);
+        em.persistAll(pc.getOneMany());
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        Collection<AnnoTest2> many = pc.getOneMany();
+        assertEquals(2, many.size());
+        for (AnnoTest2 pc2 : many) {
+            switch ((int) pc2.getPk1()) {
+                case 15:
+                    assertEquals("foo", pc2.getPk2());
+                    break;
+                case 20:
+                    assertEquals("foobar", pc2.getPk2());
+                    break;
+                default:
+                    fail("unknown element:" + pc2.getPk1());
+            }
+        }
+        endEm(em);
+    }
+
+    public void testInverseOwnerOneToMany() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc.getInverseOwnerOneMany().add(pc2);
+        pc2.setOneManyOwner(pc);
+        pc2 = new AnnoTest2(20, "foobar");
+        pc.getInverseOwnerOneMany().add(pc2);
+        pc2.setOneManyOwner(pc);
+        em.persist(pc);
+        em.persistAll(pc.getInverseOwnerOneMany());
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager)currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        Collection<AnnoTest2> many = pc.getInverseOwnerOneMany();
+        assertEquals(2, many.size());
+        for (AnnoTest2 pc3 : many) {
+            assertEquals(pc, pc3.getOneManyOwner());
+            switch ((int) pc3.getPk1()) {
+                case 15:
+                    assertEquals("foo", pc3.getPk2());
+                    break;
+                case 20:
+                    assertEquals("foobar", pc3.getPk2());
+                    break;
+                default:
+                    fail("unknown element:" + pc3.getPk1());
+            }
+        }
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToOne.java
index bbf0384..834cca8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestOneToOne.java
@@ -1,146 +1,146 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * Test for 1-1
- *
- * @author Steve Kim
- */
-public class TestOneToOne extends AnnotationTestCase
-{
-
-	public TestOneToOne(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp() {
-        deleteAll(AnnoTest1.class);
-        deleteAll(AnnoTest2.class);
-    }
-
-    public void testOneToOne() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc.setOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        pc2 = pc.getOneOne();
-        assertNotNull(pc2);
-        assertEquals(15, pc2.getPk1());
-        assertEquals("foo", pc2.getPk2());
-        endEm(em);
-    }
-
-    public void testSelfOneToOne() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest1 pc2 = new AnnoTest1(15);
-        pc.setSelfOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        pc2 = pc.getSelfOneOne();
-        assertNotNull(pc2);
-        assertEquals(new Long(15), pc2.getPk());
-        endEm(em);
-    }
-
-    public void testPKJoinSelfOneToOne() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest1 pc2 = new AnnoTest1(15);
-        pc.setSelfOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        pc2 = pc.getSelfOneOne();
-        assertNotNull(pc2);
-        assertEquals(new Long(15), pc2.getPk());
-        endEm(em);
-    }
-
-    public void testOtherTableOneToOne() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc.setOtherTableOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        pc2 = pc.getOtherTableOneOne();
-        assertNotNull(pc2);
-        assertEquals(15, pc2.getPk1());
-        assertEquals("foo", pc2.getPk2());
-        endEm(em);
-    }
-
-    public void testInverseOneToOne() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc2.setInverseOneOne(pc);
-        em.persist(pc);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        pc2 = pc.getInverseOwnerOneOne();
-        assertNotNull(pc2);
-        assertEquals(15, pc2.getPk1());
-        assertEquals("foo", pc2.getPk2());
-        assertEquals(pc, pc2.getInverseOneOne());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * Test for 1-1
+ *
+ * @author Steve Kim
+ */
+public class TestOneToOne extends AnnotationTestCase
+{
+
+	public TestOneToOne(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp() {
+        deleteAll(AnnoTest1.class);
+        deleteAll(AnnoTest2.class);
+    }
+
+    public void testOneToOne() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc.setOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        pc2 = pc.getOneOne();
+        assertNotNull(pc2);
+        assertEquals(15, pc2.getPk1());
+        assertEquals("foo", pc2.getPk2());
+        endEm(em);
+    }
+
+    public void testSelfOneToOne() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest1 pc2 = new AnnoTest1(15);
+        pc.setSelfOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        pc2 = pc.getSelfOneOne();
+        assertNotNull(pc2);
+        assertEquals(new Long(15), pc2.getPk());
+        endEm(em);
+    }
+
+    public void testPKJoinSelfOneToOne() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest1 pc2 = new AnnoTest1(15);
+        pc.setSelfOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        pc2 = pc.getSelfOneOne();
+        assertNotNull(pc2);
+        assertEquals(new Long(15), pc2.getPk());
+        endEm(em);
+    }
+
+    public void testOtherTableOneToOne() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc.setOtherTableOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        pc2 = pc.getOtherTableOneOne();
+        assertNotNull(pc2);
+        assertEquals(15, pc2.getPk1());
+        assertEquals("foo", pc2.getPk2());
+        endEm(em);
+    }
+
+    public void testInverseOneToOne() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc2.setInverseOneOne(pc);
+        em.persist(pc);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        pc2 = pc.getInverseOwnerOneOne();
+        assertNotNull(pc2);
+        assertEquals(15, pc2.getPk1());
+        assertEquals("foo", pc2.getPk2());
+        assertEquals(pc, pc2.getInverseOneOne());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestPropertyAccess.java
index 4cb2f74..e061cdc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestPropertyAccess.java
@@ -1,121 +1,121 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-
-
-public class TestPropertyAccess extends AnnotationTestCase
-{
-	public TestPropertyAccess(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    public void setUp() {
-        deleteAll(PropertyAccess1.class);
-    }
-
-    public void testPropertyAccessBasicCreation() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
-        pa1_1.setName("foo");
-        em.persist(pa1_1);
-        endTx(em);
-
-        // getting a new EM should not be necessary once the extended PC stuff
-        // is complete.
-        em = (OpenJPAEntityManager) currentEntityManager();
-
-        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
-        assertNotSame(pa1_1, pa1_2);
-        assertNotNull(pa1_2);
-        assertEquals(10, pa1_2.getId());
-        assertEquals("foo", pa1_2.getName());
-    }
-
-    public void testPropertyAccessBasicMutation() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
-        pa1_1.setName("foo");
-        em.persist(pa1_1);
-        endTx(em);
-
-        // getting a new EM should not be necessary once the extended PC stuff
-        // is complete.
-        em = (OpenJPAEntityManager) currentEntityManager();
-
-        startTx(em);
-        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
-        pa1_2.setName(pa1_2.getName() + "bar");
-        endTx(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        PropertyAccess1 pa1_3 = em.find(PropertyAccess1.class, 10);
-        assertNotSame(pa1_2, pa1_3);
-        assertEquals("foobar", pa1_3.getName());
-    }
-
-    public void testJPQL() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        em.createQuery("select o from PropertyAccess1 o where " +
-            "o.name = 'foo'").getResultList();
-        em.createQuery("select o from PropertyAccess1 o order by " +
-            "o.name asc").getResultList();
-        endEm(em);
-    }
-
-    public void testJPQLWithFieldNameMismatch() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        em.createQuery("select o from PropertyAccess1 o where " +
-            "o.intValue = 0").getResultList();
-        em.createQuery("select o from PropertyAccess1 o order by " +
-            "o.intValue asc").getResultList();
-        endEm(em);
-    }
-
-    /*public void testJDOQL() {
-        PersistenceManager pm = getPM();
-        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
-            + "where name == 'foo'").execute();
-        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
-            + "order by name ascending").execute();
-        pm.close();
-    }
-
-    public void testJDOQLWithFieldNameMismatch() {
-        PersistenceManager pm = getPM();
-        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
-            + "where intValue == 0").execute();
-        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
-            + "order by intValue asc").execute();
-        pm.close();
-    }*/
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+
+
+public class TestPropertyAccess extends AnnotationTestCase
+{
+	public TestPropertyAccess(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    public void setUp() {
+        deleteAll(PropertyAccess1.class);
+    }
+
+    public void testPropertyAccessBasicCreation() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
+        pa1_1.setName("foo");
+        em.persist(pa1_1);
+        endTx(em);
+
+        // getting a new EM should not be necessary once the extended PC stuff
+        // is complete.
+        em = (OpenJPAEntityManager) currentEntityManager();
+
+        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
+        assertNotSame(pa1_1, pa1_2);
+        assertNotNull(pa1_2);
+        assertEquals(10, pa1_2.getId());
+        assertEquals("foo", pa1_2.getName());
+    }
+
+    public void testPropertyAccessBasicMutation() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
+        pa1_1.setName("foo");
+        em.persist(pa1_1);
+        endTx(em);
+
+        // getting a new EM should not be necessary once the extended PC stuff
+        // is complete.
+        em = (OpenJPAEntityManager) currentEntityManager();
+
+        startTx(em);
+        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
+        pa1_2.setName(pa1_2.getName() + "bar");
+        endTx(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        PropertyAccess1 pa1_3 = em.find(PropertyAccess1.class, 10);
+        assertNotSame(pa1_2, pa1_3);
+        assertEquals("foobar", pa1_3.getName());
+    }
+
+    public void testJPQL() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        em.createQuery("select o from PropertyAccess1 o where " +
+            "o.name = 'foo'").getResultList();
+        em.createQuery("select o from PropertyAccess1 o order by " +
+            "o.name asc").getResultList();
+        endEm(em);
+    }
+
+    public void testJPQLWithFieldNameMismatch() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        em.createQuery("select o from PropertyAccess1 o where " +
+            "o.intValue = 0").getResultList();
+        em.createQuery("select o from PropertyAccess1 o order by " +
+            "o.intValue asc").getResultList();
+        endEm(em);
+    }
+
+    /*public void testJDOQL() {
+        PersistenceManager pm = getPM();
+        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
+            + "where name == 'foo'").execute();
+        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
+            + "order by name ascending").execute();
+        pm.close();
+    }
+
+    public void testJDOQLWithFieldNameMismatch() {
+        PersistenceManager pm = getPM();
+        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
+            + "where intValue == 0").execute();
+        pm.newQuery("select from persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1 "
+            + "order by intValue asc").execute();
+        pm.close();
+    }*/
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestSerializedLobs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestSerializedLobs.java
index f9d6722..c754b40 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestSerializedLobs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestSerializedLobs.java
@@ -1,146 +1,146 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import java.sql.*;
-import java.util.Date;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.sql.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-
-
-/**
- * Test for serialized, clob, and lob types.
- *
- * @author Steve Kim
- */
-public class TestSerializedLobs extends AnnotationTestCase
-{
-
-	public TestSerializedLobs(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-    private static final Date DATE = new Date();
-
-    public void setUp() {
-        deleteAll(AnnoTest1.class);
-    }
-
-    // Serialized fields not being read properly
-    public void testSerialized() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        AnnoTest1 pc1 = new AnnoTest1(1);
-        AnnoTest1 pc2 = new AnnoTest1(2);
-        pc1.setSerialized("ASDASD");
-        pc2.setSerialized(DATE);
-        em.persist(pc1);
-        em.persist(pc2);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc1 = em.find(AnnoTest1.class, em.getObjectId(pc1));
-        pc2 = em.find(AnnoTest1.class, em.getObjectId(pc2));
-        assertEquals("ASDASD", pc1.getSerialized());
-        assertEquals(DATE, pc2.getSerialized());
-        endEm(em);
-    }
-
-    public void testBlob()
-        throws Exception {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        AnnoTest1 pc = new AnnoTest1(1);
-        pc.setBlob("Not Null".getBytes());
-        em.persist(pc);
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
-        assertEquals("Not Null", new String(pc.getBlob()));
-        Connection conn = (Connection) em.getConnection();
-        Statement stmnt = conn.createStatement();
-        ResultSet rs = stmnt.executeQuery("SELECT BLOBVAL FROM ANNOTEST1 "
-            + "WHERE PK = 1");
-        assertTrue(rs.next());
-
-       /** JDBCConfiguration conf = (JDBCConfiguration) em.getConfiguration();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        if (dict.useGetBytesForBlobs)
-            rs.getBytes(1);
-        else if (dict.useGetObjectForBlobs)
-            rs.getObject(1);
-        else {
-            Blob blob = rs.getBlob(1);
-            blob.getBytes(1L, (int) blob.length());
-        }
-        assertEquals("Not Null", new String(pc.getBlob()));
-
-        try {
-            rs.close();
-        } catch (SQLException e) {
-        }
-        try {
-            stmnt.close();
-        } catch (SQLException e) {
-        }
-        try {
-            conn.close();
-        } catch (SQLException e) {
-        }**/
-        endEm(em);
-    }
-
-    public void testClob()
-        throws Exception {
-        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        AnnoTest1 pc = new AnnoTest1(1);
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < 1000; i++)
-            buf.append((char) ('a' + (i % 24)));
-        pc.setClob(buf.toString());
-        em.persist(pc);
-        endTx(em);
-        endEm(em);
-
-        em =(OpenJPAEntityManager) currentEntityManager();
-        pc = em.find(AnnoTest1.class,em.getObjectId(pc));
-        String str = pc.getClob();
-        assertEquals(1000, str.length());
-        for (int i = 0; i < str.length(); i++)
-            assertEquals('a' + (i % 24), str.charAt(i));
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import java.sql.*;
+import java.util.Date;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.sql.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+
+
+/**
+ * Test for serialized, clob, and lob types.
+ *
+ * @author Steve Kim
+ */
+public class TestSerializedLobs extends AnnotationTestCase
+{
+
+	public TestSerializedLobs(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+    private static final Date DATE = new Date();
+
+    public void setUp() {
+        deleteAll(AnnoTest1.class);
+    }
+
+    // Serialized fields not being read properly
+    public void testSerialized() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        AnnoTest1 pc1 = new AnnoTest1(1);
+        AnnoTest1 pc2 = new AnnoTest1(2);
+        pc1.setSerialized("ASDASD");
+        pc2.setSerialized(DATE);
+        em.persist(pc1);
+        em.persist(pc2);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc1 = em.find(AnnoTest1.class, em.getObjectId(pc1));
+        pc2 = em.find(AnnoTest1.class, em.getObjectId(pc2));
+        assertEquals("ASDASD", pc1.getSerialized());
+        assertEquals(DATE, pc2.getSerialized());
+        endEm(em);
+    }
+
+    public void testBlob()
+        throws Exception {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        AnnoTest1 pc = new AnnoTest1(1);
+        pc.setBlob("Not Null".getBytes());
+        em.persist(pc);
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class, em.getObjectId(pc));
+        assertEquals("Not Null", new String(pc.getBlob()));
+        Connection conn = (Connection) em.getConnection();
+        Statement stmnt = conn.createStatement();
+        ResultSet rs = stmnt.executeQuery("SELECT BLOBVAL FROM ANNOTEST1 "
+            + "WHERE PK = 1");
+        assertTrue(rs.next());
+
+       /** JDBCConfiguration conf = (JDBCConfiguration) em.getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        if (dict.useGetBytesForBlobs)
+            rs.getBytes(1);
+        else if (dict.useGetObjectForBlobs)
+            rs.getObject(1);
+        else {
+            Blob blob = rs.getBlob(1);
+            blob.getBytes(1L, (int) blob.length());
+        }
+        assertEquals("Not Null", new String(pc.getBlob()));
+
+        try {
+            rs.close();
+        } catch (SQLException e) {
+        }
+        try {
+            stmnt.close();
+        } catch (SQLException e) {
+        }
+        try {
+            conn.close();
+        } catch (SQLException e) {
+        }**/
+        endEm(em);
+    }
+
+    public void testClob()
+        throws Exception {
+        OpenJPAEntityManager em =(OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        AnnoTest1 pc = new AnnoTest1(1);
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < 1000; i++)
+            buf.append((char) ('a' + (i % 24)));
+        pc.setClob(buf.toString());
+        em.persist(pc);
+        endTx(em);
+        endEm(em);
+
+        em =(OpenJPAEntityManager) currentEntityManager();
+        pc = em.find(AnnoTest1.class,em.getObjectId(pc));
+        String str = pc.getClob();
+        assertEquals(1000, str.length());
+        for (int i = 0; i < str.length(); i++)
+            assertEquals('a' + (i % 24), str.charAt(i));
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestTablePerClassInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestTablePerClassInheritance.java
index 2d92a05..5a680fa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestTablePerClassInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestTablePerClassInheritance.java
@@ -1,108 +1,108 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.meta.strats.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
-import junit.framework.*;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-
-
-/**
- * <p>Test that InheritanceType.TABLE_PER_CLASS JPA mapping is translated
- * correctly.  See the <code>kodo.jdbc.meta.tableperclass</code> test package
- * for more detailed tests of functionality.</p>
- *
- * @author Abe White
- */
-public class TestTablePerClassInheritance extends AnnotationTestCase
-{
-
-	public TestTablePerClassInheritance(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-   /** public void testMapping() {
-        ClassMapping mapping = ((JDBCConfiguration) getConfiguration()).
-            getMappingRepositoryInstance().getMapping(TablePerClass2.class,
-            null, true);
-        assertTrue(mapping.getStrategy() instanceof FullClassStrategy);
-        assertTrue(mapping.getDiscriminator().getStrategy()
-            instanceof NoneDiscriminatorStrategy);
-        assertNull(mapping.getJoinForeignKey());
-        assertNull(mapping.getJoinablePCSuperclassMapping());
-        assertEquals("TPC_BASIC", mapping.getFieldMapping("basic").
-            getColumns()[0].getName());
-        ClassMapping embed = mapping.getFieldMapping("embed").
-            currentEntityManager()beddedMapping();
-        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
-            getColumns()[0].getName());
-
-        ClassMapping sup = mapping.getPCSuperclassMapping();
-        assertEquals(TablePerClass1.class, sup.getDescribedType());
-        assertTrue(sup.getStrategy() instanceof FullClassStrategy);
-        assertTrue(sup.getDiscriminator().getStrategy()
-            instanceof NoneDiscriminatorStrategy);
-        assertEquals("TPC_BASIC", sup.getFieldMapping("basic").
-            getColumns()[0].getName());
-        embed = sup.getFieldMapping("embed").currentEntityManager()beddedMapping();
-        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
-            getColumns()[0].getName());
-    }**/
-
-    public void testInsertAndRetrieve() {
-        deleteAll(TablePerClass1.class);
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-       startTx(em);
-        TablePerClass1 tpc1 = new TablePerClass1();
-        tpc1.setBasic(1);
-        EmbedValue ev = new EmbedValue();
-        ev.setBasic("11");
-        tpc1.setEmbed(ev);
-        TablePerClass2 tpc2 = new TablePerClass2();
-        tpc2.setBasic(2);
-        tpc2.setBasic2("2");
-        ev = new EmbedValue();
-        ev.setBasic("22");
-        tpc2.setEmbed(ev);
-        em.persistAll(tpc1, tpc2);
-       endTx(em);
-        int id1 = tpc1.getPk();
-        int id2 = tpc2.getPk();
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        tpc1 = em.find(TablePerClass1.class, id1);
-        assertEquals(1, tpc1.getBasic());
-        assertEquals("11", tpc1.getEmbed().getBasic());
-        tpc2 = (TablePerClass2) em.find(TablePerClass1.class, id2);
-        assertEquals(2, tpc2.getBasic());
-        assertEquals("2", tpc2.getBasic2());
-        assertEquals("22", tpc2.getEmbed().getBasic());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.*;
+import junit.framework.*;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+
+
+/**
+ * <p>Test that InheritanceType.TABLE_PER_CLASS JPA mapping is translated
+ * correctly.  See the <code>kodo.jdbc.meta.tableperclass</code> test package
+ * for more detailed tests of functionality.</p>
+ *
+ * @author Abe White
+ */
+public class TestTablePerClassInheritance extends AnnotationTestCase
+{
+
+	public TestTablePerClassInheritance(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+   /** public void testMapping() {
+        ClassMapping mapping = ((JDBCConfiguration) getConfiguration()).
+            getMappingRepositoryInstance().getMapping(TablePerClass2.class,
+            null, true);
+        assertTrue(mapping.getStrategy() instanceof FullClassStrategy);
+        assertTrue(mapping.getDiscriminator().getStrategy()
+            instanceof NoneDiscriminatorStrategy);
+        assertNull(mapping.getJoinForeignKey());
+        assertNull(mapping.getJoinablePCSuperclassMapping());
+        assertEquals("TPC_BASIC", mapping.getFieldMapping("basic").
+            getColumns()[0].getName());
+        ClassMapping embed = mapping.getFieldMapping("embed").
+            currentEntityManager()beddedMapping();
+        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
+            getColumns()[0].getName());
+
+        ClassMapping sup = mapping.getPCSuperclassMapping();
+        assertEquals(TablePerClass1.class, sup.getDescribedType());
+        assertTrue(sup.getStrategy() instanceof FullClassStrategy);
+        assertTrue(sup.getDiscriminator().getStrategy()
+            instanceof NoneDiscriminatorStrategy);
+        assertEquals("TPC_BASIC", sup.getFieldMapping("basic").
+            getColumns()[0].getName());
+        embed = sup.getFieldMapping("embed").currentEntityManager()beddedMapping();
+        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
+            getColumns()[0].getName());
+    }**/
+
+    public void testInsertAndRetrieve() {
+        deleteAll(TablePerClass1.class);
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+       startTx(em);
+        TablePerClass1 tpc1 = new TablePerClass1();
+        tpc1.setBasic(1);
+        EmbedValue ev = new EmbedValue();
+        ev.setBasic("11");
+        tpc1.setEmbed(ev);
+        TablePerClass2 tpc2 = new TablePerClass2();
+        tpc2.setBasic(2);
+        tpc2.setBasic2("2");
+        ev = new EmbedValue();
+        ev.setBasic("22");
+        tpc2.setEmbed(ev);
+        em.persistAll(tpc1, tpc2);
+       endTx(em);
+        int id1 = tpc1.getPk();
+        int id2 = tpc2.getPk();
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        tpc1 = em.find(TablePerClass1.class, id1);
+        assertEquals(1, tpc1.getBasic());
+        assertEquals("11", tpc1.getEmbed().getBasic());
+        tpc2 = (TablePerClass2) em.find(TablePerClass1.class, id2);
+        assertEquals(2, tpc2.getBasic());
+        assertEquals("2", tpc2.getBasic2());
+        assertEquals("22", tpc2.getEmbed().getBasic());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestVersion.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestVersion.java
index e4e9726..56ed85f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestVersion.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/TestVersion.java
@@ -1,240 +1,240 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations;
-
-import javax.persistence.* ;
-
-import org.apache.openjpa.jdbc.conf.* ;
-import org.apache.openjpa.jdbc.meta.* ;
-import org.apache.openjpa.jdbc.meta.strats.* ;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.* ;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-/*
-   Test for opt-lock
-
-   @author Steve Kim
-  */
-public class TestVersion extends AnnotationTestCase
-{
-	private Object oid;
-
-	private Object oid1;
-
-	private Object oid2;
-
-	public TestVersion(String name)
-	{
-		super(name, "annotationcactusapp");
-	}
-
-	public void setUp()
-	{
-		new AnnoTest1();
-		new AnnoTest2();
-		new AnnoTest3();
-
-		deleteAll(AnnoTest1.class);
-		deleteAll(AnnoTest2.class);
-
-		OpenJPAEntityManager em = currentEntityManager();
-		startTx(em);
-		AnnoTest1 test1 = new AnnoTest1();
-		test1.setPk(new Long(5));
-		test1.setBasic(50);
-		test1.setTransient(500);
-		em.persist(test1);
-
-		AnnoTest2 test2 = new AnnoTest2();
-		test2.setPk1(5);
-		test2.setPk2("bar");
-		test2.setBasic("50");
-		em.persist(test2);
-
-		AnnoTest3 test3 = new AnnoTest3();
-		test3.setPk(new Long(3));
-		test3.setBasic2(50);
-		em.persist(test3);
-		oid = em.getObjectId(test1);
-		oid1 = em.getObjectId(test2);
-		oid2 = em.getObjectId(test3);
-
-		endTx(em);
-		endEm(em);
-	}
-
-/*
- * Fix Me aokeke -- Testcases causes deadlock during runtime CR307216 is used to track this issue.
- */
- public void testVersionNumeric()
-	{
-		OpenJPAEntityManager em1 = currentEntityManager();
-		startTx(em1);
-		EntityManager em2 = getEmf().createEntityManager();
-
-		AnnoTest1 pc1 = em1.find(AnnoTest1.class, oid);
-		AnnoTest1 pc2 = em2.find(AnnoTest1.class, oid);
-		assertEquals(1, pc1.getVersion());
-		assertEquals(1, pc2.getVersion());
-		assertEquals(0, pc1.getTransient());
-		pc1.setBasic(75);
-
-		endTx(em1);
-		endEm(em1);
-
-		em2.getTransaction().begin();
-		pc2.setBasic(75);
-		em1 = (OpenJPAEntityManager) currentEntityManager();
-		pc1 = em1.find(AnnoTest1.class, oid);
-		assertEquals(2, pc1.getVersion());
-		endEm(em1);
-		try
-		{
-			em2.getTransaction().commit();
-			fail("Optimistic fail");
-		}
-		catch (RuntimeException re)
-		{}
-		catch (Exception e)
-		{}
-		finally
-		{
-			em2.close();
-		}
-	}
-
-	public void testVersionTimestamp()
-	{
-		OpenJPAEntityManager em1 = currentEntityManager();
-		startTx(em1);
-		OpenJPAEntityManager em2 = getEmf().createEntityManager();
-
-		AnnoTest2 pc1 = em1.find(AnnoTest2.class, oid1);
-		AnnoTest2 pc2 = em2.find(AnnoTest2.class, oid1);
-		assertNotNull(pc1.getVersion());
-		assertEquals(pc1.getVersion(), pc2.getVersion());
-		pc1.setBasic("75");
-
-		endTx(em1);
-		endEm(em1);
-
-		em2.getTransaction().begin();
-		pc2.setBasic("75");
-
-		em1 = (OpenJPAEntityManager) currentEntityManager();
-		pc1 = em1.find(AnnoTest2.class, oid1);
-		assertTrue(pc1.getVersion().compareTo(pc2.getVersion()) > 0);
-		endEm(em1);
-		try
-		{
-			em2.getTransaction().commit();
-			fail("Optimistic fail");
-		}
-		catch (RuntimeException re)
-		{}
-		catch (Exception e)
-		{}
-		finally
-		{
-			em2.close();
-		}
-	}
-
-	public void testVersionSubclass()
-	{
-		OpenJPAEntityManager em1 = currentEntityManager();
-		startTx(em1);
-		OpenJPAEntityManager em2 = getEmf().createEntityManager();
-
-		AnnoTest3 pc1 = em1.find(AnnoTest3.class, oid2);
-		AnnoTest3 pc2 = em2.find(AnnoTest3.class, oid2);
-		assertEquals(1, pc1.getVersion());
-		assertEquals(1, pc2.getVersion());
-		pc1.setBasic2(75);
-
-		endTx(em1);
-		endEm(em1);
-
-
-		em2.getTransaction().begin();
-		pc2.setBasic2(75);
-
-
-		em1 = (OpenJPAEntityManager) currentEntityManager();
-		pc1 = em1.find(AnnoTest3.class, oid2);
-		assertEquals(2, pc1.getVersion());
-		endEm(em1);
-		try
-		{
-			em2.getTransaction().commit();
-			fail("Optimistic fail");
-		}
-		catch (RuntimeException re)
-		{}
-		catch (Exception e)
-		{}
-		finally
-		{
-			em2.close();
-		}
-	}
-
-	public void testVersionNoChange()
-	{
-		OpenJPAEntityManager em = currentEntityManager();
-		startTx(em);
-
-		AnnoTest1 pc = em.find(AnnoTest1.class, oid);
-		assertEquals(1, pc.getVersion());
-		assertEquals(0, pc.getTransient());
-		pc.setTransient(750);
-		endTx(em);
-		endEm(em);
-
-		em = (OpenJPAEntityManager) currentEntityManager();
-		pc = em.find(AnnoTest1.class, oid);
-		assertEquals(1, pc.getVersion());
-		assertEquals(0, pc.getTransient());
-		endEm(em);
-	}
-
-	   public void testNoDefaultVersionWithoutFieldOrColumn()
-	   {
-			OpenJPAEntityManager pm = (OpenJPAEntityManager) currentEntityManager();
-		   ClassMapping cls =  ((JDBCConfigurationImpl)((OpenJPAEntityManagerSPI) OpenJPAPersistence.cast(pm)).getConfiguration()).getMappingRepositoryInstance().getMapping(EmbedOwner.class, null, true);
-		   assertEquals(NoneVersionStrategy.getInstance(),
-				   cls.getVersion().getStrategy()); assertEquals(0,
-						   cls.getVersion().getColumns().length);
-			endEm(pm);
-	   }
-
-	   public void testVersionWithField()
-	   {
-		   OpenJPAEntityManager pm = (OpenJPAEntityManager) currentEntityManager();
-		   ClassMapping cls = ((JDBCConfigurationImpl)((OpenJPAEntityManagerSPI) OpenJPAPersistence.cast(pm)).getConfiguration()).getMappingRepositoryInstance().getMapping(AnnoTest1.class, null, true);
-		   assertTrue(NoneVersionStrategy.getInstance() !=
-			   cls.getVersion().getStrategy()); assertEquals(1,
-					   cls.getVersion().getColumns().length);
-			endEm(pm);
-	   }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations;
+
+import javax.persistence.* ;
+
+import org.apache.openjpa.jdbc.conf.* ;
+import org.apache.openjpa.jdbc.meta.* ;
+import org.apache.openjpa.jdbc.meta.strats.* ;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.* ;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/*
+   Test for opt-lock
+
+   @author Steve Kim
+  */
+public class TestVersion extends AnnotationTestCase
+{
+	private Object oid;
+
+	private Object oid1;
+
+	private Object oid2;
+
+	public TestVersion(String name)
+	{
+		super(name, "annotationcactusapp");
+	}
+
+	public void setUp()
+	{
+		new AnnoTest1();
+		new AnnoTest2();
+		new AnnoTest3();
+
+		deleteAll(AnnoTest1.class);
+		deleteAll(AnnoTest2.class);
+
+		OpenJPAEntityManager em = currentEntityManager();
+		startTx(em);
+		AnnoTest1 test1 = new AnnoTest1();
+		test1.setPk(new Long(5));
+		test1.setBasic(50);
+		test1.setTransient(500);
+		em.persist(test1);
+
+		AnnoTest2 test2 = new AnnoTest2();
+		test2.setPk1(5);
+		test2.setPk2("bar");
+		test2.setBasic("50");
+		em.persist(test2);
+
+		AnnoTest3 test3 = new AnnoTest3();
+		test3.setPk(new Long(3));
+		test3.setBasic2(50);
+		em.persist(test3);
+		oid = em.getObjectId(test1);
+		oid1 = em.getObjectId(test2);
+		oid2 = em.getObjectId(test3);
+
+		endTx(em);
+		endEm(em);
+	}
+
+/*
+ * Fix Me aokeke -- Testcases causes deadlock during runtime CR307216 is used to track this issue.
+ */
+ public void testVersionNumeric()
+	{
+		OpenJPAEntityManager em1 = currentEntityManager();
+		startTx(em1);
+		EntityManager em2 = getEmf().createEntityManager();
+
+		AnnoTest1 pc1 = em1.find(AnnoTest1.class, oid);
+		AnnoTest1 pc2 = em2.find(AnnoTest1.class, oid);
+		assertEquals(1, pc1.getVersion());
+		assertEquals(1, pc2.getVersion());
+		assertEquals(0, pc1.getTransient());
+		pc1.setBasic(75);
+
+		endTx(em1);
+		endEm(em1);
+
+		em2.getTransaction().begin();
+		pc2.setBasic(75);
+		em1 = (OpenJPAEntityManager) currentEntityManager();
+		pc1 = em1.find(AnnoTest1.class, oid);
+		assertEquals(2, pc1.getVersion());
+		endEm(em1);
+		try
+		{
+			em2.getTransaction().commit();
+			fail("Optimistic fail");
+		}
+		catch (RuntimeException re)
+		{}
+		catch (Exception e)
+		{}
+		finally
+		{
+			em2.close();
+		}
+	}
+
+	public void testVersionTimestamp()
+	{
+		OpenJPAEntityManager em1 = currentEntityManager();
+		startTx(em1);
+		OpenJPAEntityManager em2 = getEmf().createEntityManager();
+
+		AnnoTest2 pc1 = em1.find(AnnoTest2.class, oid1);
+		AnnoTest2 pc2 = em2.find(AnnoTest2.class, oid1);
+		assertNotNull(pc1.getVersion());
+		assertEquals(pc1.getVersion(), pc2.getVersion());
+		pc1.setBasic("75");
+
+		endTx(em1);
+		endEm(em1);
+
+		em2.getTransaction().begin();
+		pc2.setBasic("75");
+
+		em1 = (OpenJPAEntityManager) currentEntityManager();
+		pc1 = em1.find(AnnoTest2.class, oid1);
+		assertTrue(pc1.getVersion().compareTo(pc2.getVersion()) > 0);
+		endEm(em1);
+		try
+		{
+			em2.getTransaction().commit();
+			fail("Optimistic fail");
+		}
+		catch (RuntimeException re)
+		{}
+		catch (Exception e)
+		{}
+		finally
+		{
+			em2.close();
+		}
+	}
+
+	public void testVersionSubclass()
+	{
+		OpenJPAEntityManager em1 = currentEntityManager();
+		startTx(em1);
+		OpenJPAEntityManager em2 = getEmf().createEntityManager();
+
+		AnnoTest3 pc1 = em1.find(AnnoTest3.class, oid2);
+		AnnoTest3 pc2 = em2.find(AnnoTest3.class, oid2);
+		assertEquals(1, pc1.getVersion());
+		assertEquals(1, pc2.getVersion());
+		pc1.setBasic2(75);
+
+		endTx(em1);
+		endEm(em1);
+
+
+		em2.getTransaction().begin();
+		pc2.setBasic2(75);
+
+
+		em1 = (OpenJPAEntityManager) currentEntityManager();
+		pc1 = em1.find(AnnoTest3.class, oid2);
+		assertEquals(2, pc1.getVersion());
+		endEm(em1);
+		try
+		{
+			em2.getTransaction().commit();
+			fail("Optimistic fail");
+		}
+		catch (RuntimeException re)
+		{}
+		catch (Exception e)
+		{}
+		finally
+		{
+			em2.close();
+		}
+	}
+
+	public void testVersionNoChange()
+	{
+		OpenJPAEntityManager em = currentEntityManager();
+		startTx(em);
+
+		AnnoTest1 pc = em.find(AnnoTest1.class, oid);
+		assertEquals(1, pc.getVersion());
+		assertEquals(0, pc.getTransient());
+		pc.setTransient(750);
+		endTx(em);
+		endEm(em);
+
+		em = (OpenJPAEntityManager) currentEntityManager();
+		pc = em.find(AnnoTest1.class, oid);
+		assertEquals(1, pc.getVersion());
+		assertEquals(0, pc.getTransient());
+		endEm(em);
+	}
+
+	   public void testNoDefaultVersionWithoutFieldOrColumn()
+	   {
+			OpenJPAEntityManager pm = (OpenJPAEntityManager) currentEntityManager();
+		   ClassMapping cls =  ((JDBCConfigurationImpl)((OpenJPAEntityManagerSPI) OpenJPAPersistence.cast(pm)).getConfiguration()).getMappingRepositoryInstance().getMapping(EmbedOwner.class, null, true);
+		   assertEquals(NoneVersionStrategy.getInstance(),
+				   cls.getVersion().getStrategy()); assertEquals(0,
+						   cls.getVersion().getColumns().length);
+			endEm(pm);
+	   }
+
+	   public void testVersionWithField()
+	   {
+		   OpenJPAEntityManager pm = (OpenJPAEntityManager) currentEntityManager();
+		   ClassMapping cls = ((JDBCConfigurationImpl)((OpenJPAEntityManagerSPI) OpenJPAPersistence.cast(pm)).getConfiguration()).getMappingRepositoryInstance().getMapping(AnnoTest1.class, null, true);
+		   assertTrue(NoneVersionStrategy.getInstance() !=
+			   cls.getVersion().getStrategy()); assertEquals(1,
+					   cls.getVersion().getColumns().length);
+			endEm(pm);
+	   }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest1.java
index 4e4b108..9cbecb9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest1.java
@@ -1,311 +1,311 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.jdbc.*;
-
-@Entity
-@Table(name = "ANNOTEST1")
-@Inheritance(strategy = InheritanceType.JOINED)
-@DiscriminatorColumn(name = "ANNOCLS")
-@DiscriminatorValue("ANNO1")
-@SecondaryTables({ @SecondaryTable(name = "OTHER_ANNOTEST1",
-    pkJoinColumns = @PrimaryKeyJoinColumn(name = "OTHER_PK",
-        referencedColumnName = "PK")) })
-public class AnnoTest1 {
-
-    @Id
-    @Column(name = "PK")
-    private Long pk;
-
-    @Version
-    @Column(name = "ANNOVER")
-    private int version;
-
-    @Basic
-    private int basic;
-
-    @Transient
-    private int trans;
-
-    @Basic
-    @Column(name = "OTHERVALUE", table = "OTHER_ANNOTEST1")
-    private int otherTableBasic;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "SELFONEONE_PK", referencedColumnName = "PK")
-    private AnnoTest1 selfOneOne;
-
-    @OneToOne
-    @PrimaryKeyJoinColumn
-    private AnnoTest1 pkJoinSelfOneOne;
-
-    @OneToOne
-    @JoinColumns({
-    @JoinColumn(name = "ONEONE_PK1", referencedColumnName = "PK1"),
-    @JoinColumn(name = "ONEONE_PK2", referencedColumnName = "PK2") })
-    private AnnoTest2 oneOne;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @JoinColumns({
-    @JoinColumn(name = "OTHERONE_PK1", referencedColumnName = "PK1",
-        table = "OTHER_ANNOTEST1"),
-    @JoinColumn(name = "OTHERONE_PK2", referencedColumnName = "PK2",
-        table = "OTHER_ANNOTEST1") })
-    private AnnoTest2 otherTableOneOne;
-
-    @OneToOne(mappedBy = "inverseOneOne", fetch = FetchType.LAZY)
-    private AnnoTest2 inverseOwnerOneOne;
-
-    @Lob
-    @Column(name = "BLOBVAL")
-    private byte[] blob;
-
-    @Basic
-    @Lob
-    @Column(name = "SERVAL")
-    private Object serial;
-
-    @Column(name = "CLOBVAL")
-    @Lob
-    private String clob;
-
-    // un-annotated enum should be persisted by default
-    @Column(name = "ENUMVAL")
-    private InheritanceType enumeration;
-
-    @Enumerated
-    @Column(name = "ORD_ENUMVAL")
-    private InheritanceType ordinalEnumeration;
-
-    @Enumerated(EnumType.STRING)
-    @Column(name = "STR_ENUMVAL")
-    private InheritanceType stringEnumeration;
-
-    @OneToMany
-    @ElementJoinColumn(name = "ONEMANY_PK", referencedColumnName = "PK")
-    private Set<AnnoTest2> oneMany = new HashSet();
-
-    @OneToMany(mappedBy = "oneManyOwner")
-    private Set<AnnoTest2> inverseOwnerOneMany = new HashSet();
-
-    @ManyToMany
-    @JoinTable(name = "ANNOTEST1_MANYMANY",
-        joinColumns = @JoinColumn(name = "MANY_PK"),
-        inverseJoinColumns = {
-        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
-        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") })
-    private Set<AnnoTest2> manyMany = new HashSet();
-
-    @ManyToMany(mappedBy = "manyMany")
-    private Set<AnnoTest2> inverseOwnerManyMany = new HashSet();
-
-    @MapKey
-    @OneToMany
-    private Map<Integer, Flat1> defaultMapKey = new HashMap();
-
-    @MapKey(name = "basic")
-    @OneToMany
-    private Map<Integer, Flat1> namedMapKey = new HashMap();
-
-    @MapKey(name = "basic")
-    @OneToMany(mappedBy = "oneManyOwner")
-    private Map<String, AnnoTest2> inverseOwnerMapKey = new HashMap();
-
-    public AnnoTest1() {
-    }
-
-    public AnnoTest1(long pk) {
-        this.pk = new Long(pk);
-    }
-
-//    public AnnoTest1(Long pk) {
-//        this.pk = pk;
-//    }
-
-    public void setPk(Long val) {
-        pk = val;
-    }
-
-    public Long getPk() {
-        return pk;
-    }
-
-    public int getVersion() {
-        return version;
-    }
-
-    public void setBasic(int i) {
-        basic = i;
-    }
-
-    public int getBasic() {
-        return basic;
-    }
-
-    public void setTransient(int i) {
-        trans = i;
-    }
-
-    public int getTransient() {
-        return trans;
-    }
-
-    public void setOtherTableBasic(int i) {
-        otherTableBasic = i;
-    }
-
-    public int getOtherTableBasic() {
-        return otherTableBasic;
-    }
-
-    public void setSelfOneOne(AnnoTest1 other) {
-        selfOneOne = other;
-    }
-
-    public AnnoTest1 getSelfOneOne() {
-        return selfOneOne;
-    }
-
-    public void setPKJoinSelfOneOne(AnnoTest1 other) {
-        pkJoinSelfOneOne = other;
-    }
-
-    public AnnoTest1 getPKJoinSelfOneOne() {
-        return pkJoinSelfOneOne;
-    }
-
-    public void setOneOne(AnnoTest2 other) {
-        oneOne = other;
-    }
-
-    public AnnoTest2 getOneOne() {
-        return oneOne;
-    }
-
-    public void setOtherTableOneOne(AnnoTest2 other) {
-        otherTableOneOne = other;
-    }
-
-    public AnnoTest2 getOtherTableOneOne() {
-        return otherTableOneOne;
-    }
-
-    public void setInverseOwnerOneOne(AnnoTest2 other) {
-        inverseOwnerOneOne = other;
-    }
-
-    public AnnoTest2 getInverseOwnerOneOne() {
-        return inverseOwnerOneOne;
-    }
-
-    public void setBlob(byte[] bytes) {
-        blob = bytes;
-    }
-
-    public byte[] getBlob() {
-        return blob;
-    }
-
-    public void setSerialized(Object o) {
-        serial = o;
-    }
-
-    public Object getSerialized() {
-        return serial;
-    }
-
-    public void setClob(String s) {
-        clob = s;
-    }
-
-    public String getClob() {
-        return clob;
-    }
-
-    public InheritanceType getEnumeration() {
-        return enumeration;
-    }
-
-    public void setEnumeration(InheritanceType val) {
-        enumeration = val;
-    }
-
-    public InheritanceType getOrdinalEnumeration() {
-        return ordinalEnumeration;
-    }
-
-    public void setOrdinalEnumeration(InheritanceType val) {
-        ordinalEnumeration = val;
-    }
-
-    public InheritanceType getStringEnumeration() {
-        return stringEnumeration;
-    }
-
-    public void setStringEnumeration(InheritanceType val) {
-        stringEnumeration = val;
-    }
-
-    public Set<AnnoTest2> getOneMany() {
-        return oneMany;
-    }
-
-    public Set<AnnoTest2> getInverseOwnerOneMany() {
-        return inverseOwnerOneMany;
-    }
-
-    public Set<AnnoTest2> getManyMany() {
-        return manyMany;
-    }
-
-    public Set<AnnoTest2> getInverseOwnerManyMany() {
-        return inverseOwnerManyMany;
-    }
-
-    public Map<Integer, Flat1> getDefaultMapKey() {
-        return this.defaultMapKey;
-    }
-
-    public void setDefaultMapKey(Map<Integer, Flat1> defaultMapKey) {
-        this.defaultMapKey = defaultMapKey;
-    }
-
-    public Map<Integer, Flat1> getNamedMapKey() {
-        return this.namedMapKey;
-    }
-
-    public void setNamedMapKey(Map<Integer, Flat1> namedMapKey) {
-        this.namedMapKey = namedMapKey;
-    }
-
-    public Map<String, AnnoTest2> getInverseOwnerMapKey() {
-        return this.inverseOwnerMapKey;
-    }
-
-    public void setInverseOwnerMapKey(
-        Map<String, AnnoTest2> inverseOwnerMapKey) {
-        this.inverseOwnerMapKey = inverseOwnerMapKey;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.jdbc.*;
+
+@Entity
+@Table(name = "ANNOTEST1")
+@Inheritance(strategy = InheritanceType.JOINED)
+@DiscriminatorColumn(name = "ANNOCLS")
+@DiscriminatorValue("ANNO1")
+@SecondaryTables({ @SecondaryTable(name = "OTHER_ANNOTEST1",
+    pkJoinColumns = @PrimaryKeyJoinColumn(name = "OTHER_PK",
+        referencedColumnName = "PK")) })
+public class AnnoTest1 {
+
+    @Id
+    @Column(name = "PK")
+    private Long pk;
+
+    @Version
+    @Column(name = "ANNOVER")
+    private int version;
+
+    @Basic
+    private int basic;
+
+    @Transient
+    private int trans;
+
+    @Basic
+    @Column(name = "OTHERVALUE", table = "OTHER_ANNOTEST1")
+    private int otherTableBasic;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "SELFONEONE_PK", referencedColumnName = "PK")
+    private AnnoTest1 selfOneOne;
+
+    @OneToOne
+    @PrimaryKeyJoinColumn
+    private AnnoTest1 pkJoinSelfOneOne;
+
+    @OneToOne
+    @JoinColumns({
+    @JoinColumn(name = "ONEONE_PK1", referencedColumnName = "PK1"),
+    @JoinColumn(name = "ONEONE_PK2", referencedColumnName = "PK2") })
+    private AnnoTest2 oneOne;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @JoinColumns({
+    @JoinColumn(name = "OTHERONE_PK1", referencedColumnName = "PK1",
+        table = "OTHER_ANNOTEST1"),
+    @JoinColumn(name = "OTHERONE_PK2", referencedColumnName = "PK2",
+        table = "OTHER_ANNOTEST1") })
+    private AnnoTest2 otherTableOneOne;
+
+    @OneToOne(mappedBy = "inverseOneOne", fetch = FetchType.LAZY)
+    private AnnoTest2 inverseOwnerOneOne;
+
+    @Lob
+    @Column(name = "BLOBVAL")
+    private byte[] blob;
+
+    @Basic
+    @Lob
+    @Column(name = "SERVAL")
+    private Object serial;
+
+    @Column(name = "CLOBVAL")
+    @Lob
+    private String clob;
+
+    // un-annotated enum should be persisted by default
+    @Column(name = "ENUMVAL")
+    private InheritanceType enumeration;
+
+    @Enumerated
+    @Column(name = "ORD_ENUMVAL")
+    private InheritanceType ordinalEnumeration;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "STR_ENUMVAL")
+    private InheritanceType stringEnumeration;
+
+    @OneToMany
+    @ElementJoinColumn(name = "ONEMANY_PK", referencedColumnName = "PK")
+    private Set<AnnoTest2> oneMany = new HashSet();
+
+    @OneToMany(mappedBy = "oneManyOwner")
+    private Set<AnnoTest2> inverseOwnerOneMany = new HashSet();
+
+    @ManyToMany
+    @JoinTable(name = "ANNOTEST1_MANYMANY",
+        joinColumns = @JoinColumn(name = "MANY_PK"),
+        inverseJoinColumns = {
+        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
+        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") })
+    private Set<AnnoTest2> manyMany = new HashSet();
+
+    @ManyToMany(mappedBy = "manyMany")
+    private Set<AnnoTest2> inverseOwnerManyMany = new HashSet();
+
+    @MapKey
+    @OneToMany
+    private Map<Integer, Flat1> defaultMapKey = new HashMap();
+
+    @MapKey(name = "basic")
+    @OneToMany
+    private Map<Integer, Flat1> namedMapKey = new HashMap();
+
+    @MapKey(name = "basic")
+    @OneToMany(mappedBy = "oneManyOwner")
+    private Map<String, AnnoTest2> inverseOwnerMapKey = new HashMap();
+
+    public AnnoTest1() {
+    }
+
+    public AnnoTest1(long pk) {
+        this.pk = new Long(pk);
+    }
+
+//    public AnnoTest1(Long pk) {
+//        this.pk = pk;
+//    }
+
+    public void setPk(Long val) {
+        pk = val;
+    }
+
+    public Long getPk() {
+        return pk;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setBasic(int i) {
+        basic = i;
+    }
+
+    public int getBasic() {
+        return basic;
+    }
+
+    public void setTransient(int i) {
+        trans = i;
+    }
+
+    public int getTransient() {
+        return trans;
+    }
+
+    public void setOtherTableBasic(int i) {
+        otherTableBasic = i;
+    }
+
+    public int getOtherTableBasic() {
+        return otherTableBasic;
+    }
+
+    public void setSelfOneOne(AnnoTest1 other) {
+        selfOneOne = other;
+    }
+
+    public AnnoTest1 getSelfOneOne() {
+        return selfOneOne;
+    }
+
+    public void setPKJoinSelfOneOne(AnnoTest1 other) {
+        pkJoinSelfOneOne = other;
+    }
+
+    public AnnoTest1 getPKJoinSelfOneOne() {
+        return pkJoinSelfOneOne;
+    }
+
+    public void setOneOne(AnnoTest2 other) {
+        oneOne = other;
+    }
+
+    public AnnoTest2 getOneOne() {
+        return oneOne;
+    }
+
+    public void setOtherTableOneOne(AnnoTest2 other) {
+        otherTableOneOne = other;
+    }
+
+    public AnnoTest2 getOtherTableOneOne() {
+        return otherTableOneOne;
+    }
+
+    public void setInverseOwnerOneOne(AnnoTest2 other) {
+        inverseOwnerOneOne = other;
+    }
+
+    public AnnoTest2 getInverseOwnerOneOne() {
+        return inverseOwnerOneOne;
+    }
+
+    public void setBlob(byte[] bytes) {
+        blob = bytes;
+    }
+
+    public byte[] getBlob() {
+        return blob;
+    }
+
+    public void setSerialized(Object o) {
+        serial = o;
+    }
+
+    public Object getSerialized() {
+        return serial;
+    }
+
+    public void setClob(String s) {
+        clob = s;
+    }
+
+    public String getClob() {
+        return clob;
+    }
+
+    public InheritanceType getEnumeration() {
+        return enumeration;
+    }
+
+    public void setEnumeration(InheritanceType val) {
+        enumeration = val;
+    }
+
+    public InheritanceType getOrdinalEnumeration() {
+        return ordinalEnumeration;
+    }
+
+    public void setOrdinalEnumeration(InheritanceType val) {
+        ordinalEnumeration = val;
+    }
+
+    public InheritanceType getStringEnumeration() {
+        return stringEnumeration;
+    }
+
+    public void setStringEnumeration(InheritanceType val) {
+        stringEnumeration = val;
+    }
+
+    public Set<AnnoTest2> getOneMany() {
+        return oneMany;
+    }
+
+    public Set<AnnoTest2> getInverseOwnerOneMany() {
+        return inverseOwnerOneMany;
+    }
+
+    public Set<AnnoTest2> getManyMany() {
+        return manyMany;
+    }
+
+    public Set<AnnoTest2> getInverseOwnerManyMany() {
+        return inverseOwnerManyMany;
+    }
+
+    public Map<Integer, Flat1> getDefaultMapKey() {
+        return this.defaultMapKey;
+    }
+
+    public void setDefaultMapKey(Map<Integer, Flat1> defaultMapKey) {
+        this.defaultMapKey = defaultMapKey;
+    }
+
+    public Map<Integer, Flat1> getNamedMapKey() {
+        return this.namedMapKey;
+    }
+
+    public void setNamedMapKey(Map<Integer, Flat1> namedMapKey) {
+        this.namedMapKey = namedMapKey;
+    }
+
+    public Map<String, AnnoTest2> getInverseOwnerMapKey() {
+        return this.inverseOwnerMapKey;
+    }
+
+    public void setInverseOwnerMapKey(
+        Map<String, AnnoTest2> inverseOwnerMapKey) {
+        this.inverseOwnerMapKey = inverseOwnerMapKey;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest2.java
index cb3a21c..8ef6311 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest2.java
@@ -1,165 +1,165 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.*;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name = "ANNOTEST2")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "ANNOCLS")
-@DiscriminatorValue("ANNO2")
-@IdClass(AnnoTest2.Oid.class)
-public class AnnoTest2 {
-
-    @Id
-    @Column(name = "PK1")
-    protected long pk1;
-
-    @Id
-    @Column(name = "PK2")
-    protected String pk2;
-
-    @Version
-    @Column(name = "ANNOVER")
-    protected Date version;
-
-    @Basic
-    protected String basic;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "INVERSEONEONE_PK", referencedColumnName = "PK")
-    protected AnnoTest1 inverseOneOne;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "MANYONEONE_PK", referencedColumnName = "PK")
-    protected AnnoTest1 oneManyOwner;
-
-    @ManyToMany
-    @JoinTable(name = "ANNOTEST2_MANYMANY",
-        joinColumns = {
-        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
-        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") },
-        inverseJoinColumns =
-        @JoinColumn(name = "MANYE_PK", referencedColumnName = "PK"))
-    protected Set<AnnoTest1> manyMany = new HashSet();
-
-    public AnnoTest2() {
-    }
-
-    public AnnoTest2(long pk1, String pk2) {
-        this.pk1 = pk1;
-        this.pk2 = pk2;
-    }
-
-    public void setPk1(long val) {
-        pk1 = val;
-    }
-
-    public long getPk1() {
-        return pk1;
-    }
-
-    public void setPk2(String str) {
-        pk2 = str;
-    }
-
-    public String getPk2() {
-        return pk2;
-    }
-
-    public Date getVersion() {
-        return version;
-    }
-
-    public void setBasic(String s) {
-        basic = s;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setInverseOneOne(AnnoTest1 other) {
-        inverseOneOne = other;
-    }
-
-    public AnnoTest1 getInverseOneOne() {
-        return inverseOneOne;
-    }
-
-    public void setOneManyOwner(AnnoTest1 other) {
-        oneManyOwner = other;
-    }
-
-    public AnnoTest1 getOneManyOwner() {
-        return oneManyOwner;
-    }
-
-    public Set getManyMany() {
-        return manyMany;
-    }
-
-    public static class Oid {
-
-        public long pk1;
-        public String pk2;
-
-        public Oid() {
-        }
-
-        public Oid(long pk1, String pk2) {
-            this.pk1 = pk1;
-            this.pk2 = pk2;
-        }
-
-        public Oid(String str) {
-            if (str != null) {
-                int index = str.indexOf(",");
-                pk1 = Long.parseLong(str.substring(0, index));
-                pk2 = str.substring(index + 1);
-                if ("null".equals(pk2))
-                    pk2 = null;
-            }
-        }
-
-        public boolean equals(Object o) {
-            if (o == this)
-                return true;
-            if (!(o instanceof Oid))
-                return false;
-            Oid other = (Oid) o;
-            if (pk1 != other.pk1)
-                return false;
-            if (pk2 == null)
-                return other.pk2 == null;
-            return pk2.equals(other.pk2);
-        }
-
-        public int hashCode() {
-            return ((int) pk1) + (pk2 == null ? 0 : pk2.hashCode());
-        }
-
-        public String toString() {
-            return pk1 + "," + (pk2 == null ? "null" : pk2);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.*;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "ANNOTEST2")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "ANNOCLS")
+@DiscriminatorValue("ANNO2")
+@IdClass(AnnoTest2.Oid.class)
+public class AnnoTest2 {
+
+    @Id
+    @Column(name = "PK1")
+    protected long pk1;
+
+    @Id
+    @Column(name = "PK2")
+    protected String pk2;
+
+    @Version
+    @Column(name = "ANNOVER")
+    protected Date version;
+
+    @Basic
+    protected String basic;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "INVERSEONEONE_PK", referencedColumnName = "PK")
+    protected AnnoTest1 inverseOneOne;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "MANYONEONE_PK", referencedColumnName = "PK")
+    protected AnnoTest1 oneManyOwner;
+
+    @ManyToMany
+    @JoinTable(name = "ANNOTEST2_MANYMANY",
+        joinColumns = {
+        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
+        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") },
+        inverseJoinColumns =
+        @JoinColumn(name = "MANYE_PK", referencedColumnName = "PK"))
+    protected Set<AnnoTest1> manyMany = new HashSet();
+
+    public AnnoTest2() {
+    }
+
+    public AnnoTest2(long pk1, String pk2) {
+        this.pk1 = pk1;
+        this.pk2 = pk2;
+    }
+
+    public void setPk1(long val) {
+        pk1 = val;
+    }
+
+    public long getPk1() {
+        return pk1;
+    }
+
+    public void setPk2(String str) {
+        pk2 = str;
+    }
+
+    public String getPk2() {
+        return pk2;
+    }
+
+    public Date getVersion() {
+        return version;
+    }
+
+    public void setBasic(String s) {
+        basic = s;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setInverseOneOne(AnnoTest1 other) {
+        inverseOneOne = other;
+    }
+
+    public AnnoTest1 getInverseOneOne() {
+        return inverseOneOne;
+    }
+
+    public void setOneManyOwner(AnnoTest1 other) {
+        oneManyOwner = other;
+    }
+
+    public AnnoTest1 getOneManyOwner() {
+        return oneManyOwner;
+    }
+
+    public Set getManyMany() {
+        return manyMany;
+    }
+
+    public static class Oid {
+
+        public long pk1;
+        public String pk2;
+
+        public Oid() {
+        }
+
+        public Oid(long pk1, String pk2) {
+            this.pk1 = pk1;
+            this.pk2 = pk2;
+        }
+
+        public Oid(String str) {
+            if (str != null) {
+                int index = str.indexOf(",");
+                pk1 = Long.parseLong(str.substring(0, index));
+                pk2 = str.substring(index + 1);
+                if ("null".equals(pk2))
+                    pk2 = null;
+            }
+        }
+
+        public boolean equals(Object o) {
+            if (o == this)
+                return true;
+            if (!(o instanceof Oid))
+                return false;
+            Oid other = (Oid) o;
+            if (pk1 != other.pk1)
+                return false;
+            if (pk2 == null)
+                return other.pk2 == null;
+            return pk2.equals(other.pk2);
+        }
+
+        public int hashCode() {
+            return ((int) pk1) + (pk2 == null ? 0 : pk2.hashCode());
+        }
+
+        public String toString() {
+            return pk1 + "," + (pk2 == null ? "null" : pk2);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest3.java
index e4c5ed1..8c398b4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/AnnoTest3.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@DiscriminatorValue("ANNO3")
-@Table(name = "ANNOTEST3")
-@PrimaryKeyJoinColumns(@PrimaryKeyJoinColumn(name = "SUB_PK",
-    referencedColumnName = "PK"))
-public class AnnoTest3 extends AnnoTest1 {
-
-    @Basic
-    @Column(name = "SUBBASIC")
-    protected int basic2;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    protected AnnoTest2 subOneOne;
-
-    public AnnoTest3() {
-    }
-
-    public AnnoTest3(long pk) {
-        super(pk);
-    }
-
-    public AnnoTest3(Long pk) {
-        super(pk);
-    }
-
-    public void setBasic2(int i) {
-        basic2 = i;
-    }
-
-    public int getBasic2() {
-        return basic2;
-    }
-
-    public AnnoTest2 getSubOneOne() {
-        return subOneOne;
-    }
-
-    public void setSubOneOne(AnnoTest2 anno2) {
-        subOneOne = anno2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorValue("ANNO3")
+@Table(name = "ANNOTEST3")
+@PrimaryKeyJoinColumns(@PrimaryKeyJoinColumn(name = "SUB_PK",
+    referencedColumnName = "PK"))
+public class AnnoTest3 extends AnnoTest1 {
+
+    @Basic
+    @Column(name = "SUBBASIC")
+    protected int basic2;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    protected AnnoTest2 subOneOne;
+
+    public AnnoTest3() {
+    }
+
+    public AnnoTest3(long pk) {
+        super(pk);
+    }
+
+    public AnnoTest3(Long pk) {
+        super(pk);
+    }
+
+    public void setBasic2(int i) {
+        basic2 = i;
+    }
+
+    public int getBasic2() {
+        return basic2;
+    }
+
+    public AnnoTest2 getSubOneOne() {
+        return subOneOne;
+    }
+
+    public void setSubOneOne(AnnoTest2 anno2) {
+        subOneOne = anno2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/CallbackStorage.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/CallbackStorage.java
index 42f0074..a81e004 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/CallbackStorage.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/CallbackStorage.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Singleton class to store callback invocation hits
- * @author aokeke
- *
- */
-public class CallbackStorage
-{
-	private static CallbackStorage store = new CallbackStorage();
-
-	private static List<String> clist = new ArrayList<String>();
-
-	private CallbackStorage()
-	{}
-
-	public static CallbackStorage getInstance()
-	{
-		if(store == null)
-			store = new CallbackStorage();
-		return store;
-	}
-
-	public List<String> getClist() {
-		return clist;
-	}
-
-	public void setClist(List<String> clist) {
-		CallbackStorage.clist = clist;
-	}
-
-	public static void clearStore()
-	{
-		clist = new ArrayList<String>();
-	}
-
-	public static boolean isEmpty()
-	{
-		return clist.isEmpty();
-	}
-
-	public static int size()
-	{
-		return clist.size();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Singleton class to store callback invocation hits
+ * @author aokeke
+ *
+ */
+public class CallbackStorage
+{
+	private static CallbackStorage store = new CallbackStorage();
+
+	private static List<String> clist = new ArrayList<String>();
+
+	private CallbackStorage()
+	{}
+
+	public static CallbackStorage getInstance()
+	{
+		if(store == null)
+			store = new CallbackStorage();
+		return store;
+	}
+
+	public List<String> getClist() {
+		return clist;
+	}
+
+	public void setClist(List<String> clist) {
+		CallbackStorage.clist = clist;
+	}
+
+	public static void clearStore()
+	{
+		clist = new ArrayList<String>();
+	}
+
+	public static boolean isEmpty()
+	{
+		return clist.isEmpty();
+	}
+
+	public static int size()
+	{
+		return clist.size();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/ContractEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/ContractEmployee.java
index e66dbd9..14ed950 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/ContractEmployee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/ContractEmployee.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.ArrayList;
-
-import javax.persistence.*;
-
-@Entity
-@ExcludeSuperclassListeners
-@EntityListeners(LongNameValidator.class)
-public class ContractEmployee extends Employee
-{
-	private int dailyRate;
-	private int term;
-
-	public ContractEmployee(){}
-
-	public ContractEmployee(int id, String name, int dRate, int term)
-	{
-		super(id, name);
-		this.dailyRate = dRate;
-		this.term = term;
-	}
-
-	@PrePersist
-	public void verifyTerm()
-	{
-		System.out.println("VerifyTerm of ContractEmployee running on"+this);
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("contractemployee");
-	}
-
-
-	public int getDailyRate() {
-		return dailyRate;
-	}
-	public void setDailyRate(int dailyRate) {
-		this.dailyRate = dailyRate;
-	}
-	public int getTerm() {
-		return term;
-	}
-	public void setTerm(int term) {
-		this.term = term;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.ArrayList;
+
+import javax.persistence.*;
+
+@Entity
+@ExcludeSuperclassListeners
+@EntityListeners(LongNameValidator.class)
+public class ContractEmployee extends Employee
+{
+	private int dailyRate;
+	private int term;
+
+	public ContractEmployee(){}
+
+	public ContractEmployee(int id, String name, int dRate, int term)
+	{
+		super(id, name);
+		this.dailyRate = dRate;
+		this.term = term;
+	}
+
+	@PrePersist
+	public void verifyTerm()
+	{
+		System.out.println("VerifyTerm of ContractEmployee running on"+this);
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("contractemployee");
+	}
+
+
+	public int getDailyRate() {
+		return dailyRate;
+	}
+	public void setDailyRate(int dailyRate) {
+		this.dailyRate = dailyRate;
+	}
+	public int getTerm() {
+		return term;
+	}
+	public void setTerm(int term) {
+		this.term = term;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DateValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DateValidator.java
index 3e052aa..7026713 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DateValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DateValidator.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-public class DateValidator
-{
-	@PrePersist
-	public void prePersist(Schedule sched)
-	{
-		if(sched.getStartDate() == null)
-		{
-			System.out.println("Date cannot be null");
-			throw new NullPointerException();
-		}
-	}
-
-	@PostPersist
-	public void postPersist(Schedule sched)
-	{
-		System.out.println("Schedule "+sched+" is successfully persisted: DateValidator.class");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+public class DateValidator
+{
+	@PrePersist
+	public void prePersist(Schedule sched)
+	{
+		if(sched.getStartDate() == null)
+		{
+			System.out.println("Date cannot be null");
+			throw new NullPointerException();
+		}
+	}
+
+	@PostPersist
+	public void postPersist(Schedule sched)
+	{
+		System.out.println("Schedule "+sched+" is successfully persisted: DateValidator.class");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DefaultCallbackListener.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DefaultCallbackListener.java
index 46dccef..24bc9e9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DefaultCallbackListener.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/DefaultCallbackListener.java
@@ -1,83 +1,83 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.PrePersist;
-import javax.persistence.PostPersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PostRemove;
-import javax.persistence.PostUpdate;
-import javax.persistence.PreUpdate;
-import javax.persistence.PostLoad;
-
-public class DefaultCallbackListener 
-{
-	public DefaultCallbackListener()
-	{}
-	
-	@PrePersist
-	public void prePersist(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-prepersist");
-	}
-	
-	@PostPersist
-	public void postPersist(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postpersist");
-	}
-	
-	@PostRemove
-	public void postRemove(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postremove");
-	}
-	
-	@PreRemove
-	public void preRemove(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-preremove");
-	}
-	
-	@PostUpdate	
-	public void postUpdate(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postupdate");
-	}
-	
-	@PreUpdate
-	public void preUpdate(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-preupdate");
-	}
-	
-	@PostLoad
-	public void postLoad(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postload");
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.PrePersist;
+import javax.persistence.PostPersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PreUpdate;
+import javax.persistence.PostLoad;
+
+public class DefaultCallbackListener 
+{
+	public DefaultCallbackListener()
+	{}
+	
+	@PrePersist
+	public void prePersist(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-prepersist");
+	}
+	
+	@PostPersist
+	public void postPersist(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postpersist");
+	}
+	
+	@PostRemove
+	public void postRemove(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postremove");
+	}
+	
+	@PreRemove
+	public void preRemove(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-preremove");
+	}
+	
+	@PostUpdate	
+	public void postUpdate(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postupdate");
+	}
+	
+	@PreUpdate
+	public void preUpdate(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-preupdate");
+	}
+	
+	@PostLoad
+	public void postLoad(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postload");
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedOwner.java
index 3247314..0e46ead 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedOwner.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@SqlResultSetMapping(name = "EmbedMapping", entities = {
-@EntityResult(entityClass = EmbedOwner.class, fields = {
-@FieldResult(name = "pk", column = "OWNER_PK"),
-@FieldResult(name = "basic", column = "OWNER_BASIC"),
-@FieldResult(name = "embed.basic", column = "EMBED_BASIC"),
-@FieldResult(name = "embed.clob", column = "EMBED_CLOB")
-    })
-    })
-public class EmbedOwner {
-
-    @Embedded
-    @AttributeOverride(name = "basic", column = @Column(name = "OVER_BASIC"))
-    @AssociationOverride(name = "owner",
-        joinColumns = @JoinColumn(name = "OVER_OWNER"))
-    protected EmbedValue embed;
-
-    @Basic
-    @Column(name = "OWN_BASIC")
-    protected String basic;
-
-    @Id
-    @GeneratedValue
-    protected int pk;
-
-    public int getPk() {
-        return pk;
-    }
-
-    public void setBasic(String basic) {
-        this.basic = basic;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setEmbed(EmbedValue embed) {
-        this.embed = embed;
-    }
-
-    public EmbedValue getEmbed() {
-        return embed;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@SqlResultSetMapping(name = "EmbedMapping", entities = {
+@EntityResult(entityClass = EmbedOwner.class, fields = {
+@FieldResult(name = "pk", column = "OWNER_PK"),
+@FieldResult(name = "basic", column = "OWNER_BASIC"),
+@FieldResult(name = "embed.basic", column = "EMBED_BASIC"),
+@FieldResult(name = "embed.clob", column = "EMBED_CLOB")
+    })
+    })
+public class EmbedOwner {
+
+    @Embedded
+    @AttributeOverride(name = "basic", column = @Column(name = "OVER_BASIC"))
+    @AssociationOverride(name = "owner",
+        joinColumns = @JoinColumn(name = "OVER_OWNER"))
+    protected EmbedValue embed;
+
+    @Basic
+    @Column(name = "OWN_BASIC")
+    protected String basic;
+
+    @Id
+    @GeneratedValue
+    protected int pk;
+
+    public int getPk() {
+        return pk;
+    }
+
+    public void setBasic(String basic) {
+        this.basic = basic;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setEmbed(EmbedValue embed) {
+        this.embed = embed;
+    }
+
+    public EmbedValue getEmbed() {
+        return embed;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue.java
index 79098f1..ded0639 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Embeddable
-public class EmbedValue {
-
-    @Basic
-    @Column(name = "EMB_BASIC")
-    protected String basic;
-
-    @Lob
-    @Column(name = "EMB_CLOB")
-    protected String clob;
-
-    @Lob
-    @Column(name = "EMB_BLOB")
-    protected byte[] blob;
-
-    @ManyToOne
-    @JoinColumn(name = "EMB_REL")
-    protected EmbedOwner owner;
-
-    public void setBasic(String basic) {
-        this.basic = basic;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setClob(String clob) {
-        this.clob = clob;
-    }
-
-    public String getClob() {
-        return clob;
-    }
-
-    public void setBlob(byte[] blob) {
-        this.blob = blob;
-    }
-
-    public byte[] getBlob() {
-        return blob;
-    }
-
-    public void setOwner(EmbedOwner owner) {
-        this.owner = owner;
-    }
-
-    public EmbedOwner getOwner() {
-        return owner;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Embeddable
+public class EmbedValue {
+
+    @Basic
+    @Column(name = "EMB_BASIC")
+    protected String basic;
+
+    @Lob
+    @Column(name = "EMB_CLOB")
+    protected String clob;
+
+    @Lob
+    @Column(name = "EMB_BLOB")
+    protected byte[] blob;
+
+    @ManyToOne
+    @JoinColumn(name = "EMB_REL")
+    protected EmbedOwner owner;
+
+    public void setBasic(String basic) {
+        this.basic = basic;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setClob(String clob) {
+        this.clob = clob;
+    }
+
+    public String getClob() {
+        return clob;
+    }
+
+    public void setBlob(byte[] blob) {
+        this.blob = blob;
+    }
+
+    public byte[] getBlob() {
+        return blob;
+    }
+
+    public void setOwner(EmbedOwner owner) {
+        this.owner = owner;
+    }
+
+    public EmbedOwner getOwner() {
+        return owner;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue2.java
index c5694dc..5f408b2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbedValue2.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-/**
- * Same as EmbedValue but no blobs for suitable use as key/value/element
- * in oracle.
- */
-@Embeddable
-public class EmbedValue2 {
-
-    @Basic
-    @Column(name = "EMB_BASIC")
-    protected String basic;
-
-    @Basic
-    @Column(name = "EMB_INTBASIC")
-    protected int intBasic;
-
-    public void setBasic(String basic) {
-        this.basic = basic;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setIntBasic(int intBasic) {
-        this.intBasic = intBasic;
-    }
-
-    public int getIntBasic() {
-        return intBasic;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+/**
+ * Same as EmbedValue but no blobs for suitable use as key/value/element
+ * in oracle.
+ */
+@Embeddable
+public class EmbedValue2 {
+
+    @Basic
+    @Column(name = "EMB_BASIC")
+    protected String basic;
+
+    @Basic
+    @Column(name = "EMB_INTBASIC")
+    protected int intBasic;
+
+    public void setBasic(String basic) {
+        this.basic = basic;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setIntBasic(int intBasic) {
+        this.intBasic = intBasic;
+    }
+
+    public int getIntBasic() {
+        return intBasic;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuper.java
index e3fb2d1..0093c44 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuper.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@MappedSuperclass
-public class EmbeddableSuper {
-
-    @Id
-    @GeneratedValue
-    @Column(name = "ID")
-    private long pk;
-
-    @Version
-    @Column(name = "SUPVERS")
-    private int version;
-
-    @Transient
-    private int trans;
-
-    @Lob
-    @Column(name = "CLOBVAL")
-    protected String clob;
-
-    public EmbeddableSuper() {
-    }
-
-    public long getPK() {
-        return this.pk;
-    }
-
-    public void setPK(long pk) {
-        this.pk = pk;
-    }
-
-    public int getTrans() {
-        return this.trans;
-    }
-
-    public void setTrans(int trans) {
-        this.trans = trans;
-    }
-
-    public String getClob() {
-        return this.clob;
-    }
-
-    public void setClob(String clob) {
-        this.clob = clob;
-    }
-
-    public int getVersion() {
-        return this.version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@MappedSuperclass
+public class EmbeddableSuper {
+
+    @Id
+    @GeneratedValue
+    @Column(name = "ID")
+    private long pk;
+
+    @Version
+    @Column(name = "SUPVERS")
+    private int version;
+
+    @Transient
+    private int trans;
+
+    @Lob
+    @Column(name = "CLOBVAL")
+    protected String clob;
+
+    public EmbeddableSuper() {
+    }
+
+    public long getPK() {
+        return this.pk;
+    }
+
+    public void setPK(long pk) {
+        this.pk = pk;
+    }
+
+    public int getTrans() {
+        return this.trans;
+    }
+
+    public void setTrans(int trans) {
+        this.trans = trans;
+    }
+
+    public String getClob() {
+        return this.clob;
+    }
+
+    public void setClob(String clob) {
+        this.clob = clob;
+    }
+
+    public int getVersion() {
+        return this.version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuperSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuperSub.java
index 4ec4cbe..7109223 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuperSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddableSuperSub.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@DiscriminatorColumn(name = "DISC")
-@AttributeOverrides({
-    @AttributeOverride(name = "clob", column = @Column(name = "CC")),
-    @AttributeOverride(name = "version", column = @Column(name = "VERSVAL"))
-})
-public class EmbeddableSuperSub
-    extends EmbeddableSuper {
-
-    @ManyToOne
-    private EmbeddableSuperSub sub;
-
-    @ManyToOne
-    private EmbeddableSuper sup;
-
-    public EmbeddableSuperSub() {
-    }
-
-    public EmbeddableSuperSub getSub() {
-        return this.sub;
-    }
-
-    public void setSub(EmbeddableSuperSub sub) {
-        this.sub = sub;
-    }
-
-    public EmbeddableSuper getSup() {
-        return this.sup;
-    }
-
-    public void setSup(EmbeddableSuper sup) {
-        this.sup = sup;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorColumn(name = "DISC")
+@AttributeOverrides({
+    @AttributeOverride(name = "clob", column = @Column(name = "CC")),
+    @AttributeOverride(name = "version", column = @Column(name = "VERSVAL"))
+})
+public class EmbeddableSuperSub
+    extends EmbeddableSuper {
+
+    @ManyToOne
+    private EmbeddableSuperSub sub;
+
+    @ManyToOne
+    private EmbeddableSuper sup;
+
+    public EmbeddableSuperSub() {
+    }
+
+    public EmbeddableSuperSub getSub() {
+        return this.sub;
+    }
+
+    public void setSub(EmbeddableSuperSub sub) {
+        this.sub = sub;
+    }
+
+    public EmbeddableSuper getSup() {
+        return this.sup;
+    }
+
+    public void setSup(EmbeddableSuper sup) {
+        this.sup = sup;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdClass.java
index 50218bc..7ab7564 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdClass.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Embeddable
-public class EmbeddedIdClass {
-
-    @Column(name = "EPK1")
-    private long pk1;
-
-    @Column(name = "EPK2")
-    private long pk2;
-
-    @Column(name = "EPK3")
-    @GeneratedValue
-    private long pk3;
-
-    public long getPk1() {
-        return pk1;
-    }
-
-    public void setPk1(long pk1) {
-        this.pk1 = pk1;
-    }
-
-    public long getPk2() {
-        return pk2;
-    }
-
-    public void setPk2(long pk2) {
-        this.pk2 = pk2;
-    }
-
-    public long getPk3() {
-        return pk3;
-    }
-
-    public void setPk3(long pk3) {
-        this.pk3 = pk3;
-    }
-
-    public String toString() {
-        return pk1 + ":" + pk2 + ":" + pk3;
-    }
-
-    public int hashCode() {
-        return (int) ((pk1 ^ pk2 ^ pk3) % Integer.MAX_VALUE);
-    }
-
-    public boolean equals(Object other) {
-        if (other == this)
-            return true;
-        if (!(other instanceof EmbeddedIdClass))
-            return false;
-
-        EmbeddedIdClass id = (EmbeddedIdClass) other;
-        return id.pk1 == pk1
-            && id.pk2 == pk2
-            && id.pk3 == pk3;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Embeddable
+public class EmbeddedIdClass {
+
+    @Column(name = "EPK1")
+    private long pk1;
+
+    @Column(name = "EPK2")
+    private long pk2;
+
+    @Column(name = "EPK3")
+    @GeneratedValue
+    private long pk3;
+
+    public long getPk1() {
+        return pk1;
+    }
+
+    public void setPk1(long pk1) {
+        this.pk1 = pk1;
+    }
+
+    public long getPk2() {
+        return pk2;
+    }
+
+    public void setPk2(long pk2) {
+        this.pk2 = pk2;
+    }
+
+    public long getPk3() {
+        return pk3;
+    }
+
+    public void setPk3(long pk3) {
+        this.pk3 = pk3;
+    }
+
+    public String toString() {
+        return pk1 + ":" + pk2 + ":" + pk3;
+    }
+
+    public int hashCode() {
+        return (int) ((pk1 ^ pk2 ^ pk3) % Integer.MAX_VALUE);
+    }
+
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (!(other instanceof EmbeddedIdClass))
+            return false;
+
+        EmbeddedIdClass id = (EmbeddedIdClass) other;
+        return id.pk1 == pk1
+            && id.pk2 == pk2
+            && id.pk3 == pk3;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdEntity.java
index 70f9a25..a182ea3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/EmbeddedIdEntity.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name = "EMIDENTITY")
-@SqlResultSetMapping(name = "EmbeddedIdMapping", entities = {
-@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
-@FieldResult(name = "id.pk1", column = "OWNER_PK1"),
-@FieldResult(name = "id.pk2", column = "OWNER_PK2"),
-@FieldResult(name = "id.pk3", column = "OWNER_PK3"),
-@FieldResult(name = "value", column = "OWNER_VAL"),
-@FieldResult(name = "relation.id.pk1", column = "REL_PK1"),
-@FieldResult(name = "relation.id.pk2", column = "REL_PK2"),
-@FieldResult(name = "relation.id.pk3", column = "REL_PK3")
-    }),
-@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
-@FieldResult(name = "id.pk1", column = "REL_PK1"),
-@FieldResult(name = "id.pk2", column = "REL_PK2"),
-@FieldResult(name = "id.pk3", column = "REL_PK3"),
-@FieldResult(name = "value", column = "REL_VAL")
-    })
-    })
-public class EmbeddedIdEntity {
-
-    @EmbeddedId
-    private EmbeddedIdClass id;
-
-    @Column(name = "VAL")
-    private String value;
-
-    @ManyToOne
-    private EmbeddedIdEntity relation;
-
-    @ManyToOne
-    @JoinColumns({
-    @JoinColumn(name = "MREL_PK1", referencedColumnName = "EPK1"),
-    @JoinColumn(name = "MREL_PK2", referencedColumnName = "EPK2")
-        })
-    private EmbeddedIdEntity mapOverrideRelation;
-
-    public EmbeddedIdClass getId() {
-        return id;
-    }
-
-    public void setId(EmbeddedIdClass id) {
-        this.id = id;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    public EmbeddedIdEntity getRelation() {
-        return relation;
-    }
-
-    public void setRelation(EmbeddedIdEntity relation) {
-        this.relation = relation;
-    }
-
-    public EmbeddedIdEntity getMappingOverrideRelation() {
-        return mapOverrideRelation;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "EMIDENTITY")
+@SqlResultSetMapping(name = "EmbeddedIdMapping", entities = {
+@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
+@FieldResult(name = "id.pk1", column = "OWNER_PK1"),
+@FieldResult(name = "id.pk2", column = "OWNER_PK2"),
+@FieldResult(name = "id.pk3", column = "OWNER_PK3"),
+@FieldResult(name = "value", column = "OWNER_VAL"),
+@FieldResult(name = "relation.id.pk1", column = "REL_PK1"),
+@FieldResult(name = "relation.id.pk2", column = "REL_PK2"),
+@FieldResult(name = "relation.id.pk3", column = "REL_PK3")
+    }),
+@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
+@FieldResult(name = "id.pk1", column = "REL_PK1"),
+@FieldResult(name = "id.pk2", column = "REL_PK2"),
+@FieldResult(name = "id.pk3", column = "REL_PK3"),
+@FieldResult(name = "value", column = "REL_VAL")
+    })
+    })
+public class EmbeddedIdEntity {
+
+    @EmbeddedId
+    private EmbeddedIdClass id;
+
+    @Column(name = "VAL")
+    private String value;
+
+    @ManyToOne
+    private EmbeddedIdEntity relation;
+
+    @ManyToOne
+    @JoinColumns({
+    @JoinColumn(name = "MREL_PK1", referencedColumnName = "EPK1"),
+    @JoinColumn(name = "MREL_PK2", referencedColumnName = "EPK2")
+        })
+    private EmbeddedIdEntity mapOverrideRelation;
+
+    public EmbeddedIdClass getId() {
+        return id;
+    }
+
+    public void setId(EmbeddedIdClass id) {
+        this.id = id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public EmbeddedIdEntity getRelation() {
+        return relation;
+    }
+
+    public void setRelation(EmbeddedIdEntity relation) {
+        this.relation = relation;
+    }
+
+    public EmbeddedIdEntity getMappingOverrideRelation() {
+        return mapOverrideRelation;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Employee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Employee.java
index 6750281..3d89651 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Employee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Employee.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy=InheritanceType.JOINED)
-@EntityListeners({NameValidator.class, LongNameValidator.class})
-public class Employee implements NamedEntity
-{
-	@Id
-	private int id;
-
-	@Basic
-	protected String name;
-
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	protected int lifecheck;
-
-	@Transient
-	protected long syncTime;
-
-	public Employee()
-	{}
-
-	public Employee(int id, String name)
-	{
-		this.id = id;
-		this.name = name;
-	}
-
-	public String getName()
-	{
-		return name;
-	}
-
-	public void setName(String name)
-	{
-		this.name = name;
-	}
-
-	public void setId(int id)
-	{
-		this.id = id;
-	}
-
-	public int getId()
-	{
-		return id;
-	}
-
-	@PostPersist
-	private void resetSyncTime()
-	{
-		System.out.println("resetSyncTime is running on "+this+"GEN #: "+lifecheck);
-		syncTime = System.currentTimeMillis();
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("employeepop");
-		store.getClist().add("gen#"+lifecheck);
-	}
-
-	@PostLoad
-	public void pload()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("employeepol");
-	}
-
-	@PostUpdate
-	public void pupdate()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("employeepou");
-	}
-
-	public String toString()
-	{
-		return "Name: "+name+" of "+this.getClass().getName()+" Id: "+id+" Synctime: "+syncTime;
-	}
-
-	public int getCheck() {
-		return this.lifecheck;
-	}
-
-	public void setCheck(int check) {
-		this.lifecheck = check;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy=InheritanceType.JOINED)
+@EntityListeners({NameValidator.class, LongNameValidator.class})
+public class Employee implements NamedEntity
+{
+	@Id
+	private int id;
+
+	@Basic
+	protected String name;
+
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	protected int lifecheck;
+
+	@Transient
+	protected long syncTime;
+
+	public Employee()
+	{}
+
+	public Employee(int id, String name)
+	{
+		this.id = id;
+		this.name = name;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+	public void setId(int id)
+	{
+		this.id = id;
+	}
+
+	public int getId()
+	{
+		return id;
+	}
+
+	@PostPersist
+	private void resetSyncTime()
+	{
+		System.out.println("resetSyncTime is running on "+this+"GEN #: "+lifecheck);
+		syncTime = System.currentTimeMillis();
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("employeepop");
+		store.getClist().add("gen#"+lifecheck);
+	}
+
+	@PostLoad
+	public void pload()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("employeepol");
+	}
+
+	@PostUpdate
+	public void pupdate()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("employeepou");
+	}
+
+	public String toString()
+	{
+		return "Name: "+name+" of "+this.getClass().getName()+" Id: "+id+" Synctime: "+syncTime;
+	}
+
+	public int getCheck() {
+		return this.lifecheck;
+	}
+
+	public void setCheck(int check) {
+		this.lifecheck = check;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity1.java
index 79711d5..7a6fd45 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity1.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-
-@Entity
-@Table(name="entity_1")
-@Inheritance(strategy=InheritanceType.JOINED)
-@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
-public class Entity1 implements Serializable
-{
-	private static final long serialVersionUID = 2882935803066041165L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
-	protected Entity2 entity2Field;
-
-	@Version
-	protected int versionField;
-
-	public Entity1()
-	{}
-
-	public Entity1 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-
-	public void setEntity2Field (Entity2 val)
-	{
-		entity2Field = val;
-	}
-
-
-	public Entity2 getEntity2Field ()
-	{
-		return entity2Field;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+
+@Entity
+@Table(name="entity_1")
+@Inheritance(strategy=InheritanceType.JOINED)
+@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
+public class Entity1 implements Serializable
+{
+	private static final long serialVersionUID = 2882935803066041165L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
+	protected Entity2 entity2Field;
+
+	@Version
+	protected int versionField;
+
+	public Entity1()
+	{}
+
+	public Entity1 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+
+	public void setEntity2Field (Entity2 val)
+	{
+		entity2Field = val;
+	}
+
+
+	public Entity2 getEntity2Field ()
+	{
+		return entity2Field;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity2.java
index 5c37ea0..b2a3406 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Entity2.java
@@ -1,95 +1,95 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-
-//@Entity(name="entity2ExplicitName")
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class Entity2 implements Serializable
-{
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 4723739219953167343L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	public Entity2()
-	{}
-
-
-	public Entity2 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+
+//@Entity(name="entity2ExplicitName")
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class Entity2 implements Serializable
+{
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 4723739219953167343L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	public Entity2()
+	{}
+
+
+	public Entity2 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat1.java
index b705278..b4f1373 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat1.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "EJB_CLS")
-public class Flat1 {
-
-    @Id
-    @Column(name = "PK")
-    protected int pk;
-
-    @Version
-    @Column(name = "EJB_VER")
-    protected int version;
-
-    @Basic
-    protected int basic;
-
-    public Flat1() {
-    }
-
-    public Flat1(int pk) {
-        this.pk = pk;
-    }
-
-    public void setPk(int val) {
-        pk = val;
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public int getVersion() {
-        return version;
-    }
-
-    public void setBasic(int i) {
-        basic = i;
-    }
-
-    public int getBasic() {
-        return basic;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "EJB_CLS")
+public class Flat1 {
+
+    @Id
+    @Column(name = "PK")
+    protected int pk;
+
+    @Version
+    @Column(name = "EJB_VER")
+    protected int version;
+
+    @Basic
+    protected int basic;
+
+    public Flat1() {
+    }
+
+    public Flat1(int pk) {
+        this.pk = pk;
+    }
+
+    public void setPk(int val) {
+        pk = val;
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setBasic(int i) {
+        basic = i;
+    }
+
+    public int getBasic() {
+        return basic;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat2.java
index a94862b..5370d5a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Flat2.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-public class Flat2
-    extends Flat1 {
-
-    @Basic
-    protected String basic2;
-
-    public Flat2() {
-    }
-
-    public Flat2(int pk) {
-        super(pk);
-    }
-
-    public void setBasic2(String s) {
-        basic2 = s;
-    }
-
-    public String getBasic2() {
-        return basic2;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+public class Flat2
+    extends Flat1 {
+
+    @Basic
+    protected String basic2;
+
+    public Flat2() {
+    }
+
+    public Flat2(int pk) {
+        super(pk);
+    }
+
+    public void setBasic2(String s) {
+        basic2 = s;
+    }
+
+    public String getBasic2() {
+        return basic2;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/FlightSchedule.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/FlightSchedule.java
index 4ee43d4..9fe8e3a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/FlightSchedule.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/FlightSchedule.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-import java.util.*;
-
-@Entity
-@DiscriminatorValue("fsched")
-@Table(name="Flight_Sched",
-		uniqueConstraints=@UniqueConstraint(columnNames={"planeName"}))
-public class FlightSchedule extends Schedule
-{
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int FlightNum;
-
-	@Column(nullable=false)
-	private String planeName;
-
-	public FlightSchedule(){}
-
-	public FlightSchedule(String name, Calendar cad, Date start, Date end, String pname)
-	{
-		super(name, cad, start, end);
-		this.planeName = pname;
-	}
-
-	public String getFlightName() {
-		return planeName;
-	}
-
-	public void setFlightName(String flightName) {
-		planeName = flightName;
-	}
-
-	public int getFlightNum() {
-		return FlightNum;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+import java.util.*;
+
+@Entity
+@DiscriminatorValue("fsched")
+@Table(name="Flight_Sched",
+		uniqueConstraints=@UniqueConstraint(columnNames={"planeName"}))
+public class FlightSchedule extends Schedule
+{
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int FlightNum;
+
+	@Column(nullable=false)
+	private String planeName;
+
+	public FlightSchedule(){}
+
+	public FlightSchedule(String name, Calendar cad, Date start, Date end, String pname)
+	{
+		super(name, cad, start, end);
+		this.planeName = pname;
+	}
+
+	public String getFlightName() {
+		return planeName;
+	}
+
+	public void setFlightName(String flightName) {
+		planeName = flightName;
+	}
+
+	public int getFlightNum() {
+		return FlightNum;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Generator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Generator.java
index 3476f60..74d4c7d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Generator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Generator.java
@@ -1,109 +1,109 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.*;
-
-import javax.persistence.*;
-
-@Entity
-// non-psql/ora dbs cause issues with SequenceGenerator in auto-mapping
-//@SequenceGenerator(name="seq", sequenceName="ejb_sequence")
-@TableGenerator(name = "tab")
-@IdClass(Generator.Oid.class)
-public class Generator {
-
-    @Id
-    protected int pk;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab")
-    protected Integer pk2;
-
-    @Id
-    @GeneratedValue
-    protected long pk3;
-
-    @Basic
-    protected String stringField;
-
-    // for non-seq
-    public void setPk(int pk) {
-        this.pk = pk;
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public Integer getPk2() {
-        return pk2;
-    }
-
-    public long getPk3() {
-        return pk3;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public static class Oid {
-
-        public int pk;
-        public Integer pk2;
-        public long pk3;
-
-        public Oid() {
-        }
-
-        public Oid(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ",");
-            pk = Integer.parseInt(tok.nextToken());
-            pk2 = Integer.valueOf(tok.nextToken());
-            pk3 = Long.valueOf(tok.nextToken());
-        }
-
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof Oid))
-                return false;
-            Oid other = (Oid) o;
-            if (pk != other.pk)
-                return false;
-            if (pk3 != other.pk3)
-                return false;
-            if (pk2 == null)
-                return other.pk2 == null;
-            return pk2.equals(other.pk2);
-        }
-
-        public int hashCode() {
-            return pk + (pk2 == null ? 0 : pk2.hashCode())
-                + (int) (pk3 % Integer.MAX_VALUE);
-        }
-
-        public String toString() {
-            return pk + "," + pk2 + "," + pk3;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.*;
+
+import javax.persistence.*;
+
+@Entity
+// non-psql/ora dbs cause issues with SequenceGenerator in auto-mapping
+//@SequenceGenerator(name="seq", sequenceName="ejb_sequence")
+@TableGenerator(name = "tab")
+@IdClass(Generator.Oid.class)
+public class Generator {
+
+    @Id
+    protected int pk;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab")
+    protected Integer pk2;
+
+    @Id
+    @GeneratedValue
+    protected long pk3;
+
+    @Basic
+    protected String stringField;
+
+    // for non-seq
+    public void setPk(int pk) {
+        this.pk = pk;
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public Integer getPk2() {
+        return pk2;
+    }
+
+    public long getPk3() {
+        return pk3;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public static class Oid {
+
+        public int pk;
+        public Integer pk2;
+        public long pk3;
+
+        public Oid() {
+        }
+
+        public Oid(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ",");
+            pk = Integer.parseInt(tok.nextToken());
+            pk2 = Integer.valueOf(tok.nextToken());
+            pk3 = Long.valueOf(tok.nextToken());
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof Oid))
+                return false;
+            Oid other = (Oid) o;
+            if (pk != other.pk)
+                return false;
+            if (pk3 != other.pk3)
+                return false;
+            if (pk2 == null)
+                return other.pk2 == null;
+            return pk2.equals(other.pk2);
+        }
+
+        public int hashCode() {
+            return pk + (pk2 == null ? 0 : pk2.hashCode())
+                + (int) (pk3 % Integer.MAX_VALUE);
+        }
+
+        public String toString() {
+            return pk + "," + pk2 + "," + pk3;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/LongNameValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/LongNameValidator.java
index b1dcb9f..b8e3013 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/LongNameValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/LongNameValidator.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-public class LongNameValidator
-{
-	@PrePersist
-	public void validateName(NamedEntity obj)
-	{
-		System.out.println("LongNameValidator is running on "+obj);
-		if(obj.getName().equals("") || obj.getName() == null)
-			throw new NullPointerException();
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("longnamevalidatorprr");
-	}
-
-	@PostUpdate
-	public void testpost(NamedEntity obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("longnamevalidatorpou");
-	}
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+public class LongNameValidator
+{
+	@PrePersist
+	public void validateName(NamedEntity obj)
+	{
+		System.out.println("LongNameValidator is running on "+obj);
+		if(obj.getName().equals("") || obj.getName() == null)
+			throw new NullPointerException();
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("longnamevalidatorprr");
+	}
+
+	@PostUpdate
+	public void testpost(NamedEntity obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("longnamevalidatorpou");
+	}
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NameValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NameValidator.java
index faaa110..6dcc184 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NameValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NameValidator.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-public class NameValidator
-{
-	@PrePersist
-	public void validateName(NamedEntity obj)
-	{
-		System.out.println("NameValidator is running on "+obj);
-		if(obj.getName().equals("") || obj.getName() == null)
-			throw new NullPointerException();
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidator");
-	}
-
-	@PostUpdate
-	public void testpost(NamedEntity obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidatorpou");
-	}
-
-	@PostRemove
-	public void validateNothing(NamedEntity obj)
-	{
-		System.out.println("NameValidator is running on ");
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidatorpor");
-	}
-
-	@PreRemove
-	public void validateNothing1(NamedEntity obj)
-	{
-		System.out.println("NameValidator is running on ");
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidatorprr");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+public class NameValidator
+{
+	@PrePersist
+	public void validateName(NamedEntity obj)
+	{
+		System.out.println("NameValidator is running on "+obj);
+		if(obj.getName().equals("") || obj.getName() == null)
+			throw new NullPointerException();
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidator");
+	}
+
+	@PostUpdate
+	public void testpost(NamedEntity obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidatorpou");
+	}
+
+	@PostRemove
+	public void validateNothing(NamedEntity obj)
+	{
+		System.out.println("NameValidator is running on ");
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidatorpor");
+	}
+
+	@PreRemove
+	public void validateNothing1(NamedEntity obj)
+	{
+		System.out.println("NameValidator is running on ");
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidatorprr");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NamedEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NamedEntity.java
index fb7e93c..6cc2c14 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NamedEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/NamedEntity.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-
-public interface NamedEntity
-{
-	public String getName();
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+
+public interface NamedEntity
+{
+	public String getName();
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/OrderByEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/OrderByEntity.java
index 8f89fdb..d09cb34 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/OrderByEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/OrderByEntity.java
@@ -1,84 +1,84 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.*;
-
-/**
- * <p>Entity used to test parsing of @OrderBy.</p>
- *
- * @author Abe White
- */
-@Entity
-public class OrderByEntity {
-
-    @Id
-    private long id;
-    private String string;
-
-    @PersistentCollection
-    @OrderBy
-    private List<String> strings = new ArrayList();
-
-    @ManyToMany
-    @OrderBy
-    @JoinTable(name = "ORDERBY_PKRELS",
-        inverseJoinColumns = @JoinColumn(name = "REL_ID",
-            referencedColumnName = "ID"))
-    private List<OrderByEntity> pkRels = new ArrayList();
-
-    @ManyToMany
-    @OrderBy("string desc")
-    @JoinTable(name = "ORDERBY_STRINGRELS",
-        inverseJoinColumns = @JoinColumn(name = "REL_ID",
-            referencedColumnName = "ID"))
-    private List<OrderByEntity> stringRels = new ArrayList();
-
-    public long getId() {
-        return this.id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getString() {
-        return this.string;
-    }
-
-    public void setString(String string) {
-        this.string = string;
-    }
-
-    public List<String> getStrings() {
-        return this.strings;
-    }
-
-    public List<OrderByEntity> getPKRels() {
-        return this.pkRels;
-    }
-
-    public List<OrderByEntity> getStringRels() {
-        return this.stringRels;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.*;
+
+/**
+ * <p>Entity used to test parsing of @OrderBy.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class OrderByEntity {
+
+    @Id
+    private long id;
+    private String string;
+
+    @PersistentCollection
+    @OrderBy
+    private List<String> strings = new ArrayList();
+
+    @ManyToMany
+    @OrderBy
+    @JoinTable(name = "ORDERBY_PKRELS",
+        inverseJoinColumns = @JoinColumn(name = "REL_ID",
+            referencedColumnName = "ID"))
+    private List<OrderByEntity> pkRels = new ArrayList();
+
+    @ManyToMany
+    @OrderBy("string desc")
+    @JoinTable(name = "ORDERBY_STRINGRELS",
+        inverseJoinColumns = @JoinColumn(name = "REL_ID",
+            referencedColumnName = "ID"))
+    private List<OrderByEntity> stringRels = new ArrayList();
+
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getString() {
+        return this.string;
+    }
+
+    public void setString(String string) {
+        this.string = string;
+    }
+
+    public List<String> getStrings() {
+        return this.strings;
+    }
+
+    public List<OrderByEntity> getPKRels() {
+        return this.pkRels;
+    }
+
+    public List<OrderByEntity> getStringRels() {
+        return this.stringRels;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/PropertyAccess1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/PropertyAccess1.java
index 595d5af..dcd4e03 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/PropertyAccess1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/PropertyAccess1.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-/**
- * Entity test object that uses property access mode.
- */
-@Entity
-public class PropertyAccess1 {
-
-    private int id;
-    private String name;
-    private int intVal; // this intentionally does not match the getter name
-
-    protected PropertyAccess1() {
-    }
-
-    public PropertyAccess1(int id) {
-        this.id = id;
-    }
-
-    @Id
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String n) {
-        this.name = n;
-    }
-
-    public int getIntValue() {
-        return intVal;
-    }
-
-    public void setIntValue(int intVal) {
-        this.intVal = intVal;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+/**
+ * Entity test object that uses property access mode.
+ */
+@Entity
+public class PropertyAccess1 {
+
+    private int id;
+    private String name;
+    private int intVal; // this intentionally does not match the getter name
+
+    protected PropertyAccess1() {
+    }
+
+    public PropertyAccess1(int id) {
+        this.id = id;
+    }
+
+    @Id
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String n) {
+        this.name = n;
+    }
+
+    public int getIntValue() {
+        return intVal;
+    }
+
+    public void setIntValue(int intVal) {
+        this.intVal = intVal;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Schedule.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Schedule.java
index f48483b..e8c9768 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Schedule.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/Schedule.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.Date;
-import java.util.Calendar;
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
-@EntityListeners({DateValidator.class, StringValidator.class})
-public class Schedule
-{
-	@Id
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int id;
-
-	@Temporal(TemporalType.DATE)
-	@Basic(fetch=FetchType.EAGER)
-	private Calendar dob;
-
-	@Temporal(TemporalType.TIME)
-	@Basic
-	private Date startDate;
-
-	@Temporal(TemporalType.TIMESTAMP)
-	@Basic
-	private Date endDate;
-
-	@Basic
-	private String name;
-
-	public Schedule(){}
-
-	public Schedule(String name, Calendar cad, Date sdate, Date endDate)
-	{
-		this.name = name;
-		this.dob = cad;
-		this.startDate = sdate;
-		this.endDate = endDate;
-	}
-
-	public Calendar getDob() {
-		return dob;
-	}
-
-	public void setDob(Calendar dob) {
-		this.dob = dob;
-	}
-
-	public Date getStartDate() {
-		return startDate;
-	}
-
-	public void setStartDate(Date startDate) {
-		this.startDate = startDate;
-	}
-
-	public Date getEndDate() {
-		return endDate;
-	}
-
-	public void setEndDate(Date endDate) {
-		this.endDate = endDate;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String toString()
-	{
-		return "Schedule "+name+" Date "+startDate;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.Date;
+import java.util.Calendar;
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
+@EntityListeners({DateValidator.class, StringValidator.class})
+public class Schedule
+{
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int id;
+
+	@Temporal(TemporalType.DATE)
+	@Basic(fetch=FetchType.EAGER)
+	private Calendar dob;
+
+	@Temporal(TemporalType.TIME)
+	@Basic
+	private Date startDate;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Basic
+	private Date endDate;
+
+	@Basic
+	private String name;
+
+	public Schedule(){}
+
+	public Schedule(String name, Calendar cad, Date sdate, Date endDate)
+	{
+		this.name = name;
+		this.dob = cad;
+		this.startDate = sdate;
+		this.endDate = endDate;
+	}
+
+	public Calendar getDob() {
+		return dob;
+	}
+
+	public void setDob(Calendar dob) {
+		this.dob = dob;
+	}
+
+	public Date getStartDate() {
+		return startDate;
+	}
+
+	public void setStartDate(Date startDate) {
+		this.startDate = startDate;
+	}
+
+	public Date getEndDate() {
+		return endDate;
+	}
+
+	public void setEndDate(Date endDate) {
+		this.endDate = endDate;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String toString()
+	{
+		return "Schedule "+name+" Date "+startDate;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/StringValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/StringValidator.java
index 4c3c773..390ea71 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/StringValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/StringValidator.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-public class StringValidator
-{
-	@PrePersist
-	public void prePersist(FlightSchedule sched)
-	{
-		if(sched.getName().length() == 0 || sched.getName().equals(""))
-			throw new IllegalArgumentException("Needs a valid name");
-	}
-
-	@PostPersist
-	public void postPersist(FlightSchedule sched)
-	{
-		System.out.println("Schedule "+sched+" is successfully persisted: StringValidator.class");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+public class StringValidator
+{
+	@PrePersist
+	public void prePersist(FlightSchedule sched)
+	{
+		if(sched.getName().length() == 0 || sched.getName().equals(""))
+			throw new IllegalArgumentException("Needs a valid name");
+	}
+
+	@PostPersist
+	public void postPersist(FlightSchedule sched)
+	{
+		System.out.println("Schedule "+sched+" is successfully persisted: StringValidator.class");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass1.java
index 4f4aeb2..c2d468f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass1.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
-public class TablePerClass1 {
-
-    @Id
-    @GeneratedValue
-    protected int pk;
-
-    @Column(name = "TPC_BASIC")
-    protected int basic;
-
-    @Embedded
-    @AttributeOverrides({
-    @AttributeOverride(name = "basic",
-        column = @Column(name = "TPC_EMB_BASIC")),
-    @AttributeOverride(name = "clob", column = @Column(name = "TPC_EMB_CLOB")),
-    @AttributeOverride(name = "blob", column = @Column(name = "TPC_EMB_BLOB"))
-        })
-    protected EmbedValue embed;
-
-    public int getPk() {
-        return pk;
-    }
-
-    public void setBasic(int i) {
-        basic = i;
-    }
-
-    public int getBasic() {
-        return basic;
-    }
-
-    public EmbedValue getEmbed() {
-        return embed;
-    }
-
-    public void setEmbed(EmbedValue ev) {
-        embed = ev;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class TablePerClass1 {
+
+    @Id
+    @GeneratedValue
+    protected int pk;
+
+    @Column(name = "TPC_BASIC")
+    protected int basic;
+
+    @Embedded
+    @AttributeOverrides({
+    @AttributeOverride(name = "basic",
+        column = @Column(name = "TPC_EMB_BASIC")),
+    @AttributeOverride(name = "clob", column = @Column(name = "TPC_EMB_CLOB")),
+    @AttributeOverride(name = "blob", column = @Column(name = "TPC_EMB_BLOB"))
+        })
+    protected EmbedValue embed;
+
+    public int getPk() {
+        return pk;
+    }
+
+    public void setBasic(int i) {
+        basic = i;
+    }
+
+    public int getBasic() {
+        return basic;
+    }
+
+    public EmbedValue getEmbed() {
+        return embed;
+    }
+
+    public void setEmbed(EmbedValue ev) {
+        embed = ev;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass2.java
index 0ecb463..e9ff8e0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TablePerClass2.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import javax.persistence.*;
-
-@Entity
-public class TablePerClass2
-    extends TablePerClass1 {
-
-    @Basic
-    protected String basic2;
-
-    public void setBasic2(String s) {
-        basic2 = s;
-    }
-
-    public String getBasic2() {
-        return basic2;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import javax.persistence.*;
+
+@Entity
+public class TablePerClass2
+    extends TablePerClass1 {
+
+    @Basic
+    protected String basic2;
+
+    public void setBasic2(String s) {
+        basic2 = s;
+    }
+
+    public String getBasic2() {
+        return basic2;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TxRollbackEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TxRollbackEntity.java
index b88a9fe..0f0c554 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TxRollbackEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/TxRollbackEntity.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
-
-import java.util.ArrayList;
-
-import javax.persistence.Basic;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.PostLoad;
-import javax.persistence.PostPersist;
-import javax.persistence.Entity;
-import javax.persistence.PostRemove;
-import javax.persistence.Table;
-
-@Entity
-@Table(name="TX_ROLLBACK_ENT")
-public class TxRollbackEntity
-{
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	@Id
-	private int id;
-
-	@Basic
-	private String name;
-
-	public TxRollbackEntity(String name)
-	{
-		this.name = name;
-	}
-
-	@PostLoad
-	public void rollBackException()
-	{
-		//should throw a null pointer exception causing the tx to be rolled back
-		ArrayList<Integer> list = null;
-		list.add(1);
-	}
-
-	@PostRemove
-	public void bomb()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("rollbackpor1");
-	}
-
-	public void bomb2()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("rollbackpor");
-	}
-
-	public int getId() {
-		return id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype;
+
+import java.util.ArrayList;
+
+import javax.persistence.Basic;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.Entity;
+import javax.persistence.PostRemove;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="TX_ROLLBACK_ENT")
+public class TxRollbackEntity
+{
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Id
+	private int id;
+
+	@Basic
+	private String name;
+
+	public TxRollbackEntity(String name)
+	{
+		this.name = name;
+	}
+
+	@PostLoad
+	public void rollBackException()
+	{
+		//should throw a null pointer exception causing the tx to be rolled back
+		ArrayList<Integer> list = null;
+		list.add(1);
+	}
+
+	@PostRemove
+	public void bomb()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("rollbackpor1");
+	}
+
+	public void bomb2()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("rollbackpor");
+	}
+
+	public int getId() {
+		return id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/CallbackStorage.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/CallbackStorage.java
index 0068148..c2b3ea5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/CallbackStorage.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/CallbackStorage.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Singleton class to store callback invocation hits
- * @author aokeke
- *
- */
-public class CallbackStorage
-{
-	private static CallbackStorage store = new CallbackStorage();
-
-	private static List<String> clist = new ArrayList<String>();
-
-	private CallbackStorage()
-	{}
-
-	public static CallbackStorage getInstance()
-	{
-		if(store == null)
-			store = new CallbackStorage();
-		return store;
-	}
-
-	public List<String> getClist() {
-		return clist;
-	}
-
-	public void setClist(List<String> clist) {
-		CallbackStorage.clist = clist;
-	}
-
-	public static void clearStore()
-	{
-		clist = new ArrayList<String>();
-	}
-
-	public static boolean isEmpty()
-	{
-		return clist.isEmpty();
-	}
-
-	public static int size()
-	{
-		return clist.size();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Singleton class to store callback invocation hits
+ * @author aokeke
+ *
+ */
+public class CallbackStorage
+{
+	private static CallbackStorage store = new CallbackStorage();
+
+	private static List<String> clist = new ArrayList<String>();
+
+	private CallbackStorage()
+	{}
+
+	public static CallbackStorage getInstance()
+	{
+		if(store == null)
+			store = new CallbackStorage();
+		return store;
+	}
+
+	public List<String> getClist() {
+		return clist;
+	}
+
+	public void setClist(List<String> clist) {
+		CallbackStorage.clist = clist;
+	}
+
+	public static void clearStore()
+	{
+		clist = new ArrayList<String>();
+	}
+
+	public static boolean isEmpty()
+	{
+		return clist.isEmpty();
+	}
+
+	public static int size()
+	{
+		return clist.size();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/ContractEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/ContractEmployee.java
index d50fd9c..91f8403 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/ContractEmployee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/ContractEmployee.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import java.util.ArrayList;
-
-import javax.persistence.*;
-
-@Entity
-@ExcludeSuperclassListeners
-@EntityListeners(LongNameValidator.class)
-public class ContractEmployee extends Employee
-{
-	private int dailyRate;
-	private int term;
-
-	public ContractEmployee(){}
-
-	public ContractEmployee(int id, String name, int dRate, int term)
-	{
-		super(id, name);
-		this.dailyRate = dRate;
-		this.term = term;
-	}
-
-	@PrePersist
-	public void verifyTerm()
-	{
-		System.out.println("VerifyTerm of ContractEmployee running on"+this);
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("contractemployee");
-	}
-
-
-	public int getDailyRate() {
-		return dailyRate;
-	}
-	public void setDailyRate(int dailyRate) {
-		this.dailyRate = dailyRate;
-	}
-	public int getTerm() {
-		return term;
-	}
-	public void setTerm(int term) {
-		this.term = term;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import java.util.ArrayList;
+
+import javax.persistence.*;
+
+@Entity
+@ExcludeSuperclassListeners
+@EntityListeners(LongNameValidator.class)
+public class ContractEmployee extends Employee
+{
+	private int dailyRate;
+	private int term;
+
+	public ContractEmployee(){}
+
+	public ContractEmployee(int id, String name, int dRate, int term)
+	{
+		super(id, name);
+		this.dailyRate = dRate;
+		this.term = term;
+	}
+
+	@PrePersist
+	public void verifyTerm()
+	{
+		System.out.println("VerifyTerm of ContractEmployee running on"+this);
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("contractemployee");
+	}
+
+
+	public int getDailyRate() {
+		return dailyRate;
+	}
+	public void setDailyRate(int dailyRate) {
+		this.dailyRate = dailyRate;
+	}
+	public int getTerm() {
+		return term;
+	}
+	public void setTerm(int term) {
+		this.term = term;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DateValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DateValidator.java
index 5a9e5b3..7e91140 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DateValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DateValidator.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-public class DateValidator
-{
-	@PrePersist
-	public void prePersist(Schedule sched)
-	{
-		if(sched.getStartDate() == null)
-		{
-			System.out.println("Date cannot be null");
-			throw new NullPointerException();
-		}
-	}
-
-	@PostPersist
-	public void postPersist(Schedule sched)
-	{
-		System.out.println("Schedule "+sched+" is successfully persisted: DateValidator.class");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+public class DateValidator
+{
+	@PrePersist
+	public void prePersist(Schedule sched)
+	{
+		if(sched.getStartDate() == null)
+		{
+			System.out.println("Date cannot be null");
+			throw new NullPointerException();
+		}
+	}
+
+	@PostPersist
+	public void postPersist(Schedule sched)
+	{
+		System.out.println("Schedule "+sched+" is successfully persisted: DateValidator.class");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DefaultCallbackListener.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DefaultCallbackListener.java
index 08ce085..abacdb1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DefaultCallbackListener.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/DefaultCallbackListener.java
@@ -1,85 +1,85 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.PrePersist;
-import javax.persistence.PostPersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PostRemove;
-import javax.persistence.PostUpdate;
-import javax.persistence.PreUpdate;
-import javax.persistence.PostLoad;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
-
-public class DefaultCallbackListener 
-{
-	public DefaultCallbackListener()
-	{}
-	
-//	@PrePersist
-	public void prePersist(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-prepersist");
-	}
-	
-//	@PostPersist
-	public void postPersist(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postpersist");
-	}
-	
-//	@PostRemove
-	public void postRemove(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postremove");
-	}
-	
-//	@PreRemove
-	public void preRemove(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-preremove");
-	}
-	
-//	@PostUpdate	
-	public void postUpdate(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postupdate");
-	}
-	
-//	@PreUpdate
-	public void preUpdate(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-preupdate");
-	}
-	
-//	@PostLoad
-	public void postLoad(Object obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def-postload");
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.PrePersist;
+import javax.persistence.PostPersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PreUpdate;
+import javax.persistence.PostLoad;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
+
+public class DefaultCallbackListener 
+{
+	public DefaultCallbackListener()
+	{}
+	
+//	@PrePersist
+	public void prePersist(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-prepersist");
+	}
+	
+//	@PostPersist
+	public void postPersist(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postpersist");
+	}
+	
+//	@PostRemove
+	public void postRemove(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postremove");
+	}
+	
+//	@PreRemove
+	public void preRemove(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-preremove");
+	}
+	
+//	@PostUpdate	
+	public void postUpdate(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postupdate");
+	}
+	
+//	@PreUpdate
+	public void preUpdate(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-preupdate");
+	}
+	
+//	@PostLoad
+	public void postLoad(Object obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def-postload");
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Employee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Employee.java
index 58b8b60..c28a2ed 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Employee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Employee.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy=InheritanceType.JOINED)
-@EntityListeners({NameValidator.class, LongNameValidator.class})
-public class Employee implements NamedEntity
-{
-	@Id
-	private int id;
-
-	@Basic
-	protected String name;
-
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	protected int lifecheck;
-
-	@Transient
-	protected long syncTime;
-
-	public Employee()
-	{}
-
-	public Employee(int id, String name)
-	{
-		this.id = id;
-		this.name = name;
-	}
-
-	public String getName()
-	{
-		return name;
-	}
-
-	public void setName(String name)
-	{
-		this.name = name;
-	}
-
-	public void setId(int id)
-	{
-		this.id = id;
-	}
-
-	public int getId()
-	{
-		return id;
-	}
-
-	@PostPersist
-	private void resetSyncTime()
-	{
-		System.out.println("resetSyncTime is running on "+this+"GEN #: "+lifecheck);
-		syncTime = System.currentTimeMillis();
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("employeepop");
-		store.getClist().add("gen#"+lifecheck);
-	}
-
-	@PostLoad
-	public void pload()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("employeepol");
-	}
-
-	@PostUpdate
-	public void pupdate()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("employeepou");
-	}
-
-	public String toString()
-	{
-		return "Name: "+name+" of "+this.getClass().getName()+" Id: "+id+" Synctime: "+syncTime;
-	}
-
-	public int getCheck() {
-		return this.lifecheck;
-	}
-
-	public void setCheck(int check) {
-		this.lifecheck = check;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy=InheritanceType.JOINED)
+@EntityListeners({NameValidator.class, LongNameValidator.class})
+public class Employee implements NamedEntity
+{
+	@Id
+	private int id;
+
+	@Basic
+	protected String name;
+
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	protected int lifecheck;
+
+	@Transient
+	protected long syncTime;
+
+	public Employee()
+	{}
+
+	public Employee(int id, String name)
+	{
+		this.id = id;
+		this.name = name;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+	public void setId(int id)
+	{
+		this.id = id;
+	}
+
+	public int getId()
+	{
+		return id;
+	}
+
+	@PostPersist
+	private void resetSyncTime()
+	{
+		System.out.println("resetSyncTime is running on "+this+"GEN #: "+lifecheck);
+		syncTime = System.currentTimeMillis();
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("employeepop");
+		store.getClist().add("gen#"+lifecheck);
+	}
+
+	@PostLoad
+	public void pload()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("employeepol");
+	}
+
+	@PostUpdate
+	public void pupdate()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("employeepou");
+	}
+
+	public String toString()
+	{
+		return "Name: "+name+" of "+this.getClass().getName()+" Id: "+id+" Synctime: "+syncTime;
+	}
+
+	public int getCheck() {
+		return this.lifecheck;
+	}
+
+	public void setCheck(int check) {
+		this.lifecheck = check;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity1.java
index e1ce408..c59ca36 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity1.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-
-@Entity
-@Table(name="entity_1")
-@Inheritance(strategy=InheritanceType.JOINED)
-@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
-public class Entity1 implements Serializable
-{
-	private static final long serialVersionUID = 2882935803066041165L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
-	protected Entity2 entity2Field;
-
-	@Version
-	protected int versionField;
-
-	public Entity1()
-	{}
-
-	public Entity1 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-
-	public void setEntity2Field (Entity2 val)
-	{
-		entity2Field = val;
-	}
-
-
-	public Entity2 getEntity2Field ()
-	{
-		return entity2Field;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+
+@Entity
+@Table(name="entity_1")
+@Inheritance(strategy=InheritanceType.JOINED)
+@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
+public class Entity1 implements Serializable
+{
+	private static final long serialVersionUID = 2882935803066041165L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
+	protected Entity2 entity2Field;
+
+	@Version
+	protected int versionField;
+
+	public Entity1()
+	{}
+
+	public Entity1 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+
+	public void setEntity2Field (Entity2 val)
+	{
+		entity2Field = val;
+	}
+
+
+	public Entity2 getEntity2Field ()
+	{
+		return entity2Field;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity2.java
index cca1870..f9f8e15 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Entity2.java
@@ -1,95 +1,95 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-
-//@Entity(name="entity2ExplicitName")
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class Entity2 implements Serializable
-{
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 4723739219953167343L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	public Entity2()
-	{}
-
-
-	public Entity2 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+
+//@Entity(name="entity2ExplicitName")
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class Entity2 implements Serializable
+{
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 4723739219953167343L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	public Entity2()
+	{}
+
+
+	public Entity2 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener.java
index 800b7c4..b165dbb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
-
-public class EntityDDListener 
-{
-	public EntityDDListener()
-	{}
-	
-	public void verifyPostRemove(Object lcd)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifypor");
-	}
-	
-	public void verifyPostUpdate(Object lcd)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifypou");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
+
+public class EntityDDListener 
+{
+	public EntityDDListener()
+	{}
+	
+	public void verifyPostRemove(Object lcd)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifypor");
+	}
+	
+	public void verifyPostUpdate(Object lcd)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifypou");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener2.java
index 9fef57d..55e81e5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/EntityDDListener2.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
-
-public class EntityDDListener2 
-{
-	public void verifyPreUpdate(Object lcd)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def2-verifypru");
-	}
-	
-	public void verifyPostLoad(Object lcd)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("def2-verifypol");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
+
+public class EntityDDListener2 
+{
+	public void verifyPreUpdate(Object lcd)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def2-verifypru");
+	}
+	
+	public void verifyPostLoad(Object lcd)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("def2-verifypol");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/FlightSchedule.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/FlightSchedule.java
index 6bf8a02..8d1a74a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/FlightSchedule.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/FlightSchedule.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-import java.util.*;
-
-@Entity
-@DiscriminatorValue("fsched")
-//@Table(name="Flight_Sched",
-//		uniqueConstraints=@UniqueConstraint(columnNames={"planeName"}))
-public class FlightSchedule extends Schedule
-{
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int FlightNum;
-
-	@Column(name="flight_name")
-	private String planeName;
-
-	public FlightSchedule(){}
-
-	public FlightSchedule(String name, Calendar cad, Date start, Date end, String pname)
-	{
-		super(name, cad, start, end);
-		this.planeName = pname;
-	}
-
-	public String getFlightName() {
-		return planeName;
-	}
-
-	public void setFlightName(String flightName) {
-		planeName = flightName;
-	}
-
-	public int getFlightNum() {
-		return FlightNum;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+import java.util.*;
+
+@Entity
+@DiscriminatorValue("fsched")
+//@Table(name="Flight_Sched",
+//		uniqueConstraints=@UniqueConstraint(columnNames={"planeName"}))
+public class FlightSchedule extends Schedule
+{
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int FlightNum;
+
+	@Column(name="flight_name")
+	private String planeName;
+
+	public FlightSchedule(){}
+
+	public FlightSchedule(String name, Calendar cad, Date start, Date end, String pname)
+	{
+		super(name, cad, start, end);
+		this.planeName = pname;
+	}
+
+	public String getFlightName() {
+		return planeName;
+	}
+
+	public void setFlightName(String flightName) {
+		planeName = flightName;
+	}
+
+	public int getFlightNum() {
+		return FlightNum;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDD.java
index 3c38950..7127e1e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDD.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-public interface LifeCycleDD 
-{
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+public interface LifeCycleDD 
+{
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity.java
index 101f406..5263cce 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity.java
@@ -1,89 +1,89 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
-
-@Entity
-public class LifeCycleDDEntity
-{
-	@Id
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int id;
-	
-	@Basic
-	private String name;
-	
-	@Basic
-	private String surname;
-	
-	public LifeCycleDDEntity()
-	{}
-	
-	public LifeCycleDDEntity(String name, String surname)
-	{
-		this.name = name;
-		this.surname = surname;
-	}
-	
-	public void verifyPrePersist()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifyprp");
-	}
-	
-	public void verifyPostPersist()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifypop");
-	}
-	
-    public void verifyPreRemove()
-    {
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifyprr");
-    }
-    
-    public int getId()
-    {
-    	return id;
-    }
-    
-    public void setName(String name)
-    {
-    	this.name = name;
-    }
-    
-    public String getName()
-    {
-    	return name;
-    }
-    
-    public void setSurName(String name)
-    {
-    	this.surname = name;
-    }
-    
-    public String getSurName()
-    {
-    	return surname;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
+
+@Entity
+public class LifeCycleDDEntity
+{
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int id;
+	
+	@Basic
+	private String name;
+	
+	@Basic
+	private String surname;
+	
+	public LifeCycleDDEntity()
+	{}
+	
+	public LifeCycleDDEntity(String name, String surname)
+	{
+		this.name = name;
+		this.surname = surname;
+	}
+	
+	public void verifyPrePersist()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifyprp");
+	}
+	
+	public void verifyPostPersist()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifypop");
+	}
+	
+    public void verifyPreRemove()
+    {
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifyprr");
+    }
+    
+    public int getId()
+    {
+    	return id;
+    }
+    
+    public void setName(String name)
+    {
+    	this.name = name;
+    }
+    
+    public String getName()
+    {
+    	return name;
+    }
+    
+    public void setSurName(String name)
+    {
+    	this.surname = name;
+    }
+    
+    public String getSurName()
+    {
+    	return surname;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity2.java
index 3d7fa92..d3f9c84 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntity2.java
@@ -1,105 +1,105 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.Basic;
-import javax.persistence.Entity;
-import javax.persistence.EntityListeners;
-import javax.persistence.ExcludeDefaultListeners;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.PostPersist;
-import javax.persistence.PrePersist;
-import javax.persistence.PreRemove;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LongNameValidator;
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.NameValidator;
-
-@Entity
-public class LifeCycleDDEntity2
-{
-	@Id
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int id;
-	
-	@Basic
-	private String name;
-	
-	@Basic
-	private String surname;
-	
-	public LifeCycleDDEntity2()
-	{		
-	}
-	
-	public LifeCycleDDEntity2(String name, String surname)
-	{
-		this.name = name;
-		this.surname = surname;
-	}
-	
-	@PrePersist
-	public void verifyPrePersist()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifyprp");
-	}
-	
-	@PostPersist
-	public void verifyPostPersist()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifypop");
-	}
-	
-	@PreRemove
-    public void verifyPreRemove()
-    {
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("verifyprr");
-    }
-    
-    public int getId()
-    {
-    	return id;
-    }
-    
-    public void setName(String name)
-    {
-    	this.name = name;
-    }
-    
-    public String getName()
-    {
-    	return name;
-    }
-    
-    public void setSurName(String name)
-    {
-    	this.surname = name;
-    }
-    
-    public String getSurName()
-    {
-    	return surname;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.ExcludeDefaultListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PostPersist;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LongNameValidator;
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.NameValidator;
+
+@Entity
+public class LifeCycleDDEntity2
+{
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int id;
+	
+	@Basic
+	private String name;
+	
+	@Basic
+	private String surname;
+	
+	public LifeCycleDDEntity2()
+	{		
+	}
+	
+	public LifeCycleDDEntity2(String name, String surname)
+	{
+		this.name = name;
+		this.surname = surname;
+	}
+	
+	@PrePersist
+	public void verifyPrePersist()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifyprp");
+	}
+	
+	@PostPersist
+	public void verifyPostPersist()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifypop");
+	}
+	
+	@PreRemove
+    public void verifyPreRemove()
+    {
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("verifyprr");
+    }
+    
+    public int getId()
+    {
+    	return id;
+    }
+    
+    public void setName(String name)
+    {
+    	this.name = name;
+    }
+    
+    public String getName()
+    {
+    	return name;
+    }
+    
+    public void setSurName(String name)
+    {
+    	this.surname = name;
+    }
+    
+    public String getSurName()
+    {
+    	return surname;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntitySub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntitySub.java
index a571626..5738e3e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntitySub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LifeCycleDDEntitySub.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
-
-@Entity
-@DiscriminatorValue("SUB")
-public class LifeCycleDDEntitySub extends LifeCycleDDEntity
-{
-	public LifeCycleDDEntitySub()
-	{}
-	
-	public LifeCycleDDEntitySub(String n, String sn)
-	{
-		super(n, sn);
-	}
-	
-	public void verifyPrePersist()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("over-verifyprp");
-	}
-	
-	public void verifyPostPersist()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("over-verifypop");
-	}
-	
-    public void verifyPreRemove()
-    {
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("over-verifyprr");
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.CallbackStorage;
+
+@Entity
+@DiscriminatorValue("SUB")
+public class LifeCycleDDEntitySub extends LifeCycleDDEntity
+{
+	public LifeCycleDDEntitySub()
+	{}
+	
+	public LifeCycleDDEntitySub(String n, String sn)
+	{
+		super(n, sn);
+	}
+	
+	public void verifyPrePersist()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("over-verifyprp");
+	}
+	
+	public void verifyPostPersist()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("over-verifypop");
+	}
+	
+    public void verifyPreRemove()
+    {
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("over-verifyprr");
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LongNameValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LongNameValidator.java
index a5c2841..c3fcefc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LongNameValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/LongNameValidator.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-public class LongNameValidator
-{
-	@PrePersist
-	public void validateName(NamedEntity obj)
-	{
-		System.out.println("LongNameValidator is running on "+obj);
-		if(obj.getName().equals("") || obj.getName() == null)
-			throw new NullPointerException();
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("longnamevalidatorprr");
-	}
-
-	@PostUpdate
-	public void testpost(NamedEntity obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("longnamevalidatorpou");
-	}
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+public class LongNameValidator
+{
+	@PrePersist
+	public void validateName(NamedEntity obj)
+	{
+		System.out.println("LongNameValidator is running on "+obj);
+		if(obj.getName().equals("") || obj.getName() == null)
+			throw new NullPointerException();
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("longnamevalidatorprr");
+	}
+
+	@PostUpdate
+	public void testpost(NamedEntity obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("longnamevalidatorpou");
+	}
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NameValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NameValidator.java
index 9076686..5d81852 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NameValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NameValidator.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-public class NameValidator
-{
-	@PrePersist
-	public void validateName(NamedEntity obj)
-	{
-		System.out.println("NameValidator is running on "+obj);
-		if(obj.getName().equals("") || obj.getName() == null)
-			throw new NullPointerException();
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidator");
-	}
-
-	@PostUpdate
-	public void testpost(NamedEntity obj)
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidatorpou");
-	}
-
-	@PostRemove
-	public void validateNothing(NamedEntity obj)
-	{
-		System.out.println("NameValidator is running on ");
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidatorpor");
-	}
-
-	@PreRemove
-	public void validateNothing1(NamedEntity obj)
-	{
-		System.out.println("NameValidator is running on ");
-
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("namevalidatorprr");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+public class NameValidator
+{
+	@PrePersist
+	public void validateName(NamedEntity obj)
+	{
+		System.out.println("NameValidator is running on "+obj);
+		if(obj.getName().equals("") || obj.getName() == null)
+			throw new NullPointerException();
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidator");
+	}
+
+	@PostUpdate
+	public void testpost(NamedEntity obj)
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidatorpou");
+	}
+
+	@PostRemove
+	public void validateNothing(NamedEntity obj)
+	{
+		System.out.println("NameValidator is running on ");
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidatorpor");
+	}
+
+	@PreRemove
+	public void validateNothing1(NamedEntity obj)
+	{
+		System.out.println("NameValidator is running on ");
+
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("namevalidatorprr");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NamedEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NamedEntity.java
index 61f63da..2cc2b47 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NamedEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/NamedEntity.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-
-public interface NamedEntity
-{
-	public String getName();
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+
+public interface NamedEntity
+{
+	public String getName();
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Schedule.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Schedule.java
index 23de65e..f5ffbce 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Schedule.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/Schedule.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import java.util.Date;
-import java.util.Calendar;
-
-import javax.persistence.*;
-
-@Entity
-//@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-@EntityListeners({DateValidator.class, StringValidator.class})
-public class Schedule
-{
-	@Id
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int id;
-
-	@Temporal(TemporalType.DATE)
-	@Basic
-	private Calendar dob;
-
-	@Temporal(TemporalType.TIME)
-	@Basic
-	private Date startDate;
-
-	@Temporal(TemporalType.TIMESTAMP)
-	@Basic
-	private Date endDate;
-
-	@Basic
-	private String name;
-
-	public Schedule(){}
-
-	public Schedule(String name, Calendar cad, Date sdate, Date endDate)
-	{
-		this.name = name;
-		this.dob = cad;
-		this.startDate = sdate;
-		this.endDate = endDate;
-	}
-
-	public Calendar getDob() {
-		return dob;
-	}
-
-	public void setDob(Calendar dob) {
-		this.dob = dob;
-	}
-
-	public Date getStartDate() {
-		return startDate;
-	}
-
-	public void setStartDate(Date startDate) {
-		this.startDate = startDate;
-	}
-
-	public Date getEndDate() {
-		return endDate;
-	}
-
-	public void setEndDate(Date endDate) {
-		this.endDate = endDate;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String toString()
-	{
-		return "Schedule "+name+" Date "+startDate;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import java.util.Date;
+import java.util.Calendar;
+
+import javax.persistence.*;
+
+@Entity
+//@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@EntityListeners({DateValidator.class, StringValidator.class})
+public class Schedule
+{
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int id;
+
+	@Temporal(TemporalType.DATE)
+	@Basic
+	private Calendar dob;
+
+	@Temporal(TemporalType.TIME)
+	@Basic
+	private Date startDate;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Basic
+	private Date endDate;
+
+	@Basic
+	private String name;
+
+	public Schedule(){}
+
+	public Schedule(String name, Calendar cad, Date sdate, Date endDate)
+	{
+		this.name = name;
+		this.dob = cad;
+		this.startDate = sdate;
+		this.endDate = endDate;
+	}
+
+	public Calendar getDob() {
+		return dob;
+	}
+
+	public void setDob(Calendar dob) {
+		this.dob = dob;
+	}
+
+	public Date getStartDate() {
+		return startDate;
+	}
+
+	public void setStartDate(Date startDate) {
+		this.startDate = startDate;
+	}
+
+	public Date getEndDate() {
+		return endDate;
+	}
+
+	public void setEndDate(Date endDate) {
+		this.endDate = endDate;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String toString()
+	{
+		return "Schedule "+name+" Date "+startDate;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/StringValidator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/StringValidator.java
index 8fa87b3..894ce58 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/StringValidator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/StringValidator.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import javax.persistence.*;
-
-public class StringValidator
-{
-	@PrePersist
-	public void prePersist(FlightSchedule sched)
-	{
-		if(sched.getName().length() == 0 || sched.getName().equals(""))
-			throw new IllegalArgumentException("Needs a valid name");
-	}
-
-	@PostPersist
-	public void postPersist(FlightSchedule sched)
-	{
-		System.out.println("Schedule "+sched+" is successfully persisted: StringValidator.class");
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import javax.persistence.*;
+
+public class StringValidator
+{
+	@PrePersist
+	public void prePersist(FlightSchedule sched)
+	{
+		if(sched.getName().length() == 0 || sched.getName().equals(""))
+			throw new IllegalArgumentException("Needs a valid name");
+	}
+
+	@PostPersist
+	public void postPersist(FlightSchedule sched)
+	{
+		System.out.println("Schedule "+sched+" is successfully persisted: StringValidator.class");
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/TxRollbackEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/TxRollbackEntity.java
index 633d8a2..7f5af1a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/TxRollbackEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/TxRollbackEntity.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
-
-import java.util.ArrayList;
-
-import javax.persistence.Basic;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.PostLoad;
-import javax.persistence.PostPersist;
-import javax.persistence.Entity;
-import javax.persistence.PostRemove;
-import javax.persistence.Table;
-
-@Entity
-@Table(name="TX_ROLLBACK_ENT")
-public class TxRollbackEntity
-{
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	@Id
-	private int id;
-
-	@Basic
-	private String name;
-
-	public TxRollbackEntity(String name)
-	{
-		this.name = name;
-	}
-
-	@PostLoad
-	public void rollBackException()
-	{
-		//should throw a null pointer exception causing the tx to be rolled back
-		ArrayList<Integer> list = null;
-		list.add(1);
-	}
-
-	@PostRemove
-	public void bomb()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("rollbackpor1");
-	}
-
-	public void bomb2()
-	{
-		CallbackStorage store = CallbackStorage.getInstance();
-		store.getClist().add("rollbackpor");
-	}
-
-	public int getId() {
-		return id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype;
+
+import java.util.ArrayList;
+
+import javax.persistence.Basic;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.Entity;
+import javax.persistence.PostRemove;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="TX_ROLLBACK_ENT")
+public class TxRollbackEntity
+{
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Id
+	private int id;
+
+	@Basic
+	private String name;
+
+	public TxRollbackEntity(String name)
+	{
+		this.name = name;
+	}
+
+	@PostLoad
+	public void rollBackException()
+	{
+		//should throw a null pointer exception causing the tx to be rolled back
+		ArrayList<Integer> list = null;
+		list.add(1);
+	}
+
+	@PostRemove
+	public void bomb()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("rollbackpor1");
+	}
+
+	public void bomb2()
+	{
+		CallbackStorage store = CallbackStorage.getInstance();
+		store.getClist().add("rollbackpor");
+	}
+
+	public int getId() {
+		return id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/TestQueryCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/TestQueryCache.java
index 49d1a4c..1636b5f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/TestQueryCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/TestQueryCache.java
@@ -1,183 +1,183 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.cache;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.NamedQuery;
-
-import org.apache.openjpa.persistence.cache.common.apps.Entity1;
-import org.apache.openjpa.persistence.cache.common.apps.Entity2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-@NamedQuery(name = "setParam1",
-    query = "SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-public class TestQueryCache extends AbstractTestCase {
-
-    EntityManager em;
-
-    public TestQueryCache(String name) {
-        super(name);
-        System.setProperty("cactus.contextURL",
-            "http://localhost:9000/cachecactus");
-        em = currentEntityManager();
-    }
-
-    /*public static Test suite()
-    {
-        ServletTestSuite suite = new ServletTestSuite();
-        suite.addTestSuite(TestQueryCache.class);
-        return suite;
-    }*/
-    public void setUp() {
-        System.setProperty("cactus.contextURL",
-            "http://localhost:9000/cactuswebapp");
-
-        //deleteAll(Entity2.class);
-        deleteAll(Entity1.class);
-
-        int instNum = 10;
-
-        startTx(em);
-
-        //create and persist multiple entity1 instances
-        for (int i = 0; i < instNum; i++) {
-            Entity1 ent = new Entity1(i, "string" + i, i + 2);
-            Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
-            ent.setEntity2Field(ent2);
-            em.persist(ent);
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testResultList() {
-        em = currentEntityManager();
-        List list = em.createQuery("Select object(o) from Entity1 o")
-            .getResultList();
-
-        assertEquals(10, list.size());
-
-        endEm(em);
-    }
-
-    public void testGetSingleList() {
-        em = currentEntityManager();
-        String curr = 2 + "";
-
-        Entity1 ret = (Entity1) em
-            .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", curr)
-            .getSingleResult();
-
-        assertNotNull(ret);
-        assertEquals("string2", ret.getStringField());
-        assertEquals(4, ret.getIntField());
-
-        endEm(em);
-    }
-
-    public void testExecuteUpdate() {
-        String curr = 2 + "";
-        String curr2 = 22 + "";
-
-        em = currentEntityManager();
-        startTx(em);
-
-        Entity1 entity1 = (Entity1) em
-            .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", curr)
-            .getSingleResult();
-
-        int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", curr)
-            .executeUpdate();
-        assertEquals(ret, 1);
-
-//cascade remove doesn't remove the entity2
-        int retTmp = em.createQuery("Delete FROM Entity2 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", entity1.getEntity2Field().getPk())
-            .executeUpdate();
-
-        int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", curr2)
-            .executeUpdate();
-
-        assertEquals(ret2, 0);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testSetMaxResults() {
-        em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from Entity1 o")
-            .setMaxResults(5)
-            .getResultList();
-
-        assertNotNull(l);
-        assertEquals(5, l.size());
-
-        endEm(em);
-    }
-
-    public void testSetFirstResults() {
-        em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from Entity1 o")
-            .setFirstResult(3)
-            .getResultList();
-
-        Entity1 ent = (Entity1) l.get(0);
-
-        assertNotNull(ent);
-        assertEquals("string3", ent.getStringField());
-        assertEquals(5, ent.getIntField());
-
-        endEm(em);
-    }
-
-    // Tests Binding an argument to a named parameter.
-    // pk, the named parameter --Not working yet--
-    public void xxxtestSetParameter1() {
-
-        em = currentEntityManager();
-        String curr = 2 + "";
-
-        List ret = em.createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", curr)
-            .getResultList();
-
-        assertNotNull(ret);
-        assertEquals(1, ret.size());
-
-        ret = em.createNamedQuery("setParam1")
-            .setParameter("pk", curr)
-            .getResultList();
-
-        assertNotNull(ret);
-        assertEquals(1, ret.size());
-
-        endTx(em);
-    }
-
-    //rest of the interface is tested by the CTS
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.cache;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.NamedQuery;
+
+import org.apache.openjpa.persistence.cache.common.apps.Entity1;
+import org.apache.openjpa.persistence.cache.common.apps.Entity2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+@NamedQuery(name = "setParam1",
+    query = "SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
+public class TestQueryCache extends AbstractTestCase {
+
+    EntityManager em;
+
+    public TestQueryCache(String name) {
+        super(name);
+        System.setProperty("cactus.contextURL",
+            "http://localhost:9000/cachecactus");
+        em = currentEntityManager();
+    }
+
+    /*public static Test suite()
+    {
+        ServletTestSuite suite = new ServletTestSuite();
+        suite.addTestSuite(TestQueryCache.class);
+        return suite;
+    }*/
+    public void setUp() {
+        System.setProperty("cactus.contextURL",
+            "http://localhost:9000/cactuswebapp");
+
+        //deleteAll(Entity2.class);
+        deleteAll(Entity1.class);
+
+        int instNum = 10;
+
+        startTx(em);
+
+        //create and persist multiple entity1 instances
+        for (int i = 0; i < instNum; i++) {
+            Entity1 ent = new Entity1(i, "string" + i, i + 2);
+            Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
+            ent.setEntity2Field(ent2);
+            em.persist(ent);
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testResultList() {
+        em = currentEntityManager();
+        List list = em.createQuery("Select object(o) from Entity1 o")
+            .getResultList();
+
+        assertEquals(10, list.size());
+
+        endEm(em);
+    }
+
+    public void testGetSingleList() {
+        em = currentEntityManager();
+        String curr = 2 + "";
+
+        Entity1 ret = (Entity1) em
+            .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", curr)
+            .getSingleResult();
+
+        assertNotNull(ret);
+        assertEquals("string2", ret.getStringField());
+        assertEquals(4, ret.getIntField());
+
+        endEm(em);
+    }
+
+    public void testExecuteUpdate() {
+        String curr = 2 + "";
+        String curr2 = 22 + "";
+
+        em = currentEntityManager();
+        startTx(em);
+
+        Entity1 entity1 = (Entity1) em
+            .createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", curr)
+            .getSingleResult();
+
+        int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", curr)
+            .executeUpdate();
+        assertEquals(ret, 1);
+
+//cascade remove doesn't remove the entity2
+        int retTmp = em.createQuery("Delete FROM Entity2 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", entity1.getEntity2Field().getPk())
+            .executeUpdate();
+
+        int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", curr2)
+            .executeUpdate();
+
+        assertEquals(ret2, 0);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testSetMaxResults() {
+        em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from Entity1 o")
+            .setMaxResults(5)
+            .getResultList();
+
+        assertNotNull(l);
+        assertEquals(5, l.size());
+
+        endEm(em);
+    }
+
+    public void testSetFirstResults() {
+        em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from Entity1 o")
+            .setFirstResult(3)
+            .getResultList();
+
+        Entity1 ent = (Entity1) l.get(0);
+
+        assertNotNull(ent);
+        assertEquals("string3", ent.getStringField());
+        assertEquals(5, ent.getIntField());
+
+        endEm(em);
+    }
+
+    // Tests Binding an argument to a named parameter.
+    // pk, the named parameter --Not working yet--
+    public void xxxtestSetParameter1() {
+
+        em = currentEntityManager();
+        String curr = 2 + "";
+
+        List ret = em.createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", curr)
+            .getResultList();
+
+        assertNotNull(ret);
+        assertEquals(1, ret.size());
+
+        ret = em.createNamedQuery("setParam1")
+            .setParameter("pk", curr)
+            .getResultList();
+
+        assertNotNull(ret);
+        assertEquals(1, ret.size());
+
+        endTx(em);
+    }
+
+    //rest of the interface is tested by the CTS
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwned.java
index 58fad63..1ab7d99 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwned.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwned.java
@@ -1,89 +1,89 @@
-package org.apache.openjpa.persistence.cache.common.apps;
-
-import javax.persistence.*;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-/**
- * A persistent entity that is owned by unidirectional single-valued 
- * relationship.
- * A unidirectional relationship has only one owning side and the other side
- * called as owned side is this receiver.
- * Given the following relationship between Entity A and Entity B:
- *   Entity A refers a single instance of Entity B 
- *   Entity B does not refer Entity A (owner)
- * Entity A is called owner and Entity B is called owned with respect
- * to the above relationship.
- * 
- * Used to test identical application behavior with or without DataCache.
- * 
- * @see BidirectionalOne2OneOwned
- * @see TestDataCacheBehavesIdentical
- * @see Section 2.1.8.3 of JPA Specification Version 1.0
- * 
- * @author Pinaki Poddar
- *
- */
-
-@Entity
-public class BidirectionalOne2OneOwned {
-	@Id
-	private long id;
-	
-	private String name;
-	
-	@OneToOne(mappedBy="owned")
-	private BidirectionalOne2OneOwner owner;
-	
-	@Version
-	private int version;
-
-	public long getId() {
-		return id;
-	}
-
-	public void setId(long id) {
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public BidirectionalOne2OneOwner getOwner() {
-		return owner;
-	}
-
-	public void setOwner(BidirectionalOne2OneOwner owner) {
-		this.owner = owner;
-	}
-
-	public int getVersion() {
-		return version;
-	}
-	
-	public String toString() {
-		return this.getClass().getSimpleName() + ":" + id + ":" + name;
-	}
-
-}
+package org.apache.openjpa.persistence.cache.common.apps;
+
+import javax.persistence.*;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+/**
+ * A persistent entity that is owned by unidirectional single-valued 
+ * relationship.
+ * A unidirectional relationship has only one owning side and the other side
+ * called as owned side is this receiver.
+ * Given the following relationship between Entity A and Entity B:
+ *   Entity A refers a single instance of Entity B 
+ *   Entity B does not refer Entity A (owner)
+ * Entity A is called owner and Entity B is called owned with respect
+ * to the above relationship.
+ * 
+ * Used to test identical application behavior with or without DataCache.
+ * 
+ * @see BidirectionalOne2OneOwned
+ * @see TestDataCacheBehavesIdentical
+ * @see Section 2.1.8.3 of JPA Specification Version 1.0
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+
+@Entity
+public class BidirectionalOne2OneOwned {
+	@Id
+	private long id;
+	
+	private String name;
+	
+	@OneToOne(mappedBy="owned")
+	private BidirectionalOne2OneOwner owner;
+	
+	@Version
+	private int version;
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public BidirectionalOne2OneOwner getOwner() {
+		return owner;
+	}
+
+	public void setOwner(BidirectionalOne2OneOwner owner) {
+		this.owner = owner;
+	}
+
+	public int getVersion() {
+		return version;
+	}
+	
+	public String toString() {
+		return this.getClass().getSimpleName() + ":" + id + ":" + name;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwner.java
index 6c0c9a9..caf7ff8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/BidirectionalOne2OneOwner.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-package org.apache.openjpa.persistence.cache.common.apps;
-
-import javax.persistence.*;
-
-/**
- * A persistent entity that owns bidirectional single-valued relationship.
- * A bidirectional relationship has only an owning side, which is this receiver.
- * Given the following relationship between Entity A and Entity B:
- *   Entity A refers to a single instance of Entity B 
- *   Entity B refers to a single instance of Entity A 
- * If Entity B qualifies its relation to the Entity A with mappedBy 
- * annotation qualifier then Entity B is called owned and Entity A is called 
- * owner with respect to the above relationship.
- * 
- * Used to test identical application behavior with or without DataCache.
- * 
- * @see BidirectionalOne2OneOwned
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class BidirectionalOne2OneOwner {
-	@Id
-	private long id;
-	
-	private String name;
-	
-	@OneToOne
-	private BidirectionalOne2OneOwned owned;
-	
-	@Version
-	private int version;
-
-	public long getId() {
-		return id;
-	}
-
-	public void setId(long id) {
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public BidirectionalOne2OneOwned getOwned() {
-		return owned;
-	}
-
-	public void setOwned(BidirectionalOne2OneOwned owned) {
-		this.owned = owned;
-	}
-	
-	public int getVersion() {
-		return version;
-	}
-	
-	public String toString() {
-		return this.getClass().getSimpleName() + ":" + id + ":" + name;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.persistence.cache.common.apps;
+
+import javax.persistence.*;
+
+/**
+ * A persistent entity that owns bidirectional single-valued relationship.
+ * A bidirectional relationship has only an owning side, which is this receiver.
+ * Given the following relationship between Entity A and Entity B:
+ *   Entity A refers to a single instance of Entity B 
+ *   Entity B refers to a single instance of Entity A 
+ * If Entity B qualifies its relation to the Entity A with mappedBy 
+ * annotation qualifier then Entity B is called owned and Entity A is called 
+ * owner with respect to the above relationship.
+ * 
+ * Used to test identical application behavior with or without DataCache.
+ * 
+ * @see BidirectionalOne2OneOwned
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class BidirectionalOne2OneOwner {
+	@Id
+	private long id;
+	
+	private String name;
+	
+	@OneToOne
+	private BidirectionalOne2OneOwned owned;
+	
+	@Version
+	private int version;
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public BidirectionalOne2OneOwned getOwned() {
+		return owned;
+	}
+
+	public void setOwned(BidirectionalOne2OneOwned owned) {
+		this.owned = owned;
+	}
+	
+	public int getVersion() {
+		return version;
+	}
+	
+	public String toString() {
+		return this.getClass().getSimpleName() + ":" + id + ":" + name;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity1.java
index 84392a2..379003f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity1.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.cache.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Version;
-
-@Entity
-@Inheritance(strategy = InheritanceType.JOINED)
-@SqlResultSetMapping(name = "NativeTestResult",
-    entities = @EntityResult(entityClass = Entity1.class))
-public class Entity1 implements Serializable {
-
-    private static final long serialVersionUID = 2882935803066041165L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
-    protected Entity2 entity2Field;
-
-    @Version
-    protected int versionField;
-
-    public Entity1() {
-    }
-
-    public Entity1(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setEntity2Field(Entity2 val) {
-        entity2Field = val;
-    }
-
-    public Entity2 getEntity2Field() {
-        return entity2Field;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.cache.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Version;
+
+@Entity
+@Inheritance(strategy = InheritanceType.JOINED)
+@SqlResultSetMapping(name = "NativeTestResult",
+    entities = @EntityResult(entityClass = Entity1.class))
+public class Entity1 implements Serializable {
+
+    private static final long serialVersionUID = 2882935803066041165L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
+    protected Entity2 entity2Field;
+
+    @Version
+    protected int versionField;
+
+    public Entity1() {
+    }
+
+    public Entity1(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setEntity2Field(Entity2 val) {
+        entity2Field = val;
+    }
+
+    public Entity2 getEntity2Field() {
+        return entity2Field;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity2.java
index 16c51cc..db3e279 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/Entity2.java
@@ -1,82 +1,82 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.cache.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-//@Entity(name="entity2ExplicitName")
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class Entity2 implements Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 4723739219953167343L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    public Entity2() {
-    }
-
-    public Entity2(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.cache.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+//@Entity(name="entity2ExplicitName")
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class Entity2 implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4723739219953167343L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    public Entity2() {
+    }
+
+    public Entity2(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwned.java
index 35243e1..520657e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwned.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwned.java
@@ -1,77 +1,77 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-package org.apache.openjpa.persistence.cache.common.apps;
-
-import javax.persistence.*;
-/**
- * A persistent entity that is owned by unidirectional single-valued 
- * relationship.
- * A unidirectional relationship has only one owning side and the other side
- * called as owned side is this receiver.
- * Given the following relationship between Entity A and Entity B:
- *   Entity A refers a single instance of Entity B 
- *   Entity B does not refer Entity A (owner)
- * Entity A is called owner and Entity B is called owned with respect
- * to the above relationship.
- * 
- * Used to test identical application behavior with or without DataCache.
- * 
- * @see UnidirectionalOne2OneOwned
- * @see TestDataCacheBehavesIdentical
- * @see Section 2.1.8.3 of JPA Specification Version 1.0
- * 
- * @author Pinaki Poddar
- *
- */
-
-@Entity
-public class UnidirectionalOne2OneOwned {
-	@Id
-	private long id;
-	
-	private String name;
-	
-	@Version
-	private int version;
-
-	public long getId() {
-		return id;
-	}
-
-	public void setId(long id) {
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public int getVersion() {
-		return version;
-	}
-	
-	public String toString() {
-		return this.getClass().getSimpleName() + ":" + id + ":" + name;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.persistence.cache.common.apps;
+
+import javax.persistence.*;
+/**
+ * A persistent entity that is owned by unidirectional single-valued 
+ * relationship.
+ * A unidirectional relationship has only one owning side and the other side
+ * called as owned side is this receiver.
+ * Given the following relationship between Entity A and Entity B:
+ *   Entity A refers a single instance of Entity B 
+ *   Entity B does not refer Entity A (owner)
+ * Entity A is called owner and Entity B is called owned with respect
+ * to the above relationship.
+ * 
+ * Used to test identical application behavior with or without DataCache.
+ * 
+ * @see UnidirectionalOne2OneOwned
+ * @see TestDataCacheBehavesIdentical
+ * @see Section 2.1.8.3 of JPA Specification Version 1.0
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+
+@Entity
+public class UnidirectionalOne2OneOwned {
+	@Id
+	private long id;
+	
+	private String name;
+	
+	@Version
+	private int version;
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public int getVersion() {
+		return version;
+	}
+	
+	public String toString() {
+		return this.getClass().getSimpleName() + ":" + id + ":" + name;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwner.java
index 84922b1..558d85a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/common/apps/UnidirectionalOne2OneOwner.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-package org.apache.openjpa.persistence.cache.common.apps;
-
-import javax.persistence.*;
-
-/**
- * A persistent entity that owns unidirectional single-valued relationship.
- * A unidirectional relationship has only one owning side, which is this 
- * receiver.
- * Given the following relationship between Entity A and Entity B:
- *   Entity A refers a single instance of Entity B 
- *   Entity B does not refer Entity A (owner)
- * Entity A is called owner and Entity B is called owned with respect
- * to the above relationship.
- * 
- * Used to test identical application behavior with or without DataCache.
- * 
- * @see UnidirectionalOne2OneOwned
- * @see TestDataCacheBehavesIdentical
- * @see Section 2.1.8.3 of JPA Specification Version 1.0
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class UnidirectionalOne2OneOwner {
-	@Id
-	private long id;
-	
-	private String name;
-	
-	@OneToOne
-	private UnidirectionalOne2OneOwned owned;
-	
-	@Version
-	private int version;
-
-	public long getId() {
-		return id;
-	}
-
-	public void setId(long id) {
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public UnidirectionalOne2OneOwned getOwned() {
-		return owned;
-	}
-
-	public void setOwned(UnidirectionalOne2OneOwned owned) {
-		this.owned = owned;
-	}
-	
-	public int getVersion() {
-		return version;
-	}
-	
-	public String toString() {
-		return this.getClass().getSimpleName() + ":" + id + ":" + name;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.openjpa.persistence.cache.common.apps;
+
+import javax.persistence.*;
+
+/**
+ * A persistent entity that owns unidirectional single-valued relationship.
+ * A unidirectional relationship has only one owning side, which is this 
+ * receiver.
+ * Given the following relationship between Entity A and Entity B:
+ *   Entity A refers a single instance of Entity B 
+ *   Entity B does not refer Entity A (owner)
+ * Entity A is called owner and Entity B is called owned with respect
+ * to the above relationship.
+ * 
+ * Used to test identical application behavior with or without DataCache.
+ * 
+ * @see UnidirectionalOne2OneOwned
+ * @see TestDataCacheBehavesIdentical
+ * @see Section 2.1.8.3 of JPA Specification Version 1.0
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class UnidirectionalOne2OneOwner {
+	@Id
+	private long id;
+	
+	private String name;
+	
+	@OneToOne
+	private UnidirectionalOne2OneOwned owned;
+	
+	@Version
+	private int version;
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public UnidirectionalOne2OneOwned getOwned() {
+		return owned;
+	}
+
+	public void setOwned(UnidirectionalOne2OneOwned owned) {
+		this.owned = owned;
+	}
+	
+	public int getVersion() {
+		return version;
+	}
+	
+	public String toString() {
+		return this.getClass().getSimpleName() + ":" + id + ":" + name;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerEntity.java
index f5ffce8..05ed349 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerEntity.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.callbacks;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.EntityListeners;
-
-@Entity
-@EntityListeners(value = ListenerImpl.class)
-public class EntityListenerEntity implements ListenerTestEntity {
-    @Id @GeneratedValue
-    private long id;
-
-    private int value;
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public void setValue(int value) {
-        this.value = value;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.EntityListeners;
+
+@Entity
+@EntityListeners(value = ListenerImpl.class)
+public class EntityListenerEntity implements ListenerTestEntity {
+    @Id @GeneratedValue
+    private long id;
+
+    private int value;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void setValue(int value) {
+        this.value = value;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/GlobalListenerEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/GlobalListenerEntity.java
index 317f85a..2b13764 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/GlobalListenerEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/GlobalListenerEntity.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.callbacks;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.EntityListeners;
-
-import org.apache.openjpa.persistence.callbacks.ListenerImpl;
-
-@Entity
-public class GlobalListenerEntity implements ListenerTestEntity {
-    @Id @GeneratedValue
-    private long id;
-
-    private int value;
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public void setValue(int value) {
-        this.value = value;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.EntityListeners;
+
+import org.apache.openjpa.persistence.callbacks.ListenerImpl;
+
+@Entity
+public class GlobalListenerEntity implements ListenerTestEntity {
+    @Id @GeneratedValue
+    private long id;
+
+    private int value;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void setValue(int value) {
+        this.value = value;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerImpl.java
index 7274672..39ef5ea 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerImpl.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.callbacks;
-
-import javax.persistence.PrePersist;
-import javax.persistence.PostPersist;
-import javax.persistence.PostLoad;
-import javax.persistence.PreUpdate;
-import javax.persistence.PostUpdate;
-import javax.persistence.PreRemove;
-import javax.persistence.PostRemove;
-
-public class ListenerImpl {
-
-    static int prePersistCount;
-    static int postPersistCount;
-    static int preUpdateCount;
-    static int postUpdateCount;
-    static int preRemoveCount;
-    static int postRemoveCount;
-    static int postLoadCount;
-
-    @PrePersist
-    public void prePersist(Object o) {
-        prePersistCount++;
-    }
-
-    @PostPersist
-    public void postPersist(Object o) {
-        postPersistCount++;
-    }
-
-    @PostLoad
-    public void postLoad(Object o) {
-        postLoadCount++;
-    }
-
-    @PreUpdate
-    public void preUpdate(Object o) {
-        preUpdateCount++;
-    }
-
-    @PostUpdate
-    public void postUpdate(Object o) {
-        postUpdateCount++;
-    }
-
-    @PreRemove
-    public void preRemove(Object o) {
-        preRemoveCount++;
-    }
-
-    @PostRemove
-    public void postRemove(Object o) {
-        postRemoveCount++;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import javax.persistence.PrePersist;
+import javax.persistence.PostPersist;
+import javax.persistence.PostLoad;
+import javax.persistence.PreUpdate;
+import javax.persistence.PostUpdate;
+import javax.persistence.PreRemove;
+import javax.persistence.PostRemove;
+
+public class ListenerImpl {
+
+    static int prePersistCount;
+    static int postPersistCount;
+    static int preUpdateCount;
+    static int postUpdateCount;
+    static int preRemoveCount;
+    static int postRemoveCount;
+    static int postLoadCount;
+
+    @PrePersist
+    public void prePersist(Object o) {
+        prePersistCount++;
+    }
+
+    @PostPersist
+    public void postPersist(Object o) {
+        postPersistCount++;
+    }
+
+    @PostLoad
+    public void postLoad(Object o) {
+        postLoadCount++;
+    }
+
+    @PreUpdate
+    public void preUpdate(Object o) {
+        preUpdateCount++;
+    }
+
+    @PostUpdate
+    public void postUpdate(Object o) {
+        postUpdateCount++;
+    }
+
+    @PreRemove
+    public void preRemove(Object o) {
+        preRemoveCount++;
+    }
+
+    @PostRemove
+    public void postRemove(Object o) {
+        postRemoveCount++;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerTestEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerTestEntity.java
index f8ad91e..7d009a8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerTestEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerTestEntity.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.callbacks;
-
-public interface ListenerTestEntity {
-
-    public long getId();
-
-    public int getValue();
-
-    public void setValue(int val);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+public interface ListenerTestEntity {
+
+    public long getId();
+
+    public int getValue();
+
+    public void setValue(int val);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/Message.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/Message.java
new file mode 100644
index 0000000..e5151b9
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/Message.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import java.util.Date;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * A very simple persistent entity that holds a "message", has a "created" field
+ * that is initialized to the time at which the object was created, and an id
+ * field that is initialized to the current time.
+ */
+@Entity
+@EntityListeners(value = MessageListenerImpl.class)
+public class Message {
+    @Id
+    @GeneratedValue
+    private long id;
+
+    @Basic
+    private String message;
+
+    @Basic
+    private Date created = null;
+
+    @Basic
+    private Date updated = null;
+
+    @Version
+    Integer version;
+
+    public Message() {
+    }
+
+    public Message(String msg) {
+        message = msg;
+    }
+
+    public void setId(long val) {
+        id = val;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setMessage(String msg) {
+        message = msg;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setCreated(Date date) {
+        created = date;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Integer getVersion() {
+        return version;
+    }
+
+    public void setVersion(Integer version) {
+        this.version = version;
+    }
+
+    public Date getUpdated() {
+        return updated;
+    }
+
+    public void setUpdated(Date updated) {
+        this.updated = updated;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof Message) {
+            Message other = (Message) o;
+            return other.getId() == this.getId();
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/MessageListenerImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/MessageListenerImpl.java
new file mode 100644
index 0000000..9141e1e
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/MessageListenerImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import java.util.Date;
+
+import javax.persistence.PrePersist;
+import javax.persistence.PostPersist;
+import javax.persistence.PostLoad;
+import javax.persistence.PreUpdate;
+import javax.persistence.PostUpdate;
+import javax.persistence.PreRemove;
+import javax.persistence.PostRemove;
+
+public class MessageListenerImpl {
+
+    public static int prePersistCount;
+    public static int postPersistCount;
+    public static int preUpdateCount;
+    public static int postUpdateCount;
+    public static int preRemoveCount;
+    public static int postRemoveCount;
+    public static int postLoadCount;
+
+    @PrePersist
+    public void prePersist(Object o) {
+        prePersistCount++;
+
+        if (o instanceof Message) {
+            ((Message) o).setCreated(new Date());
+            ((Message) o).setUpdated(new Date());
+        }
+    }
+
+    @PostPersist
+    public void postPersist(Object o) {
+        postPersistCount++;
+    }
+
+    @PostLoad
+    public void postLoad(Object o) {
+        postLoadCount++;
+    }
+
+    @PreUpdate
+    public void preUpdate(Object o) {
+        preUpdateCount++;
+
+        if (o instanceof Message) {
+            ((Message) o).setUpdated(new Date());
+        }
+    }
+
+    @PostUpdate
+    public void postUpdate(Object o) {
+        postUpdateCount++;
+    }
+
+    @PreRemove
+    public void preRemove(Object o) {
+        preRemoveCount++;
+    }
+
+    @PostRemove
+    public void postRemove(Object o) {
+        postRemoveCount++;
+    }
+
+    public static void resetCounters() {
+        prePersistCount = 0;
+        postPersistCount = 0;
+        preUpdateCount = 0;
+        postUpdateCount = 0;
+        preRemoveCount = 0;
+        postRemoveCount = 0;
+        postLoadCount = 0;
+    }
+
+    public static String getStates() {
+        return "prePersistCount = " + prePersistCount + ", postPersistCount = "
+            + postPersistCount + ", preUpdateCount = " + preUpdateCount
+            + ", postUpdateCount = " + postUpdateCount + ", preRemoveCount = "
+            + preRemoveCount + ", postRemoveCount = " + postRemoveCount
+            + ", postLoadCount = " + postLoadCount;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestEntityListeners.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestEntityListeners.java
index d8684f3..6211807 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestEntityListeners.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestEntityListeners.java
@@ -1,114 +1,114 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.callbacks;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestEntityListeners extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(CLEAR_TABLES);
-        ListenerImpl.prePersistCount = 0;
-        ListenerImpl.postPersistCount = 0;
-        ListenerImpl.preUpdateCount = 0;
-        ListenerImpl.postUpdateCount = 0;
-        ListenerImpl.preRemoveCount = 0;
-        ListenerImpl.postRemoveCount = 0;
-        ListenerImpl.postLoadCount = 0;
-    }
-
-    @Override
-    protected String getPersistenceUnitName() {
-        return "listener-pu";
-    }
-
-    public void testEntityListeners() {
-        helper(true);
-    }
-
-    public void testGlobalListeners() {
-        helper(false);
-    }
-
-    public void helper(boolean entityListeners) {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        try {
-            em.getTransaction().begin();
-            ListenerTestEntity o;
-            if (entityListeners)
-                o = new EntityListenerEntity();
-            else
-                o = new GlobalListenerEntity();
-            em.persist(o);
-
-            assertStatus(1, 0, 0, 0, 0, 0, 0);
-
-            em.getTransaction().commit();
-            long id = o.getId();
-            em.close();
-
-            assertStatus(1, 1, 0, 0, 0, 0, 0);
-
-            em = emf.createEntityManager();
-            em.getTransaction().begin();
-            if (entityListeners)
-                o = em.find(EntityListenerEntity.class, id);
-            else
-                o = em.find(GlobalListenerEntity.class, id);
-
-            assertNotNull(o);
-            assertStatus(1, 1, 0, 0, 0, 0, 1);
-
-            o.setValue(o.getValue() + 1);
-
-            em.flush();
-            assertStatus(1, 1, 1, 1, 0, 0, 1);
-
-            em.remove(o);
-            assertStatus(1, 1, 1, 1, 1, 0, 1);
-
-            em.getTransaction().commit();
-
-            assertStatus(1, 1, 1, 1, 1, 1, 1);
-
-            em.close();
-        } finally {
-            if (em != null && em.getTransaction().isActive())
-                em.getTransaction().rollback();
-            if (em != null && em.isOpen())
-                em.close();
-        }
-    }
-
-    private void assertStatus(
-        int prePersist, int postPersist,
-        int preUpdate, int postUpdate,
-        int preRemove, int postRemove,
-        int postLoad) {
-        assertEquals(prePersist, ListenerImpl.prePersistCount);
-        assertEquals(postPersist, ListenerImpl.postPersistCount);
-        assertEquals(preUpdate, ListenerImpl.preUpdateCount);
-        assertEquals(postUpdate, ListenerImpl.postUpdateCount);
-        assertEquals(preRemove, ListenerImpl.preRemoveCount);
-        assertEquals(postRemove, ListenerImpl.postRemoveCount);
-        assertEquals(postLoad, ListenerImpl.postLoadCount);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestEntityListeners extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(CLEAR_TABLES);
+        ListenerImpl.prePersistCount = 0;
+        ListenerImpl.postPersistCount = 0;
+        ListenerImpl.preUpdateCount = 0;
+        ListenerImpl.postUpdateCount = 0;
+        ListenerImpl.preRemoveCount = 0;
+        ListenerImpl.postRemoveCount = 0;
+        ListenerImpl.postLoadCount = 0;
+    }
+
+    @Override
+    protected String getPersistenceUnitName() {
+        return "listener-pu";
+    }
+
+    public void testEntityListeners() {
+        helper(true);
+    }
+
+    public void testGlobalListeners() {
+        helper(false);
+    }
+
+    public void helper(boolean entityListeners) {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        try {
+            em.getTransaction().begin();
+            ListenerTestEntity o;
+            if (entityListeners)
+                o = new EntityListenerEntity();
+            else
+                o = new GlobalListenerEntity();
+            em.persist(o);
+
+            assertStatus(1, 0, 0, 0, 0, 0, 0);
+
+            em.getTransaction().commit();
+            long id = o.getId();
+            em.close();
+
+            assertStatus(1, 1, 0, 0, 0, 0, 0);
+
+            em = emf.createEntityManager();
+            em.getTransaction().begin();
+            if (entityListeners)
+                o = em.find(EntityListenerEntity.class, id);
+            else
+                o = em.find(GlobalListenerEntity.class, id);
+
+            assertNotNull(o);
+            assertStatus(1, 1, 0, 0, 0, 0, 1);
+
+            o.setValue(o.getValue() + 1);
+
+            em.flush();
+            assertStatus(1, 1, 1, 1, 0, 0, 1);
+
+            em.remove(o);
+            assertStatus(1, 1, 1, 1, 1, 0, 1);
+
+            em.getTransaction().commit();
+
+            assertStatus(1, 1, 1, 1, 1, 1, 1);
+
+            em.close();
+        } finally {
+            if (em != null && em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            if (em != null && em.isOpen())
+                em.close();
+        }
+    }
+
+    private void assertStatus(
+        int prePersist, int postPersist,
+        int preUpdate, int postUpdate,
+        int preRemove, int postRemove,
+        int postLoad) {
+        assertEquals(prePersist, ListenerImpl.prePersistCount);
+        assertEquals(postPersist, ListenerImpl.postPersistCount);
+        assertEquals(preUpdate, ListenerImpl.preUpdateCount);
+        assertEquals(postUpdate, ListenerImpl.postUpdateCount);
+        assertEquals(preRemove, ListenerImpl.preRemoveCount);
+        assertEquals(postRemove, ListenerImpl.postRemoveCount);
+        assertEquals(postLoad, ListenerImpl.postLoadCount);
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMessageListeners.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMessageListeners.java
new file mode 100644
index 0000000..3675c3a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMessageListeners.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestMessageListeners extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(DROP_TABLES);
+    }
+
+    @Override
+    protected String getPersistenceUnitName() {
+        return "listener-pu";
+    }
+
+    public void testUpdateInPrePersist() {
+        // Create a new EntityManager from the EntityManagerFactory. The
+        // EntityManager is the main object in the persistence API, and is
+        // used to create, delete, and query objects, as well as access
+        // the current transaction
+        OpenJPAEntityManager em = emf.createEntityManager();
+        try {
+            // Begin a new local transaction so that we can persist a new entity
+            em.getTransaction().begin();
+
+            MessageListenerImpl.resetCounters();
+
+            // Create and persist a new Message entity
+            Message message = new Message("Hello Persistence!");
+            assertNull("Test message's created field to be null.", message
+                .getCreated());
+            assertNull("Test message's updated field to be null.", message
+                .getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(1, 0, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message
+                .getCreated());
+            assertNotNull("Test message's updated field being set.", message
+                .getUpdated());
+
+            em.flush();
+            // Post-persist invoked
+            assertStatus(1, 1, 0, 0, 0, 0, 0);
+
+            em.clear();
+
+            // Perform a simple query to get the Message
+            Query q = em.createQuery("select m from Message m where m.id="
+                + message.getId());
+            Message m = (Message) q.getSingleResult();
+
+            assertEquals("Test first expected message.", "Hello Persistence!",
+                m.getMessage());
+            assertNotNull("Test message's created field being set.", m
+                .getCreated());
+            assertNotNull("Test message's updated field being set.", m
+                .getUpdated());
+
+            // query trigger a load because em is cleared.
+            assertStatus(1, 1, 0, 0, 0, 0, 1);
+
+            em.getTransaction().commit();
+
+            // since data is flushed, commit data with no event fired.
+            assertStatus(1, 1, 0, 0, 0, 0, 1);
+        } finally {
+            if (em != null && em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            if (em != null && em.isOpen())
+                em.close();
+        }
+    }
+
+    public void testUpdateInPreUpdate() {
+        // Create a new EntityManager from the EntityManagerFactory. The
+        // EntityManager is the main object in the persistence API, and is
+        // used to create, delete, and query objects, as well as access
+        // the current transaction
+        OpenJPAEntityManager em = emf.createEntityManager();
+        try {
+            // Begin a new local transaction so that we can persist a new entity
+            em.getTransaction().begin();
+
+            MessageListenerImpl.resetCounters();
+
+            // Create and persist a new Message entity
+            Message message = new Message("Hello Persistence!");
+            assertNull("Test message's created field to be null.", message
+                .getCreated());
+            assertNull("Test message's updated field to be null.", message
+                .getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(1, 0, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message
+                .getCreated());
+            assertNotNull("Test message's updated field being set.", message
+                .getUpdated());
+
+            // Perform a simple query to get the Message
+            Query q = em.createQuery("select m from Message m where m.id="
+                + message.getId());
+            Message m = (Message) q.getSingleResult();
+            assertEquals("Test first expected message.", "Hello Persistence!",
+                m.getMessage());
+            assertNotNull("Test message's created field being set.", m
+                .getCreated());
+            assertNotNull("Test message's updated field being set.", m
+                .getUpdated());
+
+            // Query cause flush to occur, hence fire the postPersist event
+            assertStatus(1, 1, 0, 0, 0, 0, 0);
+
+            // Create and persist another new Message entity
+            message = new Message("Hello Persistence 2!");
+            assertNull("Test message's created field to be null.", message
+                .getCreated());
+            assertNull("Test message's updated field to be null.", message
+                .getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(2, 1, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message
+                .getCreated());
+            assertNotNull("Test message's updated field being set.", message
+                .getUpdated());
+
+            em.getTransaction().commit();
+
+            // Complete the 2nd @postPersist
+            //assertStatus(2, 2, 0, 0, 0, 0, 0);
+            // preUpdate and postUpdate are called in 1.2.x but not in 2.0
+            assertStatus(2, 2, 1, 1, 0, 0, 0);
+            
+            // Make an update to trigger the pre/postUpdater callbacks
+            em.getTransaction().begin();
+            message = em.find(Message.class,message.getId());
+            message.setMessage("Update field and trigger pre/postUpdate");
+            em.getTransaction().commit();
+            
+            // Complete the 2nd @postPersist
+            assertStatus(2, 2, 2, 2, 0, 0, 0);
+
+        } finally {
+            if (em != null && em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            if (em != null && em.isOpen())
+                em.close();
+        }
+    }
+
+    private void assertStatus(int prePersist, int postPersist, int preUpdate,
+        int postUpdate, int preRemove, int postRemove, int postLoad) {
+        assertEquals(prePersist, MessageListenerImpl.prePersistCount);
+        assertEquals(postPersist, MessageListenerImpl.postPersistCount);
+        assertEquals(preUpdate, MessageListenerImpl.preUpdateCount);
+        assertEquals(postUpdate, MessageListenerImpl.postUpdateCount);
+        assertEquals(preRemove, MessageListenerImpl.preRemoveCount);
+        assertEquals(postRemove, MessageListenerImpl.postRemoveCount);
+        assertEquals(postLoad, MessageListenerImpl.postLoadCount);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Address.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Address.java
index 6989f53..0b09aa1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Address.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Address.java
@@ -1,94 +1,94 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.*;
-
-@Entity
-public class Address
-{
-	@Basic
-	@Column(length=50)
-	private String streetAd;
-
-	@Basic
-	@Column(length=50)
-	private String city;
-
-	@Basic
-	@Column(length=50)
-	private String country;
-
-	@Basic
-	@Column(length=25)
-	private String zipcode;
-
-	@OneToOne(mappedBy="address")
-	private CompUser user;
-
-	@Id
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	private int id;
-
-	public Address(){}
-
-	public Address(String streetAd, String city, String country, String zipcode)
-	{
-		this.streetAd = streetAd;
-		this.city = city;
-		this.country = country;
-		this.zipcode = zipcode;
-	}
-
-	public String getCity() {
-		return city;
-	}
-
-	public void setCity(String city) {
-		this.city = city;
-	}
-
-	public String getCountry() {
-		return country;
-	}
-
-	public void setCountry(String country) {
-		this.country = country;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public String getStreetAd() {
-		return streetAd;
-	}
-
-	public void setStreetAd(String streetAd) {
-		this.streetAd = streetAd;
-	}
-
-	public String getZipcode() {
-		return zipcode;
-	}
-
-	public void setZipcode(String zipcode) {
-		this.zipcode = zipcode;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.*;
+
+@Entity
+public class Address
+{
+	@Basic
+	@Column(length=50)
+	private String streetAd;
+
+	@Basic
+	@Column(length=50)
+	private String city;
+
+	@Basic
+	@Column(length=50)
+	private String country;
+
+	@Basic
+	@Column(length=25)
+	private String zipcode;
+
+	@OneToOne(mappedBy="address")
+	private CompUser user;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private int id;
+
+	public Address(){}
+
+	public Address(String streetAd, String city, String country, String zipcode)
+	{
+		this.streetAd = streetAd;
+		this.city = city;
+		this.country = country;
+		this.zipcode = zipcode;
+	}
+
+	public String getCity() {
+		return city;
+	}
+
+	public void setCity(String city) {
+		this.city = city;
+	}
+
+	public String getCountry() {
+		return country;
+	}
+
+	public void setCountry(String country) {
+		this.country = country;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public String getStreetAd() {
+		return streetAd;
+	}
+
+	public void setStreetAd(String streetAd) {
+		this.streetAd = streetAd;
+	}
+
+	public String getZipcode() {
+		return zipcode;
+	}
+
+	public void setZipcode(String zipcode) {
+		this.zipcode = zipcode;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ArtCourse.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ArtCourse.java
index 14918e1..c3405f1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ArtCourse.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ArtCourse.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity
-@DiscriminatorValue("Art")
-public class ArtCourse extends Course
-{
-	private static final long serialVersionUID = 1L;
-
-	private String relCourse;
-
-	public ArtCourse(String relCourse)
-	{
-		this.relCourse = relCourse;
-	}
-
-	public ArtCourse(int id, String relCourse)
-	{
-		super(id);
-		this.relCourse = relCourse;
-	}
-
-	public String getRelCourse()
-	{
-		return relCourse;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("Art")
+public class ArtCourse extends Course
+{
+	private static final long serialVersionUID = 1L;
+
+	private String relCourse;
+
+	public ArtCourse(String relCourse)
+	{
+		this.relCourse = relCourse;
+	}
+
+	public ArtCourse(int id, String relCourse)
+	{
+		super(id);
+		this.relCourse = relCourse;
+	}
+
+	public String getRelCourse()
+	{
+		return relCourse;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/CompUser.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/CompUser.java
index a26e5ad0..eb9a35a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/CompUser.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/CompUser.java
@@ -1,98 +1,129 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.*;
-import org.apache.openjpa.persistence.*;
-
-import java.util.*;
-
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class CompUser
-{
-	@Basic
-	@Column(length=50)
-	private String name;
-
-	@Basic
-	private int age;
-
-	@Basic
-	@Column(name="compName", length=50)
-	private String computerName;
-
-	@PersistentCollection
-	private String[] nicknames = new String[0];
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	@JoinColumn(name="ADD_ID")
-	private Address address;
-
-	@Id
-	@GeneratedValue(strategy=GenerationType.AUTO)
-	public int userid;
-
-	public CompUser(){}
-
-	public CompUser(String name, String cName, Address address, int age)
-	{
-		this.name = name;
-		this.computerName = cName;
-		this.address = address;
-		this.age = age;
-	}
-
-	public String getComputerName() {
-		return computerName;
-	}
-
-	public void setComputerName(String computerName) {
-		this.computerName = computerName;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public int getUserid() {
-		return userid;
-	}
-
-	public Address getAddress() {
-		return address;
-	}
-
-	public void setAddress(Address address) {
-		this.address = address;
-	}
-
-	public int getAge() {
-		return age;
-	}
-
-	public void setAge(int age) {
-		this.age = age;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.OneToOne;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class CompUser
+{
+	@Basic
+	@Column(length=50)
+	private String name;
+
+	@Basic
+	private int age;
+
+	@Basic
+	@Column(name="compName", length=50)
+	private String computerName;
+    
+	@Basic
+    @Lob
+    private String nameAsLob;
+	
+	@PersistentCollection
+	private String[] nicknames = new String[0];
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	@JoinColumn(name="ADD_ID")
+	private Address address;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	public int userid;
+
+	public CompUser(){}
+
+	public CompUser(String name, String cName, Address address, int age)
+	{
+		this.name = name;
+		this.computerName = cName;
+		this.address = address;
+		this.age = age;
+		this.nameAsLob = name;
+	}
+
+	public String getComputerName() {
+		return computerName;
+	}
+
+	public void setComputerName(String computerName) {
+		this.computerName = computerName;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public int getUserid() {
+		return userid;
+	}
+
+	public Address getAddress() {
+		return address;
+	}
+
+	public String[] getNicknames() {
+        return nicknames;
+    }
+
+    public void setNicknames(String[] nicknames) {
+        this.nicknames = nicknames;
+    }
+
+    public void setAddress(Address address) {
+		this.address = address;
+	}
+
+	public int getAge() {
+		return age;
+	}
+
+	public void setAge(int age) {
+		this.age = age;
+	}
+
+	public String getNameAsLob() {
+		return nameAsLob;
+	}
+
+	public void setNameAsLob(String nameAsLob) {
+		this.nameAsLob = nameAsLob;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ComplexEmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ComplexEmbeddedPC.java
index 1eddd4e..74a6f9b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ComplexEmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ComplexEmbeddedPC.java
@@ -1,77 +1,77 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-
-/**
- *	<p>Embedded type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-public class ComplexEmbeddedPC
-{
-	@Basic
-	private String 				stringField;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private EmbeddedOwnerPC		ownerField;
-
-	private Set					stringSet = new HashSet ();
-
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-
-	public EmbeddedOwnerPC getOwnerField ()
-	{
-		return this.ownerField;
-	}
-
-
-	public void setOwnerField (EmbeddedOwnerPC ownerField)
-	{
-		this.ownerField = ownerField;
-	}
-
-
-	public Set getStringSet ()
-	{
-		return this.stringSet;
-	}
-
-	public void setStringSet (Set stringSet)
-	{
-		this.stringSet = stringSet;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+
+/**
+ *	<p>Embedded type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+public class ComplexEmbeddedPC
+{
+	@Basic
+	private String 				stringField;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private EmbeddedOwnerPC		ownerField;
+
+	private Set					stringSet = new HashSet ();
+
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+
+	public EmbeddedOwnerPC getOwnerField ()
+	{
+		return this.ownerField;
+	}
+
+
+	public void setOwnerField (EmbeddedOwnerPC ownerField)
+	{
+		this.ownerField = ownerField;
+	}
+
+
+	public Set getStringSet ()
+	{
+		return this.stringSet;
+	}
+
+	public void setStringSet (Set stringSet)
+	{
+		this.stringSet = stringSet;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Course.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Course.java
index 04603d6..0d73f98 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Course.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Course.java
@@ -1,82 +1,82 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import java.io.Serializable;
-import java.util.List;
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class Course implements Serializable
-{
-	@Transient
-	private static final long serialVersionUID = 1L;
-
-	@Basic
-	private String name;
-
-	@Basic
-	private int units;
-
-	@ManyToMany(mappedBy="course")
-	private List<Student> students;
-
-	@Id
-	private int courseId;
-
-	public Course(){}
-
-	public Course(int courseId)
-	{
-		this.courseId = courseId;
-	}
-
-	public Course(String name, int units, int courseId)
-	{
-		this.name = name;
-		this.units = units;
-		this.courseId = courseId;
-	}
-
-	public int getCourseId() {
-		return courseId;
-	}
-
-	public void setCourseId(int courseId) {
-		this.courseId = courseId;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public int getUnits() {
-		return units;
-	}
-
-	public void setUnits(int units) {
-		this.units = units;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class Course implements Serializable
+{
+	@Transient
+	private static final long serialVersionUID = 1L;
+
+	@Basic
+	private String name;
+
+	@Basic
+	private int units;
+
+	@ManyToMany(mappedBy="course")
+	private List<Student> students;
+
+	@Id
+	private int courseId;
+
+	public Course(){}
+
+	public Course(int courseId)
+	{
+		this.courseId = courseId;
+	}
+
+	public Course(String name, int units, int courseId)
+	{
+		this.name = name;
+		this.units = units;
+		this.courseId = courseId;
+	}
+
+	public int getCourseId() {
+		return courseId;
+	}
+
+	public void setCourseId(int courseId) {
+		this.courseId = courseId;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public int getUnits() {
+		return units;
+	}
+
+	public void setUnits(int units) {
+		this.units = units;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Department.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Department.java
index 45ba51e..eba988c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Department.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Department.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.*;
-import java.io.*;
-import java.util.*;
-
-
-@Entity
-public class Department implements Serializable
-{
-	@Transient
-	private static final long serialVersionUID = 1L;
-
-	@Id
-	private int id;
-
-	@Basic
-	private String name;
-
-	@ManyToMany(mappedBy="department")
-	private List<Student> slist;
-
-	public Department(){}
-
-	public Department(int id)
-	{
-		this.id = id;
-	}
-
-	public Department(String name, List<Student> slist, int id)
-	{
-		this.name = name;
-		this.slist = slist;
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public List<Student> getSlist() {
-		return slist;
-	}
-
-	public void setSlist(List<Student> slist) {
-		this.slist = slist;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.*;
+import java.io.*;
+import java.util.*;
+
+
+@Entity
+public class Department implements Serializable
+{
+	@Transient
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	private int id;
+
+	@Basic
+	private String name;
+
+	@ManyToMany(mappedBy="department")
+	private List<Student> slist;
+
+	public Department(){}
+
+	public Department(int id)
+	{
+		this.id = id;
+	}
+
+	public Department(String name, List<Student> slist, int id)
+	{
+		this.name = name;
+		this.slist = slist;
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<Student> getSlist() {
+		return slist;
+	}
+
+	public void setSlist(List<Student> slist) {
+		this.slist = slist;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedOwnerPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedOwnerPC.java
index 5e10e0f..75d0175 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedOwnerPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedOwnerPC.java
@@ -1,158 +1,158 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.JoinColumn;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-
-/**
- *	<p>Persistent type used in testing embedded instances.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@Table(name="embownpc")
-@IdClass(EmbeddedOwnerPC.EmbKey.class)
-public class EmbeddedOwnerPC
-{
-	@Id
-	private int					id1;
-	@Id
-	private int					id2;
-	@Basic
-	private String				stringField;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private EmbeddedPC 			embedded;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private ComplexEmbeddedPC	complexEmbedded;
-
-
-	protected EmbeddedOwnerPC ()
-	{
-	}
-
-	public EmbeddedOwnerPC (int id1, int id2)
-	{
-		this.id1 = id1;
-		this.id2 = id2;
-	}
-
-
-	public int getId1 ()
-	{
-		return id1;
-	}
-
-
-	public int getId2 ()
-	{
-		return id2;
-	}
-
-
-	public EmbeddedPC getEmbedded ()
-	{
-		return this.embedded;
-	}
-
-
-	public void setEmbedded (EmbeddedPC embedded)
-	{
-		this.embedded = embedded;
-	}
-
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-
-	public ComplexEmbeddedPC getComplexEmbedded ()
-	{
-		return this.complexEmbedded;
-	}
-
-
-	public void setComplexEmbedded (ComplexEmbeddedPC complexEmbedded)
-	{
-		this.complexEmbedded = complexEmbedded;
-	}
-
-	public static class EmbKey implements Serializable
-	{
-		public int					id1;
-		public int					id2;
-
-		public EmbKey()
-		{
-		}
-
-		public EmbKey (String str)
-		{
-			int index = str.indexOf (":");
-			if (index != -1)
-			{
-				id1 = Integer.parseInt (str.substring (0, index));
-				id2 = Integer.parseInt(str.substring (index + 1));
-			}
-		}
-
-		@Override
-		public boolean equals(Object other)
-		{
-			if(!(other instanceof EmbKey))
-				  return false;
-
-	     	EmbKey touse = (EmbKey)other;
-
-			if (id2 == 0 && touse.id2 != 0)
-				return false;
-			if (id2 != 0 && touse.id2 == 0)
-				return false;
-			if (!(id1 == touse.id1))
-				return false;
-
-			return true;
-		}
-
-		@Override
-		public int hashCode()
-		{
-			return (id1 + id2+"").hashCode();
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+
+/**
+ *	<p>Persistent type used in testing embedded instances.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Table(name="embownpc")
+@IdClass(EmbeddedOwnerPC.EmbKey.class)
+public class EmbeddedOwnerPC
+{
+	@Id
+	private int					id1;
+	@Id
+	private int					id2;
+	@Basic
+	private String				stringField;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private EmbeddedPC 			embedded;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private ComplexEmbeddedPC	complexEmbedded;
+
+
+	protected EmbeddedOwnerPC ()
+	{
+	}
+
+	public EmbeddedOwnerPC (int id1, int id2)
+	{
+		this.id1 = id1;
+		this.id2 = id2;
+	}
+
+
+	public int getId1 ()
+	{
+		return id1;
+	}
+
+
+	public int getId2 ()
+	{
+		return id2;
+	}
+
+
+	public EmbeddedPC getEmbedded ()
+	{
+		return this.embedded;
+	}
+
+
+	public void setEmbedded (EmbeddedPC embedded)
+	{
+		this.embedded = embedded;
+	}
+
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+
+	public ComplexEmbeddedPC getComplexEmbedded ()
+	{
+		return this.complexEmbedded;
+	}
+
+
+	public void setComplexEmbedded (ComplexEmbeddedPC complexEmbedded)
+	{
+		this.complexEmbedded = complexEmbedded;
+	}
+
+	public static class EmbKey implements Serializable
+	{
+		public int					id1;
+		public int					id2;
+
+		public EmbKey()
+		{
+		}
+
+		public EmbKey (String str)
+		{
+			int index = str.indexOf (":");
+			if (index != -1)
+			{
+				id1 = Integer.parseInt (str.substring (0, index));
+				id2 = Integer.parseInt(str.substring (index + 1));
+			}
+		}
+
+		@Override
+		public boolean equals(Object other)
+		{
+			if(!(other instanceof EmbKey))
+				  return false;
+
+	     	EmbKey touse = (EmbKey)other;
+
+			if (id2 == 0 && touse.id2 != 0)
+				return false;
+			if (id2 != 0 && touse.id2 == 0)
+				return false;
+			if (!(id1 == touse.id1))
+				return false;
+
+			return true;
+		}
+
+		@Override
+		public int hashCode()
+		{
+			return (id1 + id2+"").hashCode();
+		}
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedPC.java
index a1b0df1..404ce1d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/EmbeddedPC.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.*;
-
-
-/**
- *	<p>Embedded type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@Table(name="embpc")
-public class EmbeddedPC
-{
-	@Id
-	private int		intField;
-
-	private String 	stringField;
-
-
-	public int getIntField ()
-	{
-		return this.intField;
-	}
-
-	public void setIntField (int intField)
-	{
-		this.intField = intField;
-	}
-
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.*;
+
+
+/**
+ *	<p>Embedded type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Table(name="embpc")
+public class EmbeddedPC
+{
+	@Id
+	private int		intField;
+
+	private String 	stringField;
+
+
+	public int getIntField ()
+	{
+		return this.intField;
+	}
+
+	public void setIntField (int intField)
+	{
+		this.intField = intField;
+	}
+
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity1.java
index aa5402e..04f6da6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity1.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-
-@Entity
-@Table(name="entity_1")
-@Inheritance(strategy=InheritanceType.JOINED)
-@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
-public class Entity1 implements Serializable
-{
-	private static final long serialVersionUID = 2882935803066041165L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
-	protected Entity2 entity2Field;
-
-	@Version
-	protected int versionField;
-
-	public Entity1()
-	{}
-
-	public Entity1 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-
-	public void setEntity2Field (Entity2 val)
-	{
-		entity2Field = val;
-	}
-
-
-	public Entity2 getEntity2Field ()
-	{
-		return entity2Field;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+
+@Entity
+@Table(name="entity_1")
+@Inheritance(strategy=InheritanceType.JOINED)
+@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
+public class Entity1 implements Serializable
+{
+	private static final long serialVersionUID = 2882935803066041165L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
+	protected Entity2 entity2Field;
+
+	@Version
+	protected int versionField;
+
+	public Entity1()
+	{}
+
+	public Entity1 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+
+	public void setEntity2Field (Entity2 val)
+	{
+		entity2Field = val;
+	}
+
+
+	public Entity2 getEntity2Field ()
+	{
+		return entity2Field;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity2.java
index 732d0af..a535cc7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Entity2.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-
-//@Entity(name="entity2ExplicitName")
-//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-/**FIX-ME 
- * 
- * It should complain if i uncomment the above strategies...but it does
- */
-@Entity
-public class Entity2 implements Serializable
-{
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 4723739219953167343L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	public Entity2()
-	{}
-
-
-	public Entity2 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+
+//@Entity(name="entity2ExplicitName")
+//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+/**FIX-ME 
+ * 
+ * It should complain if i uncomment the above strategies...but it does
+ */
+@Entity
+public class Entity2 implements Serializable
+{
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 4723739219953167343L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	public Entity2()
+	{}
+
+
+	public Entity2 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/FemaleUser.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/FemaleUser.java
index ded6ff4..e0077a4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/FemaleUser.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/FemaleUser.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity(name="FemUser")
-@DiscriminatorValue(value="F")
-public class FemaleUser extends CompUser
-{
-
-	public FemaleUser(){}
-
-	public FemaleUser(String name, String cname, Address add, int age, int id)
-	{
-		super(name, cname, add, age);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity(name="FemUser")
+@DiscriminatorValue(value="F")
+public class FemaleUser extends CompUser
+{
+
+	public FemaleUser(){}
+
+	public FemaleUser(String name, String cname, Address add, int age, int id)
+	{
+		super(name, cname, add, age);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/MaleUser.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/MaleUser.java
index 81740f2..463ff26 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/MaleUser.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/MaleUser.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.*;
-
-@Entity
-@DiscriminatorValue(value="M")
-public class MaleUser extends CompUser
-{
-	public MaleUser(){}
-
-	public MaleUser(String name, String cname, Address add, int age, int id)
-	{
-		super(name, cname, add, age);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorValue(value="M")
+public class MaleUser extends CompUser
+{
+	public MaleUser(){}
+
+	public MaleUser(String name, String cname, Address add, int age, int id)
+	{
+		super(name, cname, add, age);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java
index 0babcfd..a74e3b4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java
@@ -1,143 +1,143 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import java.io.*;
-import java.math.*;
-import java.util.*;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-
-/**
- *	<p>Persitent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@Table(name="rtest1")
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class RuntimeTest1 implements Serializable
-{
-
-	private static final long serialVersionUID = 1L;
-
-	@Transient
-	public static final String someStaticField = "someField";
-
-	private Locale		localeField;
-
-	@Id
-	private int			intField;
-
-	@Column(length=35)
-	private String		stringField;
-
-	// transactional only
-	@Column(length=35)
-	public String		transString;
-
-	// relations
-	//@Transient
-	@OneToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private RuntimeTest1	selfOneOne;
-
-	@Transient
-	private Set		selfOneMany = new HashSet ();
-
-
-	public RuntimeTest1 ()
-	{}
-
-	public RuntimeTest1(int key)
-	{
-		this.intField = key;
-	}
-
-	public RuntimeTest1 (String str, int i)
-	{
-		stringField = str;
-		intField = i;
-	}
-
-	public int getIntField ()
-	{
-		return this.intField;
-	}
-
-
-	public void setIntField (int intField)
-	{
-		this.intField = intField;
-	}
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-	public RuntimeTest1 getSelfOneOne ()
-	{
-		return this.selfOneOne;
-	}
-
-	public void setSelfOneOne (RuntimeTest1 selfOneOne)
-	{
-		this.selfOneOne = selfOneOne;
-	}
-
-	public Set getSelfOneMany ()
-	{
-		return this.selfOneMany;
-	}
-
-	public void setSelfOneMany (Set selfOneMany)
-	{
-		this.selfOneMany = selfOneMany;
-	}
-
-	public String toString()
-	{
-		return "IntField: "+intField+", StringField: "+stringField+" .";
-	}
-
-	public Locale getLocaleField() {
-		return localeField;
-	}
-
-	public void setLocaleField(Locale localeField) {
-		this.localeField = localeField;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+
+/**
+ *	<p>Persitent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Table(name="rtest1")
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class RuntimeTest1 implements Serializable
+{
+
+	private static final long serialVersionUID = 1L;
+
+	@Transient
+	public static final String someStaticField = "someField";
+
+	private Locale		localeField;
+
+	@Id
+	private int			intField;
+
+	@Column(length=35)
+	private String		stringField;
+
+	// transactional only
+	@Column(length=35)
+	public String		transString;
+
+	// relations
+	//@Transient
+	@OneToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private RuntimeTest1	selfOneOne;
+
+	@Transient
+	private Set		selfOneMany = new HashSet ();
+
+
+	public RuntimeTest1 ()
+	{}
+
+	public RuntimeTest1(int key)
+	{
+		this.intField = key;
+	}
+
+	public RuntimeTest1 (String str, int i)
+	{
+		stringField = str;
+		intField = i;
+	}
+
+	public int getIntField ()
+	{
+		return this.intField;
+	}
+
+
+	public void setIntField (int intField)
+	{
+		this.intField = intField;
+	}
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+	public RuntimeTest1 getSelfOneOne ()
+	{
+		return this.selfOneOne;
+	}
+
+	public void setSelfOneOne (RuntimeTest1 selfOneOne)
+	{
+		this.selfOneOne = selfOneOne;
+	}
+
+	public Set getSelfOneMany ()
+	{
+		return this.selfOneMany;
+	}
+
+	public void setSelfOneMany (Set selfOneMany)
+	{
+		this.selfOneMany = selfOneMany;
+	}
+
+	public String toString()
+	{
+		return "IntField: "+intField+", StringField: "+stringField+" .";
+	}
+
+	public Locale getLocaleField() {
+		return localeField;
+	}
+
+	public void setLocaleField(Locale localeField) {
+		this.localeField = localeField;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java
index c79b740..ffda367 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.Table;
-
-
-/**
- *	<p>Persitent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@DiscriminatorValue("RT2")
-public class RuntimeTest2 extends RuntimeTest1
-{
-	private static final long serialVersionUID = 1L;
-	private int intField2;
-
-	public RuntimeTest2 (int key)
-	{
-		super(key);
-	}
-
-	public RuntimeTest2 (String str, int i)
-	{
-		super (str, i);
-	}
-
-	public int getIntField2 ()
-	{
-		return this.intField2;
-	}
-
-	public void setIntField2 (int intField2)
-	{
-		this.intField2 = intField2;
-	}
-
-	public String toString()
-	{
-		return "IntField: "+intField2+", StringField: "+super.getStringField()+" .";
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.Table;
+
+
+/**
+ *	<p>Persitent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@DiscriminatorValue("RT2")
+public class RuntimeTest2 extends RuntimeTest1
+{
+	private static final long serialVersionUID = 1L;
+	private int intField2;
+
+	public RuntimeTest2 (int key)
+	{
+		super(key);
+	}
+
+	public RuntimeTest2 (String str, int i)
+	{
+		super (str, i);
+	}
+
+	public int getIntField2 ()
+	{
+		return this.intField2;
+	}
+
+	public void setIntField2 (int intField2)
+	{
+		this.intField2 = intField2;
+	}
+
+	public String toString()
+	{
+		return "IntField: "+intField2+", StringField: "+super.getStringField()+" .";
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java
index 40e9f0f..c968e1a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity
-@DiscriminatorValue("Science")
-public class ScienceCourse extends Course
-{
-	private static final long serialVersionUID = 1L;
-
-	private String relCourse;
-
-	public ScienceCourse(String relCourse)
-	{
-		this.relCourse = relCourse;
-	}
-
-	public ScienceCourse(int id, String relCourse)
-	{
-		super(id);
-		this.relCourse = relCourse;
-	}
-
-	public String getRelCourse()
-	{
-		return relCourse;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("Science")
+public class ScienceCourse extends Course
+{
+	private static final long serialVersionUID = 1L;
+
+	private String relCourse;
+
+	public ScienceCourse(String relCourse)
+	{
+		this.relCourse = relCourse;
+	}
+
+	public ScienceCourse(int id, String relCourse)
+	{
+		super(id);
+		this.relCourse = relCourse;
+	}
+
+	public String getRelCourse()
+	{
+		return relCourse;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java
index c46f05a..bfe3b9d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.apps;
-
-import java.io.Serializable;
-import java.util.List;
-
-import javax.persistence.*;
-
-@Entity
-public class Student implements Serializable {
-
-	@Transient
-	private static final long serialVersionUID = 1L;
-
-	@Id
-	@Column(length=50)
-	private String name;
-
-	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	@JoinTable(name="STUD_COURSE",
-		            joinColumns=@JoinColumn(name="STUD_ID"),
-		            inverseJoinColumns=@JoinColumn(name="CRSE_ID"))
-	private List<Course> course;
-
-	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	@JoinTable(name="STUD_DEP",
-		            joinColumns=@JoinColumn(name="STUD_ID"),
-		            inverseJoinColumns=@JoinColumn(name="DEP_ID"))
-	private List<Department> department;
-
-	public Student(){}
-
-	public Student(String name)
-	{
-		this.name = name;
-	}
-
-	public Student(String name, List<Course> clist, List<Department> dlist)
-	{
-		this.name = name;
-		this.course = clist;
-		this.department = dlist;
-	}
-
-	public List<Course> getCourse() {
-		return course;
-	}
-
-	public void setCourse(List<Course> course) {
-		this.course = course;
-	}
-
-	public List<Department> getDepartment() {
-		return department;
-	}
-
-	public void setDepartment(List<Department> department) {
-		this.department = department;
-	}
-
-	public String getName()
-	{
-		return name;
-	}
-
-	public void setName(String name)
-	{
-		this.name = name;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.apps;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+public class Student implements Serializable {
+
+	@Transient
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@Column(length=50)
+	private String name;
+
+	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	@JoinTable(name="STUD_COURSE",
+		            joinColumns=@JoinColumn(name="STUD_ID"),
+		            inverseJoinColumns=@JoinColumn(name="CRSE_ID"))
+	private List<Course> course;
+
+	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	@JoinTable(name="STUD_DEP",
+		            joinColumns=@JoinColumn(name="STUD_ID"),
+		            inverseJoinColumns=@JoinColumn(name="DEP_ID"))
+	private List<Department> department;
+
+	public Student(){}
+
+	public Student(String name)
+	{
+		this.name = name;
+	}
+
+	public Student(String name, List<Course> clist, List<Department> dlist)
+	{
+		this.name = name;
+		this.course = clist;
+		this.department = dlist;
+	}
+
+	public List<Course> getCourse() {
+		return course;
+	}
+
+	public void setCourse(List<Course> course) {
+		this.course = course;
+	}
+
+	public List<Department> getDepartment() {
+		return department;
+	}
+
+	public void setDepartment(List<Department> department) {
+		this.department = department;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java
index dfbf272..fe473bc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java
@@ -1,1216 +1,1216 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.utils;
-
-import java.util.Map;
-import java.util.Date;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Iterator;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.StringTokenizer;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.math.BigInteger;
-import java.math.BigDecimal;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ObjectInputStream;
-import java.io.StringWriter;
-import java.io.PrintWriter;
-import java.io.PrintStream;
-import java.net.URL;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-import javax.persistence.EntityManagerFactory;
-import javax.management.IntrospectionException;
-
-import org.apache.regexp.RESyntaxException;
-import org.apache.regexp.RE;
-import org.apache.regexp.REUtil;
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.meta.ClassMetaData;
-
-public abstract class AbstractTestCase extends PersistenceTestCase {
-
-    private String persistenceXmlResource;
-    private Map<Map,OpenJPAEntityManagerFactory> emfs =
-        new HashMap<Map,OpenJPAEntityManagerFactory>();
-    private OpenJPAEntityManager currentEntityManager;
-
-    protected enum Platform {
-        EMPRESS,
-        HYPERSONIC,
-        POSTGRESQL,
-        MYSQL,
-        SQLSERVER,
-        DB2,
-        ORACLE,
-        DERBY,
-        INFORMIX,
-        POINTBASE,
-        SYBASE,
-    }
-
-    protected String multiThreadExecuting = null;
-    protected boolean inTimeoutThread = false;
-
-
-    public AbstractTestCase(String name, String s) {
-        setName(name);
-        persistenceXmlResource = computePersistenceXmlResource(s);
-    }
-
-    public void tearDown() throws Exception {
-        try {
-            super.tearDown();
-        } finally {
-            for (EntityManagerFactory emf : emfs.values()) {
-                try {
-                    closeEMF(emf);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    public AbstractTestCase() {
-    }
-
-    public AbstractTestCase(String name) {
-        setName(name);
-    }
-
-    protected String computePersistenceXmlResource(String s) {
-        String resourceName = getClass().getPackage().getName()
-            .replaceAll("\\.", "/");
-        resourceName += "/common/apps/META-INF/persistence.xml";
-        URL resource = getClass().getClassLoader().getResource(resourceName);
-        if (resource != null)
-            return resourceName;
-        return defaultPersistenceXmlResource();
-    }
-
-    protected String defaultPersistenceXmlResource() {
-        return "org/apache/openjpa/persistence/" +
-            "common/apps/META-INF/persistence.xml";
-    }
-
-    protected OpenJPAStateManager getStateManager(Object obj,
-        EntityManager em) {
-        return JPAFacadeHelper.toBroker(em).getStateManager(obj);
-    }
-
-    protected int deleteAll(Class type, EntityManager em) {
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(em, type);
-        if (meta != null)
-            return em.createQuery("delete from " + meta.getTypeAlias())
-                .executeUpdate();
-        else
-            return -1;
-    }
-
-    protected int deleteAll(Class... types) {
-        EntityManager em = getEmf().createEntityManager();
-        em.getTransaction().begin();
-        int ret = 0;
-        for (Class type : types)
-            ret += deleteAll(type, em);
-        em.getTransaction().commit();
-        em.close();
-        return ret;
-    }
-
-    protected OpenJPAEntityManagerFactory getEmf(Map map) {
-        if (map == null)
-            map = new HashMap();
-        Collection keys = new ArrayList();
-        for (Object key : map.keySet())
-            if (key.toString().startsWith("kodo"))
-                keys.add(key);
-        if (keys.size() > 0)
-            throw new IllegalArgumentException(
-                "kodo-prefixed properties must be converted to openjpa. " +
-                    "Properties: " + keys);
-
-        addProperties(map);
-
-        OpenJPAEntityManagerFactory emf = emfs.get(map);
-        if (emf == null) {
-            emf = OpenJPAPersistence.createEntityManagerFactory(
-                "TestConv", persistenceXmlResource, map);
-            emfs.put(map, emf);
-        }
-        return emf;
-    }
-
-    protected void addProperties(Map map) {
-        if (!map.containsKey("openjpa.jdbc.SynchronizeMappings"))
-            map.put("openjpa.jdbc.SynchronizeMappings",
-                "buildSchema(ForeignKeys=true," +
-                    "SchemaAction='add,deleteTableContents')");
-    }
-
-    protected OpenJPAEntityManagerFactory getEmf() {
-        Map m = new HashMap();
-        return getEmf(m);
-    }
-
-    protected BrokerFactory getBrokerFactory() {
-        return JPAFacadeHelper.toBrokerFactory(getEmf());
-    }
-
-    protected BrokerFactory getBrokerFactory(String[] args) {
-        if (args.length % 2 != 0)
-            throw new IllegalArgumentException(
-                "odd number of elements in arg array");
-        Map map = new HashMap();
-        for (int i = 0; i < args.length; i = i + 2)
-            map.put(args[i], args[i+1]);
-        return JPAFacadeHelper.toBrokerFactory(getEmf(map));
-    }
-
-    protected OpenJPAEntityManager currentEntityManager() {
-        if (currentEntityManager == null || !currentEntityManager.isOpen())
-            currentEntityManager = getEmf().createEntityManager();
-        return currentEntityManager;
-    }
-
-    protected void startTx(EntityManager em) {
-        em.getTransaction().begin();
-    }
-
-    protected boolean isActiveTx(EntityManager em) {
-        return em.getTransaction().isActive();
-    }
-
-    protected void endTx(EntityManager em) {
-        if (em.getTransaction().isActive()) {
-            if (em.getTransaction().getRollbackOnly())
-                em.getTransaction().rollback();
-            else
-                em.getTransaction().commit();
-        }
-    }
-
-    protected void rollbackTx(EntityManager em) {
-        em.getTransaction().rollback();
-    }
-
-    protected void endEm(EntityManager em) {
-        if (em.isOpen())
-            em.close();
-        if (em == currentEntityManager)
-        currentEntityManager = null;
-    }
-
-    protected Object getStackTrace(Throwable t) {
-        throw new UnsupportedOperationException();
-    }
-
-    protected OpenJPAConfiguration getConfiguration() {
-        return getEmf().getConfiguration();
-    }
-
-    protected Platform getCurrentPlatform() {
-        throw new UnsupportedOperationException();
-    }
-
-    protected void bug(int id, String s) {
-        bug(id, null, s);
-    }
-    
-    protected void bug(Platform platform, int id, Throwable t, String s) {
-        bug(EnumSet.of(platform), id, t, s);
-    }
-
-    protected void bug(EnumSet<Platform> platforms, int id, Throwable t, String s) {
-        if (platforms.contains(getCurrentPlatform()))
-            bug(id, t, s);
-        else
-            fail(String.format(
-                "bug %s is unexpectedly occurring on platform %s",
-                id, getCurrentPlatform()));
-    }
-
-    protected void bug(int id, Throwable t, String s) {
-        if (t != null) {
-            if (t instanceof RuntimeException)
-                throw (RuntimeException) t;
-            else
-                throw new RuntimeException(t);
-        } else {
-            fail(s);
-        }
-    }
-
-    /**
-     * Support method to get a random Integer for testing.
-     */
-    public static Integer randomInt() {
-        return new Integer((int) (Math.random() * Integer.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Character for testing.
-     */
-    public static Character randomChar() {
-        char [] TEST_CHAR_ARRAY = new char []{
-            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
-            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
-            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
-            '2', '3', '4', '5', '6', '7', '8', '9' };
-
-        return new Character(TEST_CHAR_ARRAY[
-                (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
-    }
-
-    /**
-     * Support method to get a random Long for testing.
-     */
-    public static Long randomLong() {
-        return new Long((long) (Math.random() * Long.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Short for testing.
-     */
-    public static Short randomShort() {
-        return new Short((short) (Math.random() * Short.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Double for testing.
-     */
-    public static Double randomDouble() {
-        return new Double((double) (Math.round(Math.random() * 5000d)) / 1000d);
-    }
-
-    /**
-     * Support method to get a random Float for testing.
-     */
-    public static Float randomFloat() {
-        return new Float((float) (Math.round(Math.random() * 5000f)) / 1000f);
-    }
-
-    /**
-     * Support method to get a random Byte for testing.
-     */
-    public static Byte randomByte() {
-        return new Byte((byte) (Math.random() * Byte.MAX_VALUE));
-    }
-
-    /**
-     * Support method to get a random Boolean for testing.
-     */
-    public static Boolean randomBoolean() {
-        return new Boolean(Math.random() > 0.5 ? true : false);
-    }
-
-    /**
-     * Support method to get a random Date for testing.
-     */
-    public static Date randomDate() {
-        long millis = (long) (Math.random() * System.currentTimeMillis());
-
-        // round millis to the nearest 1000: this is because some
-        // databases do not store the milliseconds correctly (e.g., MySQL).
-        // This is a really a bug we should fix. FC #27.
-        millis -= (millis % 1000);
-
-        return new Date(millis);
-    }
-
-    /**
-     * Support method to get a random String for testing.
-     */
-    public static String randomString() {
-        // default to a small string, in case column sizes are
-        // limited (such as with a string primary key)
-        return randomString(50);
-    }
-
-    /**
-     * Support method to get a random String for testing.
-     */
-    public static String randomString(int len) {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
-            buf.append(randomChar());
-        return buf.toString();
-    }
-
-    /**
-     * Support method to get a random clob for testing.
-     */
-    public static String randomClob() {
-        StringBuffer sbuf = new StringBuffer();
-        while (sbuf.length() < (5 * 1024)) // at least 5K
-        {
-            sbuf.append(randomString(1024));
-        }
-
-        return sbuf.toString();
-    }
-
-    /**
-     * Support method to get a random BigInteger for testing.
-     */
-    public static BigInteger randomBigInteger() {
-        // too many of our test databases don't support bigints > MAX_LONG:
-        // I don't like it, but for now, let's only test below MAX_LONG
-        BigInteger lng = new BigInteger(
-                ((long) (Math.random() * Long.MAX_VALUE)) + "");
-
-        BigInteger multiplier = new BigInteger("1");
-        // (1 + (int)(Math.random () * 10000)) + "");
-        if (Math.random() < 0.5)
-            multiplier = multiplier.multiply(new BigInteger("-1"));
-
-        return lng.multiply(multiplier);
-    }
-
-    /**
-     * Support method to get a random BigDecimal for testing.
-     */
-    public static BigDecimal randomBigDecimal() {
-        BigInteger start = randomBigInteger();
-        String str = start.toString();
-        // truncate off the last 8 digits: we still get some
-        // overflows with lame databases.
-        for (int i = 0; i < 8; i++)
-            if (str.length() > 2)
-                str = str.substring(0, str.length() - 1);
-        start = new BigInteger(str);
-
-        String val = start + "."
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10))
-                + ((int) (Math.random() * 10));
-
-        return new BigDecimal(val);
-    }
-
-    /**
-     * Support method to get a random blob for testing.
-     */
-    public static byte[] randomBlob() {
-        // up to 100K blob
-        byte [] blob = new byte [(int) (Math.random() * 1024 * 100)];
-        for (int i = 0; i < blob.length; i++)
-            blob[i] = randomByte().byteValue();
-
-        return blob;
-    }
-
-    /**
-     * Invoke setters for pimitives and primitive wrappers on the
-     * specified object.
-     */
-    public static Object randomizeBean(Object bean)
-    throws IntrospectionException, IllegalAccessException,
-        InvocationTargetException, java.beans.IntrospectionException {
-        BeanInfo info = Introspector.getBeanInfo(bean.getClass());
-        PropertyDescriptor[] props = info.getPropertyDescriptors();
-        for (int i = 0; i < props.length; i++) {
-            Method write = props[i].getWriteMethod();
-            if (write == null)
-                continue;
-
-            Class [] params = write.getParameterTypes();
-            if (params == null || params.length != 1)
-                continue;
-
-            Class paramType = params[0];
-            Object arg = null;
-
-            if (paramType == boolean.class || paramType == Boolean.class)
-                arg = randomBoolean();
-            else if (paramType == byte.class || paramType == Byte.class)
-                arg = randomByte();
-            else if (paramType == char.class || paramType == Character.class)
-                arg = randomChar();
-            else if (paramType == short.class || paramType == Short.class)
-                arg = randomShort();
-            else if (paramType == int.class || paramType == Integer.class)
-                arg = randomInt();
-            else if (paramType == long.class || paramType == Long.class)
-                arg = randomLong();
-            else if (paramType == double.class || paramType == Double.class)
-                arg = randomDouble();
-            else if (paramType == float.class || paramType == Float.class)
-                arg = randomFloat();
-            else if (paramType == String.class)
-                arg = randomString();
-            else if (paramType == BigInteger.class)
-                arg = randomBigInteger();
-            else if (paramType == BigDecimal.class)
-                arg = randomBigDecimal();
-            else if (paramType == Date.class)
-                arg = randomDate();
-
-            if (arg != null)
-                write.invoke(bean, new Object []{ arg });
-        }
-
-        return bean;
-    }
-
-    protected void assertSize(int size, Collection c) {
-        assertEquals(size, c.size());
-    }
-
-    protected void assertSize(int size, Query q) {
-        assertEquals(size, q.getResultList().size());
-    }
-
-    /**
-     * Serialize and deserialize the object.
-     *
-     * @param validateEquality make sure the hashCode and equals
-     * methods hold true
-     */
-    public static Object roundtrip(Object orig, boolean validateEquality)
-        throws IOException, ClassNotFoundException {
-        assertNotNull(orig);
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(bout);
-        out.writeObject(orig);
-        ByteArrayInputStream bin = new ByteArrayInputStream(
-            bout.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bin);
-        Object result = in.readObject();
-
-        if (validateEquality) {
-            assertEquals(orig.hashCode(), result.hashCode());
-            assertEquals(orig, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * @return true if the specified input matches the regular expression regex.
-     */
-    public static boolean matches(String regex, String input)
-        throws RESyntaxException {
-        RE re = REUtil.createRE(regex);
-        return re.match(input);
-    }
-
-    public static void assertMatches(String regex, String input) {
-        try {
-            if (!(matches(regex, input)))
-                fail("Expected regular expression: <" + regex + ">"
-                    + " did not match: <" + input + ">");
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    public static void assertNotMatches(String regex, String input) {
-        try {
-            if (matches(regex, input))
-                fail("Regular expression: <" + regex + ">"
-                    + " should not match: <" + input + ">");
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    /**
-     * Check the list if strings and return the ones that match
-     * the specified match.
-     */
-    public static List matches(String regex, Collection input)
-        throws RESyntaxException {
-        List matches = new ArrayList();
-        for (Iterator i = input.iterator(); i.hasNext();) {
-            String check = (String) i.next();
-            if (matches(regex, check))
-                matches.add(check);
-        }
-
-        return matches;
-    }
-
-    /**
-     * Assert that the specified collection of Strings contains at least
-     * one string that matches the specified regular expression.
-     */
-    public static void assertMatches(String regex, Collection input) {
-        try {
-            if (matches(regex, input).size() == 0)
-                fail("The specified list of size " + input.size()
-                    + " did not contain any strings that match the"
-                    + " specified regular expression(\"" + regex + "\")");
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    /**
-     * Assert that the specified collection of Strings does not match
-     * the specified regular expression.
-     */
-    public static void assertNotMatches(String regex, Collection input) {
-        try {
-            List matches;
-
-            if (((matches = matches(regex, input))).size() > 0)
-                fail("The specified list of size " + input.size()
-                    + " did contain one or more strings that matchs the"
-                    + " specified illegal regular expression"
-                    + " (\"" + regex + "\")."
-                    + " First example of a matching message is: "
-                    + matches.iterator().next());
-        } catch (RESyntaxException e) {
-            throw new IllegalArgumentException(e.toString());
-        }
-    }
-
-    protected Log getLog() {
-        return getConfiguration().getLog("Tests");
-    }
-
-    ///////////////////
-    // Multi threading
-    ///////////////////
-
-    /**
-     * Re-execute the invoking method a random number of times
-     * in a random number of Threads.
-     */
-    public void mttest() throws ThreadingException {
-        // 6 iterations in 8 threads is a good trade-off between
-        // tests taking way too long and having a decent chance of
-        // identifying MT problems.
-        int iterations = 6;
-        int threads = 8;
-
-        mttest(threads, iterations);
-    }
-
-    /**
-     * Execute the calling method <code>iterations</code>
-     * times in <code>threads</code> Threads.
-     */
-    public void mttest(int threads, int iterations) {
-        mttest(0, threads, iterations);
-    }
-
-    public void mttest(int serialCount, int threads, int iterations)
-        throws ThreadingException {
-        String methodName = callingMethod("mttest");
-        mttest(serialCount, threads, iterations, methodName, new Object [0]);
-    }
-
-    /**
-     * Execute a test method in multiple threads.
-     *
-     * @param threads the number of Threads to run in
-     * @param iterations the number of times the method should
-     * be execute in a single Thread
-     * @param method the name of the method to execute
-     * @param args the arguments to pass to the method
-     * @throws ThreadingException if an errors occur in
-     * any of the Threads. The actual exceptions
-     * will be embedded in the exception. Note that
-     * this means that assert() failures will be
-     * treated as errors rather than warnings.
-     * @author Marc Prud'hommeaux
-     */
-    public void mttest(int threads, int iterations, final String method,
-        final Object [] args) throws ThreadingException {
-        mttest(0, threads, iterations, method, args);
-    }
-
-    public void mttest(int serialCount,
-        int threads, int iterations, final String method, final Object [] args)
-        throws ThreadingException {
-        if (multiThreadExecuting != null && multiThreadExecuting.equals(method))
-        {
-            // we are currently executing in multi-threaded mode:
-            // don't deadlock!
-            return;
-        }
-
-        multiThreadExecuting = method;
-
-        try {
-            Class [] paramClasses = new Class [args.length];
-            for (int i = 0; i < paramClasses.length; i++)
-                paramClasses[i] = args[i].getClass();
-
-            final Method meth;
-
-            try {
-                meth = getClass().getMethod(method, paramClasses);
-            } catch (NoSuchMethodException nsme) {
-                throw new ThreadingException(nsme.toString(), nsme);
-            }
-
-            final Object thiz = this;
-
-            mttest("reflection invocation: (" + method + ")",
-                serialCount, threads, iterations, new VolatileRunnable() {
-                public void run() throws Exception {
-                    meth.invoke(thiz, args);
-                }
-            });
-        } finally {
-            multiThreadExecuting = null;
-        }
-    }
-
-    public void mttest(String title, final int threads, final int iterations,
-        final VolatileRunnable runner) throws ThreadingException {
-        mttest(title, 0, threads, iterations, runner);
-    }
-
-    /**
-     * Execute a test method in multiple threads.
-     *
-     * @param title a description of the test, for inclusion in the
-     * error message
-     * @param serialCount the number of times to run the method
-     * serially before spawning threads.
-     * @param threads the number of Threads to run in
-     * @param iterations the number of times the method should
-     * @param runner the VolatileRunnable that will execute
-     * the actual test from within the Thread.
-     * @throws ThreadingException if an errors occur in
-     * any of the Threads. The actual exceptions
-     * will be embedded in the exception. Note that
-     * this means that assert() failures will be
-     * treated as errors rather than warnings.
-     * @author Marc Prud'hommeaux be execute in a single Thread
-     * @author Marc Prud'hommeaux
-     */
-    public void mttest(String title, final int serialCount,
-        final int threads, final int iterations, final VolatileRunnable runner)
-        throws ThreadingException {
-        final List exceptions = Collections.synchronizedList(new LinkedList());
-
-        Thread [] runners = new Thread [threads];
-
-        final long startMillis = System.currentTimeMillis() + 1000;
-
-        for (int i = 1; i <= threads; i++) {
-            final int thisThread = i;
-
-            runners[i - 1] =
-                new Thread(title + " [" + i + " of " + threads + "]") {
-                    public void run() {
-                        // do our best to have all threads start at the exact
-                        // same time. This is imperfect, but the closer we
-                        // get to everyone starting at the same time, the
-                        // better chance we have for identifying MT problems.
-                        while (System.currentTimeMillis() < startMillis)
-                            yield();
-
-                        int thisIteration = 1;
-                        try {
-                            for (; thisIteration <= iterations; thisIteration++)
-                            {
-                                // go go go!
-                                runner.run();
-                            }
-                        } catch (Throwable error) {
-                            synchronized (exceptions) {
-                                // embed the exception into something that gives
-                                // us some more information about the threading
-                                // environment
-                                exceptions.add(new ThreadingException("thread="
-                                    + this.toString()
-                                    + ";threadNum=" + thisThread
-                                    + ";maxThreads=" + threads
-                                    + ";iteration=" + thisIteration
-                                    + ";maxIterations=" + iterations, error));
-                            }
-                        }
-                    }
-                };
-        }
-
-        // start the serial tests(does not spawn the threads)
-        for (int i = 0; i < serialCount; i++) {
-            runners[0].run();
-        }
-
-        // start the multithreaded
-        for (int i = 0; i < threads; i++) {
-            runners[i].start();
-        }
-
-        // wait for them all to complete
-        for (int i = 0; i < threads; i++) {
-            try {
-                runners[i].join();
-            } catch (InterruptedException e) {
-            }
-        }
-
-        if (exceptions.size() == 0)
-            return; // sweeeeeeeet: no errors
-
-        // embed all the exceptions that were throws into a
-        // ThreadingException
-        Throwable [] errors = (Throwable []) exceptions.toArray(
-            new Throwable [0]);
-        throw new ThreadingException("The "
-            + errors.length + " embedded errors "
-            + "occured in the execution of " + iterations + " iterations "
-            + "of " + threads + " threads: [" + title + "]", errors);
-    }
-
-    /**
-     * Check to see if we are in the top-level execution stack.
-     */
-    public boolean isRootThread() {
-        return multiThreadExecuting == null;
-    }
-
-    /**
-     * A Runnable that can throw an Exception: used to test cases.
-     */
-    public static interface VolatileRunnable {
-
-        public void run() throws Exception;
-    }
-
-    /**
-     * Exception for errors caught during threading tests.
-     */
-    public class ThreadingException extends RuntimeException {
-
-        private final Throwable[] _nested;
-
-        public ThreadingException(String msg, Throwable nested) {
-            super(msg);
-            if (nested == null)
-                _nested = new Throwable[0];
-            else
-                _nested = new Throwable[]{ nested };
-        }
-
-        public ThreadingException(String msg, Throwable[] nested) {
-            super(msg);
-            if (nested == null)
-                _nested = new Throwable[0];
-            else
-                _nested = nested;
-        }
-
-        public void printStackTrace() {
-            printStackTrace(System.out);
-        }
-
-        public void printStackTrace(PrintStream out) {
-            printStackTrace(new PrintWriter(out));
-        }
-
-        public void printStackTrace(PrintWriter out) {
-            super.printStackTrace(out);
-            for (int i = 0; i < _nested.length; i++) {
-                out.print("Nested Throwable #" + (i + 1) + ": ");
-                _nested[i].printStackTrace(out);
-            }
-        }
-    }
-
-    /**
-     * Return the last method name that called this one by
-     * parsing the current stack trace.
-     *
-     * @param exclude a method name to skip
-     * @throws IllegalStateException If the calling method could not be
-     * identified.
-     * @author Marc Prud'hommeaux
-     */
-    public String callingMethod(String exclude) {
-        // determine the currently executing method by
-        // looking at the stack track. Hackish, but convenient.
-        StringWriter sw = new StringWriter();
-        new Exception().printStackTrace(new PrintWriter(sw));
-        for (StringTokenizer stackTrace = new StringTokenizer(sw.toString(),
-            System.getProperty("line.separator"));
-            stackTrace.hasMoreTokens();) {
-            String line = stackTrace.nextToken().trim();
-
-            // not a stack trace element
-            if (!(line.startsWith("at ")))
-                continue;
-
-            String fullMethodName = line.substring(0, line.indexOf("("));
-
-            String shortMethodName = fullMethodName.substring(
-                fullMethodName.lastIndexOf(".") + 1);
-
-            // skip our own methods!
-            if (shortMethodName.equals("callingMethod"))
-                continue;
-            if (exclude != null && shortMethodName.equals(exclude))
-                continue;
-
-            return shortMethodName;
-        }
-
-        throw new IllegalStateException("Could not identify calling "
-            + "method in stack trace");
-    }
-
-    //////////
-    // Timing
-    //////////
-
-    /**
-     * Sleep the current Thread for a random amount of time from 0-1000 ms.
-     */
-    public void sleepRandom() {
-        sleepRandom(1000);
-    }
-
-    /**
-     * Sleep the current Thread for a random amount of time from
-     * 0-<code>max</code> ms.
-     */
-    public void sleepRandom(int max) {
-        try {
-            Thread.currentThread().sleep((long) (Math.random() * max));
-        } catch (InterruptedException ex) {
-        }
-    }
-
-    /**
-     * Re-run this method in the current thread, timing out
-     * after the specified number of seconds.
-     * Usage:
-     * <pre> public void timeOutOperation() { if (timeout(5 * 1000)) return;
-     *  Thread.currentThread().sleep(10 * 1000); }
-     * </pre>
-     * <p/>
-     * <p/>
-     * <strong>Warning</strong> this method should be used sparingly,
-     * and only when you expect that a timeout will <strong>not</strong>
-     * occur. It utilized the deprecated {@link Thread#stop()} and
-     * {@link Thread#interrupt} methods, which can leave monitors in an
-     * invalid state. It is only used because it provides more
-     * meaningful information than just seeing that the entire autobuild
-     * timed out.
-     *
-     * @param millis the number of milliseconds we should wait.
-     * @return true if we are are in the thread that requested the
-     *         timeout, false if we are in the timeout thread itself.
-     */
-    public boolean timeout(long millis) throws Throwable {
-        String methodName = callingMethod("timeout");
-        return timeout(millis, methodName);
-    }
-
-    /**
-     * @see #timeout(long)
-     */
-    public boolean timeout(long millis, String methodName) throws Throwable {
-        // we are in the timing out-thread: do nothing so the
-        // actual test method can run
-        if (inTimeoutThread)
-            return false;
-
-        inTimeoutThread = true;
-        long endTime = System.currentTimeMillis() + millis;
-
-        try {
-            final Method method = getClass().
-                getMethod(methodName, (Class[]) null);
-            final Object thz = this;
-
-            // spawn thread
-            TimeOutThread tot = new TimeOutThread("TimeOutThread ["
-                + methodName + "] (" + millis + "ms)") {
-                public void run() {
-                    try {
-                        method.invoke(thz, (Object[]) null);
-                    } catch (Throwable t) {
-                        throwable = t;
-                    } finally {
-                        completed = true;
-                    }
-                }
-            };
-
-            tot.start();
-
-            // wait for the completion or a timeout to occur
-            tot.join(millis);
-
-            // have we timed out? Kill the thread and throw an exception
-            if (System.currentTimeMillis() >= endTime) {
-                // if we are waiting on a monitor, this will give
-                // us a useful stack trace.
-                try {
-                    tot.interrupt();
-                } catch (Throwable e) {
-                }
-                Thread.currentThread().sleep(500);
-
-                // try to kill the thread
-                try {
-                    tot.stop();
-                } catch (Throwable e) {
-                }
-                Thread.currentThread().sleep(500);
-
-                throw new OperationTimedOutException("Execution of \""
-                    + methodName + "\" timed out after "
-                    + millis + " milliseconds", tot.throwable);
-            }
-
-            // throw any exceptions that may have occured
-            if (tot.throwable != null)
-                throw tot.throwable;
-
-            // I guess everything was OK
-            return true;
-        } finally {
-            inTimeoutThread = false;
-        }
-    }
-
-    private static class TimeOutThread extends Thread {
-
-        public Throwable throwable = null;
-        public boolean completed = false;
-
-        public TimeOutThread(String name) {
-            super(name);
-            setDaemon(true);
-        }
-    }
-
-    /**
-     * Indicates that a timeout occured.
-     */
-    public static class OperationTimedOutException extends RuntimeException {
-
-        private final Throwable _err;
-
-        public OperationTimedOutException(String msg, Throwable throwable) {
-            super(msg);
-            _err = throwable;
-        }
-
-        public void printStackTrace() {
-            printStackTrace(System.out);
-        }
-
-        public void printStackTrace(PrintStream out) {
-            printStackTrace(new PrintWriter(out));
-        }
-
-        public void printStackTrace(PrintWriter out) {
-            super.printStackTrace(out);
-            if (_err != null) {
-                out.print("Nested Throwable: ");
-                _err.printStackTrace(out);
-            }
-        }
-    }
-
-    ///////////////
-    // Collections
-    ///////////////
-
-    /**
-     * Validate that the specified {@link Collection} fulfills the
-     * Collection contract as specified by the Collections API.
-     * <p/>
-     * <strong>Note</strong>: does not validate mutable operations
-     */
-    public static void validateCollection(Collection collection) {
-        int size = collection.size();
-        int iterated = 0;
-        // ensure we can walk along the iterator
-        for (Iterator i = collection.iterator(); i.hasNext();) {
-            iterated++;
-            i.next();
-        }
-
-        // ensure the number of values iterated is the same as the list size
-        assertEquals(size, iterated);
-
-        // also validate the list
-        if (collection instanceof List) {
-            List ll = new ArrayList();
-            for (int i = 0; i < 100; i++)
-                ll.add(new Integer(i));
-            validateList((List) ll);
-            validateList((List) collection);
-        }
-    }
-
-    /**
-     * Validate that the specified {@link List} fulfills the
-     * List contract as specified by the Collections API.
-     * <p/>
-     * <strong>Note</strong>: does not validate mutable operations
-     */
-    public static void validateList(List list) {
-        Object [] coreValues = list.toArray();
-        Object [] values1 = new Object [list.size()];
-        Object [] values2 = new Object [list.size()];
-        Object [] values3 = new Object [list.size()];
-        Object [] values4 = new Object [list.size()];
-
-        // fill sequential index access list
-        for (int i = 0; i < list.size(); i++)
-            values1[i] = list.get(i);
-
-        // fill sequential list
-        int index = 0;
-        ListIterator iter;
-        for (iter = list.listIterator(0); iter.hasNext();) {
-            assertEquals(index, iter.nextIndex());
-            assertEquals(index, iter.previousIndex() + 1);
-            values2[index] = iter.next();
-            assertTrue(list.contains(values2[index]));
-            index++;
-        }
-
-        // ensure NoSuchElementException is thrown as appropriate
-        try {
-            iter.next();
-            fail("next() should have resulted in a NoSuchElementException");
-        } catch (NoSuchElementException e) {
-        } // as expected
-
-        // fill reverse sequential list
-        int back = 0;
-        for (iter = list.listIterator(list.size()); iter.hasPrevious();) {
-            assertEquals(index, iter.previousIndex() + 1);
-            assertEquals(index, iter.nextIndex());
-            values3[--index] = iter.previous();
-            back++;
-        }
-        assertEquals(list.size(), back);
-
-        // ensure NoSuchElementException is thrown as appropriate
-        try {
-            iter.previous();
-            fail("previous() should have resulted in a "
-                + "NoSuchElementException");
-        } catch (NoSuchElementException e) {
-        } // as expected
-
-        // fill random access list
-        List indices = new LinkedList();
-        for (int i = 0; i < list.size(); i++)
-            indices.add(new Integer(i));
-
-        for (int i = 0; i < list.size(); i++) {
-            int rand = (int) (Math.random() * indices.size());
-            Integer randIndex = (Integer) indices.remove(rand);
-            values4[randIndex.intValue()] = list.get(randIndex.intValue());
-        }
-
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values1));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values1));
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values2));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values2));
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values4));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values4));
-        assertEquals(Arrays.asList(coreValues), Arrays.asList(values3));
-        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values3));
-    }
-
-    /**
-     * Assert that the given List contain the exact same
-     * elements. This is different than the normal List contract, which
-     * states that list1.equals(list2) if each element e1.equals(e2).
-     * This method asserts that e1 == n2.
-     */
-    public static void assertIdentical(List c1, List c2) {
-        assertEquals(c1.size(), c2.size());
-        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
-            i1.hasNext() && i2.hasNext();)
-            assertTrue(i1.next() == i2.next());
-    }
-
-    /**
-     * Assert that the collection parameter is already ordered
-     * according to the specified comparator.
-     */
-    public void assertOrdered(Collection c, Comparator comp) {
-        List l1 = new LinkedList(c);
-        List l2 = new LinkedList(c);
-        assertEquals(l1, l2);
-        Collections.sort(l2, comp);
-        assertEquals(l1, l2);
-        Collections.sort(l1, comp);
-        assertEquals(l1, l2);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.utils;
+
+import java.util.Map;
+import java.util.Date;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.math.BigInteger;
+import java.math.BigDecimal;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+import java.io.PrintStream;
+import java.net.URL;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.EntityManagerFactory;
+import javax.management.IntrospectionException;
+
+import org.apache.regexp.RESyntaxException;
+import org.apache.regexp.RE;
+import org.apache.regexp.REUtil;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.meta.ClassMetaData;
+
+public abstract class AbstractTestCase extends PersistenceTestCase {
+
+    private String persistenceXmlResource;
+    private Map<Map,OpenJPAEntityManagerFactory> emfs =
+        new HashMap<Map,OpenJPAEntityManagerFactory>();
+    private OpenJPAEntityManager currentEntityManager;
+
+    protected enum Platform {
+        EMPRESS,
+        HYPERSONIC,
+        POSTGRESQL,
+        MYSQL,
+        SQLSERVER,
+        DB2,
+        ORACLE,
+        DERBY,
+        INFORMIX,
+        POINTBASE,
+        SYBASE,
+    }
+
+    protected String multiThreadExecuting = null;
+    protected boolean inTimeoutThread = false;
+
+
+    public AbstractTestCase(String name, String s) {
+        setName(name);
+        persistenceXmlResource = computePersistenceXmlResource(s);
+    }
+
+    public void tearDown() throws Exception {
+        try {
+            super.tearDown();
+        } finally {
+            for (EntityManagerFactory emf : emfs.values()) {
+                try {
+                    closeEMF(emf);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public AbstractTestCase() {
+    }
+
+    public AbstractTestCase(String name) {
+        setName(name);
+    }
+
+    protected String computePersistenceXmlResource(String s) {
+        String resourceName = getClass().getPackage().getName()
+            .replaceAll("\\.", "/");
+        resourceName += "/common/apps/META-INF/persistence.xml";
+        URL resource = getClass().getClassLoader().getResource(resourceName);
+        if (resource != null)
+            return resourceName;
+        return defaultPersistenceXmlResource();
+    }
+
+    protected String defaultPersistenceXmlResource() {
+        return "org/apache/openjpa/persistence/" +
+            "common/apps/META-INF/persistence.xml";
+    }
+
+    protected OpenJPAStateManager getStateManager(Object obj,
+        EntityManager em) {
+        return JPAFacadeHelper.toBroker(em).getStateManager(obj);
+    }
+
+    protected int deleteAll(Class type, EntityManager em) {
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(em, type);
+        if (meta != null)
+            return em.createQuery("delete from " + meta.getTypeAlias())
+                .executeUpdate();
+        else
+            return -1;
+    }
+
+    protected int deleteAll(Class... types) {
+        EntityManager em = getEmf().createEntityManager();
+        em.getTransaction().begin();
+        int ret = 0;
+        for (Class type : types)
+            ret += deleteAll(type, em);
+        em.getTransaction().commit();
+        em.close();
+        return ret;
+    }
+
+    protected OpenJPAEntityManagerFactory getEmf(Map map) {
+        if (map == null)
+            map = new HashMap();
+        Collection keys = new ArrayList();
+        for (Object key : map.keySet())
+            if (key.toString().startsWith("kodo"))
+                keys.add(key);
+        if (keys.size() > 0)
+            throw new IllegalArgumentException(
+                "kodo-prefixed properties must be converted to openjpa. " +
+                    "Properties: " + keys);
+
+        addProperties(map);
+
+        OpenJPAEntityManagerFactory emf = emfs.get(map);
+        if (emf == null) {
+            emf = OpenJPAPersistence.createEntityManagerFactory(
+                "TestConv", persistenceXmlResource, map);
+            emfs.put(map, emf);
+        }
+        return emf;
+    }
+
+    protected void addProperties(Map map) {
+        if (!map.containsKey("openjpa.jdbc.SynchronizeMappings"))
+            map.put("openjpa.jdbc.SynchronizeMappings",
+                "buildSchema(ForeignKeys=true," +
+                    "SchemaAction='add,deleteTableContents')");
+    }
+
+    protected OpenJPAEntityManagerFactory getEmf() {
+        Map m = new HashMap();
+        return getEmf(m);
+    }
+
+    protected BrokerFactory getBrokerFactory() {
+        return JPAFacadeHelper.toBrokerFactory(getEmf());
+    }
+
+    protected BrokerFactory getBrokerFactory(String[] args) {
+        if (args.length % 2 != 0)
+            throw new IllegalArgumentException(
+                "odd number of elements in arg array");
+        Map map = new HashMap();
+        for (int i = 0; i < args.length; i = i + 2)
+            map.put(args[i], args[i+1]);
+        return JPAFacadeHelper.toBrokerFactory(getEmf(map));
+    }
+
+    protected OpenJPAEntityManager currentEntityManager() {
+        if (currentEntityManager == null || !currentEntityManager.isOpen())
+            currentEntityManager = getEmf().createEntityManager();
+        return currentEntityManager;
+    }
+
+    protected void startTx(EntityManager em) {
+        em.getTransaction().begin();
+    }
+
+    protected boolean isActiveTx(EntityManager em) {
+        return em.getTransaction().isActive();
+    }
+
+    protected void endTx(EntityManager em) {
+        if (em.getTransaction().isActive()) {
+            if (em.getTransaction().getRollbackOnly())
+                em.getTransaction().rollback();
+            else
+                em.getTransaction().commit();
+        }
+    }
+
+    protected void rollbackTx(EntityManager em) {
+        em.getTransaction().rollback();
+    }
+
+    protected void endEm(EntityManager em) {
+        if (em.isOpen())
+            em.close();
+        if (em == currentEntityManager)
+        currentEntityManager = null;
+    }
+
+    protected Object getStackTrace(Throwable t) {
+        throw new UnsupportedOperationException();
+    }
+
+    protected OpenJPAConfiguration getConfiguration() {
+        return getEmf().getConfiguration();
+    }
+
+    protected Platform getCurrentPlatform() {
+        throw new UnsupportedOperationException();
+    }
+
+    protected void bug(int id, String s) {
+        bug(id, null, s);
+    }
+    
+    protected void bug(Platform platform, int id, Throwable t, String s) {
+        bug(EnumSet.of(platform), id, t, s);
+    }
+
+    protected void bug(EnumSet<Platform> platforms, int id, Throwable t, String s) {
+        if (platforms.contains(getCurrentPlatform()))
+            bug(id, t, s);
+        else
+            fail(String.format(
+                "bug %s is unexpectedly occurring on platform %s",
+                id, getCurrentPlatform()));
+    }
+
+    protected void bug(int id, Throwable t, String s) {
+        if (t != null) {
+            if (t instanceof RuntimeException)
+                throw (RuntimeException) t;
+            else
+                throw new RuntimeException(t);
+        } else {
+            fail(s);
+        }
+    }
+
+    /**
+     * Support method to get a random Integer for testing.
+     */
+    public static Integer randomInt() {
+        return new Integer((int) (Math.random() * Integer.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Character for testing.
+     */
+    public static Character randomChar() {
+        char [] TEST_CHAR_ARRAY = new char []{
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
+            '2', '3', '4', '5', '6', '7', '8', '9' };
+
+        return new Character(TEST_CHAR_ARRAY[
+                (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
+    }
+
+    /**
+     * Support method to get a random Long for testing.
+     */
+    public static Long randomLong() {
+        return new Long((long) (Math.random() * Long.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Short for testing.
+     */
+    public static Short randomShort() {
+        return new Short((short) (Math.random() * Short.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Double for testing.
+     */
+    public static Double randomDouble() {
+        return new Double((double) (Math.round(Math.random() * 5000d)) / 1000d);
+    }
+
+    /**
+     * Support method to get a random Float for testing.
+     */
+    public static Float randomFloat() {
+        return new Float((float) (Math.round(Math.random() * 5000f)) / 1000f);
+    }
+
+    /**
+     * Support method to get a random Byte for testing.
+     */
+    public static Byte randomByte() {
+        return new Byte((byte) (Math.random() * Byte.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Boolean for testing.
+     */
+    public static Boolean randomBoolean() {
+        return new Boolean(Math.random() > 0.5 ? true : false);
+    }
+
+    /**
+     * Support method to get a random Date for testing.
+     */
+    public static Date randomDate() {
+        long millis = (long) (Math.random() * System.currentTimeMillis());
+
+        // round millis to the nearest 1000: this is because some
+        // databases do not store the milliseconds correctly (e.g., MySQL).
+        // This is a really a bug we should fix. FC #27.
+        millis -= (millis % 1000);
+
+        return new Date(millis);
+    }
+
+    /**
+     * Support method to get a random String for testing.
+     */
+    public static String randomString() {
+        // default to a small string, in case column sizes are
+        // limited (such as with a string primary key)
+        return randomString(50);
+    }
+
+    /**
+     * Support method to get a random String for testing.
+     */
+    public static String randomString(int len) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
+            buf.append(randomChar());
+        return buf.toString();
+    }
+
+    /**
+     * Support method to get a random clob for testing.
+     */
+    public static String randomClob() {
+        StringBuffer sbuf = new StringBuffer();
+        while (sbuf.length() < (5 * 1024)) // at least 5K
+        {
+            sbuf.append(randomString(1024));
+        }
+
+        return sbuf.toString();
+    }
+
+    /**
+     * Support method to get a random BigInteger for testing.
+     */
+    public static BigInteger randomBigInteger() {
+        // too many of our test databases don't support bigints > MAX_LONG:
+        // I don't like it, but for now, let's only test below MAX_LONG
+        BigInteger lng = new BigInteger(
+                ((long) (Math.random() * Long.MAX_VALUE)) + "");
+
+        BigInteger multiplier = new BigInteger("1");
+        // (1 + (int)(Math.random () * 10000)) + "");
+        if (Math.random() < 0.5)
+            multiplier = multiplier.multiply(new BigInteger("-1"));
+
+        return lng.multiply(multiplier);
+    }
+
+    /**
+     * Support method to get a random BigDecimal for testing.
+     */
+    public static BigDecimal randomBigDecimal() {
+        BigInteger start = randomBigInteger();
+        String str = start.toString();
+        // truncate off the last 8 digits: we still get some
+        // overflows with lame databases.
+        for (int i = 0; i < 8; i++)
+            if (str.length() > 2)
+                str = str.substring(0, str.length() - 1);
+        start = new BigInteger(str);
+
+        String val = start + "."
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10));
+
+        return new BigDecimal(val);
+    }
+
+    /**
+     * Support method to get a random blob for testing.
+     */
+    public static byte[] randomBlob() {
+        // up to 100K blob
+        byte [] blob = new byte [(int) (Math.random() * 1024 * 100)];
+        for (int i = 0; i < blob.length; i++)
+            blob[i] = randomByte().byteValue();
+
+        return blob;
+    }
+
+    /**
+     * Invoke setters for pimitives and primitive wrappers on the
+     * specified object.
+     */
+    public static Object randomizeBean(Object bean)
+    throws IntrospectionException, IllegalAccessException,
+        InvocationTargetException, java.beans.IntrospectionException {
+        BeanInfo info = Introspector.getBeanInfo(bean.getClass());
+        PropertyDescriptor[] props = info.getPropertyDescriptors();
+        for (int i = 0; i < props.length; i++) {
+            Method write = props[i].getWriteMethod();
+            if (write == null)
+                continue;
+
+            Class [] params = write.getParameterTypes();
+            if (params == null || params.length != 1)
+                continue;
+
+            Class paramType = params[0];
+            Object arg = null;
+
+            if (paramType == boolean.class || paramType == Boolean.class)
+                arg = randomBoolean();
+            else if (paramType == byte.class || paramType == Byte.class)
+                arg = randomByte();
+            else if (paramType == char.class || paramType == Character.class)
+                arg = randomChar();
+            else if (paramType == short.class || paramType == Short.class)
+                arg = randomShort();
+            else if (paramType == int.class || paramType == Integer.class)
+                arg = randomInt();
+            else if (paramType == long.class || paramType == Long.class)
+                arg = randomLong();
+            else if (paramType == double.class || paramType == Double.class)
+                arg = randomDouble();
+            else if (paramType == float.class || paramType == Float.class)
+                arg = randomFloat();
+            else if (paramType == String.class)
+                arg = randomString();
+            else if (paramType == BigInteger.class)
+                arg = randomBigInteger();
+            else if (paramType == BigDecimal.class)
+                arg = randomBigDecimal();
+            else if (paramType == Date.class)
+                arg = randomDate();
+
+            if (arg != null)
+                write.invoke(bean, new Object []{ arg });
+        }
+
+        return bean;
+    }
+
+    protected void assertSize(int size, Collection c) {
+        assertEquals(size, c.size());
+    }
+
+    protected void assertSize(int size, Query q) {
+        assertEquals(size, q.getResultList().size());
+    }
+
+    /**
+     * Serialize and deserialize the object.
+     *
+     * @param validateEquality make sure the hashCode and equals
+     * methods hold true
+     */
+    public static Object roundtrip(Object orig, boolean validateEquality)
+        throws IOException, ClassNotFoundException {
+        assertNotNull(orig);
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.writeObject(orig);
+        ByteArrayInputStream bin = new ByteArrayInputStream(
+            bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bin);
+        Object result = in.readObject();
+
+        if (validateEquality) {
+            assertEquals(orig.hashCode(), result.hashCode());
+            assertEquals(orig, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * @return true if the specified input matches the regular expression regex.
+     */
+    public static boolean matches(String regex, String input)
+        throws RESyntaxException {
+        RE re = REUtil.createRE(regex);
+        return re.match(input);
+    }
+
+    public static void assertMatches(String regex, String input) {
+        try {
+            if (!(matches(regex, input)))
+                fail("Expected regular expression: <" + regex + ">"
+                    + " did not match: <" + input + ">");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    public static void assertNotMatches(String regex, String input) {
+        try {
+            if (matches(regex, input))
+                fail("Regular expression: <" + regex + ">"
+                    + " should not match: <" + input + ">");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * Check the list if strings and return the ones that match
+     * the specified match.
+     */
+    public static List matches(String regex, Collection input)
+        throws RESyntaxException {
+        List matches = new ArrayList();
+        for (Iterator i = input.iterator(); i.hasNext();) {
+            String check = (String) i.next();
+            if (matches(regex, check))
+                matches.add(check);
+        }
+
+        return matches;
+    }
+
+    /**
+     * Assert that the specified collection of Strings contains at least
+     * one string that matches the specified regular expression.
+     */
+    public static void assertMatches(String regex, Collection input) {
+        try {
+            if (matches(regex, input).size() == 0)
+                fail("The specified list of size " + input.size()
+                    + " did not contain any strings that match the"
+                    + " specified regular expression(\"" + regex + "\")");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * Assert that the specified collection of Strings does not match
+     * the specified regular expression.
+     */
+    public static void assertNotMatches(String regex, Collection input) {
+        try {
+            List matches;
+
+            if (((matches = matches(regex, input))).size() > 0)
+                fail("The specified list of size " + input.size()
+                    + " did contain one or more strings that matchs the"
+                    + " specified illegal regular expression"
+                    + " (\"" + regex + "\")."
+                    + " First example of a matching message is: "
+                    + matches.iterator().next());
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    protected Log getLog() {
+        return getConfiguration().getLog("Tests");
+    }
+
+    ///////////////////
+    // Multi threading
+    ///////////////////
+
+    /**
+     * Re-execute the invoking method a random number of times
+     * in a random number of Threads.
+     */
+    public void mttest() throws ThreadingException {
+        // 6 iterations in 8 threads is a good trade-off between
+        // tests taking way too long and having a decent chance of
+        // identifying MT problems.
+        int iterations = 6;
+        int threads = 8;
+
+        mttest(threads, iterations);
+    }
+
+    /**
+     * Execute the calling method <code>iterations</code>
+     * times in <code>threads</code> Threads.
+     */
+    public void mttest(int threads, int iterations) {
+        mttest(0, threads, iterations);
+    }
+
+    public void mttest(int serialCount, int threads, int iterations)
+        throws ThreadingException {
+        String methodName = callingMethod("mttest");
+        mttest(serialCount, threads, iterations, methodName, new Object [0]);
+    }
+
+    /**
+     * Execute a test method in multiple threads.
+     *
+     * @param threads the number of Threads to run in
+     * @param iterations the number of times the method should
+     * be execute in a single Thread
+     * @param method the name of the method to execute
+     * @param args the arguments to pass to the method
+     * @throws ThreadingException if an errors occur in
+     * any of the Threads. The actual exceptions
+     * will be embedded in the exception. Note that
+     * this means that assert() failures will be
+     * treated as errors rather than warnings.
+     * @author Marc Prud'hommeaux
+     */
+    public void mttest(int threads, int iterations, final String method,
+        final Object [] args) throws ThreadingException {
+        mttest(0, threads, iterations, method, args);
+    }
+
+    public void mttest(int serialCount,
+        int threads, int iterations, final String method, final Object [] args)
+        throws ThreadingException {
+        if (multiThreadExecuting != null && multiThreadExecuting.equals(method))
+        {
+            // we are currently executing in multi-threaded mode:
+            // don't deadlock!
+            return;
+        }
+
+        multiThreadExecuting = method;
+
+        try {
+            Class [] paramClasses = new Class [args.length];
+            for (int i = 0; i < paramClasses.length; i++)
+                paramClasses[i] = args[i].getClass();
+
+            final Method meth;
+
+            try {
+                meth = getClass().getMethod(method, paramClasses);
+            } catch (NoSuchMethodException nsme) {
+                throw new ThreadingException(nsme.toString(), nsme);
+            }
+
+            final Object thiz = this;
+
+            mttest("reflection invocation: (" + method + ")",
+                serialCount, threads, iterations, new VolatileRunnable() {
+                public void run() throws Exception {
+                    meth.invoke(thiz, args);
+                }
+            });
+        } finally {
+            multiThreadExecuting = null;
+        }
+    }
+
+    public void mttest(String title, final int threads, final int iterations,
+        final VolatileRunnable runner) throws ThreadingException {
+        mttest(title, 0, threads, iterations, runner);
+    }
+
+    /**
+     * Execute a test method in multiple threads.
+     *
+     * @param title a description of the test, for inclusion in the
+     * error message
+     * @param serialCount the number of times to run the method
+     * serially before spawning threads.
+     * @param threads the number of Threads to run in
+     * @param iterations the number of times the method should
+     * @param runner the VolatileRunnable that will execute
+     * the actual test from within the Thread.
+     * @throws ThreadingException if an errors occur in
+     * any of the Threads. The actual exceptions
+     * will be embedded in the exception. Note that
+     * this means that assert() failures will be
+     * treated as errors rather than warnings.
+     * @author Marc Prud'hommeaux be execute in a single Thread
+     * @author Marc Prud'hommeaux
+     */
+    public void mttest(String title, final int serialCount,
+        final int threads, final int iterations, final VolatileRunnable runner)
+        throws ThreadingException {
+        final List exceptions = Collections.synchronizedList(new LinkedList());
+
+        Thread [] runners = new Thread [threads];
+
+        final long startMillis = System.currentTimeMillis() + 1000;
+
+        for (int i = 1; i <= threads; i++) {
+            final int thisThread = i;
+
+            runners[i - 1] =
+                new Thread(title + " [" + i + " of " + threads + "]") {
+                    public void run() {
+                        // do our best to have all threads start at the exact
+                        // same time. This is imperfect, but the closer we
+                        // get to everyone starting at the same time, the
+                        // better chance we have for identifying MT problems.
+                        while (System.currentTimeMillis() < startMillis)
+                            yield();
+
+                        int thisIteration = 1;
+                        try {
+                            for (; thisIteration <= iterations; thisIteration++)
+                            {
+                                // go go go!
+                                runner.run();
+                            }
+                        } catch (Throwable error) {
+                            synchronized (exceptions) {
+                                // embed the exception into something that gives
+                                // us some more information about the threading
+                                // environment
+                                exceptions.add(new ThreadingException("thread="
+                                    + this.toString()
+                                    + ";threadNum=" + thisThread
+                                    + ";maxThreads=" + threads
+                                    + ";iteration=" + thisIteration
+                                    + ";maxIterations=" + iterations, error));
+                            }
+                        }
+                    }
+                };
+        }
+
+        // start the serial tests(does not spawn the threads)
+        for (int i = 0; i < serialCount; i++) {
+            runners[0].run();
+        }
+
+        // start the multithreaded
+        for (int i = 0; i < threads; i++) {
+            runners[i].start();
+        }
+
+        // wait for them all to complete
+        for (int i = 0; i < threads; i++) {
+            try {
+                runners[i].join();
+            } catch (InterruptedException e) {
+            }
+        }
+
+        if (exceptions.size() == 0)
+            return; // sweeeeeeeet: no errors
+
+        // embed all the exceptions that were throws into a
+        // ThreadingException
+        Throwable [] errors = (Throwable []) exceptions.toArray(
+            new Throwable [0]);
+        throw new ThreadingException("The "
+            + errors.length + " embedded errors "
+            + "occured in the execution of " + iterations + " iterations "
+            + "of " + threads + " threads: [" + title + "]", errors);
+    }
+
+    /**
+     * Check to see if we are in the top-level execution stack.
+     */
+    public boolean isRootThread() {
+        return multiThreadExecuting == null;
+    }
+
+    /**
+     * A Runnable that can throw an Exception: used to test cases.
+     */
+    public static interface VolatileRunnable {
+
+        public void run() throws Exception;
+    }
+
+    /**
+     * Exception for errors caught during threading tests.
+     */
+    public class ThreadingException extends RuntimeException {
+
+        private final Throwable[] _nested;
+
+        public ThreadingException(String msg, Throwable nested) {
+            super(msg);
+            if (nested == null)
+                _nested = new Throwable[0];
+            else
+                _nested = new Throwable[]{ nested };
+        }
+
+        public ThreadingException(String msg, Throwable[] nested) {
+            super(msg);
+            if (nested == null)
+                _nested = new Throwable[0];
+            else
+                _nested = nested;
+        }
+
+        public void printStackTrace() {
+            printStackTrace(System.out);
+        }
+
+        public void printStackTrace(PrintStream out) {
+            printStackTrace(new PrintWriter(out));
+        }
+
+        public void printStackTrace(PrintWriter out) {
+            super.printStackTrace(out);
+            for (int i = 0; i < _nested.length; i++) {
+                out.print("Nested Throwable #" + (i + 1) + ": ");
+                _nested[i].printStackTrace(out);
+            }
+        }
+    }
+
+    /**
+     * Return the last method name that called this one by
+     * parsing the current stack trace.
+     *
+     * @param exclude a method name to skip
+     * @throws IllegalStateException If the calling method could not be
+     * identified.
+     * @author Marc Prud'hommeaux
+     */
+    public String callingMethod(String exclude) {
+        // determine the currently executing method by
+        // looking at the stack track. Hackish, but convenient.
+        StringWriter sw = new StringWriter();
+        new Exception().printStackTrace(new PrintWriter(sw));
+        for (StringTokenizer stackTrace = new StringTokenizer(sw.toString(),
+            System.getProperty("line.separator"));
+            stackTrace.hasMoreTokens();) {
+            String line = stackTrace.nextToken().trim();
+
+            // not a stack trace element
+            if (!(line.startsWith("at ")))
+                continue;
+
+            String fullMethodName = line.substring(0, line.indexOf("("));
+
+            String shortMethodName = fullMethodName.substring(
+                fullMethodName.lastIndexOf(".") + 1);
+
+            // skip our own methods!
+            if (shortMethodName.equals("callingMethod"))
+                continue;
+            if (exclude != null && shortMethodName.equals(exclude))
+                continue;
+
+            return shortMethodName;
+        }
+
+        throw new IllegalStateException("Could not identify calling "
+            + "method in stack trace");
+    }
+
+    //////////
+    // Timing
+    //////////
+
+    /**
+     * Sleep the current Thread for a random amount of time from 0-1000 ms.
+     */
+    public void sleepRandom() {
+        sleepRandom(1000);
+    }
+
+    /**
+     * Sleep the current Thread for a random amount of time from
+     * 0-<code>max</code> ms.
+     */
+    public void sleepRandom(int max) {
+        try {
+            Thread.currentThread().sleep((long) (Math.random() * max));
+        } catch (InterruptedException ex) {
+        }
+    }
+
+    /**
+     * Re-run this method in the current thread, timing out
+     * after the specified number of seconds.
+     * Usage:
+     * <pre> public void timeOutOperation() { if (timeout(5 * 1000)) return;
+     *  Thread.currentThread().sleep(10 * 1000); }
+     * </pre>
+     * <p/>
+     * <p/>
+     * <strong>Warning</strong> this method should be used sparingly,
+     * and only when you expect that a timeout will <strong>not</strong>
+     * occur. It utilized the deprecated {@link Thread#stop()} and
+     * {@link Thread#interrupt} methods, which can leave monitors in an
+     * invalid state. It is only used because it provides more
+     * meaningful information than just seeing that the entire autobuild
+     * timed out.
+     *
+     * @param millis the number of milliseconds we should wait.
+     * @return true if we are are in the thread that requested the
+     *         timeout, false if we are in the timeout thread itself.
+     */
+    public boolean timeout(long millis) throws Throwable {
+        String methodName = callingMethod("timeout");
+        return timeout(millis, methodName);
+    }
+
+    /**
+     * @see #timeout(long)
+     */
+    public boolean timeout(long millis, String methodName) throws Throwable {
+        // we are in the timing out-thread: do nothing so the
+        // actual test method can run
+        if (inTimeoutThread)
+            return false;
+
+        inTimeoutThread = true;
+        long endTime = System.currentTimeMillis() + millis;
+
+        try {
+            final Method method = getClass().
+                getMethod(methodName, (Class[]) null);
+            final Object thz = this;
+
+            // spawn thread
+            TimeOutThread tot = new TimeOutThread("TimeOutThread ["
+                + methodName + "] (" + millis + "ms)") {
+                public void run() {
+                    try {
+                        method.invoke(thz, (Object[]) null);
+                    } catch (Throwable t) {
+                        throwable = t;
+                    } finally {
+                        completed = true;
+                    }
+                }
+            };
+
+            tot.start();
+
+            // wait for the completion or a timeout to occur
+            tot.join(millis);
+
+            // have we timed out? Kill the thread and throw an exception
+            if (System.currentTimeMillis() >= endTime) {
+                // if we are waiting on a monitor, this will give
+                // us a useful stack trace.
+                try {
+                    tot.interrupt();
+                } catch (Throwable e) {
+                }
+                Thread.currentThread().sleep(500);
+
+                // try to kill the thread
+                try {
+                    tot.stop();
+                } catch (Throwable e) {
+                }
+                Thread.currentThread().sleep(500);
+
+                throw new OperationTimedOutException("Execution of \""
+                    + methodName + "\" timed out after "
+                    + millis + " milliseconds", tot.throwable);
+            }
+
+            // throw any exceptions that may have occured
+            if (tot.throwable != null)
+                throw tot.throwable;
+
+            // I guess everything was OK
+            return true;
+        } finally {
+            inTimeoutThread = false;
+        }
+    }
+
+    private static class TimeOutThread extends Thread {
+
+        public Throwable throwable = null;
+        public boolean completed = false;
+
+        public TimeOutThread(String name) {
+            super(name);
+            setDaemon(true);
+        }
+    }
+
+    /**
+     * Indicates that a timeout occured.
+     */
+    public static class OperationTimedOutException extends RuntimeException {
+
+        private final Throwable _err;
+
+        public OperationTimedOutException(String msg, Throwable throwable) {
+            super(msg);
+            _err = throwable;
+        }
+
+        public void printStackTrace() {
+            printStackTrace(System.out);
+        }
+
+        public void printStackTrace(PrintStream out) {
+            printStackTrace(new PrintWriter(out));
+        }
+
+        public void printStackTrace(PrintWriter out) {
+            super.printStackTrace(out);
+            if (_err != null) {
+                out.print("Nested Throwable: ");
+                _err.printStackTrace(out);
+            }
+        }
+    }
+
+    ///////////////
+    // Collections
+    ///////////////
+
+    /**
+     * Validate that the specified {@link Collection} fulfills the
+     * Collection contract as specified by the Collections API.
+     * <p/>
+     * <strong>Note</strong>: does not validate mutable operations
+     */
+    public static void validateCollection(Collection collection) {
+        int size = collection.size();
+        int iterated = 0;
+        // ensure we can walk along the iterator
+        for (Iterator i = collection.iterator(); i.hasNext();) {
+            iterated++;
+            i.next();
+        }
+
+        // ensure the number of values iterated is the same as the list size
+        assertEquals(size, iterated);
+
+        // also validate the list
+        if (collection instanceof List) {
+            List ll = new ArrayList();
+            for (int i = 0; i < 100; i++)
+                ll.add(new Integer(i));
+            validateList((List) ll);
+            validateList((List) collection);
+        }
+    }
+
+    /**
+     * Validate that the specified {@link List} fulfills the
+     * List contract as specified by the Collections API.
+     * <p/>
+     * <strong>Note</strong>: does not validate mutable operations
+     */
+    public static void validateList(List list) {
+        Object [] coreValues = list.toArray();
+        Object [] values1 = new Object [list.size()];
+        Object [] values2 = new Object [list.size()];
+        Object [] values3 = new Object [list.size()];
+        Object [] values4 = new Object [list.size()];
+
+        // fill sequential index access list
+        for (int i = 0; i < list.size(); i++)
+            values1[i] = list.get(i);
+
+        // fill sequential list
+        int index = 0;
+        ListIterator iter;
+        for (iter = list.listIterator(0); iter.hasNext();) {
+            assertEquals(index, iter.nextIndex());
+            assertEquals(index, iter.previousIndex() + 1);
+            values2[index] = iter.next();
+            assertTrue(list.contains(values2[index]));
+            index++;
+        }
+
+        // ensure NoSuchElementException is thrown as appropriate
+        try {
+            iter.next();
+            fail("next() should have resulted in a NoSuchElementException");
+        } catch (NoSuchElementException e) {
+        } // as expected
+
+        // fill reverse sequential list
+        int back = 0;
+        for (iter = list.listIterator(list.size()); iter.hasPrevious();) {
+            assertEquals(index, iter.previousIndex() + 1);
+            assertEquals(index, iter.nextIndex());
+            values3[--index] = iter.previous();
+            back++;
+        }
+        assertEquals(list.size(), back);
+
+        // ensure NoSuchElementException is thrown as appropriate
+        try {
+            iter.previous();
+            fail("previous() should have resulted in a "
+                + "NoSuchElementException");
+        } catch (NoSuchElementException e) {
+        } // as expected
+
+        // fill random access list
+        List indices = new LinkedList();
+        for (int i = 0; i < list.size(); i++)
+            indices.add(new Integer(i));
+
+        for (int i = 0; i < list.size(); i++) {
+            int rand = (int) (Math.random() * indices.size());
+            Integer randIndex = (Integer) indices.remove(rand);
+            values4[randIndex.intValue()] = list.get(randIndex.intValue());
+        }
+
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values1));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values1));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values2));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values2));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values4));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values4));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values3));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values3));
+    }
+
+    /**
+     * Assert that the given List contain the exact same
+     * elements. This is different than the normal List contract, which
+     * states that list1.equals(list2) if each element e1.equals(e2).
+     * This method asserts that e1 == n2.
+     */
+    public static void assertIdentical(List c1, List c2) {
+        assertEquals(c1.size(), c2.size());
+        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
+            i1.hasNext() && i2.hasNext();)
+            assertTrue(i1.next() == i2.next());
+    }
+
+    /**
+     * Assert that the collection parameter is already ordered
+     * according to the specified comparator.
+     */
+    public void assertOrdered(Collection c, Comparator comp) {
+        List l1 = new LinkedList(c);
+        List l2 = new LinkedList(c);
+        assertEquals(l1, l2);
+        Collections.sort(l2, comp);
+        assertEquals(l1, l2);
+        Collections.sort(l1, comp);
+        assertEquals(l1, l2);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java
index 3e6cbc0..11be3be 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.utils;
-
-import java.util.*;
-
-import org.apache.openjpa.lib.log.*;
-
-/**
- * Simple default log implementation to test whether certain messages
- * are logged or not.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public class BufferedLogFactory
-    extends LogFactoryImpl {
-
-    private int bufferSize = 10000;
-    private List buffer = new ArrayList();
-    private List disallowedMessages = new LinkedList();
-
-    protected LogImpl newLogImpl() {
-        return new BufferedLog();
-    }
-
-    public List getBuffer() {
-        return Collections.unmodifiableList(buffer);
-    }
-
-    public void clear() {
-        buffer.clear();
-    }
-
-    public void clearDisallowedMessages() {
-        disallowedMessages.clear();
-    }
-
-    public void addDisallowedMessage(String regexp) {
-        disallowedMessages.add(regexp);
-    }
-
-    public boolean removeDisallowedMessage(String regexp) {
-        return disallowedMessages.remove(regexp);
-    }
-
-    public List getDisallowedMessages() {
-        return Collections.unmodifiableList(disallowedMessages);
-    }
-
-    public void assertLogMessage(String regex) {
-    	AbstractTestCase.assertMatches(regex, getBuffer());
-    }
-
-    public void assertNoLogMessage(String regex) {
-    	AbstractTestCase.assertNotMatches(regex, getBuffer());
-    }
-
-    public void setBufferSize(int bufferSize) {
-        this.bufferSize = bufferSize;
-    }
-
-    public int getBufferSize() {
-        return this.bufferSize;
-    }
-
-    public class BufferedLog
-        extends LogFactoryImpl.LogImpl {
-
-        protected void log(short level, String message, Throwable t) {
-            super.log(level, message, t);
-            buffer.add(message);
-
-            // trim to max buffer length
-            while (buffer.size() > getBufferSize())
-                buffer.iterator().remove();
-
-            if (disallowedMessages.size() > 0) {
-                for (Iterator i = disallowedMessages.iterator(); i.hasNext();) {
-                    String regex = (String) i.next();
-                    AbstractTestCase.assertNotMatches(regex, message);
-                }
-            }
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.utils;
+
+import java.util.*;
+
+import org.apache.openjpa.lib.log.*;
+
+/**
+ * Simple default log implementation to test whether certain messages
+ * are logged or not.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class BufferedLogFactory
+    extends LogFactoryImpl {
+
+    private int bufferSize = 10000;
+    private List buffer = new ArrayList();
+    private List disallowedMessages = new LinkedList();
+
+    protected LogImpl newLogImpl() {
+        return new BufferedLog();
+    }
+
+    public List getBuffer() {
+        return Collections.unmodifiableList(buffer);
+    }
+
+    public void clear() {
+        buffer.clear();
+    }
+
+    public void clearDisallowedMessages() {
+        disallowedMessages.clear();
+    }
+
+    public void addDisallowedMessage(String regexp) {
+        disallowedMessages.add(regexp);
+    }
+
+    public boolean removeDisallowedMessage(String regexp) {
+        return disallowedMessages.remove(regexp);
+    }
+
+    public List getDisallowedMessages() {
+        return Collections.unmodifiableList(disallowedMessages);
+    }
+
+    public void assertLogMessage(String regex) {
+    	AbstractTestCase.assertMatches(regex, getBuffer());
+    }
+
+    public void assertNoLogMessage(String regex) {
+    	AbstractTestCase.assertNotMatches(regex, getBuffer());
+    }
+
+    public void setBufferSize(int bufferSize) {
+        this.bufferSize = bufferSize;
+    }
+
+    public int getBufferSize() {
+        return this.bufferSize;
+    }
+
+    public class BufferedLog
+        extends LogFactoryImpl.LogImpl {
+
+        protected void log(short level, String message, Throwable t) {
+            super.log(level, message, t);
+            buffer.add(message);
+
+            // trim to max buffer length
+            while (buffer.size() > getBufferSize())
+                buffer.iterator().remove();
+
+            if (disallowedMessages.size() > 0) {
+                for (Iterator i = disallowedMessages.iterator(); i.hasNext();) {
+                    String regex = (String) i.next();
+                    AbstractTestCase.assertNotMatches(regex, message);
+                }
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java
index f78ca75..99a5881 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.common.utils;
-
-import java.io.*;
-
-import junit.framework.*;
-
-/**
- * Extension of an assertion error that indicates to the outside
- * build process (if any) that an assertion failed due to a known
- * bug.
- *
- * @author Marc Prud'hommeaux
- */
-public class Bug
-    extends AssertionFailedError {
-
-    public static final String BUG_TOKEN = "SOLARBUG";
-    public static final String BUG_DELIMITER = "|";
-
-    private Throwable error = null;
-    private int trackingId;
-
-    // the the static factory method, please
-    private Bug(int trackingId, Throwable t, String message) {
-        super(BUG_DELIMITER + BUG_TOKEN + BUG_DELIMITER
-            + trackingId + BUG_DELIMITER + message);
-        this.trackingId = trackingId;
-        error = t;
-
-        printStackTrace(System.err);
-    }
-
-    public static Bug bug(int trackingId, Throwable t, String message) {
-        return new Bug(trackingId, t, message);
-    }
-
-    public void printStackTrace(PrintWriter pw) {
-        super.printStackTrace(pw);
-        if (error != null) {
-            pw.println("Embedded error message:");
-            error.printStackTrace(pw);
-        }
-    }
-
-    public void printStackTrace(PrintStream ps) {
-        super.printStackTrace(ps);
-        if (error != null) {
-            ps.println("Embedded error message:");
-            error.printStackTrace(ps);
-        }
-    }
-
-    public String getMessage() {
-        return super.getMessage() + " [reported bug #" + trackingId + "]";
-    }
-
-    public int getTrackingId() {
-        return trackingId;
-    }
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.common.utils;
+
+import java.io.*;
+
+import junit.framework.*;
+
+/**
+ * Extension of an assertion error that indicates to the outside
+ * build process (if any) that an assertion failed due to a known
+ * bug.
+ *
+ * @author Marc Prud'hommeaux
+ */
+public class Bug
+    extends AssertionFailedError {
+
+    public static final String BUG_TOKEN = "SOLARBUG";
+    public static final String BUG_DELIMITER = "|";
+
+    private Throwable error = null;
+    private int trackingId;
+
+    // the the static factory method, please
+    private Bug(int trackingId, Throwable t, String message) {
+        super(BUG_DELIMITER + BUG_TOKEN + BUG_DELIMITER
+            + trackingId + BUG_DELIMITER + message);
+        this.trackingId = trackingId;
+        error = t;
+
+        printStackTrace(System.err);
+    }
+
+    public static Bug bug(int trackingId, Throwable t, String message) {
+        return new Bug(trackingId, t, message);
+    }
+
+    public void printStackTrace(PrintWriter pw) {
+        super.printStackTrace(pw);
+        if (error != null) {
+            pw.println("Embedded error message:");
+            error.printStackTrace(pw);
+        }
+    }
+
+    public void printStackTrace(PrintStream ps) {
+        super.printStackTrace(ps);
+        if (error != null) {
+            ps.println("Embedded error message:");
+            error.printStackTrace(ps);
+        }
+    }
+
+    public String getMessage() {
+        return super.getMessage() + " [reported bug #" + trackingId + "]";
+    }
+
+    public int getTrackingId() {
+        return trackingId;
+    }
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java
index e159e41..44f95ff 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java
@@ -1,230 +1,230 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.conf;
-
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.common.utils.BufferedLogFactory;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.lib.conf.PluginValue;
-import org.apache.openjpa.lib.conf.Value;
-
-/**
- * <p>Tests the JDO configuration classes.</p>
- *
- * @author Marc Prud'hommeaux
- */
-public class TestKodoConfiguration
-    extends AbstractTestCase {
-
-    public TestKodoConfiguration(String test) {
-        super(test, "confcactusapp");
-    }
-
-    /**
-     * Test that you can set the connection factory and other properties as
-     * objects.
-     */
-    public void testSetObjects() {
-        Map map = new HashMap();
-        Object cfactory = new Object();
-        Object cfactory2 = new Object();
-        map.put("openjpa.ConnectionFactory", cfactory);
-        map.put("openjpa.ConnectionFactory2", cfactory2);
-        map.put("openjpa.Optimistic", Boolean.FALSE);
-        map.put("openjpa.LockTimeout", new Integer(503));
-
-        // use new conf so no unexpected restrictions on type of connection
-        // factory
-        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl(true, false);
-        conf.fromProperties(map);
-        assertEquals(cfactory, conf.getConnectionFactory());
-        assertEquals(cfactory2, conf.getConnectionFactory2());
-        assertEquals(false, conf.getOptimistic());
-        assertEquals(503, conf.getLockTimeout());
-
-        OpenJPAConfiguration conf2 = new OpenJPAConfigurationImpl(true, false);
-        conf2.fromProperties(map);
-        assertEquals(conf, conf2);
-
-        Map p = conf.toProperties(false);
-        assertTrue(!p.containsKey("openjpa.ConnectionFactory"));
-        assertTrue(!p.containsKey("openjpa.ConnectionFactory2"));
-        assertEquals("false", p.get("openjpa.Optimistic"));
-        assertEquals("503", p.get("openjpa.LockTimeout"));
-        assertEquals(p, conf2.toProperties(false));
-
-        map.put("openjpa.LockTimeout", new Integer(504));
-        OpenJPAConfiguration conf3 = new OpenJPAConfigurationImpl(true, false);
-        conf3.fromProperties(map);
-        assertNotEquals(conf, conf3);
-    }
-
-    public void testClassAliases()
-        throws Exception {
-        OpenJPAConfiguration conf = getConfiguration();
-        if (!(conf instanceof OpenJPAConfigurationImpl))
-            return;
-
-        Value[] values = ((OpenJPAConfigurationImpl) conf).getValues();
-        String[] aliases;
-        String clsName;
-        List failures = new ArrayList();
-        for (int i = 0; i < values.length; i++) {
-            if (!(values[i] instanceof PluginValue))
-                continue;
-
-            aliases = values[i].getAliases();
-            for (int j = 0; j < aliases.length; j += 2) {
-                try {
-                    clsName = Configurations.getClassName(aliases[j + 1]);
-                    if (clsName != null)
-                        Class.forName(clsName);
-                } catch (ClassNotFoundException cnfe) {
-                    failures.add("Key: " + aliases[j] + " for property "
-                        + values[i].getProperty() + " does not list a valid "
-                        + "class: " + aliases[j + 1]);
-                } catch (UnsupportedClassVersionError ucve) {
-                    //### JDK 5 plugin; ignore
-                }
-            }
-        }
-        if (failures.size() != 0)
-            fail(failures.toString());
-    }
-
-    public void testBeanAccessors()
-        throws Exception {
-        OpenJPAConfiguration conf = getConfiguration();
-        OpenJPAConfigurationImpl simp = (OpenJPAConfigurationImpl) conf.clone();
-
-        Value[] values = simp.getValues();
-        PropertyDescriptor[] pds = simp.getPropertyDescriptors();
-        List failures = new ArrayList();
-        for (int i = 0; i < values.length; i++) {
-            try {
-                assertNotNull(pds[i].getShortDescription());
-                assertNotNull(pds[i].getDisplayName());
-
-                Method setter = pds[i].getWriteMethod();
-                Method getter = pds[i].getReadMethod();
-                assertNotNull(setter);
-                assertNotNull(getter);
-
-                assertNotNull("Missing attribute ("
-                    + Configuration.ATTRIBUTE_TYPE
-                    + ") for property " + pds[i].getName(),
-                    pds[i].getValue(Configuration.ATTRIBUTE_TYPE));
-
-                assertNotNull("Missing attribute ("
-                    + Configuration.ATTRIBUTE_CATEGORY
-                    + ") for property " + pds[i].getName(),
-                    pds[i].getValue(Configuration.ATTRIBUTE_CATEGORY));
-
-                assertNotNull("Missing attribute ("
-                    + Configuration.ATTRIBUTE_ORDER
-                    + ") for property " + pds[i].getName(),
-                    pds[i].getValue(Configuration.ATTRIBUTE_ORDER));
-
-                pds[i].getReadMethod().invoke(simp, (Object[]) null);
-
-            } catch (Exception e) {
-                failures.add(pds[i].getName());
-            }
-        }
-        if (failures.size() != 0)
-            fail("not all properties had valid comments / setters / getters."
-                + " failed props: " + failures);
-    }
-
-    /**
-     * Tests that invalid plug-in values throw the appropriate exception
-     * type.
-     */
-    public void testInvalidPlugins() {
-        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
-        config.setLog("log3j");
-        try {
-            config.getLogFactory().getLog("Foo");
-            fail("getting the Foo log should have failed");
-        } catch (RuntimeException re) {
-            // as expected ... make sure the exception suggests the
-            // name "log4j" in the message
-            assertTrue(-1 != re.getMessage().indexOf("log4j"));
-        }
-    }
-
-    public void testInvalidConfigurationWarnings() {
-        Properties props = new Properties();
-        props.setProperty("openjpa.MaxxFetchDepth", "1");
-
-        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
-        // track the messages
-        BufferedLogFactory log = new BufferedLogFactory();
-        config.setLogFactory(log);
-
-        config.fromProperties(props);
-
-        // make sure we got a warning that contains the string with the
-        // bad property name and a hint for the valid property name.
-        log.assertLogMessage("*\"openjpa.MaxxFetchDepth\"*");
-        log.assertLogMessage("*\"openjpa.MaxFetchDepth\"*");
-
-        log.clear();
-
-        // now make sure we do *not* try to validate sub-configurations (such
-        // as kodo.jdbc.Foo).
-        props.clear();
-        props.setProperty("openjpa.jdbc.Foo", "XXX");
-        props.setProperty("oponjpa", "XXX");
-        config.fromProperties(props);
-        log.assertNoLogMessage("*\"openjpa.jdbc.Foo\"*");
-        log.assertNoLogMessage("*\"oponjpa\"*");
-    }
-
-    /**
-     * Tests that invalid fixed-list values throw the appropriate exception
-     * type.
-     */
-    public void testInvalidNonPluginValues() {
-        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
-        try {
-            config.setConnectionFactoryMode("aoeu");
-            fail("setting the ConnectionFactoryMode to aoeu should fail");
-        } catch (RuntimeException re) {
-            re.printStackTrace();
-            // as expected ... make sure the exception suggests the
-            // valid names in the message.
-            assertTrue(-1 != re.getMessage().indexOf("managed"));
-            assertTrue(-1 != re.getMessage().indexOf("local"));
-            assertTrue(-1 != re.getMessage().indexOf("true"));
-            assertTrue(-1 != re.getMessage().indexOf("false"));
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.conf;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.common.utils.BufferedLogFactory;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.conf.Value;
+
+/**
+ * <p>Tests the JDO configuration classes.</p>
+ *
+ * @author Marc Prud'hommeaux
+ */
+public class TestKodoConfiguration
+    extends AbstractTestCase {
+
+    public TestKodoConfiguration(String test) {
+        super(test, "confcactusapp");
+    }
+
+    /**
+     * Test that you can set the connection factory and other properties as
+     * objects.
+     */
+    public void testSetObjects() {
+        Map map = new HashMap();
+        Object cfactory = new Object();
+        Object cfactory2 = new Object();
+        map.put("openjpa.ConnectionFactory", cfactory);
+        map.put("openjpa.ConnectionFactory2", cfactory2);
+        map.put("openjpa.Optimistic", Boolean.FALSE);
+        map.put("openjpa.LockTimeout", new Integer(503));
+
+        // use new conf so no unexpected restrictions on type of connection
+        // factory
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl(true, false);
+        conf.fromProperties(map);
+        assertEquals(cfactory, conf.getConnectionFactory());
+        assertEquals(cfactory2, conf.getConnectionFactory2());
+        assertEquals(false, conf.getOptimistic());
+        assertEquals(503, conf.getLockTimeout());
+
+        OpenJPAConfiguration conf2 = new OpenJPAConfigurationImpl(true, false);
+        conf2.fromProperties(map);
+        assertEquals(conf, conf2);
+
+        Map p = conf.toProperties(false);
+        assertTrue(!p.containsKey("openjpa.ConnectionFactory"));
+        assertTrue(!p.containsKey("openjpa.ConnectionFactory2"));
+        assertEquals("false", p.get("openjpa.Optimistic"));
+        assertEquals("503", p.get("openjpa.LockTimeout"));
+        assertEquals(p, conf2.toProperties(false));
+
+        map.put("openjpa.LockTimeout", new Integer(504));
+        OpenJPAConfiguration conf3 = new OpenJPAConfigurationImpl(true, false);
+        conf3.fromProperties(map);
+        assertNotEquals(conf, conf3);
+    }
+
+    public void testClassAliases()
+        throws Exception {
+        OpenJPAConfiguration conf = getConfiguration();
+        if (!(conf instanceof OpenJPAConfigurationImpl))
+            return;
+
+        Value[] values = ((OpenJPAConfigurationImpl) conf).getValues();
+        String[] aliases;
+        String clsName;
+        List failures = new ArrayList();
+        for (int i = 0; i < values.length; i++) {
+            if (!(values[i] instanceof PluginValue))
+                continue;
+
+            aliases = values[i].getAliases();
+            for (int j = 0; j < aliases.length; j += 2) {
+                try {
+                    clsName = Configurations.getClassName(aliases[j + 1]);
+                    if (clsName != null)
+                        Class.forName(clsName);
+                } catch (ClassNotFoundException cnfe) {
+                    failures.add("Key: " + aliases[j] + " for property "
+                        + values[i].getProperty() + " does not list a valid "
+                        + "class: " + aliases[j + 1]);
+                } catch (UnsupportedClassVersionError ucve) {
+                    //### JDK 5 plugin; ignore
+                }
+            }
+        }
+        if (failures.size() != 0)
+            fail(failures.toString());
+    }
+
+    public void testBeanAccessors()
+        throws Exception {
+        OpenJPAConfiguration conf = getConfiguration();
+        OpenJPAConfigurationImpl simp = (OpenJPAConfigurationImpl) conf.clone();
+
+        Value[] values = simp.getValues();
+        PropertyDescriptor[] pds = simp.getPropertyDescriptors();
+        List failures = new ArrayList();
+        for (int i = 0; i < values.length; i++) {
+            try {
+                assertNotNull(pds[i].getShortDescription());
+                assertNotNull(pds[i].getDisplayName());
+
+                Method setter = pds[i].getWriteMethod();
+                Method getter = pds[i].getReadMethod();
+                assertNotNull(setter);
+                assertNotNull(getter);
+
+                assertNotNull("Missing attribute ("
+                    + Configuration.ATTRIBUTE_TYPE
+                    + ") for property " + pds[i].getName(),
+                    pds[i].getValue(Configuration.ATTRIBUTE_TYPE));
+
+                assertNotNull("Missing attribute ("
+                    + Configuration.ATTRIBUTE_CATEGORY
+                    + ") for property " + pds[i].getName(),
+                    pds[i].getValue(Configuration.ATTRIBUTE_CATEGORY));
+
+                assertNotNull("Missing attribute ("
+                    + Configuration.ATTRIBUTE_ORDER
+                    + ") for property " + pds[i].getName(),
+                    pds[i].getValue(Configuration.ATTRIBUTE_ORDER));
+
+                pds[i].getReadMethod().invoke(simp, (Object[]) null);
+
+            } catch (Exception e) {
+                failures.add(pds[i].getName());
+            }
+        }
+        if (failures.size() != 0)
+            fail("not all properties had valid comments / setters / getters."
+                + " failed props: " + failures);
+    }
+
+    /**
+     * Tests that invalid plug-in values throw the appropriate exception
+     * type.
+     */
+    public void testInvalidPlugins() {
+        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
+        config.setLog("log3j");
+        try {
+            config.getLogFactory().getLog("Foo");
+            fail("getting the Foo log should have failed");
+        } catch (RuntimeException re) {
+            // as expected ... make sure the exception suggests the
+            // name "log4j" in the message
+            assertTrue(-1 != re.getMessage().indexOf("log4j"));
+        }
+    }
+
+    public void testInvalidConfigurationWarnings() {
+        Properties props = new Properties();
+        props.setProperty("openjpa.MaxxFetchDepth", "1");
+
+        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
+        // track the messages
+        BufferedLogFactory log = new BufferedLogFactory();
+        config.setLogFactory(log);
+
+        config.fromProperties(props);
+
+        // make sure we got a warning that contains the string with the
+        // bad property name and a hint for the valid property name.
+        log.assertLogMessage("*\"openjpa.MaxxFetchDepth\"*");
+        log.assertLogMessage("*\"openjpa.MaxFetchDepth\"*");
+
+        log.clear();
+
+        // now make sure we do *not* try to validate sub-configurations (such
+        // as kodo.jdbc.Foo).
+        props.clear();
+        props.setProperty("openjpa.jdbc.Foo", "XXX");
+        props.setProperty("oponjpa", "XXX");
+        config.fromProperties(props);
+        log.assertNoLogMessage("*\"openjpa.jdbc.Foo\"*");
+        log.assertNoLogMessage("*\"oponjpa\"*");
+    }
+
+    /**
+     * Tests that invalid fixed-list values throw the appropriate exception
+     * type.
+     */
+    public void testInvalidNonPluginValues() {
+        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
+        try {
+            config.setConnectionFactoryMode("aoeu");
+            fail("setting the ConnectionFactoryMode to aoeu should fail");
+        } catch (RuntimeException re) {
+            re.printStackTrace();
+            // as expected ... make sure the exception suggests the
+            // valid names in the message.
+            assertTrue(-1 != re.getMessage().indexOf("managed"));
+            assertTrue(-1 != re.getMessage().indexOf("local"));
+            assertTrue(-1 != re.getMessage().indexOf("true"));
+            assertTrue(-1 != re.getMessage().indexOf("false"));
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java
index e60b35d..6f438b1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java
@@ -1,178 +1,178 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.AttachA;
-import org.apache.openjpa.persistence.datacache.common.apps.AttachB;
-import org.apache.openjpa.persistence.datacache.common.apps.AttachC;
-import org.apache.openjpa.persistence.datacache.common.apps.AttachD;
-import org.apache.openjpa.persistence.datacache.common.apps.AttachE;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * Tests load on the cache. To run:
- * <p/>
- * java -Dkodo.properties=hsql.properties -Dcachetest.threads=30
- * -Dcachetest.iterations=1000 kodo.datacache.CacheLoadTest
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public class CacheLoadTest
-    extends AbstractTestCase {
-
-    private EntityManagerFactory emf;
-    protected int threadCount =
-        Integer.getInteger("cachetest.threads", 30).intValue();
-    protected int interationCount =
-        Integer.getInteger("cachetest.iterations", 1000).intValue();
-
-    public void setUp() {
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.QueryCache", "true");
-        emf = getEmf(propsMap);
-    }
-
-    public void testCacheLoad()
-        throws Exception {
-        mttest(Integer.getInteger("cachetest.threads", 30).intValue(),
-            Integer.getInteger("cachetest.iterations", 1000).intValue());
-
-        switch ((int) (Math.random() * 4)) {
-            case 0:
-                insert();
-                break;
-            case 1:
-                query();
-                break;
-            case 2:
-                delete();
-                break;
-            case 3:
-                read();
-                break;
-        }
-    }
-
-    private int rnd(int num) {
-        return randomInt().intValue() % num;
-    }
-
-    private void insert()
-        throws Exception {
-
-        EntityManager em = emf.createEntityManager();
-        startTx(em);
-
-        for (int i = 0; i < (rnd(100)); i++) {
-            em.persist(randomizeBean(rndclass().newInstance()));
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    private void query() {
-
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) emf.createEntityManager();
-
-        String[] filters = new String[]{
-            "select from " + AttachA.class.getName() + " where aint > 0",
-            "select from " + AttachA.class.getName() + " where aint < 0",
-            "select from " + AttachB.class.getName() + " where aint > 0",
-            "select from " + AttachB.class.getName() + " where aint < 0",
-            "select from " + AttachC.class.getName() + " where aint > 0",
-            "select from " + AttachC.class.getName() + " where aint < 0",
-        };
-
-        for (int i = 0; i < rnd(50); i++) {
-            try {
-                new ArrayList((Collection) em
-                    .createQuery("org.apache.openjpa.kernel.jpql.JPQL",
-                        filters[randomInt().intValue() % filters.length]).
-                    getResultList());
-            } catch (IllegalStateException e) {
-                e.printStackTrace();
-            }
-        }
-
-        endEm(em);
-    }
-
-    private void delete() {
-
-        try {
-            OpenJPAEntityManager em =
-                (OpenJPAEntityManager) emf.createEntityManager();
-            startTx(em);
-
-            for (Iterator i = em.createExtent(rndclass(), Math.random() > 0.5f).
-                iterator(); i.hasNext();) {
-                Object o = i.next();
-                if (Math.random() > 0.6f)
-                    em.remove(o);
-            }
-
-            endTx(em);
-            endEm(em);
-        } catch (IllegalStateException e) {
-            e.printStackTrace();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void read() {
-
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) emf.createEntityManager();
-
-        for (Iterator i = em.createExtent(rndclass(), Math.random() > 0.5f).
-            iterator(); i.hasNext();) {
-            Object o = i.next();
-        }
-
-        endEm(em);
-    }
-
-    private Class rndclass() {
-        Class[] c = new Class[]{
-            AttachA.class,
-            AttachB.class,
-            AttachC.class,
-            AttachD.class,
-            AttachE.class,
-        };
-
-        return c[(int) (Math.random() * c.length)];
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.AttachA;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachB;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachC;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachD;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachE;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * Tests load on the cache. To run:
+ * <p/>
+ * java -Dkodo.properties=hsql.properties -Dcachetest.threads=30
+ * -Dcachetest.iterations=1000 kodo.datacache.CacheLoadTest
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class CacheLoadTest
+    extends AbstractTestCase {
+
+    private EntityManagerFactory emf;
+    protected int threadCount =
+        Integer.getInteger("cachetest.threads", 30).intValue();
+    protected int interationCount =
+        Integer.getInteger("cachetest.iterations", 1000).intValue();
+
+    public void setUp() {
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.QueryCache", "true");
+        emf = getEmf(propsMap);
+    }
+
+    public void testCacheLoad()
+        throws Exception {
+        mttest(Integer.getInteger("cachetest.threads", 30).intValue(),
+            Integer.getInteger("cachetest.iterations", 1000).intValue());
+
+        switch ((int) (Math.random() * 4)) {
+            case 0:
+                insert();
+                break;
+            case 1:
+                query();
+                break;
+            case 2:
+                delete();
+                break;
+            case 3:
+                read();
+                break;
+        }
+    }
+
+    private int rnd(int num) {
+        return randomInt().intValue() % num;
+    }
+
+    private void insert()
+        throws Exception {
+
+        EntityManager em = emf.createEntityManager();
+        startTx(em);
+
+        for (int i = 0; i < (rnd(100)); i++) {
+            em.persist(randomizeBean(rndclass().newInstance()));
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    private void query() {
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) emf.createEntityManager();
+
+        String[] filters = new String[]{
+            "select from " + AttachA.class.getName() + " where aint > 0",
+            "select from " + AttachA.class.getName() + " where aint < 0",
+            "select from " + AttachB.class.getName() + " where aint > 0",
+            "select from " + AttachB.class.getName() + " where aint < 0",
+            "select from " + AttachC.class.getName() + " where aint > 0",
+            "select from " + AttachC.class.getName() + " where aint < 0",
+        };
+
+        for (int i = 0; i < rnd(50); i++) {
+            try {
+                new ArrayList((Collection) em
+                    .createQuery("org.apache.openjpa.kernel.jpql.JPQL",
+                        filters[randomInt().intValue() % filters.length]).
+                    getResultList());
+            } catch (IllegalStateException e) {
+                e.printStackTrace();
+            }
+        }
+
+        endEm(em);
+    }
+
+    private void delete() {
+
+        try {
+            OpenJPAEntityManager em =
+                (OpenJPAEntityManager) emf.createEntityManager();
+            startTx(em);
+
+            for (Iterator i = em.createExtent(rndclass(), Math.random() > 0.5f).
+                iterator(); i.hasNext();) {
+                Object o = i.next();
+                if (Math.random() > 0.6f)
+                    em.remove(o);
+            }
+
+            endTx(em);
+            endEm(em);
+        } catch (IllegalStateException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void read() {
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) emf.createEntityManager();
+
+        for (Iterator i = em.createExtent(rndclass(), Math.random() > 0.5f).
+            iterator(); i.hasNext();) {
+            Object o = i.next();
+        }
+
+        endEm(em);
+    }
+
+    private Class rndclass() {
+        Class[] c = new Class[]{
+            AttachA.class,
+            AttachB.class,
+            AttachC.class,
+            AttachD.class,
+            AttachE.class,
+        };
+
+        return c[(int) (Math.random() * c.length)];
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
index 2558974..fa09b23 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTest.java
@@ -1,1591 +1,1591 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.AppIdCacheObject;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild2;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectBChild1;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectC;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectD;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectF;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectG;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectH;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectInterface;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
-import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.AssertionFailedError;
-import org.apache.openjpa.datacache.ConcurrentDataCache;
-import org.apache.openjpa.datacache.DataCache;
-import org.apache.openjpa.datacache.DelegatingDataCache;
-import org.apache.openjpa.datacache.QueryCache;
-import org.apache.openjpa.datacache.TypesChangedEvent;
-import org.apache.openjpa.datacache.DataCacheManager;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCData;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.util.CacheMap;
-import org.apache.openjpa.util.Id;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.ProxyDate;
-
-/**
- * ### should add 1..1 relation test ### app id compound key test
- */
-public abstract class CacheTest extends AbstractTestCase {
-
-    private static String ORIG_NAME = "origName";
-
-    private static String NEW_NAME = "newName";
-
-    private static int ORIG_AGE = 30;
-
-    private static String ORIG_PARENT_NAME = "origParentName";
-
-    private static int ORIG_PARENT_AGE = 31;
-
-    private OpenJPAEntityManagerFactory timeoutFactory = null;
-
-    private OpenJPAEntityManagerFactory factory = null;
-
-    private OpenJPAEntityManagerFactory factory2 = null;
-
-    private MetaDataRepository repos;
-
-    private Object oid;
-
-    private Object parentOid;
-
-    private Object oidwithclass;
-
-    private OpenJPAEntityManager em;
-
-    private CacheObjectA a;
-
-    public CacheTest(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    public void clear() throws Exception {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            Class[] toDelete = new Class[]{ CacheObjectA.class,
-                CacheObjectB.class, CacheObjectC.class, CacheObjectD.class,
-                CacheObjectE.class, CacheObjectJ.class,
-                AppIdCacheObject.class, };
-            for (int i = 0; i < toDelete.length; i++) {
-                startTx(em);
-                Extent e = em.createExtent(toDelete[i], true);
-                Iterator it = e.iterator();
-                while (it.hasNext()) {
-                    em.remove(it.next());
-                }
-                endTx(em);
-            }
-        }
-        catch (OpenJPAException jpae) {
-            Throwable[] ts = jpae.getNestedThrowables();
-            for (int i = 0; ts != null && i < ts.length; i++) {
-                ts[i].printStackTrace();
-            }
-//			jpae.printStackTrace();
-
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    /**
-     * Return a string array of extra configuration options for the specified
-     * cache.
-     */
-    protected abstract String[] getConfs();
-
-    /**
-     * Return a string array of extra configuration options for a second cache.
-     */
-    protected abstract String[] getConfs2();
-
-    /**
-     * Return true if this cache is a coherent one (one where changes in one
-     * cache are immediately visible elsewhere); otherwise returns false. In the
-     * context of this test class, coherence is a single-JVM thing only.
-     */
-    protected boolean isCacheCoherent() {
-        return false;
-    }
-
-    public void setUp() throws Exception {
-
-        String[] confs = getConfs();
-        for (int i = 0; i < confs.length; i = i + 2) {
-            if ("openjpa.DataCache".equals(confs[i]))
-                confs[i + 1] +=
-                    ", true(Name=not-the-default-cache, CacheSize=10)";
-        }
-
-        String[] confs2 = getConfs2();
-        for (int i = 0; i < confs2.length; i = i + 2) {
-            if ("openjpa.DataCache".equals(confs2[i]))
-                confs2[i + 1] +=
-                    ", true(Name=not-the-default-cache, CacheSize=10)";
-        }
-
-        Map propsMap1 = new HashMap();
-        for (int i = 0; i < confs.length; i += 2) {
-            propsMap1.put(confs[i], confs[i + 1]);
-        }
-        Map propsMap2 = new HashMap();
-        for (int i = 0; i < confs2.length; i += 2) {
-            propsMap2.put(confs2[i], confs2[i + 1]);
-        }
-
-        factory = (OpenJPAEntityManagerFactory) getEmf(propsMap1);
-        factory2 = (OpenJPAEntityManagerFactory) getEmf(propsMap2);
-
-        repos = JPAFacadeHelper.toBrokerFactory(factory).getConfiguration()
-            .getMetaDataRepositoryInstance();
-
-        String[] biggerConfs = new String[confs.length + 2];
-        System.arraycopy(confs, 0, biggerConfs, 0, confs.length);
-        biggerConfs[biggerConfs.length - 2] = "openjpa.DataCacheTimeout";
-        biggerConfs[biggerConfs.length - 1] = "1000";
-        Map propsMap3 = new HashMap();
-        for (int i = 0; i < biggerConfs.length; i += 2) {
-            propsMap3.put(biggerConfs[i], biggerConfs[i + 1]);
-        }
-        timeoutFactory = (OpenJPAEntityManagerFactory) getEmf(propsMap3);
-
-        clear();
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-
-        CacheObjectA a;
-        CacheObjectA aparent;
-        try {
-            // we can't specify this for UserTransaction
-            /*
-                * pm.currentTransaction().setNontransactionalRead(true);
-                * pm.currentTransaction().setOptimistic(true);
-                */
-
-//			em.setNontransactionalRead(true);
-//			em.setOptimistic(true);
-
-            a = new CacheObjectA(ORIG_NAME, ORIG_AGE);
-            aparent = new CacheObjectA(ORIG_PARENT_NAME, ORIG_PARENT_AGE);
-            a.setRelatedObject(aparent);
-            LinkedList children = new LinkedList();
-            children.add(a);
-            aparent.setRelatedCollection(children);
-
-            startTx(em);
-            em.persist(a);
-            em.persist(aparent);
-            oid = em.getObjectId(a);
-            oidwithclass = new Id(CacheObjectA.class, oid.toString());
-            parentOid = em.getObjectId(aparent);
-            endTx(em);
-        }
-        finally {
-            endEm(em);
-        }
-
-        // load an object in a separate pm before the update
-        // happens. This should not change, else we're in
-        // violation of the spec.
-        this.em = factory.createEntityManager();
-        startTx(this.em);
-        try {
-            // OpenJPAEntityManager openEm=(OpenJPAEntityManager) this.em;
-            this.a = (CacheObjectA) this.em.find(CacheObjectA.class, oid);
-
-            // load the parent for testCollections().
-            CacheObjectA rel = this.a.getRelatedObject();
-            rel.getRelatedCollection();
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-        }
-        finally {
-            endTx(this.em);
-            // endEm(this.em);
-        }
-
-        em = factory.createEntityManager();
-        try {
-            startTx(em);
-            a = (CacheObjectA) em.find(CacheObjectA.class, oid);
-            a.setName(NEW_NAME);
-
-            aparent = (CacheObjectA) em.find(CacheObjectA.class, parentOid);
-
-            CacheObjectA a2 = new CacheObjectA(ORIG_NAME, ORIG_AGE);
-            a2.setRelatedObject(aparent);
-            aparent.getRelatedCollection().add(a2);
-            em.persist(a2);
-            endTx(em);
-
-            assertNew(a);
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    public void tearDown() throws Exception {
-        endEm(em);
-
-        try {
-            factory.close();
-        }
-        catch (Exception e) {
-        }
-        try {
-            factory2.close();
-        }
-        catch (Exception e) {
-        }
-        super.tearDown();
-
-        factory = null;
-        factory2 = null;
-        timeoutFactory = null;
-        oid = null;
-        parentOid = null;
-        em = null;
-        a = null;
-    }
-
-    public void testDeletedOneToOneRelations() throws Exception {
-        EntityManager em = factory.createEntityManager();
-        try {
-            startTx(em);
-            CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
-            assertNotNull(a.getRelatedObject());
-            em.remove(a.getRelatedObject());
-            endTx(em);
-        }
-        finally {
-            endEm(em);
-        }
-
-        EntityManager em2 = factory.createEntityManager();
-        try {
-            CacheObjectA a2 = (CacheObjectA) em2.find(CacheObjectA.class, oid);
-            assertNull(a2.getRelatedObject());
-        }
-        finally {
-            endEm(em2);
-        }
-    }
-
-    public void testCanCacheExtension() throws Exception {
-        DataCache cache = cacheManager(factory).getSystemDataCache();
-
-        // first, test caching of newly created objects.
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        Object o;
-        Object oid;
-        try {
-            startTx(em);
-            o = new CacheObjectB("foo");
-            em.persist(o);
-            endTx(em);
-            oid = em.getObjectId(o);
-            assertNotNull(oid);
-            assertNull(cache.get(oid));
-        }
-        finally {
-            endEm(em);
-        }
-
-        // now, test caching of data loaded from the data store.
-        em = factory.createEntityManager();
-        try {
-            o = em.find(CacheObjectB.class, oid);
-            assertNotNull(o);
-            assertNull(cache.get(oid));
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    public void testGetCache() {
-        // first, test caching of newly created objects.
-        DataCache defaultCache = cacheManager(factory).getDataCache(
-            DataCache.NAME_DEFAULT, false);
-        assertNotNull(defaultCache);
-
-        DataCache cache = cacheManager(factory).getSystemDataCache();
-        assertEquals(defaultCache, cache);
-
-        ClassMetaData aMeta = repos.getMetaData(CacheObjectA.class, null, true);
-        ClassMetaData aChild1Meta = repos.getMetaData(CacheObjectAChild1.class,
-            null, true);
-        ClassMetaData aChild2Meta = repos.getMetaData(CacheObjectAChild2.class,
-            null, true);
-        ClassMetaData bMeta = repos.getMetaData(CacheObjectB.class, null, true);
-        ClassMetaData bChild1Meta = repos.getMetaData(CacheObjectBChild1.class,
-            null, true);
-        ClassMetaData cMeta = repos.getMetaData(CacheObjectC.class, null, true);
-        ClassMetaData dMeta = repos.getMetaData(CacheObjectD.class, null, true);
-        ClassMetaData eMeta = repos.getMetaData(CacheObjectE.class, null, true);
-
-        cache = aMeta.getDataCache();
-        assertEquals(defaultCache, cache);
-        System.out.println("******DataCacheName:"
-            + aChild2Meta.getDataCacheName());
-        assertNull(aChild2Meta.getDataCache());
-
-        assertNull(bMeta.getDataCache());
-
-        assertEquals(cMeta.getDataCache(), dMeta.getDataCache());
-        if (dMeta.getDataCache() instanceof ConcurrentDataCache) {
-            ConcurrentDataCache dCacheImpl =
-                (ConcurrentDataCache) dMeta.getDataCache();
-            assertEquals(10, dCacheImpl.getCacheSize());
-        }
-        assertEquals(aMeta.getDataCache(), eMeta.getDataCache());
-    }
-
-    public void testPrimitives() throws Exception {
-        // make sure that the 'a' that was found before changes
-        // were made is still valid.
-        assertOld(a);
-        em.refresh(a);
-        assertNew(a);
-    }
-
-    // FIXME Seetha Sep 25,2006
-    /*
-      * public void testCollections() throws Exception { CacheObjectA parent =
-      * (CacheObjectA) em.find(CacheObjectA.class,ORIG_PARENT_NAME);
-      * assertEquals(1, parent.getRelatedCollection().size());
-      * em.refresh(parent); assertEquals(2,
-      * parent.getRelatedCollection().size()); }
-      */
-
-    // FIXME Seetha Sep 25,2006
-    /*
-      * public void testExpiredCollections() { CacheObjectA parent =
-      * (CacheObjectA) em.find(CacheObjectA.class,ORIG_PARENT_NAME);
-      * em.refresh(parent); Collection relatedOids = new HashSet(); for (Iterator
-      * iter = parent.getRelatedCollection().iterator(); iter.hasNext();) {
-      * relatedOids.add(JDOHelper.getObjectId(iter.next())); }
-      *
-      * ClassMetaData meta = repos.getMetaData(CacheObjectA.class, null, true);
-      * DataCache cache = meta.getDataCache();
-      *  // drop the related data from the cache for (Iterator iter =
-      * relatedOids.iterator(); iter.hasNext();) cache.remove(iter.next());
-      *
-      * PersistenceManager pm2 = factory.getPersistenceManager(); try {
-      * assertTrue(cache.contains(parentOid)); parent = (CacheObjectA)
-      * pm2.getObjectById(parentOid, true);
-      *
-      * try { for (Iterator iter = relatedOids.iterator(); iter.hasNext();)
-      * assertFalse(cache.contains(iter.next())); } catch (AssertionFailedError
-      * e) { bug(467, "data cache can over-eagerly load relation data"); } }
-      * finally { close(pm2); } }
-      */
-
-    public void testExpiredRelations() {
-        CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
-        em.refresh(a);
-        Object relationOid = em.getObjectId(a.getRelatedObject());
-        relationOid = new Id(CacheObjectA.class, relationOid.toString());
-
-        ClassMetaData meta = repos.getMetaData(CacheObjectA.class, null, true);
-        DataCache cache = meta.getDataCache();
-
-        // drop the related data from the cache
-        cache.remove(relationOid);
-
-        OpenJPAEntityManager em2 = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            assertTrue(cache.contains(oidwithclass));
-            a = (CacheObjectA) em2.find(CacheObjectA.class, oid);
-
-            try {
-                assertFalse(cache.contains(relationOid));
-            }
-            catch (AssertionFailedError e) {
-                // bug(467, "data cache can over-eagerly load relation data");
-                e.printStackTrace();
-            }
-        }
-        finally {
-            endEm(em2);
-        }
-    }
-
-    public void testPCArrays() throws Exception {
-        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            startTx(newEm);
-            CacheObjectA parent = (CacheObjectA) newEm.find(CacheObjectA.class,
-                parentOid);
-            CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            a.setRelatedArray(new CacheObjectA[]{ parent, a });
-            endTx(newEm);
-        }
-        finally {
-            endEm(newEm);
-        }
-
-        newEm = (OpenJPAEntityManager) factory.createEntityManager();
-        try {
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            CacheObjectA[] array = a.getRelatedArray();
-            assertEquals(2, array.length);
-            assertTrue(array[0] instanceof CacheObjectA);
-            assertTrue(array[1] instanceof CacheObjectA);
-
-            Object arrayOid = newEm.getObjectId(array[0]);
-            if (!arrayOid.equals(parentOid) && !arrayOid.equals(oid)) {
-                fail("array does not contain correct oids");
-            }
-
-            arrayOid = newEm.getObjectId(array[1]);
-            if (!arrayOid.equals(parentOid) && !arrayOid.equals(oid)) {
-                fail("array does not contain correct oids");
-            }
-        }
-        finally {
-            endEm(newEm);
-        }
-    }
-
-    public void testStringArrays() throws Exception {
-        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            startTx(newEm);
-            CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            a.setStringArray(new String[]{ "string0", "string1", "string2" });
-            endTx(newEm);
-        }
-        finally {
-            endEm(newEm);
-        }
-
-        newEm = (OpenJPAEntityManager) factory.createEntityManager();
-        try {
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            String[] array = a.getStringArray();
-            assertEquals(3, array.length);
-            assertEquals("string0", array[0]);
-            assertEquals("string1", array[1]);
-            assertEquals("string2", array[2]);
-        }
-        finally {
-            endEm(newEm);
-        }
-    }
-
-    public void testPrimitiveArrays() throws Exception {
-        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            startTx(newEm);
-            CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            a.setPrimitiveArray(new float[]{ 0, 1, 2 });
-            endTx(newEm);
-        }
-        finally {
-            endEm(newEm);
-        }
-
-        newEm = (OpenJPAEntityManager) factory.createEntityManager();
-        try {
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            float[] array = a.getPrimitiveArray();
-            assertEquals(3, array.length);
-            assertEquals(0.0F, array[0], 0);
-            assertEquals(1.0F, array[1], 0);
-            assertEquals(2.0f, array[2], 0);
-        }
-        finally {
-            endEm(newEm);
-        }
-    }
-
-    public void testDateArrays() throws Exception {
-        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        CacheObjectA a;
-        Date[] dateArray;
-        try {
-            startTx(newEm);
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            dateArray = new Date[]{ new Date(), new Date(), new Date() };
-            a.setDateArray(dateArray);
-            endTx(newEm);
-        }
-        finally {
-            endEm(newEm);
-        }
-
-        newEm = (OpenJPAEntityManager) factory.createEntityManager();
-        try {
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            Date[] array = a.getDateArray();
-            if (array[0] == dateArray[0]) {
-                fail("date objects are the same");
-            }
-        }
-        finally {
-            endEm(newEm);
-        }
-    }
-
-    public void testDate() throws Exception {
-        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        CacheObjectA a;
-        Date d;
-        try {
-            startTx(newEm);
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            d = new Date();
-            a.setDate(d);
-            endTx(newEm);
-        }
-        finally {
-            endEm(newEm);
-        }
-
-        // sleep a bit so we can ensure that the date doesn't just
-        // happen to be the same.
-        Thread.sleep(100);
-
-        newEm = (OpenJPAEntityManager) factory.createEntityManager();
-        try {
-            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-            Date d2 = a.getDate();
-            if (d == d2) {
-                fail("date objects are the same");
-            }
-
-            assertEquals(d.getTime(), d2.getTime());
-        }
-        finally {
-            endEm(newEm);
-        }
-    }
-
-    public void testLocale() throws Exception {
-        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        startTx(newEm);
-        CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-        Locale l = Locale.getDefault();
-        a.setLocale(l);
-        endTx(newEm);
-
-        OpenJPAEntityManager newEm2 = (OpenJPAEntityManager) factory
-            .createEntityManager();
-
-        a = (CacheObjectA) newEm2.find(CacheObjectA.class, oid);
-        Locale l2 = a.getLocale();
-        // locales are immutable and final, so the different cached
-        // copies should be ==.
-        if (l != l2) {
-            fail("locale objects are not the same.");
-        }
-
-        endEm(newEm);
-        endEm(newEm2);
-    }
-
-    // ---------- Test query caching ----------
-    // * FCOs as params
-    // * multi-threaded stuff
-    // * access path stuff (see also TestQueryAccessPath)
-    // * serializability of returned lists
-    // * PM.setQueryCacheEnabled (false);
-    // * Query.setQueryCacheEnabled (false);
-    // * Pessimistic transactions
-
-    public void testBasicQuery() {
-        basicQueries(factory.createEntityManager(), Boolean.FALSE, 3, 1);
-        basicQueries(factory.createEntityManager(), Boolean.TRUE, 3, 1);
-
-        // manually notify the cache of changes
-        QueryCache cache = cacheManager(factory).getSystemQueryCache();
-
-        // test to see if modifying B causes A's query cache to be flushed
-        Set s = new HashSet();
-        s.add(CacheObjectB.class);
-        cache.onTypesChanged(new TypesChangedEvent(this, s));
-        basicQueries(factory.createEntityManager(), Boolean.TRUE, 3, 1);
-
-        // test to see if modifying A causes A's query cache to be flushed
-        s.add(CacheObjectA.class);
-        cache.onTypesChanged(new TypesChangedEvent(this, s));
-        basicQueries(factory.createEntityManager(), Boolean.FALSE, 3, 1);
-
-        // make sure that non-manual notification works
-        EntityManager em = factory.createEntityManager();
-        try {
-            startTx(em);
-            CacheObjectA a = new CacheObjectA(ORIG_NAME, ORIG_AGE);
-            em.persist(a);
-            endTx(em);
-        }
-        finally {
-            endEm(em);
-        }
-
-        basicQueries(factory.createEntityManager(), Boolean.FALSE, 4, 2);
-    }
-
-    protected void basicQueries(EntityManager em, Boolean inCache, int allSize,
-        int origSize) {
-        try {
-            long start;
-            long q1p1;
-            long q1p2;
-            long q2p1;
-            long q2p2;
-
-            Broker broker = JPAFacadeHelper.toBroker(em);
-            org.apache.openjpa.kernel.Query q = broker.newQuery(
-                JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectA.class.getSimpleName() + " a");
-            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
-            start = System.currentTimeMillis();
-            assertInCache(q, inCache);
-            List l = (List) q.execute();
-            iterate(l);
-            q1p1 = System.currentTimeMillis() - start;
-
-            assertEquals(allSize, l.size());
-
-            start = System.currentTimeMillis();
-            List l2 = (List) q.execute();
-            iterate(l2);
-            q1p2 = System.currentTimeMillis() - start;
-            assertEquals(allSize, l2.size());
-
-            q = broker.newQuery(JPQLParser.LANG_JPQL,
-                "select a.name,a.age from "
-                    + CacheObjectA.class.getSimpleName()
-                    + " a where a.name = :n AND a.age = :a");
-            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
-            start = System.currentTimeMillis();
-            assertInCache(q, inCache, new Object[]{ ORIG_NAME,
-                new Integer(ORIG_AGE) });
-            l = (List) q.execute(new Object[]{ ORIG_NAME,
-                new Integer(ORIG_AGE) });
-            iterate(l);
-            q2p1 = System.currentTimeMillis() - start;
-
-            assertEquals(origSize, l.size());
-
-            start = System.currentTimeMillis();
-            l2 = (List) q.execute(new Object[]{ ORIG_NAME,
-                new Integer(ORIG_AGE) });
-            iterate(l2);
-            q2p2 = System.currentTimeMillis() - start;
-
-            assertEquals(origSize, l2.size());
-            // System.out.println ("inCache: " + inCache + ";\t q1p1: " + q1p1
-            // + ";\t q1p2: " + q1p2 + ";\t q2p1: " + q2p1 + ";\t q2p2: "
-            // + q2p2);
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    public void testNonCacheableClass() {
-        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
-        try {
-            org.apache.openjpa.kernel.Query q = broker.newQuery(
-                JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectB.class.getSimpleName() + " a");
-
-            Collection c = (Collection) q.execute();
-            iterate(c);
-
-            assertInCache(q, Boolean.FALSE);
-        }
-        finally {
-            close(broker);
-        }
-    }
-
-    public void testNonCacheableAccessPath() {
-        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
-        try {
-            org.apache.openjpa.kernel.Query q = broker.newQuery(
-                JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectA.class.getSimpleName()
-                + " a where a.relatedB.str = 'foo'");
-            // "relatedB.str == 'foo'");
-            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
-
-            Collection c = (Collection) q.execute();
-            iterate(c);
-
-            assertInCache(q, Boolean.FALSE);
-        }
-        finally {
-            close(broker);
-        }
-    }
-
-    public void testNonCacheableSubclasses1() {
-        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
-        try {
-            // a query on the CacheObjectA class includes an uncacheable
-            // class; it should therefore not be cacheable.
-            org.apache.openjpa.kernel.Query q = broker.newQuery(
-                JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectA.class.getSimpleName() + " a");
-
-            Collection c = (Collection) q.execute();
-            iterate(c);
-
-            assertInCache(q, Boolean.FALSE);
-        }
-        finally {
-            close(broker);
-        }
-    }
-
-    public void testNonCacheableSubclasses2() {
-        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
-        try {
-            // a query on the CacheObjectA extent configured without
-            // subclasses does not include an uncacheable class; it should
-            // therefore be cacheable.
-            org.apache.openjpa.kernel.Query q = broker.newQuery(
-                JPQLParser.LANG_JPQL, "select a from "
-                + CacheObjectA.class.getSimpleName() + " a");
-            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
-
-            Collection c = (Collection) q.execute();
-            iterate(c);
-
-            assertInCache(q, Boolean.TRUE);
-        }
-        finally {
-            close(broker);
-        }
-    }
-
-    public void testCacheNames() {
-        assertCacheName(CacheObjectA.class, DataCache.NAME_DEFAULT);
-        assertCacheName(CacheObjectAChild1.class, DataCache.NAME_DEFAULT);
-        assertCacheName(CacheObjectAChild2.class, null);
-        assertCacheName(CacheObjectB.class, null);
-        assertCacheName(CacheObjectBChild1.class, null);
-        assertCacheName(CacheObjectC.class, "not-the-default-cache");
-        assertCacheName(CacheObjectD.class, "not-the-default-cache");
-        assertCacheName(CacheObjectE.class, DataCache.NAME_DEFAULT);
-        assertCacheName(CacheObjectF.class, DataCache.NAME_DEFAULT);
-        assertCacheName(CacheObjectG.class, DataCache.NAME_DEFAULT);
-        assertCacheName(CacheObjectH.class, DataCache.NAME_DEFAULT);
-        assertCacheName(CacheObjectJ.class, DataCache.NAME_DEFAULT);
-        assertCacheName(AppIdCacheObject.class, DataCache.NAME_DEFAULT);
-    }
-
-    private void assertCacheName(Class cls, String cacheName) {
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(factory, cls);
-        if (cacheName == null)
-            assertNull(meta.getDataCache());
-        else {
-            assertNotNull(meta.getDataCache());
-            assertEquals(cacheName, meta.getDataCache().getName());
-        }
-    }
-
-    // FIXME Seetha Sep 26,2006
-    // not able to replace pm.newQuery(CacheObjectA.class);
-    /*
-      * public void testQueryAggregates() { PersistenceManager pm =
-      * factory.getPersistenceManager(); try { Query q =
-      * pm.newQuery(CacheObjectA.class); q.setResult("max (age)"); Object o =
-      * q.execute(); assertTrue("o must be instanceof Number", o instanceof
-      * Number); } finally { close(pm); } }
-      */
-
-    public void testCache2() {
-        OpenJPAEntityManager em1 =
-            (OpenJPAEntityManager) factory.createEntityManager();
-        OpenJPAEntityManager em2 = null;
-        DataCache cache;
-
-        try {
-            CacheObjectA a1 = (CacheObjectA) em1.find(CacheObjectA.class, oid);
-
-            em2 = (OpenJPAEntityManager) factory2.createEntityManager();
-            CacheObjectA a2 = (CacheObjectA) em2.find(CacheObjectA.class, oid);
-
-            // assert that the oid is in factory2's cache
-            //MetaDataRepository repos2 = factory2.getConfiguration().getMetaDataRepositoryInstance();
-            MetaDataRepository repos2 =
-                ((((OpenJPAEntityManagerFactorySPI) factory2)).getConfiguration())
-                    .getMetaDataRepositoryInstance();
-            ClassMetaData meta = repos2
-                .getMetaData(CacheObjectA.class, em2.getClassLoader(), true);
-            cache = meta.getDataCache();
-            assertTrue(cache.contains(oidwithclass));
-
-            // modify the object.
-            startTx(em1);
-            a1.setName(a1.getName() + " changed");
-            endTx(em1);
-        }
-        finally {
-            if (em2 != null)
-                endEm(em2);
-            endEm(em1);
-        }
-
-        // if the cache is a coherent one, then the changes should be
-        // seen. Otherwise, they should not.
-        if (isCacheCoherent() || factory == factory2)
-            assertTrue("key " + oid + " was not in cache; should have been",
-                cache.contains(oidwithclass));
-        else
-            assertFalse("key " + oid + " was in cache; should not have been",
-                cache.contains(oidwithclass));
-    }
-
-    public void testTimeouts1() throws Exception {
-        timeoutsTest1(1);
-    }
-
-    public void timeoutsTest1(int tries) throws Exception {
-        // this crazy for looping stuff is here because we're seeing
-        // intermittent failures with the garbage collector kicking in
-        // during testing. So, this decreases the chances that that
-        // will happen.
-        Exception e = null;
-        int i;
-        for (i = 0; i < tries; i++) {
-            try {
-                timeoutsHelper(factory);
-                // any successes will pass the test
-                return;
-            }
-            catch (Exception ex) {
-                e = ex;
-            }
-        }
-
-        throw e;
-    }
-
-    public void testTimeouts2() throws Exception {
-        timeoutsTest2(30);
-    }
-
-    public void timeoutsTest2(int tries) throws Exception {
-        Error e = null;
-        for (int i = 0; i < tries; i++) {
-            try {
-                timeoutsHelper(timeoutFactory);
-                // any successes will pass the test
-                return;
-            }
-            catch (AssertionFailedError afe) {
-                e = afe;
-            }
-        }
-
-        throw e;
-    }
-
-    private void timeoutsHelper(OpenJPAEntityManagerFactory factory)
-        throws Exception {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            startTx(em);
-
-            CacheObjectE e = new CacheObjectE("e");
-            em.persist(e);
-
-            CacheObjectF f = new CacheObjectF("f");
-            em.persist(f);
-
-            CacheObjectG g = new CacheObjectG("g");
-            em.persist(g);
-
-            CacheObjectH h = new CacheObjectH("h");
-            em.persist(h);
-
-            endTx(em);
-
-            Object[] ids = new Object[4];
-            ids[0] = new Id(CacheObjectE.class, em.getObjectId(e).toString());
-            ids[1] = new Id(CacheObjectF.class, em.getObjectId(f).toString());
-            ids[2] = new Id(CacheObjectG.class, em.getObjectId(g).toString());
-            ids[3] = new Id(CacheObjectH.class, em.getObjectId(h).toString());
-
-            // build up some queries to test
-
-            // this one should be only on the superclass, since
-            // CacheObjectF has a timeout.
-            Broker broker = JPAFacadeHelper.toBroker(em);
-            org.apache.openjpa.kernel.Query q1 = broker.newQuery(
-                JPQLParser.LANG_JPQL, "select a from "
-                + CacheObjectE.class.getSimpleName() + " a");
-            q1.setCandidateExtent(broker.newExtent(CacheObjectE.class, false));
-            iterate((Collection) q1.execute());
-            assertInCache(q1, Boolean.TRUE);
-
-            org.apache.openjpa.kernel.Query q2 = broker.newQuery(
-                JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectF.class.getSimpleName() + " a");
-            iterate((Collection) q2.execute());
-            assertInCache(q2, Boolean.TRUE);
-
-            DataCache cache = cacheManager(factory).getDataCache(
-                DataCache.NAME_DEFAULT, false);
-            checkCache(cache, ids, new boolean[]{ true, true, true, true });
-
-            // should cause h to be dropped.
-            Thread.currentThread().sleep(551);
-            Thread.yield();
-            checkCache(cache, ids, new boolean[]{ true, true, true, false });
-
-            // if this run has a default timeout (set to 1 sec in the test
-            // case), e should be timed out by this point.
-            //boolean eStatus = !(factory.getConfiguration().getDataCacheTimeout() > 0);
-            boolean eStatus =
-                !((((OpenJPAEntityManagerFactorySPI) factory).getConfiguration())
-                    .getDataCacheTimeout() > 0);
-
-            // should cause f to be dropped.
-            Thread.currentThread().sleep(550);
-            Thread.yield();
-            checkCache(cache, ids,
-                new boolean[]{ eStatus, false, true, false });
-
-            // at this point, q2 should be dropped (because its candidate
-            // class is CacheObjectF), and q1 might be dropped, depending
-            // on whether or not we've got a timeout configured.
-            assertInCache(q1, (eStatus) ? Boolean.TRUE : Boolean.FALSE);
-            assertInCache(q2, Boolean.FALSE);
-
-            // should cause g to be dropped.
-            Thread.currentThread().sleep(4050);
-            Thread.yield();
-            checkCache(cache, ids,
-                new boolean[]{ eStatus, false, false, false });
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    public void testQueryTimeouts() throws Exception {
-        queryTimeoutsHelper(factory);
-        queryTimeoutsHelper(timeoutFactory);
-    }
-
-    private void queryTimeoutsHelper(OpenJPAEntityManagerFactory factory)
-        throws Exception {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            startTx(em);
-
-            CacheObjectE e = new CacheObjectE("e");
-            em.persist(e);
-
-            CacheObjectF f = new CacheObjectF("f");
-            em.persist(f);
-
-            endTx(em);
-
-            // build up some queries to test
-            Broker broker = JPAFacadeHelper.toBroker(em);
-            org.apache.openjpa.kernel.Query q1 = broker
-                .newQuery(JPQLParser.LANG_JPQL, "SELECT a FROM CacheObjectE a");
-
-            q1.setCandidateExtent(broker.newExtent(CacheObjectE.class, false));
-            iterate((Collection) q1.execute());
-            assertInCache(q1, Boolean.TRUE);
-
-            org.apache.openjpa.kernel.Query q2 = broker
-                .newQuery(JPQLParser.LANG_JPQL, "SELECT a FROM CacheObjectF a");
-            iterate((Collection) q2.execute());
-            assertInCache(q2, Boolean.TRUE);
-
-            // if this run has a default timeout (set to 1 sec in the test
-            // case), e should be timed out by this point.
-            //boolean eTimedOut = factory.getConfiguration().getDataCacheTimeout() > 0;
-            boolean eTimedOut =
-                ((((OpenJPAEntityManagerFactorySPI) factory).getConfiguration())
-                    .getDataCacheTimeout() > 0);
-
-            // should cause f to be dropped.
-            Thread.currentThread().sleep(1001);
-
-            // at this point, q2 should be dropped (because its candidate
-            // class is CacheObjectF), and q1 might be dropped, depending
-            // on whether or not we've got a timeout configured.
-            assertInCache(q1, (eTimedOut) ? Boolean.FALSE : Boolean.TRUE);
-            assertInCache(q2, Boolean.FALSE);
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    public void testQueryImplicitEvictions() throws Exception {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            RuntimeTest1[] helperObjs = new RuntimeTest1[5];
-            helperObjs[0] = new RuntimeTest1();
-            helperObjs[1] = new RuntimeTest1();
-            helperObjs[2] = new RuntimeTest1();
-            helperObjs[3] = new RuntimeTest1();
-            helperObjs[4] = new RuntimeTest1();
-            startTx(em);
-            em.persist(helperObjs[0]);
-            em.persist(helperObjs[1]);
-            em.persist(helperObjs[2]);
-            em.persist(helperObjs[3]);
-            em.persist(helperObjs[4]);
-            endTx(em);
-
-            DataCache cache = cacheManager(factory).getDataCache(
-                DataCache.NAME_DEFAULT, false);
-
-            if (!isOpenJPACache(cache)) {
-                bug(627, "Tangosol cache impl needs modernization");
-                return;
-            }
-
-            if (cache instanceof DelegatingDataCache)
-                cache = ((DelegatingDataCache) cache).getInnermostDelegate();
-            if (cache instanceof ConcurrentDataCache) {
-                CacheMap map = ((ConcurrentDataCache) cache).getCacheMap();
-                map.setCacheSize(3);
-                map.setSoftReferenceSize(0);
-            } else if (cache instanceof ConcurrentDataCache) {
-                CacheMap map = ((ConcurrentDataCache) cache).getCacheMap();
-                map.setCacheSize(3);
-                map.setSoftReferenceSize(0);
-            }
-
-            startTx(em);
-            CacheObjectH h = new CacheObjectH("h");
-            em.persist(h);
-            CacheObjectJ j = new CacheObjectJ("j", h);
-            em.persist(j);
-            endTx(em);
-            Object hoid = em.getObjectId(h);
-            Object joid = em.getObjectId(j);
-
-            Object hoidwithclass = new Id(CacheObjectH.class, hoid.toString());
-            Object joidwithclass = new Id(CacheObjectJ.class, joid.toString());
-            endEm(em);
-
-            // make sure j and h are in cache; may not be if not LRU
-            int attempts = 0;
-            for (; attempts < 100 && !cache.contains(joidwithclass); attempts++)
-            {
-                em = factory.createEntityManager();
-                if (!cache.contains(hoidwithclass))
-                    em.find(CacheObjectH.class, hoid);
-                if (!cache.contains(joidwithclass))
-                    em.find(CacheObjectJ.class, joid);
-                endEm(em);
-            }
-            assertTrue("Could not get queried objects into cache",
-                attempts < 100);
-
-            // build up a query that uses H in its access path...
-            em = factory.createEntityManager();
-            Broker broker = JPAFacadeHelper.toBroker(em);
-            org.apache.openjpa.kernel.Query q = broker.newQuery(
-                JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectJ.class.getSimpleName()
-                + " a where a.str = 'h'");
-            iterate((Collection) q.execute());
-            assertInCache(q, Boolean.TRUE);
-            endEm(em);
-
-            // force h out of the cache. we might have to try multiple times
-            // if the cache is not LRU
-            attempts = 0;
-            for (; attempts < 100 && cache.contains(joidwithclass); attempts++)
-            {
-                em = factory.createEntityManager();
-                for (int i = 0; i < 5; i++)
-                    em.find(RuntimeTest1.class, em.getObjectId(helperObjs[i]));
-                endEm(em);
-            }
-            assertTrue("Could not kick queried objects out of cache",
-                attempts < 100);
-
-            em = factory.createEntityManager();
-            broker = JPAFacadeHelper.toBroker(em);
-            q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM "
-                + CacheObjectJ.class.getSimpleName()
-                + " a where a.str = 'h'");
-            try {
-                assertInCache(q, null);
-            }
-            catch (AssertionFailedError e) {
-                bug(626, "query cache invalidation is broken");
-            }
-
-            // ### should test remote events causing queries to evict.
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    // FIXME SEetha Sep 26,2006
-    // not able to replace pm.newQuery(CacheObjectE.class);
-    /*
-      * public void testAllegedQueryOrderingChanges() throws Exception { //
-      * inspired by tsc 3013. pcl: I have not been able to get this // test case
-      * to actually fail. However, during analysis of // 3013's stack traces, I
-      * discovered that the // QueryKey.equals() method did not deal with the
-      * ordering // field correctly, possibly causing the problem.
-      *
-      * OpenJPAEntityManager em = (OpenJPAEntityManager)
-      * factory.createEntityManager(); try { startTx(em,
-      * ()); CacheObjectE e = new CacheObjectE("e"); em.persist(e);
-      * endTx(em); } finally {
-      * endEm(em); }
-      *
-      * em = factory.createEntityManager(); Query q; Collection c; List l; try {
-      * q = em.createQuery(CacheObjectE.class); q.setOrdering("str ascending"); c =
-      * (Collection) q.execute(); l = new LinkedList(c); assertEquals(1,
-      * c.size()); } finally { endEm(em); }
-      *
-      * em = factory.createEntityManager(); try { q =
-      * em.createQuery(CacheObjectE.class); q.setOrdering("str ascending"); c =
-      * (Collection) q.execute(); l = new LinkedList(c); assertEquals(1,
-      * c.size()); } finally { endEm(em); }
-      *
-      * try { em = factory.createEntityManager(); q =
-      * em.createQuery(CacheObjectE.class); q.setOrdering("str descending"); c =
-      * (Collection) q.execute(); assertEquals(1, c.size()); l = new
-      * LinkedList(c); } finally { endEm(em); } }
-      */
-
-    public void testAllegedConcurrentModificationException() throws Exception {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        CacheObjectE e;
-        try {
-            ClassMetaData meta = JPAFacadeHelper.getMetaData(em,
-                CacheObjectE.class);
-            if (!isOpenJPACache(meta.getDataCache()))
-                return;
-
-            startTx(em);
-            e = new CacheObjectE("e");
-            em.persist(e);
-            endTx(em);
-        }
-        finally {
-            endEm(em);
-        }
-
-        em = factory.createEntityManager();
-        try {
-            startTx(em);
-
-            // find the new object...
-            OpenJPAQuery q = em.createQuery("select a FROM "
-                + CacheObjectE.class.getSimpleName()
-                + " a where a.str = 'e'");
-            e = (CacheObjectE) ((Collection) q.getResultList()).iterator()
-                .next();
-
-            // ... and modify the changed object.
-            e.setStr("e2");
-            e.setStr("e3");
-            endTx(em);
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    private boolean isOpenJPACache(DataCache cache) {
-        if (cache instanceof DelegatingDataCache)
-            cache = ((DelegatingDataCache) cache).getInnermostDelegate();
-
-        return cache instanceof ConcurrentDataCache;
-    }
-
-    // ---------- utility methods ----------
-
-    private void checkCache(DataCache cache, Object[] ids, boolean[] stati) {
-        CacheTestHelper.checkCache(this, cache, ids, stati);
-    }
-
-    private void assertInCache(org.apache.openjpa.kernel.Query q,
-        Boolean inCache) {
-        CacheTestHelper.assertInCache(this, q, inCache);
-    }
-
-    private void assertInCache(org.apache.openjpa.kernel.Query q,
-        Boolean inCache, Object[] args) {
-        CacheTestHelper.assertInCache(this, q, inCache, args);
-    }
-
-    private void iterate(Collection c) {
-        CacheTestHelper.iterate(c);
-    }
-
-    public void testInterface() throws Exception {
-        OpenJPAEntityManager newEm =
-            (OpenJPAEntityManager) factory.createEntityManager();
-        startTx(newEm);
-        CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-        CacheObjectC c = new CacheObjectC("blah");
-        a.setRelatedInterface(c);
-        endTx(newEm);
-        Object cId = newEm.getObjectId(c);
-        endEm(newEm);
-
-        newEm = (OpenJPAEntityManager) factory.createEntityManager();
-        a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
-
-        CacheObjectInterface c2 = a.getRelatedInterface();
-        assertNotNull(c2);
-
-        assertEquals(cId, newEm.getObjectId(c2));
-    }
-
-    public void testQueriesOnCollectionsDontUseCache() {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        try {
-            startTx(em);
-            CacheObjectE e = new CacheObjectE("e");
-            em.persist(e);
-            endTx(em);
-        }
-        finally {
-            endEm(em);
-        }
-
-        em = (OpenJPAEntityManager) factory.createEntityManager();
-        OpenJPAQuery q;
-        Collection c;
-        try {
-            q = em.createQuery("select a FROM "
-                + CacheObjectE.class.getSimpleName()
-                + " a where a.str = 'e'");
-            c = new ArrayList((Collection) q.getResultList());
-            assertEquals(1, c.size());
-            q.closeAll();
-        }
-        finally {
-            endEm(em);
-        }
-
-        try {
-            em = (OpenJPAEntityManager) factory.createEntityManager();
-            q = em.createQuery("select a FROM "
-                + CacheObjectE.class.getSimpleName()
-                + " a where a.str = 'e'");
-            q.setCandidateCollection(new ArrayList(0));
-            c = (Collection) q.getResultList();
-            assertEquals(0, c.size());
-            q.closeAll();
-        }
-        finally {
-            endEm(em);
-        }
-    }
-
-    public void testDFGFieldsLoaded1() {
-        dfgFieldsLoadedHelper(false);
-    }
-
-    public void testDFGFieldsLoaded2() {
-        dfgFieldsLoadedHelper(true);
-    }
-
-    public void dfgFieldsLoadedHelper(boolean related) {
-        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        startTx(em);
-        OpenJPAQuery q;
-        Collection c;
-        try {
-
-            q = em.createQuery(
-                "select a FROM " + CacheObjectA.class.getSimpleName()
-                    + " a where a.name = :pName").setParameter("pName",
-                ORIG_NAME);
-
-            c = new ArrayList((Collection) q.getResultList());
-            assertEquals(1, c.size());
-            CacheObjectA a = (CacheObjectA) c.iterator().next();
-            if (related)
-                a.getRelatedArray();
-            em.detach(a);
-            assertEquals(ORIG_NAME, a.getName());
-            q.closeAll();
-        }
-        finally {
-            rollbackTx(em);
-            endEm(em);
-        }
-    }
-
-    // FIXME Seetha Sep 26,2006
-    /*
-      * public void testQueriesAfterModificationAreNotInCache() {
-      * OpenJPAEntityManager em = (OpenJPAEntityManager)
-      * factory.createEntityManager(); OpenJPAEntityManager em2 =
-      * (OpenJPAEntityManager) factory.createEntityManager();
-      *
-      * //FIXME Seetha Sep 26,2006 //em.setIgnoreCache(false);
-      * //em2.setIgnoreCache(false); ((FetchPlan) em.getFetchPlan()).
-      * setFlushBeforeQueries(FetchPlan.FLUSH_TRUE); ((FetchPlan)
-      * em2.getFetchPlan()). setFlushBeforeQueries(FetchPlan.FLUSH_TRUE);
-      *
-      * try { startTx(em); CacheObjectE e = new
-      * CacheObjectE("e"); em.persist(e); endTx(em,
-      * ());
-      *
-      * startTx(em);
-      *  // first, a query that should get into the cache. Broker broker =
-      * JPAFacadeHelper.toBroker(em); org.apache.openjpa.kernel.Query q =
-      * broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, "str ==
-      * \"e\""); Collection c = (Collection) q.execute(); for (Iterator iter =
-      * c.iterator(); iter.hasNext();) iter.next();
-      *
-      * assertEquals(1, c.size()); assertInCache(q, Boolean.TRUE);
-      *
-      * Broker broker2 = JPAFacadeHelper.toBroker(em2);
-      * org.apache.openjpa.kernel.Query q2 = broker2.newQuery(q.getLanguage(),
-      * q);
-      *  // make some modifications and look again. Should return // two results.
-      * e = new CacheObjectE("e"); em.persist(e);
-      *
-      * q = broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, "str ==
-      * \"e\""); c = (Collection) q.execute(); assertEquals(2, c.size()); for
-      * (Iterator iter = c.iterator(); iter.hasNext();) iter.next();
-      *  // original query should still be in cache assertInCache(q2,
-      * Boolean.TRUE);
-      *
-      * Collection c2 = (Collection) q2.execute(); assertEquals(1, c2.size());
-      *  // new query should not make it into cache
-      *
-      * q = broker .newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, null); c =
-      * (Collection) q.execute(); assertEquals(2, c.size()); for (Iterator iter =
-      * c.iterator(); iter.hasNext();) iter.next();
-      *
-      * assertInCache(q, Boolean.FALSE); } finally {
-      * rollbackTx(em);
-      * endEm(em);
-      * endEm(em2); } }
-      */
-
-    public void testCachedQueryClosureReleasesResources() {
-        // PersistenceManagerFactory factory =
-        // KodoHelper.createEntityManagerFactory ();
-        EntityManager initEm = factory.createEntityManager();
-        startTx(initEm);
-        CacheObjectE e = new CacheObjectE("e");
-        initEm.persist(e);
-        endTx(initEm);
-        endEm(initEm);
-
-        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
-        org.apache.openjpa.kernel.Query q = broker.newQuery(
-            JPQLParser.LANG_JPQL, "Select a FROM "
-            + CacheObjectE.class.getSimpleName()
-            + " a where a.str = 'e'");
-        Collection c = (Collection) q.execute();
-        for (Iterator iter = c.iterator(); iter.hasNext();)
-            iter.next();
-
-        assertEquals(1, c.size());
-        assertInCache(q, Boolean.TRUE);
-
-        ImplHelper.close(c);
-
-        broker.close();
-    }
-
-    public void testMutableSCOsAreConverted() {
-        OpenJPAEntityManager em0 = (OpenJPAEntityManager) factory
-            .createEntityManager();
-        OpenJPAEntityManager em1 = (OpenJPAEntityManager) factory
-            .createEntityManager();
-
-        startTx(em0);
-        CacheObjectA a = (CacheObjectA) em0.find(CacheObjectA.class, oid);
-
-        Date d = new Date();
-        a.setDate(d);
-
-        endTx(em0);
-        DataCache cache = cacheManager(factory).getDataCache(
-            DataCache.NAME_DEFAULT, false);
-        assertTrue(cache.contains(oidwithclass));
-        cache.remove(oidwithclass);
-
-        a = (CacheObjectA) em1.find(CacheObjectA.class, oid);
-        assertTrue(cache.contains(oidwithclass));
-
-        try {
-            PCData data = cache.get(oidwithclass);
-            ClassMetaData meta =
-                ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence
-                    .cast(factory)).getConfiguration()
-                    .getMetaDataRepositoryInstance().getMetaData(a.getClass(),
-                    null, false);
-            FieldMetaData fmd = meta.getField("date");
-            d = (Date) data.getData(fmd.getIndex());
-            Broker broker = JPAFacadeHelper.toBroker(em1);
-            OpenJPAStateManager sm = broker.getStateManager(a);
-            assertTrue(sm == ((ProxyDate) a.getDate()).getOwner());
-            assertEquals(Date.class, d.getClass());
-        }
-        finally {
-            endEm(em0);
-            endEm(em1);
-        }
-    }
-
-    public void testEmptyResultsAreCached() {
-        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
-        org.apache.openjpa.kernel.Query q = broker.newQuery(
-            JPQLParser.LANG_JPQL, "Select a FROM "
-            + CacheObjectAChild1.class.getSimpleName()
-            + " a where a.name = 'testEmptyResultsAreCached'");
-        Collection c = (Collection) q.execute();
-        assertEquals(0, c.size());
-        assertInCache(q, Boolean.TRUE);
-        broker.close();
-    }
-
-    private void doassertTrue(EntityManager em, String name, int age)
-        throws Exception {
-        CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
-        assertTrue(name.equals(a.getName()));
-        assertTrue(a.getAge() == age);
-        endEm(em);
-    }
-
-    private void assertNew(CacheObjectA a) {
-        assertTrue(NEW_NAME.equals(a.getName()));
-        assertTrue(ORIG_AGE == a.getAge());
-    }
-
-    private void assertOld(CacheObjectA a) {
-        assertTrue(ORIG_NAME.equals(a.getName()));
-        assertTrue(ORIG_AGE == a.getAge());
-    }
-
-    private DataCacheManager cacheManager(OpenJPAEntityManagerFactory factory) {
-        return CacheTestHelper
-            .cacheManager(JPAFacadeHelper.toBrokerFactory(factory));
-    }
-
-    private void close(EntityManager em) {
-        rollbackTx(em);
-        endEm(em);
-    }
-
-    private void close(Broker broker) {
-        if (broker.isActive())
-            broker.rollback();
-        broker.close();
-    }
-
-    public static void main(String[] args) throws Exception {
-        for (int i = 0; i < args.length; i++) {
-            String type = args[i];
-
-            CacheTest c;
-            if (type.equals("tcp")) {
-                c = new DistributedCacheTest("time test",
-                    ConcurrentDataCache.class);
-            } else if (type.equals("jms")) {
-                c = new DistributedCacheTest("time test",
-                    ConcurrentDataCache.class);
-            } else {
-                c = new TestLocalCache("time test");
-            }
-
-            c.setUp();
-            long start = System.currentTimeMillis();
-            int count = 1000;
-            for (int j = 0; j < count; j++) {
-                c.doassertTrue(c.factory.createEntityManager(), NEW_NAME,
-                    ORIG_AGE);
-            }
-            System.out.println(count + " iterations in "
-                + (System.currentTimeMillis() - start) + " millis");
-            c.tearDown();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.AppIdCacheObject;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild2;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectBChild1;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectC;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectD;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectF;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectG;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectH;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectInterface;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
+import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+import org.apache.openjpa.datacache.ConcurrentDataCache;
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.DelegatingDataCache;
+import org.apache.openjpa.datacache.QueryCache;
+import org.apache.openjpa.datacache.TypesChangedEvent;
+import org.apache.openjpa.datacache.DataCacheManager;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCData;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.util.CacheMap;
+import org.apache.openjpa.util.Id;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.ProxyDate;
+
+/**
+ * ### should add 1..1 relation test ### app id compound key test
+ */
+public abstract class CacheTest extends AbstractTestCase {
+
+    private static String ORIG_NAME = "origName";
+
+    private static String NEW_NAME = "newName";
+
+    private static int ORIG_AGE = 30;
+
+    private static String ORIG_PARENT_NAME = "origParentName";
+
+    private static int ORIG_PARENT_AGE = 31;
+
+    private OpenJPAEntityManagerFactory timeoutFactory = null;
+
+    private OpenJPAEntityManagerFactory factory = null;
+
+    private OpenJPAEntityManagerFactory factory2 = null;
+
+    private MetaDataRepository repos;
+
+    private Object oid;
+
+    private Object parentOid;
+
+    private Object oidwithclass;
+
+    private OpenJPAEntityManager em;
+
+    private CacheObjectA a;
+
+    public CacheTest(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    public void clear() throws Exception {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            Class[] toDelete = new Class[]{ CacheObjectA.class,
+                CacheObjectB.class, CacheObjectC.class, CacheObjectD.class,
+                CacheObjectE.class, CacheObjectJ.class,
+                AppIdCacheObject.class, };
+            for (int i = 0; i < toDelete.length; i++) {
+                startTx(em);
+                Extent e = em.createExtent(toDelete[i], true);
+                Iterator it = e.iterator();
+                while (it.hasNext()) {
+                    em.remove(it.next());
+                }
+                endTx(em);
+            }
+        }
+        catch (OpenJPAException jpae) {
+            Throwable[] ts = jpae.getNestedThrowables();
+            for (int i = 0; ts != null && i < ts.length; i++) {
+                ts[i].printStackTrace();
+            }
+//			jpae.printStackTrace();
+
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    /**
+     * Return a string array of extra configuration options for the specified
+     * cache.
+     */
+    protected abstract String[] getConfs();
+
+    /**
+     * Return a string array of extra configuration options for a second cache.
+     */
+    protected abstract String[] getConfs2();
+
+    /**
+     * Return true if this cache is a coherent one (one where changes in one
+     * cache are immediately visible elsewhere); otherwise returns false. In the
+     * context of this test class, coherence is a single-JVM thing only.
+     */
+    protected boolean isCacheCoherent() {
+        return false;
+    }
+
+    public void setUp() throws Exception {
+
+        String[] confs = getConfs();
+        for (int i = 0; i < confs.length; i = i + 2) {
+            if ("openjpa.DataCache".equals(confs[i]))
+                confs[i + 1] +=
+                    ", true(Name=not-the-default-cache, CacheSize=10)";
+        }
+
+        String[] confs2 = getConfs2();
+        for (int i = 0; i < confs2.length; i = i + 2) {
+            if ("openjpa.DataCache".equals(confs2[i]))
+                confs2[i + 1] +=
+                    ", true(Name=not-the-default-cache, CacheSize=10)";
+        }
+
+        Map propsMap1 = new HashMap();
+        for (int i = 0; i < confs.length; i += 2) {
+            propsMap1.put(confs[i], confs[i + 1]);
+        }
+        Map propsMap2 = new HashMap();
+        for (int i = 0; i < confs2.length; i += 2) {
+            propsMap2.put(confs2[i], confs2[i + 1]);
+        }
+
+        factory = (OpenJPAEntityManagerFactory) getEmf(propsMap1);
+        factory2 = (OpenJPAEntityManagerFactory) getEmf(propsMap2);
+
+        repos = JPAFacadeHelper.toBrokerFactory(factory).getConfiguration()
+            .getMetaDataRepositoryInstance();
+
+        String[] biggerConfs = new String[confs.length + 2];
+        System.arraycopy(confs, 0, biggerConfs, 0, confs.length);
+        biggerConfs[biggerConfs.length - 2] = "openjpa.DataCacheTimeout";
+        biggerConfs[biggerConfs.length - 1] = "1000";
+        Map propsMap3 = new HashMap();
+        for (int i = 0; i < biggerConfs.length; i += 2) {
+            propsMap3.put(biggerConfs[i], biggerConfs[i + 1]);
+        }
+        timeoutFactory = (OpenJPAEntityManagerFactory) getEmf(propsMap3);
+
+        clear();
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+
+        CacheObjectA a;
+        CacheObjectA aparent;
+        try {
+            // we can't specify this for UserTransaction
+            /*
+                * pm.currentTransaction().setNontransactionalRead(true);
+                * pm.currentTransaction().setOptimistic(true);
+                */
+
+//			em.setNontransactionalRead(true);
+//			em.setOptimistic(true);
+
+            a = new CacheObjectA(ORIG_NAME, ORIG_AGE);
+            aparent = new CacheObjectA(ORIG_PARENT_NAME, ORIG_PARENT_AGE);
+            a.setRelatedObject(aparent);
+            LinkedList children = new LinkedList();
+            children.add(a);
+            aparent.setRelatedCollection(children);
+
+            startTx(em);
+            em.persist(a);
+            em.persist(aparent);
+            oid = em.getObjectId(a);
+            oidwithclass = new Id(CacheObjectA.class, oid.toString());
+            parentOid = em.getObjectId(aparent);
+            endTx(em);
+        }
+        finally {
+            endEm(em);
+        }
+
+        // load an object in a separate pm before the update
+        // happens. This should not change, else we're in
+        // violation of the spec.
+        this.em = factory.createEntityManager();
+        startTx(this.em);
+        try {
+            // OpenJPAEntityManager openEm=(OpenJPAEntityManager) this.em;
+            this.a = (CacheObjectA) this.em.find(CacheObjectA.class, oid);
+
+            // load the parent for testCollections().
+            CacheObjectA rel = this.a.getRelatedObject();
+            rel.getRelatedCollection();
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+        finally {
+            endTx(this.em);
+            // endEm(this.em);
+        }
+
+        em = factory.createEntityManager();
+        try {
+            startTx(em);
+            a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+            a.setName(NEW_NAME);
+
+            aparent = (CacheObjectA) em.find(CacheObjectA.class, parentOid);
+
+            CacheObjectA a2 = new CacheObjectA(ORIG_NAME, ORIG_AGE);
+            a2.setRelatedObject(aparent);
+            aparent.getRelatedCollection().add(a2);
+            em.persist(a2);
+            endTx(em);
+
+            assertNew(a);
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    public void tearDown() throws Exception {
+        endEm(em);
+
+        try {
+            factory.close();
+        }
+        catch (Exception e) {
+        }
+        try {
+            factory2.close();
+        }
+        catch (Exception e) {
+        }
+        super.tearDown();
+
+        factory = null;
+        factory2 = null;
+        timeoutFactory = null;
+        oid = null;
+        parentOid = null;
+        em = null;
+        a = null;
+    }
+
+    public void testDeletedOneToOneRelations() throws Exception {
+        EntityManager em = factory.createEntityManager();
+        try {
+            startTx(em);
+            CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+            assertNotNull(a.getRelatedObject());
+            em.remove(a.getRelatedObject());
+            endTx(em);
+        }
+        finally {
+            endEm(em);
+        }
+
+        EntityManager em2 = factory.createEntityManager();
+        try {
+            CacheObjectA a2 = (CacheObjectA) em2.find(CacheObjectA.class, oid);
+            assertNull(a2.getRelatedObject());
+        }
+        finally {
+            endEm(em2);
+        }
+    }
+
+    public void testCanCacheExtension() throws Exception {
+        DataCache cache = cacheManager(factory).getSystemDataCache();
+
+        // first, test caching of newly created objects.
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        Object o;
+        Object oid;
+        try {
+            startTx(em);
+            o = new CacheObjectB("foo");
+            em.persist(o);
+            endTx(em);
+            oid = em.getObjectId(o);
+            assertNotNull(oid);
+            assertNull(cache.get(oid));
+        }
+        finally {
+            endEm(em);
+        }
+
+        // now, test caching of data loaded from the data store.
+        em = factory.createEntityManager();
+        try {
+            o = em.find(CacheObjectB.class, oid);
+            assertNotNull(o);
+            assertNull(cache.get(oid));
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    public void testGetCache() {
+        // first, test caching of newly created objects.
+        DataCache defaultCache = cacheManager(factory).getDataCache(
+            DataCache.NAME_DEFAULT, false);
+        assertNotNull(defaultCache);
+
+        DataCache cache = cacheManager(factory).getSystemDataCache();
+        assertEquals(defaultCache, cache);
+
+        ClassMetaData aMeta = repos.getMetaData(CacheObjectA.class, null, true);
+        ClassMetaData aChild1Meta = repos.getMetaData(CacheObjectAChild1.class,
+            null, true);
+        ClassMetaData aChild2Meta = repos.getMetaData(CacheObjectAChild2.class,
+            null, true);
+        ClassMetaData bMeta = repos.getMetaData(CacheObjectB.class, null, true);
+        ClassMetaData bChild1Meta = repos.getMetaData(CacheObjectBChild1.class,
+            null, true);
+        ClassMetaData cMeta = repos.getMetaData(CacheObjectC.class, null, true);
+        ClassMetaData dMeta = repos.getMetaData(CacheObjectD.class, null, true);
+        ClassMetaData eMeta = repos.getMetaData(CacheObjectE.class, null, true);
+
+        cache = aMeta.getDataCache();
+        assertEquals(defaultCache, cache);
+        System.out.println("******DataCacheName:"
+            + aChild2Meta.getDataCacheName());
+        assertNull(aChild2Meta.getDataCache());
+
+        assertNull(bMeta.getDataCache());
+
+        assertEquals(cMeta.getDataCache(), dMeta.getDataCache());
+        if (dMeta.getDataCache() instanceof ConcurrentDataCache) {
+            ConcurrentDataCache dCacheImpl =
+                (ConcurrentDataCache) dMeta.getDataCache();
+            assertEquals(10, dCacheImpl.getCacheSize());
+        }
+        assertEquals(aMeta.getDataCache(), eMeta.getDataCache());
+    }
+
+    public void testPrimitives() throws Exception {
+        // make sure that the 'a' that was found before changes
+        // were made is still valid.
+        assertOld(a);
+        em.refresh(a);
+        assertNew(a);
+    }
+
+    // FIXME Seetha Sep 25,2006
+    /*
+      * public void testCollections() throws Exception { CacheObjectA parent =
+      * (CacheObjectA) em.find(CacheObjectA.class,ORIG_PARENT_NAME);
+      * assertEquals(1, parent.getRelatedCollection().size());
+      * em.refresh(parent); assertEquals(2,
+      * parent.getRelatedCollection().size()); }
+      */
+
+    // FIXME Seetha Sep 25,2006
+    /*
+      * public void testExpiredCollections() { CacheObjectA parent =
+      * (CacheObjectA) em.find(CacheObjectA.class,ORIG_PARENT_NAME);
+      * em.refresh(parent); Collection relatedOids = new HashSet(); for (Iterator
+      * iter = parent.getRelatedCollection().iterator(); iter.hasNext();) {
+      * relatedOids.add(JDOHelper.getObjectId(iter.next())); }
+      *
+      * ClassMetaData meta = repos.getMetaData(CacheObjectA.class, null, true);
+      * DataCache cache = meta.getDataCache();
+      *  // drop the related data from the cache for (Iterator iter =
+      * relatedOids.iterator(); iter.hasNext();) cache.remove(iter.next());
+      *
+      * PersistenceManager pm2 = factory.getPersistenceManager(); try {
+      * assertTrue(cache.contains(parentOid)); parent = (CacheObjectA)
+      * pm2.getObjectById(parentOid, true);
+      *
+      * try { for (Iterator iter = relatedOids.iterator(); iter.hasNext();)
+      * assertFalse(cache.contains(iter.next())); } catch (AssertionFailedError
+      * e) { bug(467, "data cache can over-eagerly load relation data"); } }
+      * finally { close(pm2); } }
+      */
+
+    public void testExpiredRelations() {
+        CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+        em.refresh(a);
+        Object relationOid = em.getObjectId(a.getRelatedObject());
+        relationOid = new Id(CacheObjectA.class, relationOid.toString());
+
+        ClassMetaData meta = repos.getMetaData(CacheObjectA.class, null, true);
+        DataCache cache = meta.getDataCache();
+
+        // drop the related data from the cache
+        cache.remove(relationOid);
+
+        OpenJPAEntityManager em2 = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            assertTrue(cache.contains(oidwithclass));
+            a = (CacheObjectA) em2.find(CacheObjectA.class, oid);
+
+            try {
+                assertFalse(cache.contains(relationOid));
+            }
+            catch (AssertionFailedError e) {
+                // bug(467, "data cache can over-eagerly load relation data");
+                e.printStackTrace();
+            }
+        }
+        finally {
+            endEm(em2);
+        }
+    }
+
+    public void testPCArrays() throws Exception {
+        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            startTx(newEm);
+            CacheObjectA parent = (CacheObjectA) newEm.find(CacheObjectA.class,
+                parentOid);
+            CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            a.setRelatedArray(new CacheObjectA[]{ parent, a });
+            endTx(newEm);
+        }
+        finally {
+            endEm(newEm);
+        }
+
+        newEm = (OpenJPAEntityManager) factory.createEntityManager();
+        try {
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            CacheObjectA[] array = a.getRelatedArray();
+            assertEquals(2, array.length);
+            assertTrue(array[0] instanceof CacheObjectA);
+            assertTrue(array[1] instanceof CacheObjectA);
+
+            Object arrayOid = newEm.getObjectId(array[0]);
+            if (!arrayOid.equals(parentOid) && !arrayOid.equals(oid)) {
+                fail("array does not contain correct oids");
+            }
+
+            arrayOid = newEm.getObjectId(array[1]);
+            if (!arrayOid.equals(parentOid) && !arrayOid.equals(oid)) {
+                fail("array does not contain correct oids");
+            }
+        }
+        finally {
+            endEm(newEm);
+        }
+    }
+
+    public void testStringArrays() throws Exception {
+        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            startTx(newEm);
+            CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            a.setStringArray(new String[]{ "string0", "string1", "string2" });
+            endTx(newEm);
+        }
+        finally {
+            endEm(newEm);
+        }
+
+        newEm = (OpenJPAEntityManager) factory.createEntityManager();
+        try {
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            String[] array = a.getStringArray();
+            assertEquals(3, array.length);
+            assertEquals("string0", array[0]);
+            assertEquals("string1", array[1]);
+            assertEquals("string2", array[2]);
+        }
+        finally {
+            endEm(newEm);
+        }
+    }
+
+    public void testPrimitiveArrays() throws Exception {
+        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            startTx(newEm);
+            CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            a.setPrimitiveArray(new float[]{ 0, 1, 2 });
+            endTx(newEm);
+        }
+        finally {
+            endEm(newEm);
+        }
+
+        newEm = (OpenJPAEntityManager) factory.createEntityManager();
+        try {
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            float[] array = a.getPrimitiveArray();
+            assertEquals(3, array.length);
+            assertEquals(0.0F, array[0], 0);
+            assertEquals(1.0F, array[1], 0);
+            assertEquals(2.0f, array[2], 0);
+        }
+        finally {
+            endEm(newEm);
+        }
+    }
+
+    public void testDateArrays() throws Exception {
+        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        CacheObjectA a;
+        Date[] dateArray;
+        try {
+            startTx(newEm);
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            dateArray = new Date[]{ new Date(), new Date(), new Date() };
+            a.setDateArray(dateArray);
+            endTx(newEm);
+        }
+        finally {
+            endEm(newEm);
+        }
+
+        newEm = (OpenJPAEntityManager) factory.createEntityManager();
+        try {
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            Date[] array = a.getDateArray();
+            if (array[0] == dateArray[0]) {
+                fail("date objects are the same");
+            }
+        }
+        finally {
+            endEm(newEm);
+        }
+    }
+
+    public void testDate() throws Exception {
+        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        CacheObjectA a;
+        Date d;
+        try {
+            startTx(newEm);
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            d = new Date();
+            a.setDate(d);
+            endTx(newEm);
+        }
+        finally {
+            endEm(newEm);
+        }
+
+        // sleep a bit so we can ensure that the date doesn't just
+        // happen to be the same.
+        Thread.sleep(100);
+
+        newEm = (OpenJPAEntityManager) factory.createEntityManager();
+        try {
+            a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+            Date d2 = a.getDate();
+            if (d == d2) {
+                fail("date objects are the same");
+            }
+
+            assertEquals(d.getTime(), d2.getTime());
+        }
+        finally {
+            endEm(newEm);
+        }
+    }
+
+    public void testLocale() throws Exception {
+        OpenJPAEntityManager newEm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        startTx(newEm);
+        CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+        Locale l = Locale.getDefault();
+        a.setLocale(l);
+        endTx(newEm);
+
+        OpenJPAEntityManager newEm2 = (OpenJPAEntityManager) factory
+            .createEntityManager();
+
+        a = (CacheObjectA) newEm2.find(CacheObjectA.class, oid);
+        Locale l2 = a.getLocale();
+        // locales are immutable and final, so the different cached
+        // copies should be ==.
+        if (l != l2) {
+            fail("locale objects are not the same.");
+        }
+
+        endEm(newEm);
+        endEm(newEm2);
+    }
+
+    // ---------- Test query caching ----------
+    // * FCOs as params
+    // * multi-threaded stuff
+    // * access path stuff (see also TestQueryAccessPath)
+    // * serializability of returned lists
+    // * PM.setQueryCacheEnabled (false);
+    // * Query.setQueryCacheEnabled (false);
+    // * Pessimistic transactions
+
+    public void testBasicQuery() {
+        basicQueries(factory.createEntityManager(), Boolean.FALSE, 3, 1);
+        basicQueries(factory.createEntityManager(), Boolean.TRUE, 3, 1);
+
+        // manually notify the cache of changes
+        QueryCache cache = cacheManager(factory).getSystemQueryCache();
+
+        // test to see if modifying B causes A's query cache to be flushed
+        Set s = new HashSet();
+        s.add(CacheObjectB.class);
+        cache.onTypesChanged(new TypesChangedEvent(this, s));
+        basicQueries(factory.createEntityManager(), Boolean.TRUE, 3, 1);
+
+        // test to see if modifying A causes A's query cache to be flushed
+        s.add(CacheObjectA.class);
+        cache.onTypesChanged(new TypesChangedEvent(this, s));
+        basicQueries(factory.createEntityManager(), Boolean.FALSE, 3, 1);
+
+        // make sure that non-manual notification works
+        EntityManager em = factory.createEntityManager();
+        try {
+            startTx(em);
+            CacheObjectA a = new CacheObjectA(ORIG_NAME, ORIG_AGE);
+            em.persist(a);
+            endTx(em);
+        }
+        finally {
+            endEm(em);
+        }
+
+        basicQueries(factory.createEntityManager(), Boolean.FALSE, 4, 2);
+    }
+
+    protected void basicQueries(EntityManager em, Boolean inCache, int allSize,
+        int origSize) {
+        try {
+            long start;
+            long q1p1;
+            long q1p2;
+            long q2p1;
+            long q2p2;
+
+            Broker broker = JPAFacadeHelper.toBroker(em);
+            org.apache.openjpa.kernel.Query q = broker.newQuery(
+                JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectA.class.getSimpleName() + " a");
+            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+            start = System.currentTimeMillis();
+            assertInCache(q, inCache);
+            List l = (List) q.execute();
+            iterate(l);
+            q1p1 = System.currentTimeMillis() - start;
+
+            assertEquals(allSize, l.size());
+
+            start = System.currentTimeMillis();
+            List l2 = (List) q.execute();
+            iterate(l2);
+            q1p2 = System.currentTimeMillis() - start;
+            assertEquals(allSize, l2.size());
+
+            q = broker.newQuery(JPQLParser.LANG_JPQL,
+                "select a.name,a.age from "
+                    + CacheObjectA.class.getSimpleName()
+                    + " a where a.name = :n AND a.age = :a");
+            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+            start = System.currentTimeMillis();
+            assertInCache(q, inCache, new Object[]{ ORIG_NAME,
+                new Integer(ORIG_AGE) });
+            l = (List) q.execute(new Object[]{ ORIG_NAME,
+                new Integer(ORIG_AGE) });
+            iterate(l);
+            q2p1 = System.currentTimeMillis() - start;
+
+            assertEquals(origSize, l.size());
+
+            start = System.currentTimeMillis();
+            l2 = (List) q.execute(new Object[]{ ORIG_NAME,
+                new Integer(ORIG_AGE) });
+            iterate(l2);
+            q2p2 = System.currentTimeMillis() - start;
+
+            assertEquals(origSize, l2.size());
+            // System.out.println ("inCache: " + inCache + ";\t q1p1: " + q1p1
+            // + ";\t q1p2: " + q1p2 + ";\t q2p1: " + q2p1 + ";\t q2p2: "
+            // + q2p2);
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    public void testNonCacheableClass() {
+        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+        try {
+            org.apache.openjpa.kernel.Query q = broker.newQuery(
+                JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectB.class.getSimpleName() + " a");
+
+            Collection c = (Collection) q.execute();
+            iterate(c);
+
+            assertInCache(q, Boolean.FALSE);
+        }
+        finally {
+            close(broker);
+        }
+    }
+
+    public void testNonCacheableAccessPath() {
+        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+        try {
+            org.apache.openjpa.kernel.Query q = broker.newQuery(
+                JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectA.class.getSimpleName()
+                + " a where a.relatedB.str = 'foo'");
+            // "relatedB.str == 'foo'");
+            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+
+            Collection c = (Collection) q.execute();
+            iterate(c);
+
+            assertInCache(q, Boolean.FALSE);
+        }
+        finally {
+            close(broker);
+        }
+    }
+
+    public void testNonCacheableSubclasses1() {
+        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+        try {
+            // a query on the CacheObjectA class includes an uncacheable
+            // class; it should therefore not be cacheable.
+            org.apache.openjpa.kernel.Query q = broker.newQuery(
+                JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectA.class.getSimpleName() + " a");
+
+            Collection c = (Collection) q.execute();
+            iterate(c);
+
+            assertInCache(q, Boolean.FALSE);
+        }
+        finally {
+            close(broker);
+        }
+    }
+
+    public void testNonCacheableSubclasses2() {
+        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+        try {
+            // a query on the CacheObjectA extent configured without
+            // subclasses does not include an uncacheable class; it should
+            // therefore be cacheable.
+            org.apache.openjpa.kernel.Query q = broker.newQuery(
+                JPQLParser.LANG_JPQL, "select a from "
+                + CacheObjectA.class.getSimpleName() + " a");
+            q.setCandidateExtent(broker.newExtent(CacheObjectA.class, false));
+
+            Collection c = (Collection) q.execute();
+            iterate(c);
+
+            assertInCache(q, Boolean.TRUE);
+        }
+        finally {
+            close(broker);
+        }
+    }
+
+    public void testCacheNames() {
+        assertCacheName(CacheObjectA.class, DataCache.NAME_DEFAULT);
+        assertCacheName(CacheObjectAChild1.class, DataCache.NAME_DEFAULT);
+        assertCacheName(CacheObjectAChild2.class, null);
+        assertCacheName(CacheObjectB.class, null);
+        assertCacheName(CacheObjectBChild1.class, null);
+        assertCacheName(CacheObjectC.class, "not-the-default-cache");
+        assertCacheName(CacheObjectD.class, "not-the-default-cache");
+        assertCacheName(CacheObjectE.class, DataCache.NAME_DEFAULT);
+        assertCacheName(CacheObjectF.class, DataCache.NAME_DEFAULT);
+        assertCacheName(CacheObjectG.class, DataCache.NAME_DEFAULT);
+        assertCacheName(CacheObjectH.class, DataCache.NAME_DEFAULT);
+        assertCacheName(CacheObjectJ.class, DataCache.NAME_DEFAULT);
+        assertCacheName(AppIdCacheObject.class, DataCache.NAME_DEFAULT);
+    }
+
+    private void assertCacheName(Class cls, String cacheName) {
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(factory, cls);
+        if (cacheName == null)
+            assertNull(meta.getDataCache());
+        else {
+            assertNotNull(meta.getDataCache());
+            assertEquals(cacheName, meta.getDataCache().getName());
+        }
+    }
+
+    // FIXME Seetha Sep 26,2006
+    // not able to replace pm.newQuery(CacheObjectA.class);
+    /*
+      * public void testQueryAggregates() { PersistenceManager pm =
+      * factory.getPersistenceManager(); try { Query q =
+      * pm.newQuery(CacheObjectA.class); q.setResult("max (age)"); Object o =
+      * q.execute(); assertTrue("o must be instanceof Number", o instanceof
+      * Number); } finally { close(pm); } }
+      */
+
+    public void testCache2() {
+        OpenJPAEntityManager em1 =
+            (OpenJPAEntityManager) factory.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        DataCache cache;
+
+        try {
+            CacheObjectA a1 = (CacheObjectA) em1.find(CacheObjectA.class, oid);
+
+            em2 = (OpenJPAEntityManager) factory2.createEntityManager();
+            CacheObjectA a2 = (CacheObjectA) em2.find(CacheObjectA.class, oid);
+
+            // assert that the oid is in factory2's cache
+            //MetaDataRepository repos2 = factory2.getConfiguration().getMetaDataRepositoryInstance();
+            MetaDataRepository repos2 =
+                ((((OpenJPAEntityManagerFactorySPI) factory2)).getConfiguration())
+                    .getMetaDataRepositoryInstance();
+            ClassMetaData meta = repos2
+                .getMetaData(CacheObjectA.class, em2.getClassLoader(), true);
+            cache = meta.getDataCache();
+            assertTrue(cache.contains(oidwithclass));
+
+            // modify the object.
+            startTx(em1);
+            a1.setName(a1.getName() + " changed");
+            endTx(em1);
+        }
+        finally {
+            if (em2 != null)
+                endEm(em2);
+            endEm(em1);
+        }
+
+        // if the cache is a coherent one, then the changes should be
+        // seen. Otherwise, they should not.
+        if (isCacheCoherent() || factory == factory2)
+            assertTrue("key " + oid + " was not in cache; should have been",
+                cache.contains(oidwithclass));
+        else
+            assertFalse("key " + oid + " was in cache; should not have been",
+                cache.contains(oidwithclass));
+    }
+
+    public void testTimeouts1() throws Exception {
+        timeoutsTest1(1);
+    }
+
+    public void timeoutsTest1(int tries) throws Exception {
+        // this crazy for looping stuff is here because we're seeing
+        // intermittent failures with the garbage collector kicking in
+        // during testing. So, this decreases the chances that that
+        // will happen.
+        Exception e = null;
+        int i;
+        for (i = 0; i < tries; i++) {
+            try {
+                timeoutsHelper(factory);
+                // any successes will pass the test
+                return;
+            }
+            catch (Exception ex) {
+                e = ex;
+            }
+        }
+
+        throw e;
+    }
+
+    public void testTimeouts2() throws Exception {
+        timeoutsTest2(30);
+    }
+
+    public void timeoutsTest2(int tries) throws Exception {
+        Error e = null;
+        for (int i = 0; i < tries; i++) {
+            try {
+                timeoutsHelper(timeoutFactory);
+                // any successes will pass the test
+                return;
+            }
+            catch (AssertionFailedError afe) {
+                e = afe;
+            }
+        }
+
+        throw e;
+    }
+
+    private void timeoutsHelper(OpenJPAEntityManagerFactory factory)
+        throws Exception {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            startTx(em);
+
+            CacheObjectE e = new CacheObjectE("e");
+            em.persist(e);
+
+            CacheObjectF f = new CacheObjectF("f");
+            em.persist(f);
+
+            CacheObjectG g = new CacheObjectG("g");
+            em.persist(g);
+
+            CacheObjectH h = new CacheObjectH("h");
+            em.persist(h);
+
+            endTx(em);
+
+            Object[] ids = new Object[4];
+            ids[0] = new Id(CacheObjectE.class, em.getObjectId(e).toString());
+            ids[1] = new Id(CacheObjectF.class, em.getObjectId(f).toString());
+            ids[2] = new Id(CacheObjectG.class, em.getObjectId(g).toString());
+            ids[3] = new Id(CacheObjectH.class, em.getObjectId(h).toString());
+
+            // build up some queries to test
+
+            // this one should be only on the superclass, since
+            // CacheObjectF has a timeout.
+            Broker broker = JPAFacadeHelper.toBroker(em);
+            org.apache.openjpa.kernel.Query q1 = broker.newQuery(
+                JPQLParser.LANG_JPQL, "select a from "
+                + CacheObjectE.class.getSimpleName() + " a");
+            q1.setCandidateExtent(broker.newExtent(CacheObjectE.class, false));
+            iterate((Collection) q1.execute());
+            assertInCache(q1, Boolean.TRUE);
+
+            org.apache.openjpa.kernel.Query q2 = broker.newQuery(
+                JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectF.class.getSimpleName() + " a");
+            iterate((Collection) q2.execute());
+            assertInCache(q2, Boolean.TRUE);
+
+            DataCache cache = cacheManager(factory).getDataCache(
+                DataCache.NAME_DEFAULT, false);
+            checkCache(cache, ids, new boolean[]{ true, true, true, true });
+
+            // should cause h to be dropped.
+            Thread.currentThread().sleep(551);
+            Thread.yield();
+            checkCache(cache, ids, new boolean[]{ true, true, true, false });
+
+            // if this run has a default timeout (set to 1 sec in the test
+            // case), e should be timed out by this point.
+            //boolean eStatus = !(factory.getConfiguration().getDataCacheTimeout() > 0);
+            boolean eStatus =
+                !((((OpenJPAEntityManagerFactorySPI) factory).getConfiguration())
+                    .getDataCacheTimeout() > 0);
+
+            // should cause f to be dropped.
+            Thread.currentThread().sleep(550);
+            Thread.yield();
+            checkCache(cache, ids,
+                new boolean[]{ eStatus, false, true, false });
+
+            // at this point, q2 should be dropped (because its candidate
+            // class is CacheObjectF), and q1 might be dropped, depending
+            // on whether or not we've got a timeout configured.
+            assertInCache(q1, (eStatus) ? Boolean.TRUE : Boolean.FALSE);
+            assertInCache(q2, Boolean.FALSE);
+
+            // should cause g to be dropped.
+            Thread.currentThread().sleep(4050);
+            Thread.yield();
+            checkCache(cache, ids,
+                new boolean[]{ eStatus, false, false, false });
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    public void testQueryTimeouts() throws Exception {
+        queryTimeoutsHelper(factory);
+        queryTimeoutsHelper(timeoutFactory);
+    }
+
+    private void queryTimeoutsHelper(OpenJPAEntityManagerFactory factory)
+        throws Exception {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            startTx(em);
+
+            CacheObjectE e = new CacheObjectE("e");
+            em.persist(e);
+
+            CacheObjectF f = new CacheObjectF("f");
+            em.persist(f);
+
+            endTx(em);
+
+            // build up some queries to test
+            Broker broker = JPAFacadeHelper.toBroker(em);
+            org.apache.openjpa.kernel.Query q1 = broker
+                .newQuery(JPQLParser.LANG_JPQL, "SELECT a FROM CacheObjectE a");
+
+            q1.setCandidateExtent(broker.newExtent(CacheObjectE.class, false));
+            iterate((Collection) q1.execute());
+            assertInCache(q1, Boolean.TRUE);
+
+            org.apache.openjpa.kernel.Query q2 = broker
+                .newQuery(JPQLParser.LANG_JPQL, "SELECT a FROM CacheObjectF a");
+            iterate((Collection) q2.execute());
+            assertInCache(q2, Boolean.TRUE);
+
+            // if this run has a default timeout (set to 1 sec in the test
+            // case), e should be timed out by this point.
+            //boolean eTimedOut = factory.getConfiguration().getDataCacheTimeout() > 0;
+            boolean eTimedOut =
+                ((((OpenJPAEntityManagerFactorySPI) factory).getConfiguration())
+                    .getDataCacheTimeout() > 0);
+
+            // should cause f to be dropped.
+            Thread.currentThread().sleep(1001);
+
+            // at this point, q2 should be dropped (because its candidate
+            // class is CacheObjectF), and q1 might be dropped, depending
+            // on whether or not we've got a timeout configured.
+            assertInCache(q1, (eTimedOut) ? Boolean.FALSE : Boolean.TRUE);
+            assertInCache(q2, Boolean.FALSE);
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    public void testQueryImplicitEvictions() throws Exception {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            RuntimeTest1[] helperObjs = new RuntimeTest1[5];
+            helperObjs[0] = new RuntimeTest1();
+            helperObjs[1] = new RuntimeTest1();
+            helperObjs[2] = new RuntimeTest1();
+            helperObjs[3] = new RuntimeTest1();
+            helperObjs[4] = new RuntimeTest1();
+            startTx(em);
+            em.persist(helperObjs[0]);
+            em.persist(helperObjs[1]);
+            em.persist(helperObjs[2]);
+            em.persist(helperObjs[3]);
+            em.persist(helperObjs[4]);
+            endTx(em);
+
+            DataCache cache = cacheManager(factory).getDataCache(
+                DataCache.NAME_DEFAULT, false);
+
+            if (!isOpenJPACache(cache)) {
+                bug(627, "Tangosol cache impl needs modernization");
+                return;
+            }
+
+            if (cache instanceof DelegatingDataCache)
+                cache = ((DelegatingDataCache) cache).getInnermostDelegate();
+            if (cache instanceof ConcurrentDataCache) {
+                CacheMap map = ((ConcurrentDataCache) cache).getCacheMap();
+                map.setCacheSize(3);
+                map.setSoftReferenceSize(0);
+            } else if (cache instanceof ConcurrentDataCache) {
+                CacheMap map = ((ConcurrentDataCache) cache).getCacheMap();
+                map.setCacheSize(3);
+                map.setSoftReferenceSize(0);
+            }
+
+            startTx(em);
+            CacheObjectH h = new CacheObjectH("h");
+            em.persist(h);
+            CacheObjectJ j = new CacheObjectJ("j", h);
+            em.persist(j);
+            endTx(em);
+            Object hoid = em.getObjectId(h);
+            Object joid = em.getObjectId(j);
+
+            Object hoidwithclass = new Id(CacheObjectH.class, hoid.toString());
+            Object joidwithclass = new Id(CacheObjectJ.class, joid.toString());
+            endEm(em);
+
+            // make sure j and h are in cache; may not be if not LRU
+            int attempts = 0;
+            for (; attempts < 100 && !cache.contains(joidwithclass); attempts++)
+            {
+                em = factory.createEntityManager();
+                if (!cache.contains(hoidwithclass))
+                    em.find(CacheObjectH.class, hoid);
+                if (!cache.contains(joidwithclass))
+                    em.find(CacheObjectJ.class, joid);
+                endEm(em);
+            }
+            assertTrue("Could not get queried objects into cache",
+                attempts < 100);
+
+            // build up a query that uses H in its access path...
+            em = factory.createEntityManager();
+            Broker broker = JPAFacadeHelper.toBroker(em);
+            org.apache.openjpa.kernel.Query q = broker.newQuery(
+                JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectJ.class.getSimpleName()
+                + " a where a.str = 'h'");
+            iterate((Collection) q.execute());
+            assertInCache(q, Boolean.TRUE);
+            endEm(em);
+
+            // force h out of the cache. we might have to try multiple times
+            // if the cache is not LRU
+            attempts = 0;
+            for (; attempts < 100 && cache.contains(joidwithclass); attempts++)
+            {
+                em = factory.createEntityManager();
+                for (int i = 0; i < 5; i++)
+                    em.find(RuntimeTest1.class, em.getObjectId(helperObjs[i]));
+                endEm(em);
+            }
+            assertTrue("Could not kick queried objects out of cache",
+                attempts < 100);
+
+            em = factory.createEntityManager();
+            broker = JPAFacadeHelper.toBroker(em);
+            q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM "
+                + CacheObjectJ.class.getSimpleName()
+                + " a where a.str = 'h'");
+            try {
+                assertInCache(q, null);
+            }
+            catch (AssertionFailedError e) {
+                bug(626, "query cache invalidation is broken");
+            }
+
+            // ### should test remote events causing queries to evict.
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    // FIXME SEetha Sep 26,2006
+    // not able to replace pm.newQuery(CacheObjectE.class);
+    /*
+      * public void testAllegedQueryOrderingChanges() throws Exception { //
+      * inspired by tsc 3013. pcl: I have not been able to get this // test case
+      * to actually fail. However, during analysis of // 3013's stack traces, I
+      * discovered that the // QueryKey.equals() method did not deal with the
+      * ordering // field correctly, possibly causing the problem.
+      *
+      * OpenJPAEntityManager em = (OpenJPAEntityManager)
+      * factory.createEntityManager(); try { startTx(em,
+      * ()); CacheObjectE e = new CacheObjectE("e"); em.persist(e);
+      * endTx(em); } finally {
+      * endEm(em); }
+      *
+      * em = factory.createEntityManager(); Query q; Collection c; List l; try {
+      * q = em.createQuery(CacheObjectE.class); q.setOrdering("str ascending"); c =
+      * (Collection) q.execute(); l = new LinkedList(c); assertEquals(1,
+      * c.size()); } finally { endEm(em); }
+      *
+      * em = factory.createEntityManager(); try { q =
+      * em.createQuery(CacheObjectE.class); q.setOrdering("str ascending"); c =
+      * (Collection) q.execute(); l = new LinkedList(c); assertEquals(1,
+      * c.size()); } finally { endEm(em); }
+      *
+      * try { em = factory.createEntityManager(); q =
+      * em.createQuery(CacheObjectE.class); q.setOrdering("str descending"); c =
+      * (Collection) q.execute(); assertEquals(1, c.size()); l = new
+      * LinkedList(c); } finally { endEm(em); } }
+      */
+
+    public void testAllegedConcurrentModificationException() throws Exception {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        CacheObjectE e;
+        try {
+            ClassMetaData meta = JPAFacadeHelper.getMetaData(em,
+                CacheObjectE.class);
+            if (!isOpenJPACache(meta.getDataCache()))
+                return;
+
+            startTx(em);
+            e = new CacheObjectE("e");
+            em.persist(e);
+            endTx(em);
+        }
+        finally {
+            endEm(em);
+        }
+
+        em = factory.createEntityManager();
+        try {
+            startTx(em);
+
+            // find the new object...
+            OpenJPAQuery q = em.createQuery("select a FROM "
+                + CacheObjectE.class.getSimpleName()
+                + " a where a.str = 'e'");
+            e = (CacheObjectE) ((Collection) q.getResultList()).iterator()
+                .next();
+
+            // ... and modify the changed object.
+            e.setStr("e2");
+            e.setStr("e3");
+            endTx(em);
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    private boolean isOpenJPACache(DataCache cache) {
+        if (cache instanceof DelegatingDataCache)
+            cache = ((DelegatingDataCache) cache).getInnermostDelegate();
+
+        return cache instanceof ConcurrentDataCache;
+    }
+
+    // ---------- utility methods ----------
+
+    private void checkCache(DataCache cache, Object[] ids, boolean[] stati) {
+        CacheTestHelper.checkCache(this, cache, ids, stati);
+    }
+
+    private void assertInCache(org.apache.openjpa.kernel.Query q,
+        Boolean inCache) {
+        CacheTestHelper.assertInCache(this, q, inCache);
+    }
+
+    private void assertInCache(org.apache.openjpa.kernel.Query q,
+        Boolean inCache, Object[] args) {
+        CacheTestHelper.assertInCache(this, q, inCache, args);
+    }
+
+    private void iterate(Collection c) {
+        CacheTestHelper.iterate(c);
+    }
+
+    public void testInterface() throws Exception {
+        OpenJPAEntityManager newEm =
+            (OpenJPAEntityManager) factory.createEntityManager();
+        startTx(newEm);
+        CacheObjectA a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+        CacheObjectC c = new CacheObjectC("blah");
+        a.setRelatedInterface(c);
+        endTx(newEm);
+        Object cId = newEm.getObjectId(c);
+        endEm(newEm);
+
+        newEm = (OpenJPAEntityManager) factory.createEntityManager();
+        a = (CacheObjectA) newEm.find(CacheObjectA.class, oid);
+
+        CacheObjectInterface c2 = a.getRelatedInterface();
+        assertNotNull(c2);
+
+        assertEquals(cId, newEm.getObjectId(c2));
+    }
+
+    public void testQueriesOnCollectionsDontUseCache() {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        try {
+            startTx(em);
+            CacheObjectE e = new CacheObjectE("e");
+            em.persist(e);
+            endTx(em);
+        }
+        finally {
+            endEm(em);
+        }
+
+        em = (OpenJPAEntityManager) factory.createEntityManager();
+        OpenJPAQuery q;
+        Collection c;
+        try {
+            q = em.createQuery("select a FROM "
+                + CacheObjectE.class.getSimpleName()
+                + " a where a.str = 'e'");
+            c = new ArrayList((Collection) q.getResultList());
+            assertEquals(1, c.size());
+            q.closeAll();
+        }
+        finally {
+            endEm(em);
+        }
+
+        try {
+            em = (OpenJPAEntityManager) factory.createEntityManager();
+            q = em.createQuery("select a FROM "
+                + CacheObjectE.class.getSimpleName()
+                + " a where a.str = 'e'");
+            q.setCandidateCollection(new ArrayList(0));
+            c = (Collection) q.getResultList();
+            assertEquals(0, c.size());
+            q.closeAll();
+        }
+        finally {
+            endEm(em);
+        }
+    }
+
+    public void testDFGFieldsLoaded1() {
+        dfgFieldsLoadedHelper(false);
+    }
+
+    public void testDFGFieldsLoaded2() {
+        dfgFieldsLoadedHelper(true);
+    }
+
+    public void dfgFieldsLoadedHelper(boolean related) {
+        OpenJPAEntityManager em = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        startTx(em);
+        OpenJPAQuery q;
+        Collection c;
+        try {
+
+            q = em.createQuery(
+                "select a FROM " + CacheObjectA.class.getSimpleName()
+                    + " a where a.name = :pName").setParameter("pName",
+                ORIG_NAME);
+
+            c = new ArrayList((Collection) q.getResultList());
+            assertEquals(1, c.size());
+            CacheObjectA a = (CacheObjectA) c.iterator().next();
+            if (related)
+                a.getRelatedArray();
+            em.detach(a);
+            assertEquals(ORIG_NAME, a.getName());
+            q.closeAll();
+        }
+        finally {
+            rollbackTx(em);
+            endEm(em);
+        }
+    }
+
+    // FIXME Seetha Sep 26,2006
+    /*
+      * public void testQueriesAfterModificationAreNotInCache() {
+      * OpenJPAEntityManager em = (OpenJPAEntityManager)
+      * factory.createEntityManager(); OpenJPAEntityManager em2 =
+      * (OpenJPAEntityManager) factory.createEntityManager();
+      *
+      * //FIXME Seetha Sep 26,2006 //em.setIgnoreCache(false);
+      * //em2.setIgnoreCache(false); ((FetchPlan) em.getFetchPlan()).
+      * setFlushBeforeQueries(FetchPlan.FLUSH_TRUE); ((FetchPlan)
+      * em2.getFetchPlan()). setFlushBeforeQueries(FetchPlan.FLUSH_TRUE);
+      *
+      * try { startTx(em); CacheObjectE e = new
+      * CacheObjectE("e"); em.persist(e); endTx(em,
+      * ());
+      *
+      * startTx(em);
+      *  // first, a query that should get into the cache. Broker broker =
+      * JPAFacadeHelper.toBroker(em); org.apache.openjpa.kernel.Query q =
+      * broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, "str ==
+      * \"e\""); Collection c = (Collection) q.execute(); for (Iterator iter =
+      * c.iterator(); iter.hasNext();) iter.next();
+      *
+      * assertEquals(1, c.size()); assertInCache(q, Boolean.TRUE);
+      *
+      * Broker broker2 = JPAFacadeHelper.toBroker(em2);
+      * org.apache.openjpa.kernel.Query q2 = broker2.newQuery(q.getLanguage(),
+      * q);
+      *  // make some modifications and look again. Should return // two results.
+      * e = new CacheObjectE("e"); em.persist(e);
+      *
+      * q = broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, "str ==
+      * \"e\""); c = (Collection) q.execute(); assertEquals(2, c.size()); for
+      * (Iterator iter = c.iterator(); iter.hasNext();) iter.next();
+      *  // original query should still be in cache assertInCache(q2,
+      * Boolean.TRUE);
+      *
+      * Collection c2 = (Collection) q2.execute(); assertEquals(1, c2.size());
+      *  // new query should not make it into cache
+      *
+      * q = broker .newQuery(JPQLParser.LANG_JPQL, CacheObjectE.class, null); c =
+      * (Collection) q.execute(); assertEquals(2, c.size()); for (Iterator iter =
+      * c.iterator(); iter.hasNext();) iter.next();
+      *
+      * assertInCache(q, Boolean.FALSE); } finally {
+      * rollbackTx(em);
+      * endEm(em);
+      * endEm(em2); } }
+      */
+
+    public void testCachedQueryClosureReleasesResources() {
+        // PersistenceManagerFactory factory =
+        // KodoHelper.createEntityManagerFactory ();
+        EntityManager initEm = factory.createEntityManager();
+        startTx(initEm);
+        CacheObjectE e = new CacheObjectE("e");
+        initEm.persist(e);
+        endTx(initEm);
+        endEm(initEm);
+
+        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+        org.apache.openjpa.kernel.Query q = broker.newQuery(
+            JPQLParser.LANG_JPQL, "Select a FROM "
+            + CacheObjectE.class.getSimpleName()
+            + " a where a.str = 'e'");
+        Collection c = (Collection) q.execute();
+        for (Iterator iter = c.iterator(); iter.hasNext();)
+            iter.next();
+
+        assertEquals(1, c.size());
+        assertInCache(q, Boolean.TRUE);
+
+        ImplHelper.close(c);
+
+        broker.close();
+    }
+
+    public void testMutableSCOsAreConverted() {
+        OpenJPAEntityManager em0 = (OpenJPAEntityManager) factory
+            .createEntityManager();
+        OpenJPAEntityManager em1 = (OpenJPAEntityManager) factory
+            .createEntityManager();
+
+        startTx(em0);
+        CacheObjectA a = (CacheObjectA) em0.find(CacheObjectA.class, oid);
+
+        Date d = new Date();
+        a.setDate(d);
+
+        endTx(em0);
+        DataCache cache = cacheManager(factory).getDataCache(
+            DataCache.NAME_DEFAULT, false);
+        assertTrue(cache.contains(oidwithclass));
+        cache.remove(oidwithclass);
+
+        a = (CacheObjectA) em1.find(CacheObjectA.class, oid);
+        assertTrue(cache.contains(oidwithclass));
+
+        try {
+            PCData data = cache.get(oidwithclass);
+            ClassMetaData meta =
+                ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence
+                    .cast(factory)).getConfiguration()
+                    .getMetaDataRepositoryInstance().getMetaData(a.getClass(),
+                    null, false);
+            FieldMetaData fmd = meta.getField("date");
+            d = (Date) data.getData(fmd.getIndex());
+            Broker broker = JPAFacadeHelper.toBroker(em1);
+            OpenJPAStateManager sm = broker.getStateManager(a);
+            assertTrue(sm == ((ProxyDate) a.getDate()).getOwner());
+            assertEquals(Date.class, d.getClass());
+        }
+        finally {
+            endEm(em0);
+            endEm(em1);
+        }
+    }
+
+    public void testEmptyResultsAreCached() {
+        Broker broker = JPAFacadeHelper.toBrokerFactory(factory).newBroker();
+        org.apache.openjpa.kernel.Query q = broker.newQuery(
+            JPQLParser.LANG_JPQL, "Select a FROM "
+            + CacheObjectAChild1.class.getSimpleName()
+            + " a where a.name = 'testEmptyResultsAreCached'");
+        Collection c = (Collection) q.execute();
+        assertEquals(0, c.size());
+        assertInCache(q, Boolean.TRUE);
+        broker.close();
+    }
+
+    private void doassertTrue(EntityManager em, String name, int age)
+        throws Exception {
+        CacheObjectA a = (CacheObjectA) em.find(CacheObjectA.class, oid);
+        assertTrue(name.equals(a.getName()));
+        assertTrue(a.getAge() == age);
+        endEm(em);
+    }
+
+    private void assertNew(CacheObjectA a) {
+        assertTrue(NEW_NAME.equals(a.getName()));
+        assertTrue(ORIG_AGE == a.getAge());
+    }
+
+    private void assertOld(CacheObjectA a) {
+        assertTrue(ORIG_NAME.equals(a.getName()));
+        assertTrue(ORIG_AGE == a.getAge());
+    }
+
+    private DataCacheManager cacheManager(OpenJPAEntityManagerFactory factory) {
+        return CacheTestHelper
+            .cacheManager(JPAFacadeHelper.toBrokerFactory(factory));
+    }
+
+    private void close(EntityManager em) {
+        rollbackTx(em);
+        endEm(em);
+    }
+
+    private void close(Broker broker) {
+        if (broker.isActive())
+            broker.rollback();
+        broker.close();
+    }
+
+    public static void main(String[] args) throws Exception {
+        for (int i = 0; i < args.length; i++) {
+            String type = args[i];
+
+            CacheTest c;
+            if (type.equals("tcp")) {
+                c = new DistributedCacheTest("time test",
+                    ConcurrentDataCache.class);
+            } else if (type.equals("jms")) {
+                c = new DistributedCacheTest("time test",
+                    ConcurrentDataCache.class);
+            } else {
+                c = new TestLocalCache("time test");
+            }
+
+            c.setUp();
+            long start = System.currentTimeMillis();
+            int count = 1000;
+            for (int j = 0; j < count; j++) {
+                c.doassertTrue(c.factory.createEntityManager(), NEW_NAME,
+                    ORIG_AGE);
+            }
+            System.out.println(count + " iterations in "
+                + (System.currentTimeMillis() - start) + " millis");
+            c.tearDown();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java
index 1dd5251..55c0117 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestBroker.java
@@ -1,74 +1,74 @@
-//This class access the private class QueryCacheStoreQuery.
-//So this has to be in kodo.datacache package
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.openjpa.datacache.QueryCacheStoreQuery.CachedList;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerImpl;
-import org.apache.openjpa.kernel.QueryImpl;
-import org.apache.openjpa.kernel.StoreQuery;
-import org.apache.openjpa.lib.rop.ListResultList;
-import org.apache.openjpa.lib.rop.ListResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-
-/**
- * <p>
- * Used to mark cached query results for testing.
- * </p>
- */
-public class CacheTestBroker extends BrokerImpl {
-
-    protected QueryImpl newQueryImpl(String language, StoreQuery sq) {
-        return new CacheTestQuery(this, language, sq);
-    }
-
-    public static class CachedQueryResult extends ListResultList {
-
-        public CachedQueryResult(List list) {
-            super(list);
-        }
-    }
-
-    private static class CacheTestQuery extends QueryImpl {
-
-        public CacheTestQuery(Broker broker, String language,
-            StoreQuery query) {
-            super(broker, language, query);
-        }
-
-        protected Object toResult(StoreQuery q, StoreQuery.Executor ex,
-            ResultObjectProvider rop, StoreQuery.Range range)
-            throws Exception {
-            boolean cached = rop instanceof ListResultObjectProvider
-                && (((ListResultObjectProvider) rop)
-                .getDelegate() instanceof CachedList ||
-                ((ListResultObjectProvider) rop)
-                    .getDelegate() == Collections.EMPTY_LIST);
-            Object res = super.toResult(q, ex, rop, range);
-            if (cached && res instanceof List)
-                return new CachedQueryResult((List) res);
-            return res;
-        }
-    }
-}
+//This class access the private class QueryCacheStoreQuery.
+//So this has to be in kodo.datacache package
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.openjpa.datacache.QueryCacheStoreQuery.CachedList;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerImpl;
+import org.apache.openjpa.kernel.QueryImpl;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.lib.rop.ListResultList;
+import org.apache.openjpa.lib.rop.ListResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+
+/**
+ * <p>
+ * Used to mark cached query results for testing.
+ * </p>
+ */
+public class CacheTestBroker extends BrokerImpl {
+
+    protected QueryImpl newQueryImpl(String language, StoreQuery sq) {
+        return new CacheTestQuery(this, language, sq);
+    }
+
+    public static class CachedQueryResult extends ListResultList {
+
+        public CachedQueryResult(List list) {
+            super(list);
+        }
+    }
+
+    private static class CacheTestQuery extends QueryImpl {
+
+        public CacheTestQuery(Broker broker, String language,
+            StoreQuery query) {
+            super(broker, language, query);
+        }
+
+        protected Object toResult(StoreQuery q, StoreQuery.Executor ex,
+            ResultObjectProvider rop, StoreQuery.Range range)
+            throws Exception {
+            boolean cached = rop instanceof ListResultObjectProvider
+                && (((ListResultObjectProvider) rop)
+                .getDelegate() instanceof CachedList ||
+                ((ListResultObjectProvider) rop)
+                    .getDelegate() == Collections.EMPTY_LIST);
+            Object res = super.toResult(q, ex, rop, range);
+            if (cached && res instanceof List)
+                return new CachedQueryResult((List) res);
+            return res;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java
index 92a8689..767ecb2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheTestHelper.java
@@ -1,118 +1,118 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.apache.openjpa.datacache.DataCache;
-import org.apache.openjpa.datacache.QueryCache;
-import org.apache.openjpa.datacache.QueryKey;
-import org.apache.openjpa.datacache.DataCacheManager;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-class CacheTestHelper {
-
-    static void checkCache(AbstractTestCase tc, DataCache cache, Object[] ids,
-        boolean[] stati) {
-        for (int i = 0; i < ids.length; i++) {
-            if (stati[i])
-                tc.assertTrue("id " + i + " (" + ids[i]
-                    + ") was not in cache; should have been",
-                    cache.contains(ids[i]));
-            else
-                tc.assertFalse("id " + i + " (" + ids[i]
-                    + ") was in cache; should not have been",
-                    cache.contains(ids[i]));
-        }
-    }
-
-    static void assertInCache(AbstractTestCase tc, Query q, Boolean inCache) {
-        assertInCache(tc, q, inCache, new Object[0]);
-    }
-
-    /**
-     * Test whether the given query has valid cached results.
-     *
-     * @param inCache if {@link Boolean#TRUE}, the query must have valid
-     * cached results; if {@link Boolean#FALSE} the query
-     * must not have any cached results; if null the
-     * query may have cached results, but they cannot be
-     * valid (i.e. they can't be returned to the user)
-     */
-    static void assertInCache(AbstractTestCase tc, Query query, Boolean inCache,
-        Object[] args) {
-        QueryKey qk = QueryKey.newInstance(query, args);
-        Broker broker = query.getBroker();
-        BrokerFactory factory = broker.getBrokerFactory();
-
-        QueryCache qc = cacheManager(factory).getSystemQueryCache();
-        if (inCache == Boolean.FALSE && qc.get(qk) != null) {
-            tc.fail("query should not be in cache; was.");
-        } else if (inCache == Boolean.TRUE || (inCache == null
-            && qc.get(qk) != null)) {
-            Object res = (args == null) ? query.execute()
-                : query.execute(args);
-            if (inCache == Boolean.TRUE &&
-                !isCachedResult(res, inCache, query.getBroker()))
-                tc.fail("query should be in cache; was not.");
-            else if (inCache == null &&
-                isCachedResult(res, inCache, query.getBroker()))
-                tc.fail("query should not be returned to user; was.");
-            query.closeAll();
-        }
-    }
-
-    private static boolean isCachedResult(Object res, Boolean expected,
-        Broker broker) {
-        // we can only check for a CachedQueryResult if the
-        // Broker was configured to be a CacheTestBroker
-        if (!(broker instanceof CacheTestBroker))
-            throw new IllegalArgumentException("Broker was not set to be "
-                + "a CacheTestBroker, making it impossible to verify "
-                + "if query result is cached");
-
-        if (res instanceof Collection)
-            return res instanceof CacheTestBroker.CachedQueryResult;
-        // no way to tell if unique results from cache
-        return expected.booleanValue();
-    }
-
-    static void iterate(Collection c) {
-        // iterate through the collection so that the results have an
-        // opportunity to register themselves with the PM.
-        int count = 0;
-        for (Iterator iter = c.iterator(); iter.hasNext();) {
-            try {
-                count++;
-                iter.next();
-            } catch (NoSuchElementException e) {
-                throw e;
-            }
-        }
-    }
-
-    static DataCacheManager cacheManager(BrokerFactory factory) {
-        return factory.getConfiguration().getDataCacheManagerInstance();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.QueryCache;
+import org.apache.openjpa.datacache.QueryKey;
+import org.apache.openjpa.datacache.DataCacheManager;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+class CacheTestHelper {
+
+    static void checkCache(AbstractTestCase tc, DataCache cache, Object[] ids,
+        boolean[] stati) {
+        for (int i = 0; i < ids.length; i++) {
+            if (stati[i])
+                tc.assertTrue("id " + i + " (" + ids[i]
+                    + ") was not in cache; should have been",
+                    cache.contains(ids[i]));
+            else
+                tc.assertFalse("id " + i + " (" + ids[i]
+                    + ") was in cache; should not have been",
+                    cache.contains(ids[i]));
+        }
+    }
+
+    static void assertInCache(AbstractTestCase tc, Query q, Boolean inCache) {
+        assertInCache(tc, q, inCache, new Object[0]);
+    }
+
+    /**
+     * Test whether the given query has valid cached results.
+     *
+     * @param inCache if {@link Boolean#TRUE}, the query must have valid
+     * cached results; if {@link Boolean#FALSE} the query
+     * must not have any cached results; if null the
+     * query may have cached results, but they cannot be
+     * valid (i.e. they can't be returned to the user)
+     */
+    static void assertInCache(AbstractTestCase tc, Query query, Boolean inCache,
+        Object[] args) {
+        QueryKey qk = QueryKey.newInstance(query, args);
+        Broker broker = query.getBroker();
+        BrokerFactory factory = broker.getBrokerFactory();
+
+        QueryCache qc = cacheManager(factory).getSystemQueryCache();
+        if (inCache == Boolean.FALSE && qc.get(qk) != null) {
+            tc.fail("query should not be in cache; was.");
+        } else if (inCache == Boolean.TRUE || (inCache == null
+            && qc.get(qk) != null)) {
+            Object res = (args == null) ? query.execute()
+                : query.execute(args);
+            if (inCache == Boolean.TRUE &&
+                !isCachedResult(res, inCache, query.getBroker()))
+                tc.fail("query should be in cache; was not.");
+            else if (inCache == null &&
+                isCachedResult(res, inCache, query.getBroker()))
+                tc.fail("query should not be returned to user; was.");
+            query.closeAll();
+        }
+    }
+
+    private static boolean isCachedResult(Object res, Boolean expected,
+        Broker broker) {
+        // we can only check for a CachedQueryResult if the
+        // Broker was configured to be a CacheTestBroker
+        if (!(broker instanceof CacheTestBroker))
+            throw new IllegalArgumentException("Broker was not set to be "
+                + "a CacheTestBroker, making it impossible to verify "
+                + "if query result is cached");
+
+        if (res instanceof Collection)
+            return res instanceof CacheTestBroker.CachedQueryResult;
+        // no way to tell if unique results from cache
+        return expected.booleanValue();
+    }
+
+    static void iterate(Collection c) {
+        // iterate through the collection so that the results have an
+        // opportunity to register themselves with the PM.
+        int count = 0;
+        for (Iterator iter = c.iterator(); iter.hasNext();) {
+            try {
+                count++;
+                iter.next();
+            } catch (NoSuchElementException e) {
+                throw e;
+            }
+        }
+    }
+
+    static DataCacheManager cacheManager(BrokerFactory factory) {
+        return factory.getConfiguration().getDataCacheManagerInstance();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java
index c77fa7c..ac4fe9f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/DistributedCacheTest.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import org.apache.openjpa.lib.conf.Configurations;
-
-/**
- * Distributed cache test.
- */
-public class DistributedCacheTest
-    extends CacheTest {
-
-    private static String cache = null;
-    private static String queryCache = null;
-    private static String provider = null;
-
-    public static void setCache(String plugin) {
-        cache = plugin;
-    }
-
-    public static void setQueryCache(String plugin) {
-        queryCache = plugin;
-    }
-
-    public static void setRemoteCommitProvider(String plugin) {
-        provider = plugin;
-    }
-
-    public DistributedCacheTest(String test) {
-        super(test);
-    }
-
-    public DistributedCacheTest(String test, Class testClass) {
-        super(test);
-    }
-
-    protected String[] getConfs() {
-        return getConfs(true);
-    }
-
-    protected String[] getConfs2() {
-        return getConfs(false);
-    }
-
-    protected String[] getConfs(boolean confs1) {
-        String fullProvider = provider;
-        String props = Configurations.getProperties
-            (System.getProperty("openjpa.RemoteCommitProvider"));
-        if (props == null || props.length() == 0)
-            props = Configurations.getProperties(provider);
-        else
-            fullProvider = Configurations.getPlugin(provider, props);
-        if (props == null || props.length() == 0)
-            throw new IllegalStateException
-                ("must specify -Dkodo.RemoteCommitProvider=?");
-
-        return new String[]{
-            // use this property to differentiate factory
-            "openjpa.DataCache", cache + ", true(Name=" + confs1 + ")",
-            "openjpa.QueryCache", queryCache,
-            "openjpa.RemoteCommitProvider", fullProvider,
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import org.apache.openjpa.lib.conf.Configurations;
+
+/**
+ * Distributed cache test.
+ */
+public class DistributedCacheTest
+    extends CacheTest {
+
+    private static String cache = null;
+    private static String queryCache = null;
+    private static String provider = null;
+
+    public static void setCache(String plugin) {
+        cache = plugin;
+    }
+
+    public static void setQueryCache(String plugin) {
+        queryCache = plugin;
+    }
+
+    public static void setRemoteCommitProvider(String plugin) {
+        provider = plugin;
+    }
+
+    public DistributedCacheTest(String test) {
+        super(test);
+    }
+
+    public DistributedCacheTest(String test, Class testClass) {
+        super(test);
+    }
+
+    protected String[] getConfs() {
+        return getConfs(true);
+    }
+
+    protected String[] getConfs2() {
+        return getConfs(false);
+    }
+
+    protected String[] getConfs(boolean confs1) {
+        String fullProvider = provider;
+        String props = Configurations.getProperties
+            (System.getProperty("openjpa.RemoteCommitProvider"));
+        if (props == null || props.length() == 0)
+            props = Configurations.getProperties(provider);
+        else
+            fullProvider = Configurations.getPlugin(provider, props);
+        if (props == null || props.length() == 0)
+            throw new IllegalStateException
+                ("must specify -Dkodo.RemoteCommitProvider=?");
+
+        return new String[]{
+            // use this property to differentiate factory
+            "openjpa.DataCache", cache + ", true(Name=" + confs1 + ")",
+            "openjpa.QueryCache", queryCache,
+            "openjpa.RemoteCommitProvider", fullProvider,
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/IdentityIdClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/IdentityIdClass.java
index 245915e..5fa0005 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/IdentityIdClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/IdentityIdClass.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-@Entity
-public class IdentityIdClass {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private int id;
-
-    private String stringField;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class IdentityIdClass {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+
+    private String stringField;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Item.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Item.java
new file mode 100644
index 0000000..0c96a73
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Item.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name="CACHE_EXC_ITEM")
+public class Item {
+
+    @Id
+    private int id;
+
+    @Version
+    private int version;
+
+    private String name;
+
+    private String type;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OptimisticLockInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OptimisticLockInstance.java
index 2009236..48dfc2f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OptimisticLockInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OptimisticLockInstance.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Version;
-import javax.persistence.GeneratedValue;
-
-import javax.persistence.Table;
-
-@Entity
-@Table(name="OPTIMISTIC_LOCK_INSTANCE")
-public class OptimisticLockInstance {
-    @Id @GeneratedValue 
-    private int pk;
-
-    @Version 
-    private int oplock;
-
-    private String str;
-    private int intField;
-
-    protected OptimisticLockInstance() { }
-
-    public OptimisticLockInstance(String str) {
-        this.str = str;
-    }
-
-    public int getPK() {
-        return pk;
-    }
-
-    public int getOpLock() {
-        return oplock;
-    }
-
-    public String getStr() {
-        return str;
-    }
-}
-  
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Version;
+import javax.persistence.GeneratedValue;
+
+import javax.persistence.Table;
+
+@Entity
+@Table(name="OPTIMISTIC_LOCK_INSTANCE")
+public class OptimisticLockInstance {
+    @Id @GeneratedValue 
+    private int pk;
+
+    @Version 
+    private int oplock;
+
+    private String str;
+    private int intField;
+
+    protected OptimisticLockInstance() { }
+
+    public OptimisticLockInstance(String str) {
+        this.str = str;
+    }
+
+    public int getPK() {
+        return pk;
+    }
+
+    public int getOpLock() {
+        return oplock;
+    }
+
+    public String getStr() {
+        return str;
+    }
+}
+  
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Order.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Order.java
new file mode 100644
index 0000000..8ef9256
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Order.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name="CACHE_EXC_ORDR")
+public class Order {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    @Version
+    private int version;
+
+    private int quantity;
+
+    @OneToOne
+    private Item item;
+
+    @ManyToOne
+    private Purchase purchase;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public int getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(int quantity) {
+        this.quantity = quantity;
+    }
+
+    public Item getItem() {
+        return item;
+    }
+
+    public void setItem(Item item) {
+        this.item = item;
+    }
+
+    public Purchase getPurchase() {
+        return purchase;
+    }
+
+    public void setPurchase(Purchase purchase) {
+        this.purchase = purchase;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyChild.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyChild.java
index 24b3887..601bdb6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyChild.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyChild.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Entity;
-
-@Entity
-public class OrderedOneManyChild {
-    @Id
-    private long id;
-
-    private String name;
-
-    @ManyToOne
-    private OrderedOneManyParent parent;
-    
-    public long getId() { 
-        return id; 
-    }
-
-    public void setId(long id) { 
-        this.id = id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public OrderedOneManyParent getParent() { 
-        return parent; 
-    }
-
-    public void setParent(OrderedOneManyParent parent) { 
-        this.parent = parent; 
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Entity;
+
+@Entity
+public class OrderedOneManyChild {
+    @Id
+    private long id;
+
+    private String name;
+
+    @ManyToOne
+    private OrderedOneManyParent parent;
+    
+    public long getId() { 
+        return id; 
+    }
+
+    public void setId(long id) { 
+        this.id = id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public OrderedOneManyParent getParent() { 
+        return parent; 
+    }
+
+    public void setParent(OrderedOneManyParent parent) { 
+        this.parent = parent; 
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyParent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyParent.java
index 5b944b4..0b6caa9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyParent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/OrderedOneManyParent.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.OrderBy;
-
-@Entity
-public class OrderedOneManyParent {
-	@Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @OneToMany(mappedBy="parent")
-    @OrderBy("name ASC")
-    private List<OrderedOneManyChild> children = 
-        new ArrayList<OrderedOneManyChild>();
-
-    public long getId() { 
-        return id; 
-    }
-
-    public List<OrderedOneManyChild> getChildren() { 
-        return children; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+
+@Entity
+public class OrderedOneManyParent {
+	@Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @OneToMany(mappedBy="parent")
+    @OrderBy("name ASC")
+    private List<OrderedOneManyChild> children = 
+        new ArrayList<OrderedOneManyChild>();
+
+    public long getId() { 
+        return id; 
+    }
+
+    public List<OrderedOneManyChild> getChildren() { 
+        return children; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Purchase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Purchase.java
new file mode 100644
index 0000000..a028de5
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/Purchase.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name="CACHE_EXC_PURC")
+public class Purchase {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    @Version
+    private int version;
+
+    @OneToMany(mappedBy = "purchase", cascade = CascadeType.ALL)
+    private Collection<Order> orders;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public Collection<Order> getOrders() {
+        return orders;
+    }
+
+    public void setOrders(Collection<Order> orders) {
+        this.orders = orders;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestAutoIncrementAndDataCaching.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestAutoIncrementAndDataCaching.java
index cc14846..becb017 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestAutoIncrementAndDataCaching.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestAutoIncrementAndDataCaching.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestAutoIncrementAndDataCaching
-    extends SingleEMFTestCase {
-
-    @Override
-    public void setUp() {
-        setUp(IdentityIdClass.class, CLEAR_TABLES,
-            "openjpa.DataCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm");
-    }
-
-    public void testSimpleDataCacheOperation() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(new IdentityIdClass());
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testAccessIdBeforeCommit() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        IdentityIdClass o = new IdentityIdClass();
-        em.persist(o);
-        em.getObjectId(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestAutoIncrementAndDataCaching
+    extends SingleEMFTestCase {
+
+    @Override
+    public void setUp() {
+        setUp(IdentityIdClass.class, CLEAR_TABLES,
+            "openjpa.DataCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm");
+    }
+
+    public void testSimpleDataCacheOperation() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(new IdentityIdClass());
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testAccessIdBeforeCommit() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        IdentityIdClass o = new IdentityIdClass();
+        em.persist(o);
+        em.getObjectId(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestBulkUpdatesAndVersionColumn.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestBulkUpdatesAndVersionColumn.java
index b505deb..1206f10 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestBulkUpdatesAndVersionColumn.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestBulkUpdatesAndVersionColumn.java
@@ -1,100 +1,100 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.EntityManager;
-import javax.persistence.LockModeType;
-import javax.persistence.OptimisticLockException;
-import javax.persistence.RollbackException;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-
-public class TestBulkUpdatesAndVersionColumn
-    extends SingleEMFTestCase {
-
-    public void setUp() throws Exception {
-        setUp("openjpa.DataCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            OptimisticLockInstance.class, CLEAR_TABLES);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        OptimisticLockInstance pc = new OptimisticLockInstance("foo");
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testSelectOnOplockField() {
-        EntityManager em = emf.createEntityManager();
-        em.createQuery("select o from OptimisticLockInstance o "
-            + "where o.oplock = 0").getResultList();
-        em.close();
-    }
-
-    public void testOplockFieldMapping() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(
-            emf, OptimisticLockInstance.class);
-        FieldMapping fm = cm.getFieldMapping("oplock");
-        assertEquals(1, fm.getColumns().length);
-    }
-
-    public void testBulkUpdateWithManualVersionIncrement() {
-        bulkUpdateHelper(true);
-    }
-
-    public void testBulkUpdateWithoutManualVersionIncrement() {
-        bulkUpdateHelper(false);
-    }
-
-    private void bulkUpdateHelper(boolean incrementVersionField) {
-        EntityManager em = emf.createEntityManager();
-
-        em.getTransaction().begin();
-        OptimisticLockInstance oli = (OptimisticLockInstance) em.createQuery(
-            "SELECT o FROM OptimisticLockInstance o WHERE o.str = 'foo'")
-            .getSingleResult();
-        assertNotNull(oli);
-        em.lock(oli, LockModeType.READ);
-
-        EntityManager em2 = emf.createEntityManager();
-        em2.getTransaction().begin();
-        em2.createQuery("UPDATE OptimisticLockInstance o SET o.str = 'foo', "
-            + "o.intField = o.intField + 1"
-            + (incrementVersionField ? ", o.oplock = o.oplock + 1 " : "")
-            + "WHERE o.str = 'foo'")
-            .executeUpdate();
-        em2.getTransaction().commit();
-        em2.close();
-
-        try {
-            em.getTransaction().commit();
-            fail("transaction should have failed");
-        } catch (RollbackException re) {
-            assertTrue("nested exception must be an oplock exception",
-                re.getCause() instanceof OptimisticLockException);
-        } finally {
-            em.close();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.EntityManager;
+import javax.persistence.LockModeType;
+import javax.persistence.OptimisticLockException;
+import javax.persistence.RollbackException;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+
+public class TestBulkUpdatesAndVersionColumn
+    extends SingleEMFTestCase {
+
+    public void setUp() throws Exception {
+        setUp("openjpa.DataCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            OptimisticLockInstance.class, CLEAR_TABLES);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        OptimisticLockInstance pc = new OptimisticLockInstance("foo");
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testSelectOnOplockField() {
+        EntityManager em = emf.createEntityManager();
+        em.createQuery("select o from OptimisticLockInstance o "
+            + "where o.oplock = 0").getResultList();
+        em.close();
+    }
+
+    public void testOplockFieldMapping() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(
+            emf, OptimisticLockInstance.class);
+        FieldMapping fm = cm.getFieldMapping("oplock");
+        assertEquals(1, fm.getColumns().length);
+    }
+
+    public void testBulkUpdateWithManualVersionIncrement() {
+        bulkUpdateHelper(true);
+    }
+
+    public void testBulkUpdateWithoutManualVersionIncrement() {
+        bulkUpdateHelper(false);
+    }
+
+    private void bulkUpdateHelper(boolean incrementVersionField) {
+        EntityManager em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        OptimisticLockInstance oli = (OptimisticLockInstance) em.createQuery(
+            "SELECT o FROM OptimisticLockInstance o WHERE o.str = 'foo'")
+            .getSingleResult();
+        assertNotNull(oli);
+        em.lock(oli, LockModeType.READ);
+
+        EntityManager em2 = emf.createEntityManager();
+        em2.getTransaction().begin();
+        em2.createQuery("UPDATE OptimisticLockInstance o SET o.str = 'foo', "
+            + "o.intField = o.intField + 1"
+            + (incrementVersionField ? ", o.oplock = o.oplock + 1 " : "")
+            + "WHERE o.str = 'foo'")
+            .executeUpdate();
+        em2.getTransaction().commit();
+        em2.close();
+
+        try {
+            em.getTransaction().commit();
+            fail("transaction should have failed");
+        } catch (RollbackException re) {
+            assertTrue("nested exception must be an oplock exception",
+                re.getCause() instanceof OptimisticLockException);
+        } finally {
+            em.close();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheExclusions.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheExclusions.java
new file mode 100644
index 0000000..d47d99f
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheExclusions.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.StoreCache;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+
+public class TestCacheExclusions extends PersistenceTestCase {
+
+    private OpenJPAEntityManagerFactorySPI emf = null;
+
+    private static String[] ITEM_NAMES =
+        { "Cup", "pen", "pencil", "phone", "laptop", "keyboard", "mouse" };
+    
+    private static final String _tSep = ";";
+
+    Item[] items = new Item[ITEM_NAMES.length];
+    Order o1, o2;
+    Purchase p;
+
+    public void populate() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        int n = 0;
+        for (String s : ITEM_NAMES) {
+            items[n] = new Item();
+            items[n].setName(s);
+            items[n].setId(n);
+            em.persist(items[n++]);
+        }
+        p = new Purchase();
+        p.setOrders(new ArrayList<Order>());
+        o1 = new Order();
+        o1.setItem(em.find(Item.class, 1));
+        o1.setQuantity(2);
+        o1.setPurchase(p);
+        p.getOrders().add(o1);
+
+        o2 = new Order();
+        o2.setItem(em.find(Item.class, 4));
+        o2.setQuantity(23);
+        o2.setPurchase(p);
+        p.getOrders().add(o2);
+
+        em.persist(p);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void tearDown() throws Exception {
+        if (emf != null) {
+            EntityManager em = emf.createEntityManager();
+            em.getTransaction().begin();
+
+            for (ClassMapping mapping : ((ClassMapping[]) emf
+                .getConfiguration().getMetaDataRepositoryInstance()
+                .getMetaDatas())) {
+                Query q =
+                    em.createNativeQuery("DROP TABLE "
+                        + mapping.getTable().getName());
+                q.executeUpdate();
+            }
+            em.getTransaction().commit();
+            em.close();
+            
+            emf.close();
+        }
+        emf = null;
+        super.tearDown();
+    }
+
+    public void testCacheAll() {
+        getEntityManagerFactoryCacheSettings(null, null);
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, true, true, true);
+    }
+
+    public void testCacheItems() {
+        getEntityManagerFactoryCacheSettings(new Class[] { Item.class }, null);
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, false, false, true);
+    }
+
+    public void testCacheItemsAndPurchases() {
+        getEntityManagerFactoryCacheSettings(new Class[] { Item.class,
+            Purchase.class }, null);
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, true, false, true);
+    }
+
+    public void testCacheItemsAndOrders() {
+        getEntityManagerFactoryCacheSettings(new Class[] { Item.class,
+            Order.class }, null);
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, false, true, true);
+    }
+
+    public void testCachePurchasesAndOrders() {
+        getEntityManagerFactoryCacheSettings(new Class[] { Purchase.class,
+            Order.class }, null);
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, true, true, false);
+    }
+
+    public void testExcludePurchases() {
+        getEntityManagerFactoryCacheSettings(null,
+            new Class[] { Purchase.class });
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, false, true, true);
+    }
+
+    public void testExcludeOrders() {
+        getEntityManagerFactoryCacheSettings(null, new Class[] { Order.class });
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, true, false, true);
+    }
+
+    public void testExcludeItems() {
+        getEntityManagerFactoryCacheSettings(null, new Class[] { Item.class });
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, true, true, false);
+    }
+
+    public void testExcludeOrdersAndPurchases() {
+        getEntityManagerFactoryCacheSettings(null, new Class[] { Order.class,
+            Purchase.class });
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, false, false, true);
+    }
+
+    public void testIncludePurchaseItemExcludePurchase() {
+        getEntityManagerFactoryCacheSettings(new Class[] { Purchase.class,
+            Item.class }, new Class[] { Purchase.class });
+        populate();
+        StoreCache cache = emf.getStoreCache();
+        assertCacheContents(cache, false, false, true);
+    }
+
+    public OpenJPAEntityManagerFactorySPI getEntityManagerFactoryCacheSettings(
+        Class<?>[] includedTypes, Class<?>[] excludedTypes) {
+        StringBuilder includes = new StringBuilder();
+        if (includedTypes != null && includedTypes.length > 0) {
+            includes.append("Types=");
+            for (Class<?> c : includedTypes) {
+                includes.append(c.getName());
+                includes.append(_tSep);
+            }
+            includes.setLength(includes.length() - 1); // remove last semicolon
+        }
+        StringBuilder excludes = new StringBuilder();
+        if (excludedTypes != null && excludedTypes.length > 0) {
+            excludes.append("ExcludedTypes=");
+            for (Class<?> c : excludedTypes) {
+                excludes.append(c.getName());
+                excludes.append(_tSep);
+            }
+            excludes.setLength(excludes.length() - 1); // remove last semicolon
+        }
+        StringBuilder dataCacheSettings = new StringBuilder();
+        dataCacheSettings.append("true");
+        if (includes.length() > 0 || excludes.length() > 0) {
+            dataCacheSettings.append("(");
+            dataCacheSettings.append(includes);
+            if (includes.length() > 0 && excludes.length() > 0) {
+                dataCacheSettings.append(",");
+            }
+            dataCacheSettings.append(excludes);
+            dataCacheSettings.append(")");
+        }
+        Map<String, String> props = new HashMap<String, String>();
+        props.put("openjpa.DataCache", dataCacheSettings.toString());
+        props.put("openjpa.RemoteCommitProvider", "sjvm");
+        props.put("openjpa.MetaDataFactory", "jpa(Types="
+            + Item.class.getName() + _tSep + Purchase.class.getName() + _tSep
+            + Order.class.getName() + ")");
+        emf =
+            (OpenJPAEntityManagerFactorySPI) javax.persistence.Persistence
+                .createEntityManagerFactory("test", props);
+        return emf;
+    }
+
+    public void assertCacheContents(StoreCache cache, boolean expectPurchase,
+        boolean expectOrders, boolean expectItems) {
+        assertEquals("Expected purchases to " + (expectPurchase ? "" : "not ")
+            + "exist in the cache", expectPurchase, cache.contains(
+            Purchase.class, p.getId()));
+        assertEquals("Expected Orders to " + (expectOrders ? "" : "not ")
+            + "exist in the cache", expectOrders, cache.contains(Order.class,
+            o1.getId()));
+        assertEquals("Expected Orders to " + (expectOrders ? "" : "not ")
+            + "exist in the cache", expectOrders, cache.contains(Order.class,
+            o2.getId()));
+        for (int i = 0; i < ITEM_NAMES.length; i++) {
+            assertEquals("Expected Items to " + (expectItems ? "" : "not ")
+                + "exist in the cache", expectItems, cache.contains(Item.class,
+                items[i].getId()));
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java
index 7b8f408..0108ae5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestCacheMultiThreadedLoad.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-/**
- * Multi-threaded cache load test for running in the autobuild.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public class TestCacheMultiThreadedLoad
-    extends CacheLoadTest {
-
-    public TestCacheMultiThreadedLoad() {
-        // pared down iteration and thread count for running in the
-        // autobbuild
-        interationCount = 400;
-        threadCount = 10;
-    }
-
-    public boolean skipTest() {
-        return true;
-    }
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+/**
+ * Multi-threaded cache load test for running in the autobuild.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class TestCacheMultiThreadedLoad
+    extends CacheLoadTest {
+
+    public TestCacheMultiThreadedLoad() {
+        // pared down iteration and thread count for running in the
+        // autobbuild
+        interationCount = 400;
+        threadCount = 10;
+    }
+
+    public boolean skipTest() {
+        return true;
+    }
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java
index 0b63191..26a2613 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestConcurrentDataCache.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-/**
- * Test data caching across multiple factories in the same JVM, using
- * the single-JVM commit provider to communicate updates..
- */
-public class TestConcurrentDataCache
-    extends CacheTest {
-
-    public TestConcurrentDataCache(String test) {
-        super(test);
-    }
-
-    protected String[] getConfs() {
-        return new String[]{
-            // the second cache is there solely to differentiate between
-            // this PMF and the PMF created from confs2 below
-            "openjpa.DataCache",
-            "concurrent, concurrent(Name=differentiatingProperty1)",
-            "openjpa.QueryCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-
-    protected String[] getConfs2() {
-        return new String[]{
-            // the second cache is there solely to differentiate between
-            // this PMF and the PMF created from confs above
-            "openjpa.DataCache",
-            "concurrent, concurrent(Name=differentiatingProperty2)",
-            "openjpa.QueryCache", "concurrent",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+/**
+ * Test data caching across multiple factories in the same JVM, using
+ * the single-JVM commit provider to communicate updates..
+ */
+public class TestConcurrentDataCache
+    extends CacheTest {
+
+    public TestConcurrentDataCache(String test) {
+        super(test);
+    }
+
+    protected String[] getConfs() {
+        return new String[]{
+            // the second cache is there solely to differentiate between
+            // this PMF and the PMF created from confs2 below
+            "openjpa.DataCache",
+            "concurrent, concurrent(Name=differentiatingProperty1)",
+            "openjpa.QueryCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+
+    protected String[] getConfs2() {
+        return new String[]{
+            // the second cache is there solely to differentiate between
+            // this PMF and the PMF created from confs above
+            "openjpa.DataCache",
+            "concurrent, concurrent(Name=differentiatingProperty2)",
+            "openjpa.QueryCache", "concurrent",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java
index 0e2b756..d0ceaa1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java
@@ -1,524 +1,524 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.EntityManager;
-import javax.persistence.LockModeType;
-
-import org.apache.openjpa.persistence.EntityManagerImpl;
-import org.apache.openjpa.persistence.EntityNotFoundException;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.StoreCache;
-import org.apache.openjpa.persistence.StoreCacheImpl;
-import org.apache.openjpa.persistence.cache.common.apps.BidirectionalOne2OneOwned;
-import org.apache.openjpa.persistence.cache.common.apps.BidirectionalOne2OneOwner;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.datacache.common.apps.PObject;
-
-/**
- * Tests various application behavior with or without DataCache.
- * Ideally, an application should behave identically irrespective of the 
- * DataCache. However, purpose of this test is to identify specific scenarios
- * where this ideal is violated. The test case also demonstrates, wherever
- * possible, what extra step an application may take to ensure that its 
- * behavior with or without DataCache remains identical.   
- * 
- * So far following use cases are found to demonstrate behavioral differences:
- * 1. Inconsistent bidirectional relation
- * 2. Refresh
- * 
- * @author Pinaki Poddar
- * 
- */
-public class TestDataCacheBehavesIdentical extends AbstractTestCase {
-	private static OpenJPAEntityManagerFactorySPI emfWithDataCache;
-	private static OpenJPAEntityManagerFactorySPI emfWithoutDataCache;
-	
-	private static final boolean WITH_DATACACHE = true;
-	private static final boolean CONSISTENT = true;
-	private static final boolean DIRTY = true;
-	private static final boolean REFRESH_FROM_DATACACHE = true;
-	private static final LockModeType NOLOCK = null;
-	private static final Class ENTITY_NOT_FOUND_ERROR = EntityNotFoundException.class;
-	private static final Class NO_ERROR = null;
-
-	private static final String MARKER_DATACACHE = "in DataCache";
-	private static final String MARKER_DATABASE  = "in Database";
-	private static final String MARKER_CACHE     = "in Object Cache";
-	private static final String MARKER_DIRTY_CACHE = "in Object Cache (dirty)";
-	private static long ID_COUNTER = System.currentTimeMillis();
-	
-
-	/**
-	 * Sets up two EntityManagerFactory: one with DataCache another without.
-	 */
-	public void setUp() throws Exception {
-		super.setUp();
-		if (emfWithDataCache == null) {
-			emfWithDataCache = createEMF(
-					"openjpa.jdbc.SynchronizeMappings",	"buildSchema", 
-					"openjpa.RuntimeUnenhancedClasses",	"unsupported", 
-					"openjpa.DataCache", "true",
-					"openjpa.RemoteCommitProvider", "sjvm",
-					"openjpa.jdbc.UpdateManager", "constraint",
-					PObject.class,
-					BidirectionalOne2OneOwner.class,
-					BidirectionalOne2OneOwned.class, CLEAR_TABLES);
-			emfWithoutDataCache = createEMF(
-					"openjpa.RuntimeUnenhancedClasses",	"unsupported", 
-					"openjpa.DataCache", "false",
-					"openjpa.jdbc.UpdateManager", "constraint",
-					PObject.class,
-					BidirectionalOne2OneOwned.class,
-					BidirectionalOne2OneOwner.class, CLEAR_TABLES);
-
-			assertNotNull(emfWithDataCache);
-			assertNotNull(emfWithoutDataCache);
-
-			// StoreCache is, by design, always non-null 
-			assertNotNull(emfWithDataCache.getStoreCache());
-			assertNotNull(emfWithoutDataCache.getStoreCache());
-
-			// however, following distinguishes whether DataCache is active  
-			assertTrue(isDataCacheActive(emfWithDataCache));
-			assertFalse(isDataCacheActive(emfWithoutDataCache));
-		}
-	}
-	
-	/**
-	 * Affirms via internal structures if the given factory is configured with
-	 * active DataCache. Because, even when DataCache is configured to be
-	 * false, a no-op StoreCache is instantiated by design.
-	 */
-	boolean isDataCacheActive(OpenJPAEntityManagerFactorySPI emf) {
-		return ((StoreCacheImpl) emf.getStoreCache()).getDelegate() != null
-		    && emf.getConfiguration()
-		          .getDataCacheManagerInstance()
-		          .getSystemDataCache() != null;
-	}
-
-	/**
-	 * Create one-to-one bidirectional relation (may or may not be consistent)
-	 * between two pairs of instances. Creates four instances Owner1, Owned1,
-	 * Owner2, Owned2. The first instance has the given id. The id of the other
-	 * instances monotonically increase by 1. The relationship is set either
-	 * consistently or inconsistently. Consistent relation is when Owner1 points
-	 * to Owned1 and Owned1 points back to Owner1. Inconsistent relation is when
-	 * Owner1 points to Owned1 but Owned1 points to Owner2 instead of Owner1.
-	 * 
-	 * 
-	 * @param em
-	 *            the entity manager to persist the instances
-	 * @param id
-	 *            the identifier of the first owner instance. The identifier for
-	 *            the other instances are sequential in order of creation.
-	 * @param consistent
-	 *            if true sets the relationship as consistent.
-	 */
-	public void createBidirectionalRelation(EntityManager em, long id,
-			boolean consistent) {
-		BidirectionalOne2OneOwner owner1 = new BidirectionalOne2OneOwner();
-		BidirectionalOne2OneOwned owned1 = new BidirectionalOne2OneOwned();
-		BidirectionalOne2OneOwner owner2 = new BidirectionalOne2OneOwner();
-		BidirectionalOne2OneOwned owned2 = new BidirectionalOne2OneOwned();
-		
-		owner1.setId(id++);
-		owned1.setId(id++);
-		owner2.setId(id++);
-		owned2.setId(id++);
-		
-		owner1.setName("Owner1");
-		owned1.setName("Owned1");
-		owned2.setName("Owned2");
-		owner2.setName("Owner2");
-
-		owner1.setOwned(owned1);
-		owner2.setOwned(owned2);
-
-		if (consistent) {
-			owned1.setOwner(owner1);
-			owned2.setOwner(owner2);
-		} else {
-			owned1.setOwner(owner2);
-			owned2.setOwner(owner1);
-		}
-
-		em.getTransaction().begin();
-		em.persist(owner1);
-		em.persist(owned1);
-		em.persist(owner2);
-		em.persist(owned2);
-		em.getTransaction().commit();
-		em.clear();
-	}
-
-	/**
-	 * Verifies that bidirectionally related objects can be persisted 
-	 * and later retrieved in a different transaction. 
-	 * 
-	 * Creates interrelated set of four instances.
-	 * Establish their relation either consistently or inconsistently based
-	 * on the given flag.
-	 * Persist them and then clear the context. 
-	 * Fetch the instances in memory again by their identifiers. 
-	 * Compare the interrelations between the fetched instances with the 
-	 * relations of the original instances (which can be consistent or 
-	 * inconsistent). 
-	 * 
-	 * The mapping specification is such that the bidirectional relation is 
-	 * stored in database by a single foreign key. Hence database relation
-	 * is always consistent. Hence the instances retrieved from database are
-	 * always consistently related irrespective of whether they were created
-	 * with consistent or inconsistent relation.
-	 * However, when the instances are retrieved from the data cache, data cache
-	 * will preserve the in-memory relations even when they are inconsistent.
-	 *    
-	 * @param useDataCache
-	 *            use DataCache
-	 * @param consistent
-	 *            assume that the relationship were created as consistent.
-	 */
-	public void verifyBidirectionalRelation(boolean useDataCache,
-			boolean createConsistent, boolean expectConsistent) {
-		EntityManager em = (useDataCache) 
-		                 ? emfWithDataCache.createEntityManager() 
-		                 : emfWithoutDataCache.createEntityManager();
-		                 
-		long id = ID_COUNTER++;
-		ID_COUNTER += 4;
-		createBidirectionalRelation(em, id, createConsistent);
-		
-		
-		BidirectionalOne2OneOwner owner1 = em.find(BidirectionalOne2OneOwner.class, id);
-		BidirectionalOne2OneOwned owned1 = em.find(BidirectionalOne2OneOwned.class, id + 1);
-		BidirectionalOne2OneOwner owner2 = em.find(BidirectionalOne2OneOwner.class, id + 2);
-		BidirectionalOne2OneOwned owned2 = em.find(BidirectionalOne2OneOwned.class, id + 3);
-
-		assertNotNull(owner1);
-		assertNotNull(owner2);
-		assertNotNull(owned1);
-		assertNotNull(owned2);
-
-		assertEquals(owner1, expectConsistent 
-					? owner1.getOwned().getOwner() 
-					: owner2.getOwned().getOwner());
-		assertEquals(owner2, expectConsistent 
-					? owner2.getOwned().getOwner() 
-				    : owner1.getOwned().getOwner());
-
-
-		assertEquals(owned1, owner1.getOwned());
-		assertEquals(expectConsistent ? owner1 : owner2, owned1.getOwner());
-		assertEquals(owned2, owner2.getOwned());
-		assertEquals(expectConsistent ? owner2 : owner1, owned2.getOwner());
-	}
-
-	public void testConsitentBidirectionalRelationIsPreservedWithDataCache() {
-		verifyBidirectionalRelation(WITH_DATACACHE, CONSISTENT, CONSISTENT);
-	}
-
-	public void testConsitentBidirectionalRelationIsPreservedWithoutDataCache() {
-		verifyBidirectionalRelation(!WITH_DATACACHE, CONSISTENT, CONSISTENT);
-	}
-
-	public void testInconsitentBidirectionalRelationIsPreservedWithDataCache() {
-		verifyBidirectionalRelation(WITH_DATACACHE, !CONSISTENT, !CONSISTENT);
-	}
-
-	public void testInconsitentBidirectionalRelationIsNotPreservedWithoutDataCache() {
-		verifyBidirectionalRelation(!WITH_DATACACHE, !CONSISTENT, CONSISTENT);
-	}
-	
-	/**
-	 * Verify that refresh() may fetch state from either the data cache or the
-	 * database based on different conditions. 
-	 * The conditions that impact are 
-	 * a) whether current lock is stronger than NONE 
-	 * b) whether the instance being refreshed is dirty
-	 * 
-	 * An instance is created with data cache marker and persisted. 
-	 * A native SQL is used to update the database record with database marker. 
-	 * The in-memory instance is not aware of this out-of-band update. 
-	 * Then the in-memory instance is refreshed. The marker of the refreshed 
-	 * instance tells whether the instance is refreshed from the data cache
-	 * of the database. 
-	 * 
-	 * @param useDataCache flags if data cache is active. if not, then surely
-	 * refresh always fetch state from the database.
-	 * 
-	 * @param datacache the marker for the copy of the data cached instance
-	 * @param database the marker for the database record
-	 * @param lock lock to be used
-	 * @param makeDirtyBeforeRefresh flags if the instance be dirtied before
-	 * refresh()
-	 * @param expected The expected marker i.e. where the state is refreshed 
-	 * from. This should be always <code>MARKER_DATABASE</code>.
-	 * a) whether DataCache is active
-	 * b) whether current Lock is stronger than NOLOCK
-	 * c) whether the object to be refreshed is dirty
-	 * 
-	 * The following truth table enumerates the possibilities
-	 * 
-	 * Use Cache?   Lock?   Dirty?     Target
-	 *    Y          Y       Y         Database
-	 *    Y          N       Y         Data Cache
-	 *    Y          Y       N         Data Cache
-	 *    Y          N       N         Data Cache
-	 *    
-	 *    N          Y       Y         Database
-	 *    N          N       Y         Database
-	 *    N          Y       N         Object Cache
-	 *    N          N       N         Object Cache
-
-	 */
-	public void verifyRefresh(boolean useDataCache, LockModeType lock, 
-			boolean makeDirtyBeforeRefresh, boolean refreshFromDataCache, 
-			String expected) {
-		OpenJPAEntityManagerFactorySPI emf = (useDataCache)
-			? emfWithDataCache : emfWithoutDataCache;
-		emf.getConfiguration().setRefreshFromDataCache(refreshFromDataCache);
-		OpenJPAEntityManagerSPI em = emf.createEntityManager();
-        
-		em.getTransaction().begin();
-		PObject pc = new PObject();
-		pc.setName(useDataCache ? MARKER_DATACACHE : MARKER_CACHE);
-		em.persist(pc);
-		em.getTransaction().commit();
-		
-		Object oid = pc.getId();
-		StoreCache dataCache = emf.getStoreCache();
-		assertEquals(useDataCache, dataCache.contains(PObject.class, oid));
-		
-		// Modify the record in the database in a separate transaction using
-		// native SQL so that the in-memory instance is not altered 
-		em.getTransaction().begin();
-		String sql = "UPDATE POBJECT SET NAME='"+ MARKER_DATABASE +"' WHERE id="+oid;
-		em.createNativeQuery(sql).executeUpdate();
-		em.getTransaction().commit();
-		
-		assertEquals(useDataCache ? MARKER_DATACACHE : MARKER_CACHE, pc.getName());
-		
-		em.getTransaction().begin();
-		if (makeDirtyBeforeRefresh) {
-			pc.setName(MARKER_DIRTY_CACHE);
-		} 
-		assertEquals(makeDirtyBeforeRefresh, em.isDirty(pc));
-
-		if (lock != null) {
-			((EntityManagerImpl)em).getFetchPlan().setReadLockMode(lock);
-		}
-		em.refresh(pc);
-		
-		assertEquals(expected, pc.getName());
-		em.getTransaction().commit();
-	}
-	
-	/**
-	 * The expected marker i.e. where the state is refreshed from depends on
-	 * a) whether DataCache is active
-	 * b) whether current Lock is stronger than NOLOCK
-	 * c) whether the object to be refreshed is dirty
-	 * 
-	 * The following truth table enumerates the possibilities
-	 * 
-	 * Use Cache?   Lock?   Dirty?     Target
-	 *    Y          Y       Y         Database
-	 *    Y          N       Y         Data Cache
-	 *    Y          Y       N         Data Cache
-	 *    Y          N       N         Data Cache
-	 *    
-	 *    N          Y       Y         Database
-	 *    N          N       Y         Database
-	 *    N          Y       N         Object Cache
-	 *    N          N       N         Object Cache
-	 *    
-	 * @param datacache the marker for 
-	 * @param database
-	 * @param useDataCache
-	 * @param lock
-	 * @param makeDirtyBeforeRefresh
-	 * @return
-	 */
-	String getExpectedMarker(boolean useDataCache, LockModeType lock, 
-			boolean makeDirtyBeforeRefresh) {
-		if (useDataCache) {
-			return (lock != null) ? MARKER_DATABASE : MARKER_DATACACHE; 
-		} else {
-			return MARKER_DATABASE;
-		}
-	}
-	
-	public void testDirtyRefreshWithNoLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-	}
-	
-	public void testDirtyRefreshWithNoLockHitsDataCache() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-	}
-	
-	public void testCleanRefreshWithNoLockDoesNotHitDatabase() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-	}
-	
-	public void testCleanRefreshWithNoLockHitsDataCache() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-	}
-	
-	public void testDirtyRefreshWithReadLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-	}
-	
-	public void testCleanRefreshWithReadLockDoesNotHitDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-	}
-	
-	public void testDirtyRefreshWithWriteLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-	}
-	
-	public void testCleanRefreshWithWriteLockDoesNotHitDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
-	}
-	
-	public void testDirtyRefreshWithoutDataCacheAlwaysHitsDatabase() {
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
-	}
-	
-	public void testCleanRefreshWithoutDataCacheDoesNotHitDatabase() {
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_CACHE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, REFRESH_FROM_DATACACHE,  MARKER_CACHE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, REFRESH_FROM_DATACACHE,  MARKER_CACHE);
-		
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
-	}
-	
-	/**
-	 * Verify behavior of refreshing an instance which has been deleted by
-	 * out-of-band process (e.g. a native SQL in a separate transaction).
-	 * The behavior differs when refresh() without a lock fetches the data from
-	 * DataCache even when the original database record is deleted.
-	 * 
-	 * @param useDataCache
-	 * @param lock
-	 */
-	public void verifyDeleteDetectionOnRefresh(boolean useDataCache, 
-			boolean dirty, LockModeType lock, Class expectedExceptionType) {
-		OpenJPAEntityManagerFactorySPI emf = (useDataCache)
-			? emfWithDataCache : emfWithoutDataCache;
-			
-		OpenJPAEntityManagerSPI em = emf.createEntityManager();
-        
-		em.getTransaction().begin();
-		PObject pc = new PObject();
-		pc.setName(useDataCache ? MARKER_DATACACHE : MARKER_CACHE);
-		em.persist(pc);
-		em.getTransaction().commit();
-		
-		Object oid = pc.getId();
-		StoreCache dataCache = emf.getStoreCache();
-		assertEquals(useDataCache, dataCache.contains(PObject.class, oid));
-		
-		// delete the record in the database in a separate transaction using
-		// native SQL so that the in-memory instance is not altered 
-		em.getTransaction().begin();
-		String sql = "DELETE FROM POBJECT WHERE id="+oid;
-		em.createNativeQuery(sql).executeUpdate();
-		em.getTransaction().commit();
-		
-		// the object cache does not know that the record was deleted
-		assertTrue(em.contains(pc));
-		// nor does the data cache
-		assertEquals(useDataCache, dataCache.contains(PObject.class, oid));
-		
-		/**
-		 * refresh behavior no more depends on current lock. Refresh
-		 * will always attempt to fetch the instance from database 
-		 * raising EntityNotFoundException.
-		 *   
-		 */
-		em.getTransaction().begin();
-		em.getFetchPlan().setReadLockMode(lock);
-		if (dirty) 
-			pc.setName("Dirty Name");
-		try {
-			em.refresh(pc);
-			if (expectedExceptionType != null) {
-				fail("expected " + expectedExceptionType.getSimpleName() + 
-						" for PObject:" + oid);
-			}
-		} catch (Exception ex) {
-			boolean expectedException = expectedExceptionType != null &&
-			    expectedExceptionType.isAssignableFrom(ex.getClass());
-			if (!expectedException) {
-				ex.printStackTrace();
-				String error = (expectedExceptionType == null) 
-					? "no exception" : expectedExceptionType.getName();
-				fail("expected " + error + " for PObject:" + oid);
-			}
-		} finally {
-			em.getTransaction().rollback();
-		}
-	}
-
-	public void testDeleteIsNotDetectedOnCleanRefreshWithoutLockWithDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, NOLOCK, NO_ERROR);
-	}
-	
-	public void testDeleteIsDetectedOnCleanRefreshWithLockWithDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
-	}
-
-	public void testDeleteIsNotDetectedOnDirtyRefreshWithoutLockWithDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, NOLOCK, NO_ERROR);	
-	}
-	
-	public void testDeleteIsDetectedOnDirtyRefreshWithLockWithDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
-	}
-	
-	public void testDeleteIsDetectedOnDirtyRefreshWitDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
-	}
-	
-	public void testDeleteIsDetectedOnCleanRefreshWithoutLockWithoutDataCache() {
-		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, NOLOCK, ENTITY_NOT_FOUND_ERROR);
-	}
-	
-	public void testDeleteIsDetectedOnCleanRefreshWithLockWithoutDataCache() {
-		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
-		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.EntityManager;
+import javax.persistence.LockModeType;
+
+import org.apache.openjpa.persistence.EntityManagerImpl;
+import org.apache.openjpa.persistence.EntityNotFoundException;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.StoreCache;
+import org.apache.openjpa.persistence.StoreCacheImpl;
+import org.apache.openjpa.persistence.cache.common.apps.BidirectionalOne2OneOwned;
+import org.apache.openjpa.persistence.cache.common.apps.BidirectionalOne2OneOwner;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.datacache.common.apps.PObject;
+
+/**
+ * Tests various application behavior with or without DataCache.
+ * Ideally, an application should behave identically irrespective of the 
+ * DataCache. However, purpose of this test is to identify specific scenarios
+ * where this ideal is violated. The test case also demonstrates, wherever
+ * possible, what extra step an application may take to ensure that its 
+ * behavior with or without DataCache remains identical.   
+ * 
+ * So far following use cases are found to demonstrate behavioral differences:
+ * 1. Inconsistent bidirectional relation
+ * 2. Refresh
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class TestDataCacheBehavesIdentical extends AbstractTestCase {
+	private static OpenJPAEntityManagerFactorySPI emfWithDataCache;
+	private static OpenJPAEntityManagerFactorySPI emfWithoutDataCache;
+	
+	private static final boolean WITH_DATACACHE = true;
+	private static final boolean CONSISTENT = true;
+	private static final boolean DIRTY = true;
+	private static final boolean REFRESH_FROM_DATACACHE = true;
+	private static final LockModeType NOLOCK = null;
+	private static final Class ENTITY_NOT_FOUND_ERROR = EntityNotFoundException.class;
+	private static final Class NO_ERROR = null;
+
+	private static final String MARKER_DATACACHE = "in DataCache";
+	private static final String MARKER_DATABASE  = "in Database";
+	private static final String MARKER_CACHE     = "in Object Cache";
+	private static final String MARKER_DIRTY_CACHE = "in Object Cache (dirty)";
+	private static long ID_COUNTER = System.currentTimeMillis();
+	
+
+	/**
+	 * Sets up two EntityManagerFactory: one with DataCache another without.
+	 */
+	public void setUp() throws Exception {
+		super.setUp();
+		if (emfWithDataCache == null) {
+			emfWithDataCache = createEMF(
+					"openjpa.jdbc.SynchronizeMappings",	"buildSchema", 
+					"openjpa.RuntimeUnenhancedClasses",	"unsupported", 
+					"openjpa.DataCache", "true",
+					"openjpa.RemoteCommitProvider", "sjvm",
+					"openjpa.jdbc.UpdateManager", "constraint",
+					PObject.class,
+					BidirectionalOne2OneOwner.class,
+					BidirectionalOne2OneOwned.class, CLEAR_TABLES);
+			emfWithoutDataCache = createEMF(
+					"openjpa.RuntimeUnenhancedClasses",	"unsupported", 
+					"openjpa.DataCache", "false",
+					"openjpa.jdbc.UpdateManager", "constraint",
+					PObject.class,
+					BidirectionalOne2OneOwned.class,
+					BidirectionalOne2OneOwner.class, CLEAR_TABLES);
+
+			assertNotNull(emfWithDataCache);
+			assertNotNull(emfWithoutDataCache);
+
+			// StoreCache is, by design, always non-null 
+			assertNotNull(emfWithDataCache.getStoreCache());
+			assertNotNull(emfWithoutDataCache.getStoreCache());
+
+			// however, following distinguishes whether DataCache is active  
+			assertTrue(isDataCacheActive(emfWithDataCache));
+			assertFalse(isDataCacheActive(emfWithoutDataCache));
+		}
+	}
+	
+	/**
+	 * Affirms via internal structures if the given factory is configured with
+	 * active DataCache. Because, even when DataCache is configured to be
+	 * false, a no-op StoreCache is instantiated by design.
+	 */
+	boolean isDataCacheActive(OpenJPAEntityManagerFactorySPI emf) {
+		return ((StoreCacheImpl) emf.getStoreCache()).getDelegate() != null
+		    && emf.getConfiguration()
+		          .getDataCacheManagerInstance()
+		          .getSystemDataCache() != null;
+	}
+
+	/**
+	 * Create one-to-one bidirectional relation (may or may not be consistent)
+	 * between two pairs of instances. Creates four instances Owner1, Owned1,
+	 * Owner2, Owned2. The first instance has the given id. The id of the other
+	 * instances monotonically increase by 1. The relationship is set either
+	 * consistently or inconsistently. Consistent relation is when Owner1 points
+	 * to Owned1 and Owned1 points back to Owner1. Inconsistent relation is when
+	 * Owner1 points to Owned1 but Owned1 points to Owner2 instead of Owner1.
+	 * 
+	 * 
+	 * @param em
+	 *            the entity manager to persist the instances
+	 * @param id
+	 *            the identifier of the first owner instance. The identifier for
+	 *            the other instances are sequential in order of creation.
+	 * @param consistent
+	 *            if true sets the relationship as consistent.
+	 */
+	public void createBidirectionalRelation(EntityManager em, long id,
+			boolean consistent) {
+		BidirectionalOne2OneOwner owner1 = new BidirectionalOne2OneOwner();
+		BidirectionalOne2OneOwned owned1 = new BidirectionalOne2OneOwned();
+		BidirectionalOne2OneOwner owner2 = new BidirectionalOne2OneOwner();
+		BidirectionalOne2OneOwned owned2 = new BidirectionalOne2OneOwned();
+		
+		owner1.setId(id++);
+		owned1.setId(id++);
+		owner2.setId(id++);
+		owned2.setId(id++);
+		
+		owner1.setName("Owner1");
+		owned1.setName("Owned1");
+		owned2.setName("Owned2");
+		owner2.setName("Owner2");
+
+		owner1.setOwned(owned1);
+		owner2.setOwned(owned2);
+
+		if (consistent) {
+			owned1.setOwner(owner1);
+			owned2.setOwner(owner2);
+		} else {
+			owned1.setOwner(owner2);
+			owned2.setOwner(owner1);
+		}
+
+		em.getTransaction().begin();
+		em.persist(owner1);
+		em.persist(owned1);
+		em.persist(owner2);
+		em.persist(owned2);
+		em.getTransaction().commit();
+		em.clear();
+	}
+
+	/**
+	 * Verifies that bidirectionally related objects can be persisted 
+	 * and later retrieved in a different transaction. 
+	 * 
+	 * Creates interrelated set of four instances.
+	 * Establish their relation either consistently or inconsistently based
+	 * on the given flag.
+	 * Persist them and then clear the context. 
+	 * Fetch the instances in memory again by their identifiers. 
+	 * Compare the interrelations between the fetched instances with the 
+	 * relations of the original instances (which can be consistent or 
+	 * inconsistent). 
+	 * 
+	 * The mapping specification is such that the bidirectional relation is 
+	 * stored in database by a single foreign key. Hence database relation
+	 * is always consistent. Hence the instances retrieved from database are
+	 * always consistently related irrespective of whether they were created
+	 * with consistent or inconsistent relation.
+	 * However, when the instances are retrieved from the data cache, data cache
+	 * will preserve the in-memory relations even when they are inconsistent.
+	 *    
+	 * @param useDataCache
+	 *            use DataCache
+	 * @param consistent
+	 *            assume that the relationship were created as consistent.
+	 */
+	public void verifyBidirectionalRelation(boolean useDataCache,
+			boolean createConsistent, boolean expectConsistent) {
+		EntityManager em = (useDataCache) 
+		                 ? emfWithDataCache.createEntityManager() 
+		                 : emfWithoutDataCache.createEntityManager();
+		                 
+		long id = ID_COUNTER++;
+		ID_COUNTER += 4;
+		createBidirectionalRelation(em, id, createConsistent);
+		
+		
+		BidirectionalOne2OneOwner owner1 = em.find(BidirectionalOne2OneOwner.class, id);
+		BidirectionalOne2OneOwned owned1 = em.find(BidirectionalOne2OneOwned.class, id + 1);
+		BidirectionalOne2OneOwner owner2 = em.find(BidirectionalOne2OneOwner.class, id + 2);
+		BidirectionalOne2OneOwned owned2 = em.find(BidirectionalOne2OneOwned.class, id + 3);
+
+		assertNotNull(owner1);
+		assertNotNull(owner2);
+		assertNotNull(owned1);
+		assertNotNull(owned2);
+
+		assertEquals(owner1, expectConsistent 
+					? owner1.getOwned().getOwner() 
+					: owner2.getOwned().getOwner());
+		assertEquals(owner2, expectConsistent 
+					? owner2.getOwned().getOwner() 
+				    : owner1.getOwned().getOwner());
+
+
+		assertEquals(owned1, owner1.getOwned());
+		assertEquals(expectConsistent ? owner1 : owner2, owned1.getOwner());
+		assertEquals(owned2, owner2.getOwned());
+		assertEquals(expectConsistent ? owner2 : owner1, owned2.getOwner());
+	}
+
+	public void testConsitentBidirectionalRelationIsPreservedWithDataCache() {
+		verifyBidirectionalRelation(WITH_DATACACHE, CONSISTENT, CONSISTENT);
+	}
+
+	public void testConsitentBidirectionalRelationIsPreservedWithoutDataCache() {
+		verifyBidirectionalRelation(!WITH_DATACACHE, CONSISTENT, CONSISTENT);
+	}
+
+	public void testInconsitentBidirectionalRelationIsPreservedWithDataCache() {
+		verifyBidirectionalRelation(WITH_DATACACHE, !CONSISTENT, !CONSISTENT);
+	}
+
+	public void testInconsitentBidirectionalRelationIsNotPreservedWithoutDataCache() {
+		verifyBidirectionalRelation(!WITH_DATACACHE, !CONSISTENT, CONSISTENT);
+	}
+	
+	/**
+	 * Verify that refresh() may fetch state from either the data cache or the
+	 * database based on different conditions. 
+	 * The conditions that impact are 
+	 * a) whether current lock is stronger than NONE 
+	 * b) whether the instance being refreshed is dirty
+	 * 
+	 * An instance is created with data cache marker and persisted. 
+	 * A native SQL is used to update the database record with database marker. 
+	 * The in-memory instance is not aware of this out-of-band update. 
+	 * Then the in-memory instance is refreshed. The marker of the refreshed 
+	 * instance tells whether the instance is refreshed from the data cache
+	 * of the database. 
+	 * 
+	 * @param useDataCache flags if data cache is active. if not, then surely
+	 * refresh always fetch state from the database.
+	 * 
+	 * @param datacache the marker for the copy of the data cached instance
+	 * @param database the marker for the database record
+	 * @param lock lock to be used
+	 * @param makeDirtyBeforeRefresh flags if the instance be dirtied before
+	 * refresh()
+	 * @param expected The expected marker i.e. where the state is refreshed 
+	 * from. This should be always <code>MARKER_DATABASE</code>.
+	 * a) whether DataCache is active
+	 * b) whether current Lock is stronger than NOLOCK
+	 * c) whether the object to be refreshed is dirty
+	 * 
+	 * The following truth table enumerates the possibilities
+	 * 
+	 * Use Cache?   Lock?   Dirty?     Target
+	 *    Y          Y       Y         Database
+	 *    Y          N       Y         Data Cache
+	 *    Y          Y       N         Data Cache
+	 *    Y          N       N         Data Cache
+	 *    
+	 *    N          Y       Y         Database
+	 *    N          N       Y         Database
+	 *    N          Y       N         Object Cache
+	 *    N          N       N         Object Cache
+
+	 */
+	public void verifyRefresh(boolean useDataCache, LockModeType lock, 
+			boolean makeDirtyBeforeRefresh, boolean refreshFromDataCache, 
+			String expected) {
+		OpenJPAEntityManagerFactorySPI emf = (useDataCache)
+			? emfWithDataCache : emfWithoutDataCache;
+		emf.getConfiguration().setRefreshFromDataCache(refreshFromDataCache);
+		OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        
+		em.getTransaction().begin();
+		PObject pc = new PObject();
+		pc.setName(useDataCache ? MARKER_DATACACHE : MARKER_CACHE);
+		em.persist(pc);
+		em.getTransaction().commit();
+		
+		Object oid = pc.getId();
+		StoreCache dataCache = emf.getStoreCache();
+		assertEquals(useDataCache, dataCache.contains(PObject.class, oid));
+		
+		// Modify the record in the database in a separate transaction using
+		// native SQL so that the in-memory instance is not altered 
+		em.getTransaction().begin();
+		String sql = "UPDATE POBJECT SET NAME='"+ MARKER_DATABASE +"' WHERE id="+oid;
+		em.createNativeQuery(sql).executeUpdate();
+		em.getTransaction().commit();
+		
+		assertEquals(useDataCache ? MARKER_DATACACHE : MARKER_CACHE, pc.getName());
+		
+		em.getTransaction().begin();
+		if (makeDirtyBeforeRefresh) {
+			pc.setName(MARKER_DIRTY_CACHE);
+		} 
+		assertEquals(makeDirtyBeforeRefresh, em.isDirty(pc));
+
+		if (lock != null) {
+			((EntityManagerImpl)em).getFetchPlan().setReadLockMode(lock);
+		}
+		em.refresh(pc);
+		
+		assertEquals(expected, pc.getName());
+		em.getTransaction().commit();
+	}
+	
+	/**
+	 * The expected marker i.e. where the state is refreshed from depends on
+	 * a) whether DataCache is active
+	 * b) whether current Lock is stronger than NOLOCK
+	 * c) whether the object to be refreshed is dirty
+	 * 
+	 * The following truth table enumerates the possibilities
+	 * 
+	 * Use Cache?   Lock?   Dirty?     Target
+	 *    Y          Y       Y         Database
+	 *    Y          N       Y         Data Cache
+	 *    Y          Y       N         Data Cache
+	 *    Y          N       N         Data Cache
+	 *    
+	 *    N          Y       Y         Database
+	 *    N          N       Y         Database
+	 *    N          Y       N         Object Cache
+	 *    N          N       N         Object Cache
+	 *    
+	 * @param datacache the marker for 
+	 * @param database
+	 * @param useDataCache
+	 * @param lock
+	 * @param makeDirtyBeforeRefresh
+	 * @return
+	 */
+	String getExpectedMarker(boolean useDataCache, LockModeType lock, 
+			boolean makeDirtyBeforeRefresh) {
+		if (useDataCache) {
+			return (lock != null) ? MARKER_DATABASE : MARKER_DATACACHE; 
+		} else {
+			return MARKER_DATABASE;
+		}
+	}
+	
+	public void testDirtyRefreshWithNoLockHitsDatabase() {
+		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+	}
+	
+	public void testDirtyRefreshWithNoLockHitsDataCache() {
+		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+	}
+	
+	public void testCleanRefreshWithNoLockDoesNotHitDatabase() {
+		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+	}
+	
+	public void testCleanRefreshWithNoLockHitsDataCache() {
+		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+	}
+	
+	public void testDirtyRefreshWithReadLockHitsDatabase() {
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+	}
+	
+	public void testCleanRefreshWithReadLockDoesNotHitDatabase() {
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+	}
+	
+	public void testDirtyRefreshWithWriteLockHitsDatabase() {
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+	}
+	
+	public void testCleanRefreshWithWriteLockDoesNotHitDatabase() {
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+	}
+	
+	public void testDirtyRefreshWithoutDataCacheAlwaysHitsDatabase() {
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+	}
+	
+	public void testCleanRefreshWithoutDataCacheDoesNotHitDatabase() {
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, REFRESH_FROM_DATACACHE,  MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, REFRESH_FROM_DATACACHE,  MARKER_CACHE);
+		
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
+	}
+	
+	/**
+	 * Verify behavior of refreshing an instance which has been deleted by
+	 * out-of-band process (e.g. a native SQL in a separate transaction).
+	 * The behavior differs when refresh() without a lock fetches the data from
+	 * DataCache even when the original database record is deleted.
+	 * 
+	 * @param useDataCache
+	 * @param lock
+	 */
+	public void verifyDeleteDetectionOnRefresh(boolean useDataCache, 
+			boolean dirty, LockModeType lock, Class expectedExceptionType) {
+		OpenJPAEntityManagerFactorySPI emf = (useDataCache)
+			? emfWithDataCache : emfWithoutDataCache;
+			
+		OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        
+		em.getTransaction().begin();
+		PObject pc = new PObject();
+		pc.setName(useDataCache ? MARKER_DATACACHE : MARKER_CACHE);
+		em.persist(pc);
+		em.getTransaction().commit();
+		
+		Object oid = pc.getId();
+		StoreCache dataCache = emf.getStoreCache();
+		assertEquals(useDataCache, dataCache.contains(PObject.class, oid));
+		
+		// delete the record in the database in a separate transaction using
+		// native SQL so that the in-memory instance is not altered 
+		em.getTransaction().begin();
+		String sql = "DELETE FROM POBJECT WHERE id="+oid;
+		em.createNativeQuery(sql).executeUpdate();
+		em.getTransaction().commit();
+		
+		// the object cache does not know that the record was deleted
+		assertTrue(em.contains(pc));
+		// nor does the data cache
+		assertEquals(useDataCache, dataCache.contains(PObject.class, oid));
+		
+		/**
+		 * refresh behavior no more depends on current lock. Refresh
+		 * will always attempt to fetch the instance from database 
+		 * raising EntityNotFoundException.
+		 *   
+		 */
+		em.getTransaction().begin();
+		em.getFetchPlan().setReadLockMode(lock);
+		if (dirty) 
+			pc.setName("Dirty Name");
+		try {
+			em.refresh(pc);
+			if (expectedExceptionType != null) {
+				fail("expected " + expectedExceptionType.getSimpleName() + 
+						" for PObject:" + oid);
+			}
+		} catch (Exception ex) {
+			boolean expectedException = expectedExceptionType != null &&
+			    expectedExceptionType.isAssignableFrom(ex.getClass());
+			if (!expectedException) {
+				ex.printStackTrace();
+				String error = (expectedExceptionType == null) 
+					? "no exception" : expectedExceptionType.getName();
+				fail("expected " + error + " for PObject:" + oid);
+			}
+		} finally {
+			em.getTransaction().rollback();
+		}
+	}
+
+	public void testDeleteIsNotDetectedOnCleanRefreshWithoutLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, NOLOCK, NO_ERROR);
+	}
+	
+	public void testDeleteIsDetectedOnCleanRefreshWithLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+
+	public void testDeleteIsNotDetectedOnDirtyRefreshWithoutLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, NOLOCK, NO_ERROR);	
+	}
+	
+	public void testDeleteIsDetectedOnDirtyRefreshWithLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+	
+	public void testDeleteIsDetectedOnDirtyRefreshWitDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+	
+	public void testDeleteIsDetectedOnCleanRefreshWithoutLockWithoutDataCache() {
+		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, NOLOCK, ENTITY_NOT_FOUND_ERROR);
+	}
+	
+	public void testDeleteIsDetectedOnCleanRefreshWithLockWithoutDataCache() {
+		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheOptimisticLockRecovery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheOptimisticLockRecovery.java
index 1d3c842..d800ec3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheOptimisticLockRecovery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheOptimisticLockRecovery.java
@@ -1,175 +1,175 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import javax.persistence.EntityManager;
-import javax.persistence.RollbackException;
-import javax.persistence.LockModeType;
-import javax.sql.DataSource;
-
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.event.RemoteCommitEvent;
-
-public class TestDataCacheOptimisticLockRecovery
-    extends SingleEMFTestCase {
-
-    private int pk;
-    private int remoteCommitEventStaleCount = 0;
-    private Object staleOid;
-
-    public void setUp() {
-        setUp("openjpa.DataCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            OptimisticLockInstance.class);
-
-        emf.getConfiguration().getRemoteCommitEventManager().addListener(
-            new RemoteCommitListener() {
-                public void afterCommit(RemoteCommitEvent e) {
-                    if (e.getPayloadType() ==
-                        RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION) {
-                        remoteCommitEventStaleCount++;
-                        staleOid = e.getUpdatedObjectIds().iterator().next();
-                    }
-                }
-
-                public void close() {
-                }
-            }
-        );
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        OptimisticLockInstance oli = new OptimisticLockInstance("foo");
-        em.persist(oli);
-        em.getTransaction().commit();
-        pk = oli.getPK();
-        em.close();
-    }
-
-    public void testOptimisticLockRecovery() 
-        throws SQLException {
-
-        EntityManager em;
-        
-        // 1. get the oplock value for the instance after commit and
-        // get a read lock to ensure that we check for the optimistic
-        // lock column at tx commit.
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        OptimisticLockInstance oli = em.find(OptimisticLockInstance.class, pk);
-        Object oid = JPAFacadeHelper.toOpenJPAObjectId(
-            JPAFacadeHelper.getMetaData(oli),
-            OpenJPAPersistence.cast(em).getObjectId(oli));
-        int firstOpLockValue = oli.getOpLock();
-        em.lock(oli, LockModeType.READ);
-
-        // 2. make a change to the instance's optimistic lock column
-        // via direct SQL in a separate transaction
-        int secondOpLockValue = firstOpLockValue + 1;
-
-        OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
-            OpenJPAPersistence.cast(em).getEntityManagerFactory();
-        DataSource ds = (DataSource) emf.getConfiguration()
-            .getConnectionFactory();
-        Connection c = ds.getConnection();
-        c.setAutoCommit(false);
-        PreparedStatement ps = c.prepareStatement(
-            "UPDATE OPTIMISTIC_LOCK_INSTANCE SET OPLOCK = ? WHERE PK = ?");
-        ps.setInt(1, secondOpLockValue);
-        ps.setInt(2, pk);
-        assertEquals(1, ps.executeUpdate());
-        c.commit();
-        
-        // 3. commit the transaction, catching the expected oplock
-        // exception
-        try {
-            em.getTransaction().commit();
-            fail("tx should have failed due to out-of-band oplock change");
-        } catch (RollbackException re) {
-            // expected
-        } finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-        }
-
-        // 4. check that the corresponding remote commit event was fired
-        assertEquals(1, remoteCommitEventStaleCount);
-        assertEquals(oid, staleOid);
-
-        // 5. obtain the object in a new persistence context and
-        // assert that the oplock column is set to the one that
-        // happened in the out-of-band transaction
-        em.close();
-        em = this.emf.createEntityManager();
-        oli = em.find(OptimisticLockInstance.class, pk);
-
-        // If this fails, then the data cache has the wrong value.
-        // This is what this test case is designed to exercise.
-        assertEquals("data cache is not being cleared when oplock "
-            + "violations occur", secondOpLockValue, oli.getOpLock());
-
-        // 6. get a read lock on the instance and commit the tx; this
-        // time it should go through
-        em.getTransaction().begin();
-        em.lock(oli, LockModeType.READ);
-        try {
-            em.getTransaction().commit();
-        } catch (RollbackException e) {
-            throw e;
-        } finally {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-        }
-        em.close();
-    }
-    
-    public void testExpectedOptimisticLockException() {
-        EntityManager em;
-        
-        // 1. start a new tx
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.lock(em.find(OptimisticLockInstance.class, pk), LockModeType.READ);
-        
-        // 2. start another tx, and cause a version increment
-        EntityManager em2 = emf.createEntityManager();
-        em2.getTransaction().begin();
-        em2.lock(em2.find(OptimisticLockInstance.class, pk), 
-            LockModeType.WRITE);
-        em2.getTransaction().commit();
-        em2.close();
-        
-        // 3. try to commit. this should fail, as this is a regular optimistic
-        // lock failure situation.
-        try {
-            em.getTransaction().commit();
-            fail("write lock in em2 should trigger an optimistic lock failure");
-        } catch (RollbackException pe) {
-            // expected
-        }
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import javax.persistence.EntityManager;
+import javax.persistence.RollbackException;
+import javax.persistence.LockModeType;
+import javax.sql.DataSource;
+
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.RemoteCommitEvent;
+
+public class TestDataCacheOptimisticLockRecovery
+    extends SingleEMFTestCase {
+
+    private int pk;
+    private int remoteCommitEventStaleCount = 0;
+    private Object staleOid;
+
+    public void setUp() {
+        setUp("openjpa.DataCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            OptimisticLockInstance.class);
+
+        emf.getConfiguration().getRemoteCommitEventManager().addListener(
+            new RemoteCommitListener() {
+                public void afterCommit(RemoteCommitEvent e) {
+                    if (e.getPayloadType() ==
+                        RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION) {
+                        remoteCommitEventStaleCount++;
+                        staleOid = e.getUpdatedObjectIds().iterator().next();
+                    }
+                }
+
+                public void close() {
+                }
+            }
+        );
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        OptimisticLockInstance oli = new OptimisticLockInstance("foo");
+        em.persist(oli);
+        em.getTransaction().commit();
+        pk = oli.getPK();
+        em.close();
+    }
+
+    public void testOptimisticLockRecovery() 
+        throws SQLException {
+
+        EntityManager em;
+        
+        // 1. get the oplock value for the instance after commit and
+        // get a read lock to ensure that we check for the optimistic
+        // lock column at tx commit.
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        OptimisticLockInstance oli = em.find(OptimisticLockInstance.class, pk);
+        Object oid = JPAFacadeHelper.toOpenJPAObjectId(
+            JPAFacadeHelper.getMetaData(oli),
+            OpenJPAPersistence.cast(em).getObjectId(oli));
+        int firstOpLockValue = oli.getOpLock();
+        em.lock(oli, LockModeType.READ);
+
+        // 2. make a change to the instance's optimistic lock column
+        // via direct SQL in a separate transaction
+        int secondOpLockValue = firstOpLockValue + 1;
+
+        OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
+            OpenJPAPersistence.cast(em).getEntityManagerFactory();
+        DataSource ds = (DataSource) emf.getConfiguration()
+            .getConnectionFactory();
+        Connection c = ds.getConnection();
+        c.setAutoCommit(false);
+        PreparedStatement ps = c.prepareStatement(
+            "UPDATE OPTIMISTIC_LOCK_INSTANCE SET OPLOCK = ? WHERE PK = ?");
+        ps.setInt(1, secondOpLockValue);
+        ps.setInt(2, pk);
+        assertEquals(1, ps.executeUpdate());
+        c.commit();
+        
+        // 3. commit the transaction, catching the expected oplock
+        // exception
+        try {
+            em.getTransaction().commit();
+            fail("tx should have failed due to out-of-band oplock change");
+        } catch (RollbackException re) {
+            // expected
+        } finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+        }
+
+        // 4. check that the corresponding remote commit event was fired
+        assertEquals(1, remoteCommitEventStaleCount);
+        assertEquals(oid, staleOid);
+
+        // 5. obtain the object in a new persistence context and
+        // assert that the oplock column is set to the one that
+        // happened in the out-of-band transaction
+        em.close();
+        em = this.emf.createEntityManager();
+        oli = em.find(OptimisticLockInstance.class, pk);
+
+        // If this fails, then the data cache has the wrong value.
+        // This is what this test case is designed to exercise.
+        assertEquals("data cache is not being cleared when oplock "
+            + "violations occur", secondOpLockValue, oli.getOpLock());
+
+        // 6. get a read lock on the instance and commit the tx; this
+        // time it should go through
+        em.getTransaction().begin();
+        em.lock(oli, LockModeType.READ);
+        try {
+            em.getTransaction().commit();
+        } catch (RollbackException e) {
+            throw e;
+        } finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+        }
+        em.close();
+    }
+    
+    public void testExpectedOptimisticLockException() {
+        EntityManager em;
+        
+        // 1. start a new tx
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.lock(em.find(OptimisticLockInstance.class, pk), LockModeType.READ);
+        
+        // 2. start another tx, and cause a version increment
+        EntityManager em2 = emf.createEntityManager();
+        em2.getTransaction().begin();
+        em2.lock(em2.find(OptimisticLockInstance.class, pk), 
+            LockModeType.WRITE);
+        em2.getTransaction().commit();
+        em2.close();
+        
+        // 3. try to commit. this should fail, as this is a regular optimistic
+        // lock failure situation.
+        try {
+            em.getTransaction().commit();
+            fail("write lock in em2 should trigger an optimistic lock failure");
+        } catch (RollbackException pe) {
+            // expected
+        }
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java
index ba301e0..d0bd13e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCachePCDataGenerator.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-/**
- * Extend the single-JVM cache test to test dynamic pcdata.
- */
-public class TestDataCachePCDataGenerator
-    extends TestSJVMCache {
-
-    public TestDataCachePCDataGenerator(String test) {
-        super(test);
-    }
-
-    protected String[] getConfs() {
-        return addGenerator(super.getConfs());
-    }
-
-    protected String[] getConfs2() {
-        return addGenerator(super.getConfs2());
-    }
-
-    private String[] addGenerator(String[] confs) {
-        String[] copy = new String[confs.length + 2];
-        System.arraycopy(confs, 0, copy, 0, confs.length);
-        copy[confs.length] = "openjpa.DynamicDataStructs";
-        copy[confs.length + 1] = "true";
-        return copy;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+/**
+ * Extend the single-JVM cache test to test dynamic pcdata.
+ */
+public class TestDataCachePCDataGenerator
+    extends TestSJVMCache {
+
+    public TestDataCachePCDataGenerator(String test) {
+        super(test);
+    }
+
+    protected String[] getConfs() {
+        return addGenerator(super.getConfs());
+    }
+
+    protected String[] getConfs2() {
+        return addGenerator(super.getConfs2());
+    }
+
+    private String[] addGenerator(String[] confs) {
+        String[] copy = new String[confs.length + 2];
+        System.arraycopy(confs, 0, copy, 0, confs.length);
+        copy[confs.length] = "openjpa.DynamicDataStructs";
+        copy[confs.length + 1] = "true";
+        return copy;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
index 6f3b31c..bef983d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
@@ -1,228 +1,228 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.datacache.DataCache;
-import org.apache.openjpa.datacache.DataCacheScheduler;
-import org.apache.openjpa.datacache.ConcurrentDataCache;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.util.Id;
-
-public class TestDataCacheScheduler
-    extends AbstractTestCase {
-
-    private static final String MINUTES = getMinutes();
-
-    public TestDataCacheScheduler(String str) {
-        super(str, "datacachecactusapp");
-    }
-
-    private static String getMinutes() {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < 60; i++) {
-            if (i % 2 == 0)
-                buf.append(i).append(',');
-        }
-        return buf.toString();
-    }
-
-    public void setUp() {
-        deleteAll(ScheduledEviction.class);
-    }
-
-    public void testRuntime()
-        throws Exception {
-        String sched = MINUTES + " * * * *";
-        Map propsMap = new HashMap();
-        propsMap
-            .put("openjpa.DataCache", "true(EvictionSchedule=\"" + sched + "\")");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.FlushBeforeQueries", "true");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-        OpenJPAEntityManagerFactory emf =
-            (OpenJPAEntityManagerFactory) getEmf(propsMap);
-
-        ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf))
-            .getConfiguration().getDataCacheManagerInstance()
-            .getDataCacheScheduler().setInterval(1);
-        DataCache cache = JPAFacadeHelper.getMetaData(emf,
-            ScheduledEviction.class).getDataCache();
-
-        OpenJPAEntityManager em = (OpenJPAEntityManager) emf
-            .createEntityManager();
-        startTx(em);
-        ScheduledEviction pc = new ScheduledEviction("Foo");
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        Object oidwithclass = new Id(ScheduledEviction.class, oid.toString());
-        endTx(em);
-        endEm(em);
-
-        cache.clear();// clear and wait until next run.
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        if (cal.get(Calendar.MINUTE) % 2 == 0)
-            Thread.currentThread().sleep
-                ((60 - cal.get(Calendar.SECOND)) * 1000);
-        cal.setTime(new Date());
-        assertTrue(cal.get(Calendar.MINUTE) % 2 == 1);
-        em = (OpenJPAEntityManager) emf.createEntityManager();
-        em.find(ScheduledEviction.class, oid);
-        endEm(em);
-        assertTrue(cache.contains(oidwithclass));
-
-        Thread.currentThread().sleep(130 * 1000);
-        assertFalse(cache.contains(oidwithclass));
-        emf.close();
-    }
-
-    /**
-     * too slow ! *
-     */
-    //FIXME Seetha Sep 26,2006
-    /*public void XXXtestRunnable()
-        throws Exception {
-        KodoPersistenceManager pm = getPM();
-        OpenJPAConfiguration conf = pm.getConfiguration();
-        DataCacheScheduler scheduler = new DataCacheScheduler(conf);
-        scheduler.setInterval(1);
-
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        int minute = (cal.get(Calendar.MINUTE) + 2) % 60;
-        StringBuffer sched = new StringBuffer();
-        sched.append(minute).append(' ');
-        sched.append("* ");
-        sched.append("* ");
-        sched.append("* ");
-        sched.append("* ");
-        DummyCache cache = new DummyCache();
-        scheduler.scheduleEviction(cache, sched.toString());
-
-        Thread thread = new Thread(scheduler);
-        thread.setDaemon(true);
-        thread.start();
-        // test that it did not run yet...
-        Thread.currentThread().sleep(90 * 1000); // 90 seconds
-        assertEquals(0, cache.clearCount);
-        // test that it ran...
-        Thread.currentThread().sleep(45 * 1000); // 45 seconds
-        assertEquals(1, cache.clearCount);
-        // test that it wasn't too eager
-        Thread.currentThread().sleep(50 * 1000); // 90 seconds
-        assertEquals(1, cache.clearCount);
-        scheduler.stop();
-    }*/
-
-    /**
-     * too slow *
-     */
-    /* public void XXXtestMonth()
-        throws Exception {
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        int month = cal.get(Calendar.MONTH);
-        int month2 = month + 1;
-        if (month2 > 12)
-            month2 = 1;
-        doTest("* * " + month + " *", "* * " + month2 + " *");
-    }*/
-
-    /**
-     * too slow *
-     */
-    /* public void XXXtestDayOfMonth()
-        throws Exception {
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        int dom = cal.get(Calendar.DAY_OF_MONTH);
-        doTest("* " + dom + " * *", "* " + (dom % 12 + 1) + " * *");
-    }*/
-    public void testDayOfWeek()
-        throws Exception {
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        int day = cal.get(Calendar.DAY_OF_WEEK);
-        doTest("* * * " + day, "* * * " + (day % 7 + 1));
-    }
-
-    public void testHour()
-        throws Exception {
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        int hour = cal.get(Calendar.HOUR_OF_DAY);
-        doTest(hour + " * * *", ((hour + 1) % 24) + " * * *");
-    }
-
-    /**
-     * Pass in 4 out of 5 tokens.
-     */
-    private void doTest(String valid, String invalid)
-        throws Exception {
-
-        OpenJPAEntityManagerFactory emf =
-            (OpenJPAEntityManagerFactory) getEmf();
-        OpenJPAConfiguration conf =
-            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf))
-                .getConfiguration();
-
-        DataCacheScheduler scheduler = new DataCacheScheduler(conf);
-        scheduler.setInterval(1);
-
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(new Date());
-        String sched = ((cal.get(Calendar.MINUTE) + 1) % 60) + " ";
-        DummyCache validCache = new DummyCache();
-        scheduler.scheduleEviction(validCache, sched + valid);
-        DummyCache invalidCache = new DummyCache();
-        scheduler.scheduleEviction(invalidCache, sched + invalid);
-        Thread thread = new Thread(scheduler);
-        thread.setDaemon(true);
-        thread.start();
-        // test that it did not run yet...
-        Thread.currentThread().sleep(70 * 1000); // 70 seconds
-        scheduler.stop();
-//        assertEquals(2, validCache.clearCount);
-        assertTrue("Wrong invocation count: " + validCache.clearCount,
-            validCache.clearCount == 1 || validCache.clearCount == 2);
-        assertEquals(0, invalidCache.clearCount);
-    }
-
-    private class DummyCache extends ConcurrentDataCache {
-
-        int clearCount = 0;
-
-        public void clear() {
-            clearCount++;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.DataCacheScheduler;
+import org.apache.openjpa.datacache.ConcurrentDataCache;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.util.Id;
+
+public class TestDataCacheScheduler
+    extends AbstractTestCase {
+
+    private static final String MINUTES = getMinutes();
+
+    public TestDataCacheScheduler(String str) {
+        super(str, "datacachecactusapp");
+    }
+
+    private static String getMinutes() {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < 60; i++) {
+            if (i % 2 == 0)
+                buf.append(i).append(',');
+        }
+        return buf.toString();
+    }
+
+    public void setUp() {
+        deleteAll(ScheduledEviction.class);
+    }
+
+    public void testRuntime()
+        throws Exception {
+        String sched = MINUTES + " * * * *";
+        Map propsMap = new HashMap();
+        propsMap
+            .put("openjpa.DataCache", "true(EvictionSchedule=\"" + sched + "\")");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.FlushBeforeQueries", "true");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+        OpenJPAEntityManagerFactory emf =
+            (OpenJPAEntityManagerFactory) getEmf(propsMap);
+
+        ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf))
+            .getConfiguration().getDataCacheManagerInstance()
+            .getDataCacheScheduler().setInterval(1);
+        DataCache cache = JPAFacadeHelper.getMetaData(emf,
+            ScheduledEviction.class).getDataCache();
+
+        OpenJPAEntityManager em = (OpenJPAEntityManager) emf
+            .createEntityManager();
+        startTx(em);
+        ScheduledEviction pc = new ScheduledEviction("Foo");
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        Object oidwithclass = new Id(ScheduledEviction.class, oid.toString());
+        endTx(em);
+        endEm(em);
+
+        cache.clear();// clear and wait until next run.
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        if (cal.get(Calendar.MINUTE) % 2 == 0)
+            Thread.currentThread().sleep
+                ((60 - cal.get(Calendar.SECOND)) * 1000);
+        cal.setTime(new Date());
+        assertTrue(cal.get(Calendar.MINUTE) % 2 == 1);
+        em = (OpenJPAEntityManager) emf.createEntityManager();
+        em.find(ScheduledEviction.class, oid);
+        endEm(em);
+        assertTrue(cache.contains(oidwithclass));
+
+        Thread.currentThread().sleep(130 * 1000);
+        assertFalse(cache.contains(oidwithclass));
+        emf.close();
+    }
+
+    /**
+     * too slow ! *
+     */
+    //FIXME Seetha Sep 26,2006
+    /*public void XXXtestRunnable()
+        throws Exception {
+        KodoPersistenceManager pm = getPM();
+        OpenJPAConfiguration conf = pm.getConfiguration();
+        DataCacheScheduler scheduler = new DataCacheScheduler(conf);
+        scheduler.setInterval(1);
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        int minute = (cal.get(Calendar.MINUTE) + 2) % 60;
+        StringBuffer sched = new StringBuffer();
+        sched.append(minute).append(' ');
+        sched.append("* ");
+        sched.append("* ");
+        sched.append("* ");
+        sched.append("* ");
+        DummyCache cache = new DummyCache();
+        scheduler.scheduleEviction(cache, sched.toString());
+
+        Thread thread = new Thread(scheduler);
+        thread.setDaemon(true);
+        thread.start();
+        // test that it did not run yet...
+        Thread.currentThread().sleep(90 * 1000); // 90 seconds
+        assertEquals(0, cache.clearCount);
+        // test that it ran...
+        Thread.currentThread().sleep(45 * 1000); // 45 seconds
+        assertEquals(1, cache.clearCount);
+        // test that it wasn't too eager
+        Thread.currentThread().sleep(50 * 1000); // 90 seconds
+        assertEquals(1, cache.clearCount);
+        scheduler.stop();
+    }*/
+
+    /**
+     * too slow *
+     */
+    /* public void XXXtestMonth()
+        throws Exception {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        int month = cal.get(Calendar.MONTH);
+        int month2 = month + 1;
+        if (month2 > 12)
+            month2 = 1;
+        doTest("* * " + month + " *", "* * " + month2 + " *");
+    }*/
+
+    /**
+     * too slow *
+     */
+    /* public void XXXtestDayOfMonth()
+        throws Exception {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        int dom = cal.get(Calendar.DAY_OF_MONTH);
+        doTest("* " + dom + " * *", "* " + (dom % 12 + 1) + " * *");
+    }*/
+    public void testDayOfWeek()
+        throws Exception {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        int day = cal.get(Calendar.DAY_OF_WEEK);
+        doTest("* * * " + day, "* * * " + (day % 7 + 1));
+    }
+
+    public void testHour()
+        throws Exception {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        int hour = cal.get(Calendar.HOUR_OF_DAY);
+        doTest(hour + " * * *", ((hour + 1) % 24) + " * * *");
+    }
+
+    /**
+     * Pass in 4 out of 5 tokens.
+     */
+    private void doTest(String valid, String invalid)
+        throws Exception {
+
+        OpenJPAEntityManagerFactory emf =
+            (OpenJPAEntityManagerFactory) getEmf();
+        OpenJPAConfiguration conf =
+            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf))
+                .getConfiguration();
+
+        DataCacheScheduler scheduler = new DataCacheScheduler(conf);
+        scheduler.setInterval(1);
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        String sched = ((cal.get(Calendar.MINUTE) + 1) % 60) + " ";
+        DummyCache validCache = new DummyCache();
+        scheduler.scheduleEviction(validCache, sched + valid);
+        DummyCache invalidCache = new DummyCache();
+        scheduler.scheduleEviction(invalidCache, sched + invalid);
+        Thread thread = new Thread(scheduler);
+        thread.setDaemon(true);
+        thread.start();
+        // test that it did not run yet...
+        Thread.currentThread().sleep(70 * 1000); // 70 seconds
+        scheduler.stop();
+//        assertEquals(2, validCache.clearCount);
+        assertTrue("Wrong invocation count: " + validCache.clearCount,
+            validCache.clearCount == 1 || validCache.clearCount == 2);
+        assertEquals(0, invalidCache.clearCount);
+    }
+
+    private class DummyCache extends ConcurrentDataCache {
+
+        int clearCount = 0;
+
+        public void clear() {
+            clearCount++;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDistributedKodoDataCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDistributedKodoDataCache.java
index 820d55f..98729c1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDistributedKodoDataCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDistributedKodoDataCache.java
@@ -1,357 +1,357 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.datacache.DataCache;
-import org.apache.openjpa.event.TCPRemoteCommitProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.util.Id;
-
-public class TestDistributedKodoDataCache extends AbstractTestCase {
-
-    // We want more than 1 instance of each type of class.
-    private static final int NUM_OBJECTS = 4;
-
-    private Object[] _runtime1sOids;
-
-    private Object[] _runtime2sOids;
-
-    private Object spec_oid;
-
-    public TestDistributedKodoDataCache(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-    }
-
-    private interface ChangeOperation {
-
-        public String getName();
-
-        public void operation(OpenJPAEntityManagerFactory kpmf,
-            boolean asLarge);
-    }
-
-    private class performAsModify implements ChangeOperation {
-
-        public String getName() {
-            return "Modify SpecialRuntimeTest1";
-        }
-
-        public void operation(OpenJPAEntityManagerFactory kpmf,
-            boolean asLarge) {
-            OpenJPAEntityManager pm;
-            pm = (OpenJPAEntityManager) kpmf.createEntityManager();
-            if (asLarge)
-                //pm.setLargeTransaction(true);
-                pm.setTrackChangesByType(true);
-            startTx(pm);
-            RuntimeTest1 special = pm.find(RuntimeTest1.class, spec_oid);
-            assertNotNull(special);
-            special.setStringField("SpeicalRuntimeTest1_MODIFIED");
-
-            endTx(pm);
-            endEm(pm);
-        }
-    }
-
-    private class performAsDelete implements ChangeOperation {
-
-        public String getName() {
-            return "Delete SpecialRuntimeTest1";
-        }
-
-        public void operation(OpenJPAEntityManagerFactory kpmf,
-            boolean asLarge) {
-            OpenJPAEntityManager pm;
-            pm = (OpenJPAEntityManager) kpmf.createEntityManager();
-            if (asLarge)
-                //pm.setLargeTransaction(true);
-                pm.setTrackChangesByType(true);
-            startTx(pm);
-            RuntimeTest1 specialObj = pm.find(RuntimeTest1.class, spec_oid);
-            assertNotNull(specialObj);
-
-            pm.remove(specialObj);
-
-            endTx(pm);
-            endEm(pm);
-        }
-    }
-
-    public void testNormalTransAndDataCacheDelete() {
-        coreTestTransAndChange(new performAsDelete(), false, true);
-    }
-
-    public void testNormalTransAndDataCacheModify() {
-        coreTestTransAndChange(new performAsModify(), false, false);
-    }
-
-    public void testLargeTransAndDataCacheDelete() {
-        coreTestTransAndChange(new performAsDelete(), true, true);
-    }
-
-    public void testLargeTransAndDataCacheModify() {
-        coreTestTransAndChange(new performAsModify(), true, false);
-    }
-
-    public void coreTestTransAndChange(ChangeOperation changeOperation,
-        boolean asLargeTransaction, boolean isDelete) {
-        // Create two pmfs in a cluster that are using RCPTCP.
-        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5636, Addresses=127.0.0.1:6636");
-        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:5636");
-        // Get the datacaches from each pmf
-        DataCache dcSender =
-            ((OpenJPAEntityManagerFactorySPI) pmfSender).getConfiguration()
-                .getDataCacheManagerInstance().getSystemDataCache();
-        DataCache dcReceiver =
-            ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-                .getDataCacheManagerInstance().getSystemDataCache();
-
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-
-        _runtime1sOids = null;
-        _runtime2sOids = null;
-
-        String transType = "normal";
-        String rcpType = "OIDs";
-        if (asLargeTransaction) {
-            transType = "large";
-            rcpType = "classes";
-        }
-        System.out.println("-------------------");
-        System.out
-            .println(
-                "2 PMFs created, acting as a cluster using ports 5636 and 6636");
-        System.out.println("Testing scenario:");
-        System.out
-            .println("  1 Seed datastore with instances of RuntimeTest1 AND "
-                + "RuntimeTest2 objs.\n"
-                + "  2 pmf2 fills its cache with both sets of objs.\n"
-                + "  3 pmf1 does a "
-                + transType
-                + " tx that invokes an operation of "
-                + changeOperation.getName()
-                + " to affect a single Runtime1 \n"
-                + "    assert that both pmf1 and pmf2's data caches dropped all"
-                + "Runtime1s");
-        System.out.println("Remote commit event is transmiting " + rcpType);
-
-        // Create runtimes1s and 2s.
-        // Noraml transaction
-        OpenJPAEntityManager pmSender = (OpenJPAEntityManager) pmfSender
-            .createEntityManager();
-        seedDataStore(pmSender, NUM_OBJECTS);
-        endEm(pmSender);
-
-        // wait a bit so they get stored
-        pause(1);
-
-        OpenJPAEntityManager pm2;
-        pm2 = (OpenJPAEntityManager) pmfReceiver.createEntityManager();
-        performLoadAll(pm2);
-        endEm(pm2);
-
-        pmSender = (OpenJPAEntityManager) pmfSender.createEntityManager();
-        performLoadAll(pmSender);
-        endEm(pmSender);
-
-        // assert that pmf2's data cache now has all the Runtime1 and 2s.
-        for (int i = 0; i < _runtime1sOids.length; i++) {
-            assertTrue(dcReceiver.contains(
-                Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
-        }
-        for (int i = 0; i < _runtime2sOids.length; i++) {
-            assertTrue(dcReceiver.contains(
-                Id.newInstance(RuntimeTest2.class, _runtime2sOids[i])));
-        }
-
-        // Modify or delete exactly 1 RuntimeTest1 object during a
-        // largeTransaction
-        changeOperation.operation(pmfSender, asLargeTransaction);
-
-        // assert that pmf1's data cache now only has Runtime2 objects
-        if (asLargeTransaction) {
-            for (int i = 0; i < _runtime1sOids.length; i++) {
-                assertFalse(dcSender.contains(
-                    Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
-            }
-        } else {
-            // Normal transaction
-            for (int i = 0; i < _runtime1sOids.length; i++) {
-                if (isDelete && i == 0) {
-                    assertFalse(dcSender.contains(
-                        Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
-                } else {
-                    // modified the first elemnt, which just updated it.
-                    // (for Kodo's data cache).
-                    assertTrue(dcSender.contains(
-                        Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
-                }
-            }
-        }
-        for (int i = 0; i < _runtime2sOids.length; i++) {
-            assertTrue(dcSender.contains(
-                Id.newInstance(RuntimeTest2.class, _runtime2sOids[i])));
-        }
-        // wait a tiny bit so the rce propagates
-        pause(2);
-        // assert the pmf2's data cache also now only has Runtime2 objects
-        if (asLargeTransaction) {
-            for (int i = 0; i < _runtime1sOids.length; i++) {
-                assertFalse(dcReceiver.contains(Id.newInstance(
-                    RuntimeTest1.class, _runtime1sOids[i]))); //failing here
-            }
-        } else {
-            for (int i = 0; i < _runtime1sOids.length; i++) {
-                if (i == 0) {
-                    assertFalse(dcReceiver.contains(Id.newInstance(
-                        RuntimeTest1.class,
-                        _runtime1sOids[i])));  //failing here
-                } else {
-                    assertTrue(dcReceiver.contains(
-                        Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
-                }
-            }
-        }
-        for (int i = 0; i < _runtime2sOids.length; i++) {
-            assertTrue(dcReceiver.contains(
-                Id.newInstance(RuntimeTest2.class, _runtime2sOids[i])));
-        }
-
-        // shutdown
-        pmfSender.close();
-        pmfReceiver.close();
-    }
-
-    protected void performLoadAll(OpenJPAEntityManager pm)
-    // load in (and thus cache) all the 1s and 2s
-    {
-        startTx(pm);
-        RuntimeTest1 temp1;
-        Collection runtime1s = (Collection) pm
-            .createQuery("SELECT a FROM RuntimeTest1 a").getResultList();
-
-        for (Iterator itr = runtime1s.iterator(); itr.hasNext();)
-            temp1 = (RuntimeTest1) itr.next();
-        RuntimeTest2 temp2;
-        Collection runtime2s = (Collection) pm
-            .createQuery("SELECT a FROM RuntimeTest2 a").getResultList();
-
-        for (Iterator itr = runtime2s.iterator(); itr.hasNext();)
-            temp2 = (RuntimeTest2) itr.next();
-        endTx(pm);
-    }
-
-    protected void seedDataStore(OpenJPAEntityManager pm, int numObjects) {
-        startTx(pm);
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        _runtime1sOids = new Object[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, i);
-            pm.persist(persistables[i]);
-            _runtime1sOids[i] = pm.getObjectId(persistables[i]);
-            if (i == 0) {
-                persistables[i].setStringField("SpecialRuntimeTest1");
-                spec_oid = pm.getObjectId(persistables[i]);
-            }
-        }
-        RuntimeTest2[] persistables2 = new RuntimeTest2[numObjects];
-        _runtime2sOids = new Object[numObjects];
-        for (int i = 0; i < persistables2.length; i++) {
-            persistables2[i] = new RuntimeTest2("bar #" + i, i);
-            pm.persist(persistables2[i]);
-            _runtime2sOids[i] = pm.getObjectId(persistables2[i]);
-        }
-        endTx(pm);
-    }
-
-    static int _fetchGroupSerial = 0;
-
-    protected OpenJPAEntityManagerFactory createDistinctFactory(
-        Class providerClass, String classProps1) {
-        Map propsMap;
-
-        if (providerClass != null) {
-            // This test is for the combination of RCP, largeTrans,
-            // and Kodo's builtin DataCache.
-            // use this property to differentiate the factory
-
-            propsMap = new HashMap();
-            propsMap.put("openjpa.DataCache", "lru");
-            propsMap.put("openjpa.RemoteCommitProvider", Configurations.getPlugin(
-                providerClass.getName(), classProps1));
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup"
-                + _fetchGroupSerial);
-        } else {
-            // No RCP
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup"
-                + _fetchGroupSerial);
-        }
-        _fetchGroupSerial += 1;
-
-        return (OpenJPAEntityManagerFactory) getEmf(propsMap);
-    }
-
-    private void pause(double seconds) {
-        try {
-            Thread.currentThread().yield();
-            Thread.currentThread().sleep((int) seconds * 1000);
-        }
-        catch (Exception e) {
-        }
-    }
-}
-
-/*
- remove all Runteim1, and 2
- create a few 1 and 2s
- get them into the cache, assert
- large transaction, and modify a runtime2, assert cache only has runtime1s
-
-
- remove all Runteim1, and 2
- create a few 1 and 2s
- get them into the cache, assert
- large transaction, delete a runtime2, assert cache only has runteime1s
- */
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.util.Id;
+
+public class TestDistributedKodoDataCache extends AbstractTestCase {
+
+    // We want more than 1 instance of each type of class.
+    private static final int NUM_OBJECTS = 4;
+
+    private Object[] _runtime1sOids;
+
+    private Object[] _runtime2sOids;
+
+    private Object spec_oid;
+
+    public TestDistributedKodoDataCache(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+    }
+
+    private interface ChangeOperation {
+
+        public String getName();
+
+        public void operation(OpenJPAEntityManagerFactory kpmf,
+            boolean asLarge);
+    }
+
+    private class performAsModify implements ChangeOperation {
+
+        public String getName() {
+            return "Modify SpecialRuntimeTest1";
+        }
+
+        public void operation(OpenJPAEntityManagerFactory kpmf,
+            boolean asLarge) {
+            OpenJPAEntityManager pm;
+            pm = (OpenJPAEntityManager) kpmf.createEntityManager();
+            if (asLarge)
+                //pm.setLargeTransaction(true);
+                pm.setTrackChangesByType(true);
+            startTx(pm);
+            RuntimeTest1 special = pm.find(RuntimeTest1.class, spec_oid);
+            assertNotNull(special);
+            special.setStringField("SpeicalRuntimeTest1_MODIFIED");
+
+            endTx(pm);
+            endEm(pm);
+        }
+    }
+
+    private class performAsDelete implements ChangeOperation {
+
+        public String getName() {
+            return "Delete SpecialRuntimeTest1";
+        }
+
+        public void operation(OpenJPAEntityManagerFactory kpmf,
+            boolean asLarge) {
+            OpenJPAEntityManager pm;
+            pm = (OpenJPAEntityManager) kpmf.createEntityManager();
+            if (asLarge)
+                //pm.setLargeTransaction(true);
+                pm.setTrackChangesByType(true);
+            startTx(pm);
+            RuntimeTest1 specialObj = pm.find(RuntimeTest1.class, spec_oid);
+            assertNotNull(specialObj);
+
+            pm.remove(specialObj);
+
+            endTx(pm);
+            endEm(pm);
+        }
+    }
+
+    public void testNormalTransAndDataCacheDelete() {
+        coreTestTransAndChange(new performAsDelete(), false, true);
+    }
+
+    public void testNormalTransAndDataCacheModify() {
+        coreTestTransAndChange(new performAsModify(), false, false);
+    }
+
+    public void testLargeTransAndDataCacheDelete() {
+        coreTestTransAndChange(new performAsDelete(), true, true);
+    }
+
+    public void testLargeTransAndDataCacheModify() {
+        coreTestTransAndChange(new performAsModify(), true, false);
+    }
+
+    public void coreTestTransAndChange(ChangeOperation changeOperation,
+        boolean asLargeTransaction, boolean isDelete) {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:5636");
+        // Get the datacaches from each pmf
+        DataCache dcSender =
+            ((OpenJPAEntityManagerFactorySPI) pmfSender).getConfiguration()
+                .getDataCacheManagerInstance().getSystemDataCache();
+        DataCache dcReceiver =
+            ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+                .getDataCacheManagerInstance().getSystemDataCache();
+
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+
+        _runtime1sOids = null;
+        _runtime2sOids = null;
+
+        String transType = "normal";
+        String rcpType = "OIDs";
+        if (asLargeTransaction) {
+            transType = "large";
+            rcpType = "classes";
+        }
+        System.out.println("-------------------");
+        System.out
+            .println(
+                "2 PMFs created, acting as a cluster using ports 5636 and 6636");
+        System.out.println("Testing scenario:");
+        System.out
+            .println("  1 Seed datastore with instances of RuntimeTest1 AND "
+                + "RuntimeTest2 objs.\n"
+                + "  2 pmf2 fills its cache with both sets of objs.\n"
+                + "  3 pmf1 does a "
+                + transType
+                + " tx that invokes an operation of "
+                + changeOperation.getName()
+                + " to affect a single Runtime1 \n"
+                + "    assert that both pmf1 and pmf2's data caches dropped all"
+                + "Runtime1s");
+        System.out.println("Remote commit event is transmiting " + rcpType);
+
+        // Create runtimes1s and 2s.
+        // Noraml transaction
+        OpenJPAEntityManager pmSender = (OpenJPAEntityManager) pmfSender
+            .createEntityManager();
+        seedDataStore(pmSender, NUM_OBJECTS);
+        endEm(pmSender);
+
+        // wait a bit so they get stored
+        pause(1);
+
+        OpenJPAEntityManager pm2;
+        pm2 = (OpenJPAEntityManager) pmfReceiver.createEntityManager();
+        performLoadAll(pm2);
+        endEm(pm2);
+
+        pmSender = (OpenJPAEntityManager) pmfSender.createEntityManager();
+        performLoadAll(pmSender);
+        endEm(pmSender);
+
+        // assert that pmf2's data cache now has all the Runtime1 and 2s.
+        for (int i = 0; i < _runtime1sOids.length; i++) {
+            assertTrue(dcReceiver.contains(
+                Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
+        }
+        for (int i = 0; i < _runtime2sOids.length; i++) {
+            assertTrue(dcReceiver.contains(
+                Id.newInstance(RuntimeTest2.class, _runtime2sOids[i])));
+        }
+
+        // Modify or delete exactly 1 RuntimeTest1 object during a
+        // largeTransaction
+        changeOperation.operation(pmfSender, asLargeTransaction);
+
+        // assert that pmf1's data cache now only has Runtime2 objects
+        if (asLargeTransaction) {
+            for (int i = 0; i < _runtime1sOids.length; i++) {
+                assertFalse(dcSender.contains(
+                    Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
+            }
+        } else {
+            // Normal transaction
+            for (int i = 0; i < _runtime1sOids.length; i++) {
+                if (isDelete && i == 0) {
+                    assertFalse(dcSender.contains(
+                        Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
+                } else {
+                    // modified the first elemnt, which just updated it.
+                    // (for Kodo's data cache).
+                    assertTrue(dcSender.contains(
+                        Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
+                }
+            }
+        }
+        for (int i = 0; i < _runtime2sOids.length; i++) {
+            assertTrue(dcSender.contains(
+                Id.newInstance(RuntimeTest2.class, _runtime2sOids[i])));
+        }
+        // wait a tiny bit so the rce propagates
+        pause(2);
+        // assert the pmf2's data cache also now only has Runtime2 objects
+        if (asLargeTransaction) {
+            for (int i = 0; i < _runtime1sOids.length; i++) {
+                assertFalse(dcReceiver.contains(Id.newInstance(
+                    RuntimeTest1.class, _runtime1sOids[i]))); //failing here
+            }
+        } else {
+            for (int i = 0; i < _runtime1sOids.length; i++) {
+                if (i == 0) {
+                    assertFalse(dcReceiver.contains(Id.newInstance(
+                        RuntimeTest1.class,
+                        _runtime1sOids[i])));  //failing here
+                } else {
+                    assertTrue(dcReceiver.contains(
+                        Id.newInstance(RuntimeTest1.class, _runtime1sOids[i])));
+                }
+            }
+        }
+        for (int i = 0; i < _runtime2sOids.length; i++) {
+            assertTrue(dcReceiver.contains(
+                Id.newInstance(RuntimeTest2.class, _runtime2sOids[i])));
+        }
+
+        // shutdown
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected void performLoadAll(OpenJPAEntityManager pm)
+    // load in (and thus cache) all the 1s and 2s
+    {
+        startTx(pm);
+        RuntimeTest1 temp1;
+        Collection runtime1s = (Collection) pm
+            .createQuery("SELECT a FROM RuntimeTest1 a").getResultList();
+
+        for (Iterator itr = runtime1s.iterator(); itr.hasNext();)
+            temp1 = (RuntimeTest1) itr.next();
+        RuntimeTest2 temp2;
+        Collection runtime2s = (Collection) pm
+            .createQuery("SELECT a FROM RuntimeTest2 a").getResultList();
+
+        for (Iterator itr = runtime2s.iterator(); itr.hasNext();)
+            temp2 = (RuntimeTest2) itr.next();
+        endTx(pm);
+    }
+
+    protected void seedDataStore(OpenJPAEntityManager pm, int numObjects) {
+        startTx(pm);
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        _runtime1sOids = new Object[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+            pm.persist(persistables[i]);
+            _runtime1sOids[i] = pm.getObjectId(persistables[i]);
+            if (i == 0) {
+                persistables[i].setStringField("SpecialRuntimeTest1");
+                spec_oid = pm.getObjectId(persistables[i]);
+            }
+        }
+        RuntimeTest2[] persistables2 = new RuntimeTest2[numObjects];
+        _runtime2sOids = new Object[numObjects];
+        for (int i = 0; i < persistables2.length; i++) {
+            persistables2[i] = new RuntimeTest2("bar #" + i, i);
+            pm.persist(persistables2[i]);
+            _runtime2sOids[i] = pm.getObjectId(persistables2[i]);
+        }
+        endTx(pm);
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        Map propsMap;
+
+        if (providerClass != null) {
+            // This test is for the combination of RCP, largeTrans,
+            // and Kodo's builtin DataCache.
+            // use this property to differentiate the factory
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.DataCache", "lru");
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.getPlugin(
+                providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup"
+                + _fetchGroupSerial);
+        } else {
+            // No RCP
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup"
+                + _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return (OpenJPAEntityManagerFactory) getEmf(propsMap);
+    }
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        }
+        catch (Exception e) {
+        }
+    }
+}
+
+/*
+ remove all Runteim1, and 2
+ create a few 1 and 2s
+ get them into the cache, assert
+ large transaction, and modify a runtime2, assert cache only has runtime1s
+
+
+ remove all Runteim1, and 2
+ create a few 1 and 2s
+ get them into the cache, assert
+ large transaction, delete a runtime2, assert cache only has runteime1s
+ */
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestEmbeddedCollection.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestEmbeddedCollection.java
index 8c38a31..80f024e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestEmbeddedCollection.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestEmbeddedCollection.java
@@ -1,123 +1,123 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.StoreCacheImpl;
-import org.apache.openjpa.persistence.datacache.common.apps.EmbeddedEntity;
-import org.apache.openjpa.persistence.datacache.common.apps.EmbeddingOwnerEntity;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test removing members of embedded collection with active DataCache.
- * 
- * Originally reported in 
- * <HREF="http://issues.apache.org/jira/browse/OPENJPA-625">OPENJPA-625</A>
- * 
- * @author Pinaki Poddar
- *
- */
-public class TestEmbeddedCollection extends SingleEMFTestCase {
-
-	private static final int SIZE = 4;
-	private static OpenJPAEntityManagerFactorySPI emf = null;
-	/**
-	 * Sets up EntityManagerFactory: with DataCache.
-	 */
-	public void setUp() throws Exception {
-		if (emf == null) {
-			super.setUp("openjpa.jdbc.SynchronizeMappings", "buildSchema",
-					"openjpa.RuntimeUnenhancedClasses", "unsupported",
-					"openjpa.DataCache", "true", "openjpa.RemoteCommitProvider",
-					"sjvm", "openjpa.jdbc.UpdateManager", "constraint",
-					EmbeddingOwnerEntity.class, 
-					EmbeddedEntity.class,
-					CLEAR_TABLES);
-			emf = super.emf;
-			
-			createData();
-		}
-		assertNotNull(emf);
-		assertNotNull(emf.getStoreCache());
-		assertTrue(isDataCacheActive(emf));
-	}
-
-	boolean isDataCacheActive(OpenJPAEntityManagerFactorySPI emf) {
-		return ((StoreCacheImpl) emf.getStoreCache()).getDelegate() != null
-				&& emf.getConfiguration().getDataCacheManagerInstance()
-						.getSystemDataCache() != null;
-	}
-	
-	@Override
-	public void tearDown() throws Exception {
-		
-	}
-	
-	public void createData() {
-		EmbeddingOwnerEntity owner = new EmbeddingOwnerEntity();
-		for (int i = 0; i < SIZE; i++) {
-			EmbeddedEntity member = new EmbeddedEntity();
-			member.setMarker("Member-" + i);
-			owner.addMember(member);
-		}
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		em.persist(owner);
-		em.getTransaction().commit();
-		Object id = OpenJPAPersistence.cast(em).getObjectId(owner);
-		em.clear();
-
-		EmbeddingOwnerEntity test = em.find(EmbeddingOwnerEntity.class, id);
-		assertNotNull(test);
-		List<EmbeddedEntity> members = test.getMembers();
-		assertNotNull(members);
-		assertEquals(SIZE, members.size());
-		for (int i = 0; i < SIZE; i++)
-			members.get(i).getMarker().equals("Member-" + i);
-	}
-
-	public void testRemoveMemberFromEmbeddedCollection() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		List<EmbeddingOwnerEntity> result = em.createQuery(
-				"SELECT p FROM EmbeddingOwnerEntity p").getResultList();
-
-		assertNotNull(result);
-		assertFalse(result.isEmpty());
-
-		EmbeddingOwnerEntity owner = result.get(0);
-		Object id = owner.getId();
-		
-		assertTrue(emf.getStoreCache().contains(EmbeddingOwnerEntity.class, id));
-		
-		List<EmbeddedEntity> members = owner.getMembers();
-		members.remove(0);
-		owner.removeMember(0);
-		owner.removeMember(members.get(0));
-		em.getTransaction().commit();
-		
-		assertEquals(owner.getMembers().size(), SIZE-3); 
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.StoreCacheImpl;
+import org.apache.openjpa.persistence.datacache.common.apps.EmbeddedEntity;
+import org.apache.openjpa.persistence.datacache.common.apps.EmbeddingOwnerEntity;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test removing members of embedded collection with active DataCache.
+ * 
+ * Originally reported in 
+ * <HREF="http://issues.apache.org/jira/browse/OPENJPA-625">OPENJPA-625</A>
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestEmbeddedCollection extends SingleEMFTestCase {
+
+	private static final int SIZE = 4;
+	private static OpenJPAEntityManagerFactorySPI emf = null;
+	/**
+	 * Sets up EntityManagerFactory: with DataCache.
+	 */
+	public void setUp() throws Exception {
+		if (emf == null) {
+			super.setUp("openjpa.jdbc.SynchronizeMappings", "buildSchema",
+					"openjpa.RuntimeUnenhancedClasses", "unsupported",
+					"openjpa.DataCache", "true", "openjpa.RemoteCommitProvider",
+					"sjvm", "openjpa.jdbc.UpdateManager", "constraint",
+					EmbeddingOwnerEntity.class, 
+					EmbeddedEntity.class,
+					CLEAR_TABLES);
+			emf = super.emf;
+			
+			createData();
+		}
+		assertNotNull(emf);
+		assertNotNull(emf.getStoreCache());
+		assertTrue(isDataCacheActive(emf));
+	}
+
+	boolean isDataCacheActive(OpenJPAEntityManagerFactorySPI emf) {
+		return ((StoreCacheImpl) emf.getStoreCache()).getDelegate() != null
+				&& emf.getConfiguration().getDataCacheManagerInstance()
+						.getSystemDataCache() != null;
+	}
+	
+	@Override
+	public void tearDown() throws Exception {
+		
+	}
+	
+	public void createData() {
+		EmbeddingOwnerEntity owner = new EmbeddingOwnerEntity();
+		for (int i = 0; i < SIZE; i++) {
+			EmbeddedEntity member = new EmbeddedEntity();
+			member.setMarker("Member-" + i);
+			owner.addMember(member);
+		}
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		em.persist(owner);
+		em.getTransaction().commit();
+		Object id = OpenJPAPersistence.cast(em).getObjectId(owner);
+		em.clear();
+
+		EmbeddingOwnerEntity test = em.find(EmbeddingOwnerEntity.class, id);
+		assertNotNull(test);
+		List<EmbeddedEntity> members = test.getMembers();
+		assertNotNull(members);
+		assertEquals(SIZE, members.size());
+		for (int i = 0; i < SIZE; i++)
+			members.get(i).getMarker().equals("Member-" + i);
+	}
+
+	public void testRemoveMemberFromEmbeddedCollection() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		List<EmbeddingOwnerEntity> result = em.createQuery(
+				"SELECT p FROM EmbeddingOwnerEntity p").getResultList();
+
+		assertNotNull(result);
+		assertFalse(result.isEmpty());
+
+		EmbeddingOwnerEntity owner = result.get(0);
+		Object id = owner.getId();
+		
+		assertTrue(emf.getStoreCache().contains(EmbeddingOwnerEntity.class, id));
+		
+		List<EmbeddedEntity> members = owner.getMembers();
+		members.remove(0);
+		owner.removeMember(0);
+		owner.removeMember(members.get(0));
+		em.getTransaction().commit();
+		
+		assertEquals(owner.getMembers().size(), SIZE-3); 
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestFlushDataCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestFlushDataCache.java
index d8cf929..ae80be1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestFlushDataCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestFlushDataCache.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.FlushDataCacheObject;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestFlushDataCache
-    extends AbstractTestCase {
-
-    public TestFlushDataCache(String str) {
-        super(str, "datacachecactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(FlushDataCacheObject.class);
-    }
-
-    public void testQueryFlushPlusDataCache() {
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.FlushBeforeQueries", "true");
-        //propsMap.put("javax.jdo.option.IgnoreCache", "false");
-        //propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
-        EntityManagerFactory emf = getEmf(propsMap);
-
-        try {
-
-            //assertEquals(Class.forName("openjpa.datacache.CacheTestBroker",true,emf.getClass().getClassLoader()).getClassLoader(),emf.getClass().getClassLoader());
-            //Thread.currentThread().setContextClassLoader(emf.getClass().getClassLoader());
-            Class.forName("org.apache.openjpa.persistence.datacache.CacheTestBroker", true,
-                Thread.currentThread().getContextClassLoader());
-        } catch (Exception e) {
-
-        }
-
-        EntityManager em = emf.createEntityManager();
-        startTx(em);
-        FlushDataCacheObject o = new FlushDataCacheObject();
-        o.setString("foo");
-        em.persist(o);
-        endTx(em);
-        //Object oid = JDOHelper.getObjectId (o);
-        endEm(em);
-
-        em = emf.createEntityManager();
-        startTx(em);
-
-        Collection c = (Collection) em.createQuery(
-            "select a FROM " + FlushDataCacheObject.class.getSimpleName() +
-                " a where a.string = 'foo'").getResultList();
-
-        assertEquals(1, c.size());
-        em.remove(c.iterator().next());
-
-        c = (Collection) em.createQuery(
-            "select a FROM " + FlushDataCacheObject.class.getSimpleName() +
-                " a where a.string = 'foo'").getResultList();
-        assertEquals(0, c.size());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testEmptyCommit() {
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.FlushBeforeQueries", "true");
-        //propsMap.put("javax.jdo.option.IgnoreCache", "false");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-        EntityManagerFactory emf = getEmf(propsMap);
-        EntityManager em = emf.createEntityManager();
-        startTx(em);
-        endTx(em);
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.FlushDataCacheObject;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestFlushDataCache
+    extends AbstractTestCase {
+
+    public TestFlushDataCache(String str) {
+        super(str, "datacachecactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(FlushDataCacheObject.class);
+    }
+
+    public void testQueryFlushPlusDataCache() {
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.FlushBeforeQueries", "true");
+        //propsMap.put("javax.jdo.option.IgnoreCache", "false");
+        //propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
+        EntityManagerFactory emf = getEmf(propsMap);
+
+        try {
+
+            //assertEquals(Class.forName("openjpa.datacache.CacheTestBroker",true,emf.getClass().getClassLoader()).getClassLoader(),emf.getClass().getClassLoader());
+            //Thread.currentThread().setContextClassLoader(emf.getClass().getClassLoader());
+            Class.forName("org.apache.openjpa.persistence.datacache.CacheTestBroker", true,
+                Thread.currentThread().getContextClassLoader());
+        } catch (Exception e) {
+
+        }
+
+        EntityManager em = emf.createEntityManager();
+        startTx(em);
+        FlushDataCacheObject o = new FlushDataCacheObject();
+        o.setString("foo");
+        em.persist(o);
+        endTx(em);
+        //Object oid = JDOHelper.getObjectId (o);
+        endEm(em);
+
+        em = emf.createEntityManager();
+        startTx(em);
+
+        Collection c = (Collection) em.createQuery(
+            "select a FROM " + FlushDataCacheObject.class.getSimpleName() +
+                " a where a.string = 'foo'").getResultList();
+
+        assertEquals(1, c.size());
+        em.remove(c.iterator().next());
+
+        c = (Collection) em.createQuery(
+            "select a FROM " + FlushDataCacheObject.class.getSimpleName() +
+                " a where a.string = 'foo'").getResultList();
+        assertEquals(0, c.size());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testEmptyCommit() {
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.FlushBeforeQueries", "true");
+        //propsMap.put("javax.jdo.option.IgnoreCache", "false");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+        EntityManagerFactory emf = getEmf(propsMap);
+        EntityManager em = emf.createEntityManager();
+        startTx(em);
+        endTx(em);
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2Queries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2Queries.java
index 32cd0fd..59735eb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2Queries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2Queries.java
@@ -1,134 +1,134 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestJPQL2Queries
-    extends AbstractTestCase {
-
-    public TestJPQL2Queries(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private BrokerFactory _factory;
-
-    public void setUp() {
-        deleteAll(CacheObjectA.class);
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-        EntityManagerFactory emf = getEmf(propsMap);
-        _factory = JPAFacadeHelper.toBrokerFactory(emf);
-        Broker broker = _factory.newBroker();
-        broker.begin();
-        for (int i = 0; i < 50; i++)
-            broker.persist(new CacheObjectAChild1("", "JPQL2Queries", i),
-                null);
-        broker.commit();
-        broker.close();
-
-        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
-    }
-
-    public void tearDown()
-        throws Exception {
-        try {
-            _factory.close();
-        } catch (Exception e) {
-        }
-
-        super.tearDown();
-    }
-
-    public void testUpperRange() {
-        rangeTestHelper(0, 10);
-    }
-
-    public void testLowerRange() {
-        rangeTestHelper(5, 50);
-    }
-
-    public void testBothRanges() {
-        rangeTestHelper(20, 28);
-    }
-
-    private void rangeTestHelper(final int start, final int end) {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        q.setRange(start, end);
-
-        // should not yet be in the cache
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
-        Collection c = (Collection) q.execute();
-
-        // iterate the results. This will cause the query to be
-        // enlisted in the cache.
-        CacheTestHelper.iterate(c);
-        assertEquals(end - start, c.size());
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        broker.close();
-
-        broker = _factory.newBroker();
-        q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        q.setRange(start, end);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-        c = (Collection) q.execute();
-        assertEquals(end - start, c.size());
-
-        // now check if a smaller range is in cache
-        q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        q.setRange(start, end - 1);
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
-        c = (Collection) q.execute();
-        assertEquals(end - start - 1, c.size());
-        broker.close();
-    }
-
-    public void testResultClassIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        q.setResultType(Object.class);
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestJPQL2Queries
+    extends AbstractTestCase {
+
+    public TestJPQL2Queries(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private BrokerFactory _factory;
+
+    public void setUp() {
+        deleteAll(CacheObjectA.class);
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+        EntityManagerFactory emf = getEmf(propsMap);
+        _factory = JPAFacadeHelper.toBrokerFactory(emf);
+        Broker broker = _factory.newBroker();
+        broker.begin();
+        for (int i = 0; i < 50; i++)
+            broker.persist(new CacheObjectAChild1("", "JPQL2Queries", i),
+                null);
+        broker.commit();
+        broker.close();
+
+        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
+    }
+
+    public void tearDown()
+        throws Exception {
+        try {
+            _factory.close();
+        } catch (Exception e) {
+        }
+
+        super.tearDown();
+    }
+
+    public void testUpperRange() {
+        rangeTestHelper(0, 10);
+    }
+
+    public void testLowerRange() {
+        rangeTestHelper(5, 50);
+    }
+
+    public void testBothRanges() {
+        rangeTestHelper(20, 28);
+    }
+
+    private void rangeTestHelper(final int start, final int end) {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        q.setRange(start, end);
+
+        // should not yet be in the cache
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
+        Collection c = (Collection) q.execute();
+
+        // iterate the results. This will cause the query to be
+        // enlisted in the cache.
+        CacheTestHelper.iterate(c);
+        assertEquals(end - start, c.size());
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        broker.close();
+
+        broker = _factory.newBroker();
+        q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        q.setRange(start, end);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+        c = (Collection) q.execute();
+        assertEquals(end - start, c.size());
+
+        // now check if a smaller range is in cache
+        q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        q.setRange(start, end - 1);
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
+        c = (Collection) q.execute();
+        assertEquals(end - start - 1, c.size());
+        broker.close();
+    }
+
+    public void testResultClassIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        q.setResultType(Object.class);
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2ResultsAndResultClasses.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2ResultsAndResultClasses.java
index 1fd8f78..d5e254a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2ResultsAndResultClasses.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQL2ResultsAndResultClasses.java
@@ -1,472 +1,472 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectWithExternalizedFields;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-public class TestJPQL2ResultsAndResultClasses
-    extends AbstractTestCase {
-
-    public TestJPQL2ResultsAndResultClasses(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private BrokerFactory _factory;
-
-    public void setUp() {
-        deleteAll(CacheObjectA.class);
-        deleteAll(CacheObjectWithExternalizedFields.class);
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-        EntityManagerFactory emf =
-            getEmf(propsMap);
-        _factory = JPAFacadeHelper.toBrokerFactory(emf);
-        Broker broker = _factory.newBroker();
-        try {
-            broker.begin();
-        } catch (Exception e) {
-            System.out.println(
-                "Exception in TestJPQL2ResultsAndResultClasses setup : \n" +
-                    getStackTrace(e));
-        }
-
-        int j = 0;
-        for (int i = 0; i < 10; i++) {
-            // make some common names so that GROUP BY is useful.
-            if (i % 2 == 0)
-                j++;
-            CacheObjectA o;
-            broker.persist(o = new CacheObjectAChild1("", "results-" + j, i),
-                null);
-
-            o.setDate(new Date());
-            o.setDateArray(new Date[]{ new Date(10), new Date(20) });
-
-            if (i < 5)
-                o.setRelatedB(new CacheObjectB());
-        }
-
-        //Seetha Oct 30,2006
-        //deleteAll closes the TX.  So use the local
-        //deleteAll fn.
-        //deleteAll(CacheObjectWithExternalizedFields.class,());
-        //deleteAll(broker,CacheObjectWithExternalizedFields.class,true);
-
-        CacheObjectWithExternalizedFields o =
-            new CacheObjectWithExternalizedFields();
-        broker.persist(o, null);
-        o.setCls(Broker.class);
-
-        broker.commit();
-        broker.close();
-
-        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
-    }
-
-    public void tearDown()
-        throws Exception {
-        _factory.close();
-
-        super.tearDown();
-    }
-
-    public void testAggregateResultIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select max(a.age) FROM " +
-                CacheObjectAChild1.class.getSimpleName() + " a");
-
-        Object o = q.execute();
-        assertEquals(Long.class, o.getClass());
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        o = q.execute();
-        assertEquals(Long.class, o.getClass());
-    }
-
-    public void testAggregateNonUniqueResultIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select max(a.age) FROM " +
-                CacheObjectAChild1.class.getSimpleName() + " a");
-        q.setUnique(false);
-        List res = (List) q.execute();
-        assertEquals(1, res.size());
-        Object o = res.get(0);
-        assertEquals(Long.class, o.getClass());
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        res = (List) q.execute();
-        assertEquals(1, res.size());
-        o = res.get(0);
-        assertEquals(Long.class, o.getClass());
-    }
-
-    public void testProjectionResultIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.age FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object o = c.iterator().next();
-        assertEquals(Long.class, o.getClass());
-    }
-
-    public void testProjectionOfThisIsCached() {
-        // ##### need to test single projection
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        //CacheObjectAChild1.class, "select this");
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object o = c.iterator().next();
-        assertEquals(CacheObjectAChild1.class, o.getClass());
-        assertNotNull(broker.getObjectId(o));
-    }
-
-    public void testProjectionResultWithThisIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.name,a FROM " +
-                CacheObjectAChild1.class.getSimpleName() + " a");
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object[] result = (Object[]) c.iterator().next();
-        assertEquals(2, result.length);
-        assertEquals(String.class, result[0].getClass());
-        assertEquals(CacheObjectAChild1.class, result[1].getClass());
-        assertNotNull(broker.getObjectId(result[1]));
-    }
-
-    public void testNullProjectionValues() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.locale FROM " +
-                CacheObjectAChild1.class.getSimpleName() + " a");
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        assertNull(c.iterator().next());
-    }
-
-    public void testNullAndNotNullProjectionValues() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker
-                .newQuery(JPQLParser.LANG_JPQL, "select a.name,a.locale FROM " +
-                    CacheObjectAChild1.class.getSimpleName() + " a");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object[] result = (Object[]) c.iterator().next();
-        assertEquals(2, result.length);
-        assertEquals(String.class, result[0].getClass());
-        assertNull(result[1]);
-    }
-
-    public void XXXtestNullAggregateValues() {
-        // ???
-    }
-
-    public void testMultipleAggregateResultIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL,
-                "select max(a.age), avg(a.age), count(a.age) FROM " +
-                    CacheObjectAChild1.class.getSimpleName() + " a");
-
-        Object o = q.execute();
-        assertEquals(Object[].class, o.getClass());
-        assertEquals(3, ((Object[]) o).length);
-        assertEquals(Long.class, ((Object[]) o)[0].getClass());
-
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        o = q.execute();
-        assertEquals(Object[].class, o.getClass());
-        assertEquals(3, ((Object[]) o).length);
-        assertEquals(Long.class, ((Object[]) o)[0].getClass());
-    }
-
-    public void testFieldUsedTwice() {
-        // Postgres bug
-        Broker broker = _factory.newBroker();
-        // group avoids postgres bug
-        Query q = broker
-            .newQuery(JPQLParser.LANG_JPQL, "select a.age, avg(a.age) FROM " +
-                CacheObjectAChild1.class.getSimpleName() +
-                " a  group by a.age");
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-    }
-
-    public void testAggregateAndProjection() {
-        // Postgres bug
-        Broker broker = _factory.newBroker();
-        // group avoids postgres bug
-        Query q = broker
-            .newQuery(JPQLParser.LANG_JPQL, "select a.name, avg(a.age) FROM " +
-                CacheObjectAChild1.class.getSimpleName() +
-                " a  group by a.name");
-
-        List l = (List) q.execute();
-        CacheTestHelper.iterate(l);
-        assertEquals(Object[].class, l.get(0).getClass());
-        assertEquals(2, ((Object[]) l.get(0)).length);
-        assertEquals(String.class, ((Object[]) l.get(0))[0].getClass());
-
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        l = (List) q.execute();
-        assertEquals(Object[].class, l.get(0).getClass());
-        assertEquals(2, ((Object[]) l.get(0)).length);
-        assertEquals(String.class, ((Object[]) l.get(0))[0].getClass());
-    }
-
-    //FIXME Seetha Dec 19,2006
-    /*public void testMath() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL,"select avg(a.age) FROM "+
-                    CacheObjectAChild1.class.getSimpleName()+" a");
-        Number n = (Number) q.execute();
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-        n = (Number) q.execute();
-    }*/
-
-    public void testResultClassIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a");
-        q.setResultType(Object.class);
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-    }
-
-    public void testGroupingIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select max(a.age) FROM " +
-                CacheObjectAChild1.class.getSimpleName() +
-                " a  group by a.name");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object o = c.iterator().next();
-        assertEquals(Long.class, o.getClass());
-    }
-
-    public void testAggregateProjectionGroupingIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL,
-                "select a.name, max(a.age) FROM " +
-                    CacheObjectAChild1.class.getSimpleName() +
-                    " a  group by a.name");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object[] result = (Object[]) c.iterator().next();
-        assertEquals(2, result.length);
-        assertEquals(String.class, result[0].getClass());
-        assertEquals(Long.class, result[1].getClass());
-    }
-
-    public void testUniqueResultsAreCachedAndConsistent() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
-                CacheObjectAChild1.class.getSimpleName() +
-                " a  where a.age =1");
-
-        q.setUnique(true);
-        CacheObjectAChild1 a = (CacheObjectAChild1) q.execute();
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        CacheObjectAChild1 a2 = (CacheObjectAChild1) q.execute();
-        assertTrue(a == a2);
-    }
-
-    public void testMutableProjectionFieldsAreCopied() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.date FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a  where a.age=1");
-
-        q.setUnique(true);
-        Date d0 = (Date) q.execute(); // get it in cache
-        Date d1 = (Date) q.execute();
-        assertNotSame(d0, d1);
-
-        Date d2 = (Date) q.execute();
-        assertNotSame(d1, d2);
-    }
-
-    public void testArrayProjectionFieldsAreNotCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.dateArray FROM " +
-                CacheObjectAChild1.class.getSimpleName() + " a");
-
-        try {
-            q.execute();
-            fail("Allowed array projection query.");
-        } catch (Exception e) {
-        }
-    }
-
-    public void testCollectionProjectionFieldsAreNotCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.stringColl FROM " +
-                CacheObjectAChild1.class.getSimpleName() + " a");
-
-        try {
-            q.execute();
-            fail("Allowed array projection query.");
-        } catch (Exception e) {
-        }
-    }
-
-    public void testExternalizedSingleValueFieldIsNotCached() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.cls FROM " +
-            CacheObjectWithExternalizedFields.class.getSimpleName() + " a");
-
-        q.setUnique(true);
-        Object o = q.execute(); // get it in cache
-        // ##### assertEquals (Class.class, o);
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
-    }
-
-    public void testMutatedQueryReturnsNewResults() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL,
-                "select a.name, max(a.age) FROM " +
-                    CacheObjectAChild1.class.getSimpleName() +
-                    " a group by a.name");
-
-        List l = (List) q.execute();
-        CacheTestHelper.iterate(l);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        l = (List) q.execute();
-        Object[] result = (Object[]) l.get(0);
-        assertEquals(2, result.length);
-        assertEquals(String.class, result[0].getClass());
-        assertEquals(Long.class, result[1].getClass());
-
-        // now, mutate the query and see what happens
-        q.setQuery("select max(a.age),a.name FROM " +
-            CacheObjectAChild1.class.getSimpleName() + " a group by a.name");
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
-        l = (List) q.execute();
-        result = (Object[]) l.get(0);
-        assertEquals(2, result.length);
-        assertEquals(Long.class, result[0].getClass());
-        assertEquals(String.class, result[1].getClass());
-        CacheTestHelper.iterate(l);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        l = (List) q.execute();
-        result = (Object[]) l.get(0);
-        assertEquals(2, result.length);
-        assertEquals(Long.class, result[0].getClass());
-        assertEquals(String.class, result[1].getClass());
-    }
-
-    public void XXXtestExternalizedContainerFieldIsExternalized() {
-    }
-
-    public void XXXtestSerializedSingleValueFieldIsSerialized() {
-    }
-
-    public void XXXtestSerializedContainerFieldIsSerialized() {
-    }
-
-    public void XXXtestCustomMappedSingleValueFieldIsHandled() {
-    }
-
-    public void XXXtestCustomMappedContainerFieldIsHandled() {
-    }
-
-    private static int deleteAll(Broker broker, Class clazz,
-        boolean subclasses) {
-        final boolean useDeleteByQuery = false;
-
-        if (useDeleteByQuery) {
-            org.apache.openjpa.kernel.Query query =
-                broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
-                    clazz.getSimpleName() + " a");
-            query.setCandidateType(clazz, subclasses);
-            return (int) query.deleteAll();
-        } else {
-            org.apache.openjpa.kernel.Extent extent =
-                broker.newExtent(clazz, subclasses);
-            List list = extent.list();
-            int size = list.size();
-            broker.deleteAll(list, null);
-            return size;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectWithExternalizedFields;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+public class TestJPQL2ResultsAndResultClasses
+    extends AbstractTestCase {
+
+    public TestJPQL2ResultsAndResultClasses(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private BrokerFactory _factory;
+
+    public void setUp() {
+        deleteAll(CacheObjectA.class);
+        deleteAll(CacheObjectWithExternalizedFields.class);
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+        EntityManagerFactory emf =
+            getEmf(propsMap);
+        _factory = JPAFacadeHelper.toBrokerFactory(emf);
+        Broker broker = _factory.newBroker();
+        try {
+            broker.begin();
+        } catch (Exception e) {
+            System.out.println(
+                "Exception in TestJPQL2ResultsAndResultClasses setup : \n" +
+                    getStackTrace(e));
+        }
+
+        int j = 0;
+        for (int i = 0; i < 10; i++) {
+            // make some common names so that GROUP BY is useful.
+            if (i % 2 == 0)
+                j++;
+            CacheObjectA o;
+            broker.persist(o = new CacheObjectAChild1("", "results-" + j, i),
+                null);
+
+            o.setDate(new Date());
+            o.setDateArray(new Date[]{ new Date(10), new Date(20) });
+
+            if (i < 5)
+                o.setRelatedB(new CacheObjectB());
+        }
+
+        //Seetha Oct 30,2006
+        //deleteAll closes the TX.  So use the local
+        //deleteAll fn.
+        //deleteAll(CacheObjectWithExternalizedFields.class,());
+        //deleteAll(broker,CacheObjectWithExternalizedFields.class,true);
+
+        CacheObjectWithExternalizedFields o =
+            new CacheObjectWithExternalizedFields();
+        broker.persist(o, null);
+        o.setCls(Broker.class);
+
+        broker.commit();
+        broker.close();
+
+        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
+    }
+
+    public void tearDown()
+        throws Exception {
+        _factory.close();
+
+        super.tearDown();
+    }
+
+    public void testAggregateResultIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select max(a.age) FROM " +
+                CacheObjectAChild1.class.getSimpleName() + " a");
+
+        Object o = q.execute();
+        assertEquals(Long.class, o.getClass());
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        o = q.execute();
+        assertEquals(Long.class, o.getClass());
+    }
+
+    public void testAggregateNonUniqueResultIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select max(a.age) FROM " +
+                CacheObjectAChild1.class.getSimpleName() + " a");
+        q.setUnique(false);
+        List res = (List) q.execute();
+        assertEquals(1, res.size());
+        Object o = res.get(0);
+        assertEquals(Long.class, o.getClass());
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        res = (List) q.execute();
+        assertEquals(1, res.size());
+        o = res.get(0);
+        assertEquals(Long.class, o.getClass());
+    }
+
+    public void testProjectionResultIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.age FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object o = c.iterator().next();
+        assertEquals(Long.class, o.getClass());
+    }
+
+    public void testProjectionOfThisIsCached() {
+        // ##### need to test single projection
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        //CacheObjectAChild1.class, "select this");
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object o = c.iterator().next();
+        assertEquals(CacheObjectAChild1.class, o.getClass());
+        assertNotNull(broker.getObjectId(o));
+    }
+
+    public void testProjectionResultWithThisIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.name,a FROM " +
+                CacheObjectAChild1.class.getSimpleName() + " a");
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object[] result = (Object[]) c.iterator().next();
+        assertEquals(2, result.length);
+        assertEquals(String.class, result[0].getClass());
+        assertEquals(CacheObjectAChild1.class, result[1].getClass());
+        assertNotNull(broker.getObjectId(result[1]));
+    }
+
+    public void testNullProjectionValues() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.locale FROM " +
+                CacheObjectAChild1.class.getSimpleName() + " a");
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        assertNull(c.iterator().next());
+    }
+
+    public void testNullAndNotNullProjectionValues() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker
+                .newQuery(JPQLParser.LANG_JPQL, "select a.name,a.locale FROM " +
+                    CacheObjectAChild1.class.getSimpleName() + " a");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object[] result = (Object[]) c.iterator().next();
+        assertEquals(2, result.length);
+        assertEquals(String.class, result[0].getClass());
+        assertNull(result[1]);
+    }
+
+    public void XXXtestNullAggregateValues() {
+        // ???
+    }
+
+    public void testMultipleAggregateResultIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL,
+                "select max(a.age), avg(a.age), count(a.age) FROM " +
+                    CacheObjectAChild1.class.getSimpleName() + " a");
+
+        Object o = q.execute();
+        assertEquals(Object[].class, o.getClass());
+        assertEquals(3, ((Object[]) o).length);
+        assertEquals(Long.class, ((Object[]) o)[0].getClass());
+
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        o = q.execute();
+        assertEquals(Object[].class, o.getClass());
+        assertEquals(3, ((Object[]) o).length);
+        assertEquals(Long.class, ((Object[]) o)[0].getClass());
+    }
+
+    public void testFieldUsedTwice() {
+        // Postgres bug
+        Broker broker = _factory.newBroker();
+        // group avoids postgres bug
+        Query q = broker
+            .newQuery(JPQLParser.LANG_JPQL, "select a.age, avg(a.age) FROM " +
+                CacheObjectAChild1.class.getSimpleName() +
+                " a  group by a.age");
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+    }
+
+    public void testAggregateAndProjection() {
+        // Postgres bug
+        Broker broker = _factory.newBroker();
+        // group avoids postgres bug
+        Query q = broker
+            .newQuery(JPQLParser.LANG_JPQL, "select a.name, avg(a.age) FROM " +
+                CacheObjectAChild1.class.getSimpleName() +
+                " a  group by a.name");
+
+        List l = (List) q.execute();
+        CacheTestHelper.iterate(l);
+        assertEquals(Object[].class, l.get(0).getClass());
+        assertEquals(2, ((Object[]) l.get(0)).length);
+        assertEquals(String.class, ((Object[]) l.get(0))[0].getClass());
+
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        l = (List) q.execute();
+        assertEquals(Object[].class, l.get(0).getClass());
+        assertEquals(2, ((Object[]) l.get(0)).length);
+        assertEquals(String.class, ((Object[]) l.get(0))[0].getClass());
+    }
+
+    //FIXME Seetha Dec 19,2006
+    /*public void testMath() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL,"select avg(a.age) FROM "+
+                    CacheObjectAChild1.class.getSimpleName()+" a");
+        Number n = (Number) q.execute();
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+        n = (Number) q.execute();
+    }*/
+
+    public void testResultClassIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a");
+        q.setResultType(Object.class);
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+    }
+
+    public void testGroupingIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select max(a.age) FROM " +
+                CacheObjectAChild1.class.getSimpleName() +
+                " a  group by a.name");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object o = c.iterator().next();
+        assertEquals(Long.class, o.getClass());
+    }
+
+    public void testAggregateProjectionGroupingIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL,
+                "select a.name, max(a.age) FROM " +
+                    CacheObjectAChild1.class.getSimpleName() +
+                    " a  group by a.name");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object[] result = (Object[]) c.iterator().next();
+        assertEquals(2, result.length);
+        assertEquals(String.class, result[0].getClass());
+        assertEquals(Long.class, result[1].getClass());
+    }
+
+    public void testUniqueResultsAreCachedAndConsistent() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
+                CacheObjectAChild1.class.getSimpleName() +
+                " a  where a.age =1");
+
+        q.setUnique(true);
+        CacheObjectAChild1 a = (CacheObjectAChild1) q.execute();
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        CacheObjectAChild1 a2 = (CacheObjectAChild1) q.execute();
+        assertTrue(a == a2);
+    }
+
+    public void testMutableProjectionFieldsAreCopied() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.date FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a  where a.age=1");
+
+        q.setUnique(true);
+        Date d0 = (Date) q.execute(); // get it in cache
+        Date d1 = (Date) q.execute();
+        assertNotSame(d0, d1);
+
+        Date d2 = (Date) q.execute();
+        assertNotSame(d1, d2);
+    }
+
+    public void testArrayProjectionFieldsAreNotCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.dateArray FROM " +
+                CacheObjectAChild1.class.getSimpleName() + " a");
+
+        try {
+            q.execute();
+            fail("Allowed array projection query.");
+        } catch (Exception e) {
+        }
+    }
+
+    public void testCollectionProjectionFieldsAreNotCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.stringColl FROM " +
+                CacheObjectAChild1.class.getSimpleName() + " a");
+
+        try {
+            q.execute();
+            fail("Allowed array projection query.");
+        } catch (Exception e) {
+        }
+    }
+
+    public void testExternalizedSingleValueFieldIsNotCached() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.cls FROM " +
+            CacheObjectWithExternalizedFields.class.getSimpleName() + " a");
+
+        q.setUnique(true);
+        Object o = q.execute(); // get it in cache
+        // ##### assertEquals (Class.class, o);
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
+    }
+
+    public void testMutatedQueryReturnsNewResults() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL,
+                "select a.name, max(a.age) FROM " +
+                    CacheObjectAChild1.class.getSimpleName() +
+                    " a group by a.name");
+
+        List l = (List) q.execute();
+        CacheTestHelper.iterate(l);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        l = (List) q.execute();
+        Object[] result = (Object[]) l.get(0);
+        assertEquals(2, result.length);
+        assertEquals(String.class, result[0].getClass());
+        assertEquals(Long.class, result[1].getClass());
+
+        // now, mutate the query and see what happens
+        q.setQuery("select max(a.age),a.name FROM " +
+            CacheObjectAChild1.class.getSimpleName() + " a group by a.name");
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE);
+        l = (List) q.execute();
+        result = (Object[]) l.get(0);
+        assertEquals(2, result.length);
+        assertEquals(Long.class, result[0].getClass());
+        assertEquals(String.class, result[1].getClass());
+        CacheTestHelper.iterate(l);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        l = (List) q.execute();
+        result = (Object[]) l.get(0);
+        assertEquals(2, result.length);
+        assertEquals(Long.class, result[0].getClass());
+        assertEquals(String.class, result[1].getClass());
+    }
+
+    public void XXXtestExternalizedContainerFieldIsExternalized() {
+    }
+
+    public void XXXtestSerializedSingleValueFieldIsSerialized() {
+    }
+
+    public void XXXtestSerializedContainerFieldIsSerialized() {
+    }
+
+    public void XXXtestCustomMappedSingleValueFieldIsHandled() {
+    }
+
+    public void XXXtestCustomMappedContainerFieldIsHandled() {
+    }
+
+    private static int deleteAll(Broker broker, Class clazz,
+        boolean subclasses) {
+        final boolean useDeleteByQuery = false;
+
+        if (useDeleteByQuery) {
+            org.apache.openjpa.kernel.Query query =
+                broker.newQuery(JPQLParser.LANG_JPQL, "Select a FROM " +
+                    clazz.getSimpleName() + " a");
+            query.setCandidateType(clazz, subclasses);
+            return (int) query.deleteAll();
+        } else {
+            org.apache.openjpa.kernel.Extent extent =
+                broker.newExtent(clazz, subclasses);
+            List list = extent.list();
+            int size = list.size();
+            broker.deleteAll(list, null);
+            return size;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQLRelationProjections.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQLRelationProjections.java
index c15d777..65eb511 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQLRelationProjections.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestJPQLRelationProjections.java
@@ -1,219 +1,219 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
-import org.apache.openjpa.persistence.datacache.common.apps.SelfReferencingCacheTestObject;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.util.UserException;
-
-public class TestJPQLRelationProjections
-    extends AbstractTestCase {
-
-    public TestJPQLRelationProjections(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private BrokerFactory _factory;
-
-    public void setUp() {
-        deleteAll(CacheObjectJ.class);
-        deleteAll(CacheObjectE.class);
-        deleteAll(SelfReferencingCacheTestObject.class);
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-
-        EntityManagerFactory emf = getEmf(propsMap);
-        _factory = JPAFacadeHelper.toBrokerFactory(emf);
-        Broker broker = _factory.newBroker();
-        try {
-            broker.begin();
-        } catch (Exception e) {
-            fail("Set up failed due to exception : \n" +
-                getStackTrace(e));
-        }
-        int j = 0;
-        for (int i = 0; i < 6; i++) {
-            CacheObjectE e;
-            if (i < 3)
-                e = new CacheObjectE(i + "");
-            else
-                e = null;
-
-            // make some common names so that GROUP BY is useful.
-            if (i % 2 == 0)
-                j++;
-            broker.persist(new CacheObjectJ("projections-" + j, e), null);
-        }
-
-        broker.persist(new SelfReferencingCacheTestObject("foo",
-            new SelfReferencingCacheTestObject("bar", null)), null);
-
-        broker.commit();
-        broker.close();
-
-        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
-    }
-
-    public void tearDown()
-        throws Exception {
-        _factory.close();
-
-        super.tearDown();
-    }
-
-    public void testNullRelatedPCIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.e FROM " +
-            CacheObjectJ.class.getSimpleName() + " a where a.e is null");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        assertNull(c.iterator().next());
-    }
-
-    public void testNullRelatedPCAndProjectionIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.str,a.e FROM " +
-                CacheObjectJ.class.getSimpleName() + " a where a.e is null");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object[] result = (Object[]) c.iterator().next();
-        assertEquals(2, result.length);
-        assertEquals(String.class, result[0].getClass());
-        assertNull(result[1]);
-    }
-
-    public void testNonNullRelatedPCIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.e FROM " +
-            CacheObjectJ.class.getSimpleName() + " a where a.e  is not null");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        assertEquals(CacheObjectE.class, c.iterator().next().getClass());
-    }
-
-    public void testNonNullRelatedPCAndProjectionIsCached() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.str,a.e FROM " +
-                CacheObjectJ.class.getSimpleName() +
-                " a where a.e is not null");
-
-        Collection c = (Collection) q.execute();
-        CacheTestHelper.iterate(c);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        c = (Collection) q.execute();
-        Object[] result = (Object[]) c.iterator().next();
-        assertEquals(2, result.length);
-        assertEquals(String.class, result[0].getClass());
-        assertEquals(CacheObjectE.class, result[1].getClass());
-    }
-
-    public void testEmbeddedFields() {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select embedded FROM " +
-                SelfReferencingCacheTestObject.class.getSimpleName() +
-                " a where a.str='foo'");
-
-        List l = null;
-        try {
-            l = (List) q.execute();
-            assertEquals(CacheObjectAChild1.class, l.get(0).getClass());
-        } catch (UserException ue) {
-            //bug(1150, "embedded-field projections cause exception");
-            ue.printStackTrace();
-            return;
-        }
-
-        CacheTestHelper.iterate(l);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        l = (List) q.execute();
-        assertEquals(CacheObjectAChild1.class, l.get(0).getClass());
-    }
-
-    public void testNonNullRelationOfSameTypeAsCandidate() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.o FROM " +
-            SelfReferencingCacheTestObject.class.getSimpleName() +
-            " a where a.o IS NOT NULL");
-
-        List l = (List) q.execute();
-        assertEquals(SelfReferencingCacheTestObject.class,
-            l.get(0).getClass());
-        assertEquals("bar",
-            ((SelfReferencingCacheTestObject) l.get(0)).getStr());
-        CacheTestHelper.iterate(l);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        l = (List) q.execute();
-        assertEquals(SelfReferencingCacheTestObject.class,
-            l.get(0).getClass());
-        assertEquals("bar",
-            ((SelfReferencingCacheTestObject) l.get(0)).getStr());
-    }
-
-    public void testNullRelationOfSameTypeAsCandidate() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.o FROM " +
-            SelfReferencingCacheTestObject.class.getSimpleName() +
-            " a where a.o IS NULL");
-
-        List l = (List) q.execute();
-        assertNull(l.get(0));
-        CacheTestHelper.iterate(l);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
-
-        l = (List) q.execute();
-        assertNull(l.get(0));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
+import org.apache.openjpa.persistence.datacache.common.apps.SelfReferencingCacheTestObject;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.util.UserException;
+
+public class TestJPQLRelationProjections
+    extends AbstractTestCase {
+
+    public TestJPQLRelationProjections(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private BrokerFactory _factory;
+
+    public void setUp() {
+        deleteAll(CacheObjectJ.class);
+        deleteAll(CacheObjectE.class);
+        deleteAll(SelfReferencingCacheTestObject.class);
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+
+        EntityManagerFactory emf = getEmf(propsMap);
+        _factory = JPAFacadeHelper.toBrokerFactory(emf);
+        Broker broker = _factory.newBroker();
+        try {
+            broker.begin();
+        } catch (Exception e) {
+            fail("Set up failed due to exception : \n" +
+                getStackTrace(e));
+        }
+        int j = 0;
+        for (int i = 0; i < 6; i++) {
+            CacheObjectE e;
+            if (i < 3)
+                e = new CacheObjectE(i + "");
+            else
+                e = null;
+
+            // make some common names so that GROUP BY is useful.
+            if (i % 2 == 0)
+                j++;
+            broker.persist(new CacheObjectJ("projections-" + j, e), null);
+        }
+
+        broker.persist(new SelfReferencingCacheTestObject("foo",
+            new SelfReferencingCacheTestObject("bar", null)), null);
+
+        broker.commit();
+        broker.close();
+
+        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
+    }
+
+    public void tearDown()
+        throws Exception {
+        _factory.close();
+
+        super.tearDown();
+    }
+
+    public void testNullRelatedPCIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.e FROM " +
+            CacheObjectJ.class.getSimpleName() + " a where a.e is null");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        assertNull(c.iterator().next());
+    }
+
+    public void testNullRelatedPCAndProjectionIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.str,a.e FROM " +
+                CacheObjectJ.class.getSimpleName() + " a where a.e is null");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object[] result = (Object[]) c.iterator().next();
+        assertEquals(2, result.length);
+        assertEquals(String.class, result[0].getClass());
+        assertNull(result[1]);
+    }
+
+    public void testNonNullRelatedPCIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.e FROM " +
+            CacheObjectJ.class.getSimpleName() + " a where a.e  is not null");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        assertEquals(CacheObjectE.class, c.iterator().next().getClass());
+    }
+
+    public void testNonNullRelatedPCAndProjectionIsCached() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.str,a.e FROM " +
+                CacheObjectJ.class.getSimpleName() +
+                " a where a.e is not null");
+
+        Collection c = (Collection) q.execute();
+        CacheTestHelper.iterate(c);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        c = (Collection) q.execute();
+        Object[] result = (Object[]) c.iterator().next();
+        assertEquals(2, result.length);
+        assertEquals(String.class, result[0].getClass());
+        assertEquals(CacheObjectE.class, result[1].getClass());
+    }
+
+    public void testEmbeddedFields() {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select embedded FROM " +
+                SelfReferencingCacheTestObject.class.getSimpleName() +
+                " a where a.str='foo'");
+
+        List l = null;
+        try {
+            l = (List) q.execute();
+            assertEquals(CacheObjectAChild1.class, l.get(0).getClass());
+        } catch (UserException ue) {
+            //bug(1150, "embedded-field projections cause exception");
+            ue.printStackTrace();
+            return;
+        }
+
+        CacheTestHelper.iterate(l);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        l = (List) q.execute();
+        assertEquals(CacheObjectAChild1.class, l.get(0).getClass());
+    }
+
+    public void testNonNullRelationOfSameTypeAsCandidate() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.o FROM " +
+            SelfReferencingCacheTestObject.class.getSimpleName() +
+            " a where a.o IS NOT NULL");
+
+        List l = (List) q.execute();
+        assertEquals(SelfReferencingCacheTestObject.class,
+            l.get(0).getClass());
+        assertEquals("bar",
+            ((SelfReferencingCacheTestObject) l.get(0)).getStr());
+        CacheTestHelper.iterate(l);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        l = (List) q.execute();
+        assertEquals(SelfReferencingCacheTestObject.class,
+            l.get(0).getClass());
+        assertEquals("bar",
+            ((SelfReferencingCacheTestObject) l.get(0)).getStr());
+    }
+
+    public void testNullRelationOfSameTypeAsCandidate() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a.o FROM " +
+            SelfReferencingCacheTestObject.class.getSimpleName() +
+            " a where a.o IS NULL");
+
+        List l = (List) q.execute();
+        assertNull(l.get(0));
+        CacheTestHelper.iterate(l);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE);
+
+        l = (List) q.execute();
+        assertNull(l.get(0));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestLocalCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestLocalCache.java
index f162ae1..660f726 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestLocalCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestLocalCache.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-/**
- * Test the local cache. Tests only a single PMF.
- */
-public class TestLocalCache
-    extends CacheTest {
-
-    public TestLocalCache(String test) {
-        super(test);
-    }
-
-    protected String[] getConfs() {
-        return new String[]{
-            "openjpa.DataCache", "true",
-            "openjpa.QueryCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-
-    protected String[] getConfs2() {
-        return new String[]{
-            "openjpa.DataCache", "true",
-            "openjpa.QueryCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+/**
+ * Test the local cache. Tests only a single PMF.
+ */
+public class TestLocalCache
+    extends CacheTest {
+
+    public TestLocalCache(String test) {
+        super(test);
+    }
+
+    protected String[] getConfs() {
+        return new String[]{
+            "openjpa.DataCache", "true",
+            "openjpa.QueryCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+
+    protected String[] getConfs2() {
+        return new String[]{
+            "openjpa.DataCache", "true",
+            "openjpa.QueryCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestMutableParameters.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestMutableParameters.java
index 554a1f1..20ce60e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestMutableParameters.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestMutableParameters.java
@@ -1,172 +1,172 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-public class TestMutableParameters
-    extends AbstractTestCase {
-
-    public TestMutableParameters(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private BrokerFactory _factory;
-    private Date _startDate;
-
-    public void setUp()
-        throws Exception {
-        deleteAll(CacheObjectA.class);
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-
-        EntityManagerFactory emf = getEmf(propsMap);
-        _factory = JPAFacadeHelper.toBrokerFactory(emf);
-
-        // create a very early date so that when we mutate it, we
-        // won't need to worry about precision issues.
-        _startDate = new java.text.SimpleDateFormat("dd/MM/yyyy").
-            parse("01/01/1990");
-        Broker broker = _factory.newBroker();
-        broker.begin();
-        for (int i = 0; i < 50; i++) {
-            CacheObjectAChild1 o = new CacheObjectAChild1
-                ("", "JPQL2Queries", i);
-            o.setDate(_startDate);
-            broker.persist(o, null);
-        }
-        broker.commit();
-        broker.close();
-
-        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
-    }
-
-    public void tearDown()
-        throws Exception {
-        try {
-            _factory.close();
-        } catch (Exception e) {
-        }
-
-        super.tearDown();
-    }
-
-    public void testMutatedDateParameter() {
-        Broker broker = _factory.newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
-            "select a from " +
-                CacheObjectAChild1.class.getSimpleName() +
-                " a where a.date < :p_date");
-        Date d = new Date();
-        Collection c = (Collection) q.execute(new Object[]{ d });
-        CacheTestHelper.iterate(c);
-        int initialSize = c.size();
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE,
-            new Object[]{ d });
-        d.setTime(_startDate.getTime());
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE,
-            new Object[]{ d });
-        c = (Collection) q.execute(new Object[]{ d });
-
-        assertFalse(new Integer(initialSize).equals(new Integer(c.size())));
-    }
-
-    //FIXME Seetha Nov 10,2006
-    //need to find the JPQL query for :p_age contains
-    /*
-    public void testMutatedSetParameter() {
-        mutatedCollectionParameterHelper(true);
-    }
-
-    public void testMutatedListParameter() {
-        mutatedCollectionParameterHelper(false);
-    }
-
-    public void mutatedCollectionParameterHelper(boolean set) {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL,
-                    "select a from "+
-                    CacheObjectAChild1.class.getSimpleName()+ "a :p_ages.contains (age)");
-        Collection c_param;
-        if (set)
-            c_param = new HashSet();
-        else
-            c_param = new LinkedList();
-        c_param.add(new Long(0));
-        c_param.add(new Long(1));
-        Collection c = (Collection) q.execute(new Object[]{ c_param });
-        CacheTestHelper.iterate(c);
-        int initialSize = c.size();
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE,
-            new Object[]{ c_param });
-        c_param.add(new Long(2));
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE,
-            new Object[]{ c_param });
-        c = (Collection) q.execute(new Object[]{ c_param });
-        assertFalse(new Integer(initialSize).equals(new Integer(c.size())));
-    }
-
-    public void testMutatedSetParameterDates() {
-        mutatedCollectionParameterDatesHelper(true);
-    }
-
-    public void testMutatedListParameterDates() {
-        mutatedCollectionParameterDatesHelper(false);
-    }
-
-    public void mutatedCollectionParameterDatesHelper(boolean set) {
-        Broker broker = _factory.newBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectAChild1.class,
-                ":p_dates.contains (date)");
-        Collection c_param;
-        if (set)
-            c_param = new HashSet();
-        else
-            c_param = new LinkedList();
-        c_param.add(new Date());
-        c_param.add(new Date(System.currentTimeMillis() - 1000));
-        Collection c = (Collection) q.execute(new Object[]{ c_param });
-        CacheTestHelper.iterate(c);
-        int initialSize = c.size();
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE,
-            new Object[]{ c_param });
-        c_param.add(new Date(System.currentTimeMillis() - 500));
-        CacheTestHelper.assertInCache(this, q, Boolean.FALSE,
-            new Object[]{ c_param });
-    }*/
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+public class TestMutableParameters
+    extends AbstractTestCase {
+
+    public TestMutableParameters(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private BrokerFactory _factory;
+    private Date _startDate;
+
+    public void setUp()
+        throws Exception {
+        deleteAll(CacheObjectA.class);
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+
+        EntityManagerFactory emf = getEmf(propsMap);
+        _factory = JPAFacadeHelper.toBrokerFactory(emf);
+
+        // create a very early date so that when we mutate it, we
+        // won't need to worry about precision issues.
+        _startDate = new java.text.SimpleDateFormat("dd/MM/yyyy").
+            parse("01/01/1990");
+        Broker broker = _factory.newBroker();
+        broker.begin();
+        for (int i = 0; i < 50; i++) {
+            CacheObjectAChild1 o = new CacheObjectAChild1
+                ("", "JPQL2Queries", i);
+            o.setDate(_startDate);
+            broker.persist(o, null);
+        }
+        broker.commit();
+        broker.close();
+
+        CacheTestHelper.cacheManager(_factory).getSystemQueryCache().clear();
+    }
+
+    public void tearDown()
+        throws Exception {
+        try {
+            _factory.close();
+        } catch (Exception e) {
+        }
+
+        super.tearDown();
+    }
+
+    public void testMutatedDateParameter() {
+        Broker broker = _factory.newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
+            "select a from " +
+                CacheObjectAChild1.class.getSimpleName() +
+                " a where a.date < :p_date");
+        Date d = new Date();
+        Collection c = (Collection) q.execute(new Object[]{ d });
+        CacheTestHelper.iterate(c);
+        int initialSize = c.size();
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE,
+            new Object[]{ d });
+        d.setTime(_startDate.getTime());
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE,
+            new Object[]{ d });
+        c = (Collection) q.execute(new Object[]{ d });
+
+        assertFalse(new Integer(initialSize).equals(new Integer(c.size())));
+    }
+
+    //FIXME Seetha Nov 10,2006
+    //need to find the JPQL query for :p_age contains
+    /*
+    public void testMutatedSetParameter() {
+        mutatedCollectionParameterHelper(true);
+    }
+
+    public void testMutatedListParameter() {
+        mutatedCollectionParameterHelper(false);
+    }
+
+    public void mutatedCollectionParameterHelper(boolean set) {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL,
+                    "select a from "+
+                    CacheObjectAChild1.class.getSimpleName()+ "a :p_ages.contains (age)");
+        Collection c_param;
+        if (set)
+            c_param = new HashSet();
+        else
+            c_param = new LinkedList();
+        c_param.add(new Long(0));
+        c_param.add(new Long(1));
+        Collection c = (Collection) q.execute(new Object[]{ c_param });
+        CacheTestHelper.iterate(c);
+        int initialSize = c.size();
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE,
+            new Object[]{ c_param });
+        c_param.add(new Long(2));
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE,
+            new Object[]{ c_param });
+        c = (Collection) q.execute(new Object[]{ c_param });
+        assertFalse(new Integer(initialSize).equals(new Integer(c.size())));
+    }
+
+    public void testMutatedSetParameterDates() {
+        mutatedCollectionParameterDatesHelper(true);
+    }
+
+    public void testMutatedListParameterDates() {
+        mutatedCollectionParameterDatesHelper(false);
+    }
+
+    public void mutatedCollectionParameterDatesHelper(boolean set) {
+        Broker broker = _factory.newBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, CacheObjectAChild1.class,
+                ":p_dates.contains (date)");
+        Collection c_param;
+        if (set)
+            c_param = new HashSet();
+        else
+            c_param = new LinkedList();
+        c_param.add(new Date());
+        c_param.add(new Date(System.currentTimeMillis() - 1000));
+        Collection c = (Collection) q.execute(new Object[]{ c_param });
+        CacheTestHelper.iterate(c);
+        int initialSize = c.size();
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE,
+            new Object[]{ c_param });
+        c_param.add(new Date(System.currentTimeMillis() - 500));
+        CacheTestHelper.assertInCache(this, q, Boolean.FALSE,
+            new Object[]{ c_param });
+    }*/
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestOrderbyInDataCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestOrderbyInDataCache.java
index 2608079..967c95b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestOrderbyInDataCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestOrderbyInDataCache.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.datacache;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Defined ordering is only applied when the collection is loaded from the datastore.
- * It is not maintained by Openjpa as you modify the collection in memory. 
- * Openjpa invalid data cache in case the persistence operation may result cache in wrong order.
- * This test suite tests various cases for the above problem.
- */
-public class TestOrderbyInDataCache extends SingleEMFTestCase {
-	private long pid;
-    public void setUp() {
-        setUp("openjpa.DataCache", "true", 
-            "openjpa.RemoteCommitProvider", "sjvm", 
-            OrderedOneManyParent.class,
-            OrderedOneManyChild.class, CLEAR_TABLES);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        OrderedOneManyParent prt = new OrderedOneManyParent();
-        prt.setName("Maria");
-        em.persist(prt);
-        //insert child in reverse order
-        for (int i = 4; i > 1; i--) {
-        	OrderedOneManyChild child = new OrderedOneManyChild();
-            child.setId(i);
-            child.setName("child" + i);
-            child.setParent(prt);
-            prt.getChildren().add(child);
-            em.persist(child);
-        }        
-        em.getTransaction().commit();
-        pid = prt.getId();
-        em.close();
-    }
-
-    /**
-     * Test if child list is in order after new child list is added in setup().
-     *
-     */
-    public void testGetChildList(){
-    	EntityManager em = emf.createEntityManager();
-    	OrderedOneManyParent prt = em.find(OrderedOneManyParent.class, pid);
-        assertEquals(3, prt.getChildren().size());
-        //the order should be "child2", "child3", "child4"
-        for (int i = 1; i < 4; i++) {
-            assertEquals("child" + (i + 1), prt.getChildren().
-                get(i-1).getName());
-        }   
-        em.close();
-    }
-    
-    public void testInsertChild() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        OrderedOneManyParent prt = em.find(OrderedOneManyParent.class, pid);
-        OrderedOneManyChild child = new OrderedOneManyChild();
-        child.setId(1);
-        child.setName("child1");
-        child.setParent(prt);
-        prt.getChildren().add(child);
-        em.persist(child);
-        em.getTransaction().commit();
-        em.close();
-        
-        //obtain object in new persistence context
-        em = emf.createEntityManager();
-        prt = em.find(OrderedOneManyParent.class, pid);
-        assertEquals(4, prt.getChildren().size());
-        //the order should be "child1", "child2", "child3", "child4"
-        for (int i = 1; i < 5; i++) {
-            assertEquals("child" + i, prt.getChildren().
-                get(i-1).getName());
-        }          
-        em.close();
-    }
-    
-    public void testUpdateChildName() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        OrderedOneManyChild child = em.find(OrderedOneManyChild.class, 4);
-        child.setName("child1");
-        em.persist(child);
-        em.getTransaction().commit();
-        OrderedOneManyParent prt = em.find(OrderedOneManyParent.class, pid);
-        assertEquals(3, prt.getChildren().size());
-        //the order should be "child1", "child2", "child3"
-        for (int i = 1; i < 4; i++) {
-            assertEquals("child" + i, prt.getChildren().
-                get(i-1).getName());
-        }          
-        em.close();    	
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Defined ordering is only applied when the collection is loaded from the datastore.
+ * It is not maintained by Openjpa as you modify the collection in memory. 
+ * Openjpa invalid data cache in case the persistence operation may result cache in wrong order.
+ * This test suite tests various cases for the above problem.
+ */
+public class TestOrderbyInDataCache extends SingleEMFTestCase {
+	private long pid;
+    public void setUp() {
+        setUp("openjpa.DataCache", "true", 
+            "openjpa.RemoteCommitProvider", "sjvm", 
+            OrderedOneManyParent.class,
+            OrderedOneManyChild.class, CLEAR_TABLES);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        OrderedOneManyParent prt = new OrderedOneManyParent();
+        prt.setName("Maria");
+        em.persist(prt);
+        //insert child in reverse order
+        for (int i = 4; i > 1; i--) {
+        	OrderedOneManyChild child = new OrderedOneManyChild();
+            child.setId(i);
+            child.setName("child" + i);
+            child.setParent(prt);
+            prt.getChildren().add(child);
+            em.persist(child);
+        }        
+        em.getTransaction().commit();
+        pid = prt.getId();
+        em.close();
+    }
+
+    /**
+     * Test if child list is in order after new child list is added in setup().
+     *
+     */
+    public void testGetChildList(){
+    	EntityManager em = emf.createEntityManager();
+    	OrderedOneManyParent prt = em.find(OrderedOneManyParent.class, pid);
+        assertEquals(3, prt.getChildren().size());
+        //the order should be "child2", "child3", "child4"
+        for (int i = 1; i < 4; i++) {
+            assertEquals("child" + (i + 1), prt.getChildren().
+                get(i-1).getName());
+        }   
+        em.close();
+    }
+    
+    public void testInsertChild() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        OrderedOneManyParent prt = em.find(OrderedOneManyParent.class, pid);
+        OrderedOneManyChild child = new OrderedOneManyChild();
+        child.setId(1);
+        child.setName("child1");
+        child.setParent(prt);
+        prt.getChildren().add(child);
+        em.persist(child);
+        em.getTransaction().commit();
+        em.close();
+        
+        //obtain object in new persistence context
+        em = emf.createEntityManager();
+        prt = em.find(OrderedOneManyParent.class, pid);
+        assertEquals(4, prt.getChildren().size());
+        //the order should be "child1", "child2", "child3", "child4"
+        for (int i = 1; i < 5; i++) {
+            assertEquals("child" + i, prt.getChildren().
+                get(i-1).getName());
+        }          
+        em.close();
+    }
+    
+    public void testUpdateChildName() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        OrderedOneManyChild child = em.find(OrderedOneManyChild.class, 4);
+        child.setName("child1");
+        em.persist(child);
+        em.getTransaction().commit();
+        OrderedOneManyParent prt = em.find(OrderedOneManyParent.class, pid);
+        assertEquals(3, prt.getChildren().size());
+        //the order should be "child1", "child2", "child3"
+        for (int i = 1; i < 4; i++) {
+            assertEquals("child" + i, prt.getChildren().
+                get(i-1).getName());
+        }          
+        em.close();    	
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPCParametersInQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPCParametersInQueries.java
index 440c45e..75bf2f0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPCParametersInQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPCParametersInQueries.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-/**
- * New test case.
- */
-public class TestPCParametersInQueries extends AbstractTestCase {
-
-    public TestPCParametersInQueries(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private BrokerFactory _factory;
-    private Object _eId;
-
-    public void setUp() {
-        deleteAll(CacheObjectA.class);
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
-        EntityManagerFactory emf = getEmf(propsMap);
-        _factory = JPAFacadeHelper.toBrokerFactory(emf);
-
-        Broker broker = _factory.newBroker();
-        broker.begin();
-        CacheObjectE e = new CacheObjectE("bar");
-        CacheObjectJ j = new CacheObjectJ("foo", e);
-        broker.persist(j, null);
-        broker.persist(e, null);
-        broker.commit();
-        _eId = broker.getObjectId(e);
-        broker.close();
-    }
-
-    public void testPCParameter() {
-        Broker broker = _factory.newBroker();
-        broker.begin();
-        CacheObjectE e = (CacheObjectE) broker.find(_eId, true, null);
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
-            "select a from " +
-                CacheObjectJ.class.getSimpleName() + " a where a.e = :param");
-
-        Collection c = (Collection) q.execute(new Object[]{ e });
-        CacheTestHelper.iterate(c);
-        Object o = c.iterator().next();
-        assertTrue(o instanceof CacheObjectJ);
-        CacheTestHelper.assertInCache(this, q, Boolean.TRUE, new Object[]{ e });
-
-        q = broker.newQuery(JPQLParser.LANG_JPQL,
-            "select a from " +
-                CacheObjectJ.class.getSimpleName() + " a where a.e = :param");
-
-        c = (Collection) q.execute(new Object[]{ e });
-        Object o2 = c.iterator().next();
-        assertTrue(o2 instanceof CacheObjectJ);
-        assertTrue(o == o2);
-
-        broker.commit();
-        broker.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+/**
+ * New test case.
+ */
+public class TestPCParametersInQueries extends AbstractTestCase {
+
+    public TestPCParametersInQueries(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private BrokerFactory _factory;
+    private Object _eId;
+
+    public void setUp() {
+        deleteAll(CacheObjectA.class);
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.BrokerImpl", CacheTestBroker.class.getName());
+        EntityManagerFactory emf = getEmf(propsMap);
+        _factory = JPAFacadeHelper.toBrokerFactory(emf);
+
+        Broker broker = _factory.newBroker();
+        broker.begin();
+        CacheObjectE e = new CacheObjectE("bar");
+        CacheObjectJ j = new CacheObjectJ("foo", e);
+        broker.persist(j, null);
+        broker.persist(e, null);
+        broker.commit();
+        _eId = broker.getObjectId(e);
+        broker.close();
+    }
+
+    public void testPCParameter() {
+        Broker broker = _factory.newBroker();
+        broker.begin();
+        CacheObjectE e = (CacheObjectE) broker.find(_eId, true, null);
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
+            "select a from " +
+                CacheObjectJ.class.getSimpleName() + " a where a.e = :param");
+
+        Collection c = (Collection) q.execute(new Object[]{ e });
+        CacheTestHelper.iterate(c);
+        Object o = c.iterator().next();
+        assertTrue(o instanceof CacheObjectJ);
+        CacheTestHelper.assertInCache(this, q, Boolean.TRUE, new Object[]{ e });
+
+        q = broker.newQuery(JPQLParser.LANG_JPQL,
+            "select a from " +
+                CacheObjectJ.class.getSimpleName() + " a where a.e = :param");
+
+        c = (Collection) q.execute(new Object[]{ e });
+        Object o2 = c.iterator().next();
+        assertTrue(o2 instanceof CacheObjectJ);
+        assertTrue(o == o2);
+
+        broker.commit();
+        broker.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestQueryResultTypes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestQueryResultTypes.java
index f4d3712..f4bf2ad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestQueryResultTypes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestQueryResultTypes.java
@@ -1,98 +1,98 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-/**
- * Test some assumptions about query result metadata that the query
- * cache relies on.
- */
-public class TestQueryResultTypes extends AbstractTestCase {
-
-    public TestQueryResultTypes(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    public void testQueryResultTypesWithThis() {
-        Broker broker = getBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.name,a FROM " +
-                CacheObjectA.class.getSimpleName() + " a");
-
-        Class[] types = q.getProjectionTypes();
-        assertEquals(2, types.length);
-        assertEquals(String.class, types[0]);
-        assertEquals(CacheObjectA.class, types[1]);
-    }
-
-    public void testQueryResultTypesWithRelated() {
-        Broker broker = getBroker();
-        Query q = broker
-            .newQuery(JPQLParser.LANG_JPQL, "select a.name,a.relatedB FROM " +
-                CacheObjectA.class.getSimpleName() + " a");
-
-        //CacheObjectA.class,           "select name, relatedB");
-        Class[] types = q.getProjectionTypes();
-        assertEquals(2, types.length);
-        assertEquals(String.class, types[0]);
-        assertEquals(CacheObjectB.class, types[1]);
-    }
-
-    public void testSingleProjectionOfNonThisRelation() {
-        Broker broker = getBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a.relatedB FROM " +
-                CacheObjectA.class.getSimpleName() + " a");
-
-        Class[] types = q.getProjectionTypes();
-        assertEquals(1, types.length);
-        assertEquals(CacheObjectB.class, types[0]);
-    }
-
-    public void testSingleProjectionOfThisRelation() {
-        Broker broker = getBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
-            CacheObjectA.class.getSimpleName() + " a");
-        Class[] types = q.getProjectionTypes();
-        assertEquals(0, types.length);
-    }
-
-    public void testNoResultClause() {
-        Broker broker = getBroker();
-        Query q =
-            broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
-                CacheObjectA.class.getSimpleName() + " a");
-        Class[] types = q.getProjectionTypes();
-        assertEquals(0, types.length);
-    }
-
-    private Broker getBroker() {
-        return JPAFacadeHelper
-            .toBroker(currentEntityManager());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+/**
+ * Test some assumptions about query result metadata that the query
+ * cache relies on.
+ */
+public class TestQueryResultTypes extends AbstractTestCase {
+
+    public TestQueryResultTypes(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    public void testQueryResultTypesWithThis() {
+        Broker broker = getBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.name,a FROM " +
+                CacheObjectA.class.getSimpleName() + " a");
+
+        Class[] types = q.getProjectionTypes();
+        assertEquals(2, types.length);
+        assertEquals(String.class, types[0]);
+        assertEquals(CacheObjectA.class, types[1]);
+    }
+
+    public void testQueryResultTypesWithRelated() {
+        Broker broker = getBroker();
+        Query q = broker
+            .newQuery(JPQLParser.LANG_JPQL, "select a.name,a.relatedB FROM " +
+                CacheObjectA.class.getSimpleName() + " a");
+
+        //CacheObjectA.class,           "select name, relatedB");
+        Class[] types = q.getProjectionTypes();
+        assertEquals(2, types.length);
+        assertEquals(String.class, types[0]);
+        assertEquals(CacheObjectB.class, types[1]);
+    }
+
+    public void testSingleProjectionOfNonThisRelation() {
+        Broker broker = getBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a.relatedB FROM " +
+                CacheObjectA.class.getSimpleName() + " a");
+
+        Class[] types = q.getProjectionTypes();
+        assertEquals(1, types.length);
+        assertEquals(CacheObjectB.class, types[0]);
+    }
+
+    public void testSingleProjectionOfThisRelation() {
+        Broker broker = getBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
+            CacheObjectA.class.getSimpleName() + " a");
+        Class[] types = q.getProjectionTypes();
+        assertEquals(0, types.length);
+    }
+
+    public void testNoResultClause() {
+        Broker broker = getBroker();
+        Query q =
+            broker.newQuery(JPQLParser.LANG_JPQL, "select a FROM " +
+                CacheObjectA.class.getSimpleName() + " a");
+        Class[] types = q.getProjectionTypes();
+        assertEquals(0, types.length);
+    }
+
+    private Broker getBroker() {
+        return JPAFacadeHelper
+            .toBroker(currentEntityManager());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestResultShapes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestResultShapes.java
index 791ee9d..3d392ea 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestResultShapes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestResultShapes.java
@@ -1,322 +1,322 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-/**
- * Test that we marshall and unmarshall result types appropriately.
- */
-public class TestResultShapes extends AbstractTestCase {
-
-    public TestResultShapes(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private Broker _broker;
-
-    public void setUp() {
-        deleteAll(CacheObjectAChild1.class);
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        EntityManagerFactory emf = getEmf(propsMap);
-        BrokerFactory factory = JPAFacadeHelper.toBrokerFactory(emf);
-
-        Broker broker = factory.newBroker();
-        broker.begin();
-        broker.persist(new CacheObjectAChild1("foo", "foo", 0), null);
-        broker.persist(new CacheObjectAChild1("bar", "bar", 1), null);
-        broker.commit();
-        broker.close();
-
-        _broker = factory.newBroker();
-    }
-
-    public void tearDown() throws Exception {
-        _broker.close();
-
-        super.tearDown();
-    }
-
-    // FIXME Seetha Nov 3,2006
-    // need to know about the 'this' parameter
-
-//	public void testCollectionOfCandidateClass() 
-//	{ 
-//		Collection<String> ac = new ArrayList<String>();
-//		ac.add("this");
-//
-//		Collection<Class> bd = new ArrayList<Class>();
-//		bd.add(CacheObjectAChild1.class);
-//		
-//		arrayHelper(false, bd, null, true); 
-//		mapHelper(false, bd, ac, true);
-//		rawHelper(false, CacheObjectAChild1.class, null, true); 
-//	}
-//	
-//	public void testUniqueCandidateClass() 
-//	{ 
-//		Collection<String> ac = new ArrayList<String>();
-//		ac.add("this");
-//
-//		Collection<Class> bd = new ArrayList<Class>();
-//		bd.add(CacheObjectAChild1.class);
-//		
-//		arrayHelper(true, bd, null, true); 
-//		mapHelper(true, bd, ac, true);
-//		rawHelper(true, CacheObjectAChild1.class, null, true); 
-//	}
-
-    public void testCollectionOfSingleValuedProjection() {
-
-        Collection<String> ac = new ArrayList<String>();
-        ac.add("age");
-
-        Collection<Class> bd = new ArrayList<Class>();
-        bd.add(Long.class);
-
-        arrayHelper(false, bd, ac, true);
-        mapHelper(false, bd, ac, true);
-        rawHelper(false, Long.class, "age", true);
-    }
-
-    public void testUniqueSingleValuedProjection() {
-        Collection<String> ac = new ArrayList<String>();
-        ac.add("age");
-
-        Collection<Class> bd = new ArrayList<Class>();
-        bd.add(Long.class);
-
-        arrayHelper(true, bd, ac, true);
-        mapHelper(true, bd, ac, true);
-        rawHelper(true, Long.class, "age", true);
-    }
-
-    public void testCollectionOfMultiValuedProjection() {
-        Collection<String> ac = new ArrayList<String>();
-        ac.add("age");
-        ac.add("name");
-
-        Collection<Class> bd = new ArrayList<Class>();
-        bd.add(Long.class);
-        bd.add(String.class);
-
-        arrayHelper(false, bd, ac, true);
-
-        mapHelper(false, bd, ac, true);
-        // we put both
-        // projections in single slot in array because this is a
-        // single result that we're
-        // looking
-        // for. It just happens that the // single result format we expect is
-        // an Object[]. rawHelper(false, Object[].class, "age, name", true);
-    }
-
-    public void testUniqueMultiValuedProjection() {
-        Collection<String> ac = new ArrayList<String>();
-        ac.add("age");
-        ac.add("name");
-
-        Collection<Class> bd = new ArrayList<Class>();
-        bd.add(Long.class);
-        bd.add(String.class);
-
-        arrayHelper(true, bd, ac, true);
-        mapHelper(true, bd, ac, true);
-        // we put
-        // both
-        // projections in single slot in array because this is a
-        // single result that
-        // we're looking
-        // for.	It just happens that the // single result format we
-        // expect is an	Object[]. rawHelper(true, Object[].class, "age, name", true);
-    }
-
-    public void testUncachedQueryHasCorrectShape() {
-        Collection<String> ac = new ArrayList<String>();
-        ac.add("age");
-        ac.add("name");
-
-        Collection<Class> bd = new ArrayList<Class>();
-        bd.add(Long.class);
-        bd.add(String.class);
-
-        _broker.getFetchConfiguration().setQueryCacheEnabled(false);
-
-        arrayHelper(false, bd, ac, false);
-        mapHelper(false, bd, ac, false);
-        rawHelper(false, Object[].class, "age, a.name", false);
-    }
-
-    private void arrayHelper(boolean unique, Collection recordClasses,
-        Collection results, boolean inCache) {
-        Query q = setUpQuery(unique, results);
-        q.setResultType(Object[].class);
-        if (unique) {
-            arrayResultHelper(q.execute(), recordClasses, inCache);
-        } else {
-            for (Iterator iter = ((List) q.execute()).iterator(); iter
-                .hasNext();)
-                arrayResultHelper(iter.next(), recordClasses, inCache);
-        }
-
-        CacheTestHelper.assertInCache(this, q, new Boolean(inCache));
-
-        if (unique) {
-            arrayResultHelper(q.execute(), recordClasses, inCache);
-        } else {
-            for (Iterator iter = ((List) q.execute()).iterator(); iter
-                .hasNext();)
-                arrayResultHelper(iter.next(), recordClasses, inCache);
-        }
-    }
-
-    private void arrayResultHelper(Object result, Collection recordClasses,
-        boolean inCache) {
-        assertEquals(Object[].class, result.getClass());
-        Object[] os = (Object[]) result;
-        assertEquals(recordClasses.size(), os.length);
-        for (int i = 0; i < recordClasses.size(); i++)
-            assertEquals(((ArrayList) recordClasses).get(i), os[i].getClass());
-    }
-
-    private void mapHelper(boolean unique, Collection recordClasses,
-        Collection results, boolean inCache) {
-        Query q = setUpQuery(unique, results);
-        System.out.println("Query String " + q.getQueryString());
-        Collection coll = null;
-        if (q.execute() != null && (q.execute() instanceof Collection)) {
-            coll = (Collection) q.execute();
-        }
-        System.out.println("Type of q.execute is : " + q.execute().getClass());
-
-        Iterator it = coll.iterator();
-        while (it.hasNext())
-            System.out.println("Query result is " + it.next().getClass());
-
-        q.setResultType(HashMap.class);
-
-        if (unique) {
-            mapResultHelper(q.execute(), recordClasses, results, inCache);
-        } else {
-            for (Iterator iter = ((Collection) q.execute()).iterator();
-                iter.hasNext();)
-                mapResultHelper(iter.next(), recordClasses, results, inCache);
-        }
-
-        CacheTestHelper.assertInCache(this, q, new Boolean(inCache));
-
-        if (unique) {
-            mapResultHelper(q.execute(), recordClasses, results, inCache);
-        } else {
-            for (Iterator iter = ((List) q.execute()).iterator(); iter
-                .hasNext();)
-                mapResultHelper(iter.next(), recordClasses, results, inCache);
-        }
-    }
-
-    private void mapResultHelper(Object result, Collection recordClasses,
-        Collection results, boolean inCache) {
-        assertEquals(HashMap.class, result.getClass());
-        HashMap m = (HashMap) result;
-        assertEquals(recordClasses.size(), m.size());
-        for (int i = 0; i < recordClasses.size(); i++)
-            assertEquals("Map Contents " + m.toString() + " result: " + result
-                + " loop size: " + recordClasses.size()
-                + "Value of m.get(results[i]) "
-                + m.get(((ArrayList) results).get(i).getClass()),
-                ((ArrayList) recordClasses).get(i),
-                m.get("jpqlalias" + (i + 1)).getClass());
-    }
-
-    private void rawHelper(boolean unique, Class recordClass, String result,
-        boolean inCache) {
-        ArrayList<String> l = new ArrayList<String>();
-        l.add(result);
-        Collection res = (result == null) ? null : l;
-        Query q = setUpQuery(unique, res);
-        if (unique)
-            assertEquals(recordClass, q.execute().getClass());
-        else {
-            q.setUnique(unique);
-            for (Iterator iter = ((List) q.execute()).iterator(); iter
-                .hasNext();)
-                assertEquals(recordClass, iter.next().getClass());
-        }
-
-        CacheTestHelper.assertInCache(this, q, new Boolean(inCache));
-
-        if (unique) {
-            assertEquals(recordClass, q.execute().getClass());
-        } else {
-            for (Iterator iter = ((List) q.execute()).iterator(); iter
-                .hasNext();)
-                assertEquals(recordClass, iter.next().getClass());
-        }
-    }
-
-    private Query setUpQuery(boolean unique, Collection results) {
-        String filter = "select";
-        ArrayList resultsl = (ArrayList) results;
-        if (results != null) {
-            String resultString = "";
-            for (int i = 0; i < resultsl.size(); i++) {
-                resultString += "a." + resultsl.get(i);
-                if (i < results.size() - 1)
-                    resultString += ", ";
-            }
-            filter += " " + resultString;
-            filter += " " + "from "
-                + CacheObjectAChild1.class.getSuperclass().getSimpleName()
-                + " a";
-        } else {
-            filter += " " + "a from "
-                + CacheObjectAChild1.class.getSuperclass().getSimpleName()
-                + " a";
-        }
-
-        if (unique)
-            filter += " where a.age = 0";
-        System.out.println("****Query: " + filter);
-        Query q = _broker.newQuery(JPQLParser.LANG_JPQL, filter);
-        q.setUnique(unique);
-        q.setCandidateType(CacheObjectAChild1.class, false);
-
-        return q;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+/**
+ * Test that we marshall and unmarshall result types appropriately.
+ */
+public class TestResultShapes extends AbstractTestCase {
+
+    public TestResultShapes(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private Broker _broker;
+
+    public void setUp() {
+        deleteAll(CacheObjectAChild1.class);
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        EntityManagerFactory emf = getEmf(propsMap);
+        BrokerFactory factory = JPAFacadeHelper.toBrokerFactory(emf);
+
+        Broker broker = factory.newBroker();
+        broker.begin();
+        broker.persist(new CacheObjectAChild1("foo", "foo", 0), null);
+        broker.persist(new CacheObjectAChild1("bar", "bar", 1), null);
+        broker.commit();
+        broker.close();
+
+        _broker = factory.newBroker();
+    }
+
+    public void tearDown() throws Exception {
+        _broker.close();
+
+        super.tearDown();
+    }
+
+    // FIXME Seetha Nov 3,2006
+    // need to know about the 'this' parameter
+
+//	public void testCollectionOfCandidateClass() 
+//	{ 
+//		Collection<String> ac = new ArrayList<String>();
+//		ac.add("this");
+//
+//		Collection<Class> bd = new ArrayList<Class>();
+//		bd.add(CacheObjectAChild1.class);
+//		
+//		arrayHelper(false, bd, null, true); 
+//		mapHelper(false, bd, ac, true);
+//		rawHelper(false, CacheObjectAChild1.class, null, true); 
+//	}
+//	
+//	public void testUniqueCandidateClass() 
+//	{ 
+//		Collection<String> ac = new ArrayList<String>();
+//		ac.add("this");
+//
+//		Collection<Class> bd = new ArrayList<Class>();
+//		bd.add(CacheObjectAChild1.class);
+//		
+//		arrayHelper(true, bd, null, true); 
+//		mapHelper(true, bd, ac, true);
+//		rawHelper(true, CacheObjectAChild1.class, null, true); 
+//	}
+
+    public void testCollectionOfSingleValuedProjection() {
+
+        Collection<String> ac = new ArrayList<String>();
+        ac.add("age");
+
+        Collection<Class> bd = new ArrayList<Class>();
+        bd.add(Long.class);
+
+        arrayHelper(false, bd, ac, true);
+        mapHelper(false, bd, ac, true);
+        rawHelper(false, Long.class, "age", true);
+    }
+
+    public void testUniqueSingleValuedProjection() {
+        Collection<String> ac = new ArrayList<String>();
+        ac.add("age");
+
+        Collection<Class> bd = new ArrayList<Class>();
+        bd.add(Long.class);
+
+        arrayHelper(true, bd, ac, true);
+        mapHelper(true, bd, ac, true);
+        rawHelper(true, Long.class, "age", true);
+    }
+
+    public void testCollectionOfMultiValuedProjection() {
+        Collection<String> ac = new ArrayList<String>();
+        ac.add("age");
+        ac.add("name");
+
+        Collection<Class> bd = new ArrayList<Class>();
+        bd.add(Long.class);
+        bd.add(String.class);
+
+        arrayHelper(false, bd, ac, true);
+
+        mapHelper(false, bd, ac, true);
+        // we put both
+        // projections in single slot in array because this is a
+        // single result that we're
+        // looking
+        // for. It just happens that the // single result format we expect is
+        // an Object[]. rawHelper(false, Object[].class, "age, name", true);
+    }
+
+    public void testUniqueMultiValuedProjection() {
+        Collection<String> ac = new ArrayList<String>();
+        ac.add("age");
+        ac.add("name");
+
+        Collection<Class> bd = new ArrayList<Class>();
+        bd.add(Long.class);
+        bd.add(String.class);
+
+        arrayHelper(true, bd, ac, true);
+        mapHelper(true, bd, ac, true);
+        // we put
+        // both
+        // projections in single slot in array because this is a
+        // single result that
+        // we're looking
+        // for.	It just happens that the // single result format we
+        // expect is an	Object[]. rawHelper(true, Object[].class, "age, name", true);
+    }
+
+    public void testUncachedQueryHasCorrectShape() {
+        Collection<String> ac = new ArrayList<String>();
+        ac.add("age");
+        ac.add("name");
+
+        Collection<Class> bd = new ArrayList<Class>();
+        bd.add(Long.class);
+        bd.add(String.class);
+
+        _broker.getFetchConfiguration().setQueryCacheEnabled(false);
+
+        arrayHelper(false, bd, ac, false);
+        mapHelper(false, bd, ac, false);
+        rawHelper(false, Object[].class, "age, a.name", false);
+    }
+
+    private void arrayHelper(boolean unique, Collection recordClasses,
+        Collection results, boolean inCache) {
+        Query q = setUpQuery(unique, results);
+        q.setResultType(Object[].class);
+        if (unique) {
+            arrayResultHelper(q.execute(), recordClasses, inCache);
+        } else {
+            for (Iterator iter = ((List) q.execute()).iterator(); iter
+                .hasNext();)
+                arrayResultHelper(iter.next(), recordClasses, inCache);
+        }
+
+        CacheTestHelper.assertInCache(this, q, new Boolean(inCache));
+
+        if (unique) {
+            arrayResultHelper(q.execute(), recordClasses, inCache);
+        } else {
+            for (Iterator iter = ((List) q.execute()).iterator(); iter
+                .hasNext();)
+                arrayResultHelper(iter.next(), recordClasses, inCache);
+        }
+    }
+
+    private void arrayResultHelper(Object result, Collection recordClasses,
+        boolean inCache) {
+        assertEquals(Object[].class, result.getClass());
+        Object[] os = (Object[]) result;
+        assertEquals(recordClasses.size(), os.length);
+        for (int i = 0; i < recordClasses.size(); i++)
+            assertEquals(((ArrayList) recordClasses).get(i), os[i].getClass());
+    }
+
+    private void mapHelper(boolean unique, Collection recordClasses,
+        Collection results, boolean inCache) {
+        Query q = setUpQuery(unique, results);
+        System.out.println("Query String " + q.getQueryString());
+        Collection coll = null;
+        if (q.execute() != null && (q.execute() instanceof Collection)) {
+            coll = (Collection) q.execute();
+        }
+        System.out.println("Type of q.execute is : " + q.execute().getClass());
+
+        Iterator it = coll.iterator();
+        while (it.hasNext())
+            System.out.println("Query result is " + it.next().getClass());
+
+        q.setResultType(HashMap.class);
+
+        if (unique) {
+            mapResultHelper(q.execute(), recordClasses, results, inCache);
+        } else {
+            for (Iterator iter = ((Collection) q.execute()).iterator();
+                iter.hasNext();)
+                mapResultHelper(iter.next(), recordClasses, results, inCache);
+        }
+
+        CacheTestHelper.assertInCache(this, q, new Boolean(inCache));
+
+        if (unique) {
+            mapResultHelper(q.execute(), recordClasses, results, inCache);
+        } else {
+            for (Iterator iter = ((List) q.execute()).iterator(); iter
+                .hasNext();)
+                mapResultHelper(iter.next(), recordClasses, results, inCache);
+        }
+    }
+
+    private void mapResultHelper(Object result, Collection recordClasses,
+        Collection results, boolean inCache) {
+        assertEquals(HashMap.class, result.getClass());
+        HashMap m = (HashMap) result;
+        assertEquals(recordClasses.size(), m.size());
+        for (int i = 0; i < recordClasses.size(); i++)
+            assertEquals("Map Contents " + m.toString() + " result: " + result
+                + " loop size: " + recordClasses.size()
+                + "Value of m.get(results[i]) "
+                + m.get(((ArrayList) results).get(i).getClass()),
+                ((ArrayList) recordClasses).get(i),
+                m.get("jpqlalias" + (i + 1)).getClass());
+    }
+
+    private void rawHelper(boolean unique, Class recordClass, String result,
+        boolean inCache) {
+        ArrayList<String> l = new ArrayList<String>();
+        l.add(result);
+        Collection res = (result == null) ? null : l;
+        Query q = setUpQuery(unique, res);
+        if (unique)
+            assertEquals(recordClass, q.execute().getClass());
+        else {
+            q.setUnique(unique);
+            for (Iterator iter = ((List) q.execute()).iterator(); iter
+                .hasNext();)
+                assertEquals(recordClass, iter.next().getClass());
+        }
+
+        CacheTestHelper.assertInCache(this, q, new Boolean(inCache));
+
+        if (unique) {
+            assertEquals(recordClass, q.execute().getClass());
+        } else {
+            for (Iterator iter = ((List) q.execute()).iterator(); iter
+                .hasNext();)
+                assertEquals(recordClass, iter.next().getClass());
+        }
+    }
+
+    private Query setUpQuery(boolean unique, Collection results) {
+        String filter = "select";
+        ArrayList resultsl = (ArrayList) results;
+        if (results != null) {
+            String resultString = "";
+            for (int i = 0; i < resultsl.size(); i++) {
+                resultString += "a." + resultsl.get(i);
+                if (i < results.size() - 1)
+                    resultString += ", ";
+            }
+            filter += " " + resultString;
+            filter += " " + "from "
+                + CacheObjectAChild1.class.getSuperclass().getSimpleName()
+                + " a";
+        } else {
+            filter += " " + "a from "
+                + CacheObjectAChild1.class.getSuperclass().getSimpleName()
+                + " a";
+        }
+
+        if (unique)
+            filter += " where a.age = 0";
+        System.out.println("****Query: " + filter);
+        Query q = _broker.newQuery(JPQLParser.LANG_JPQL, filter);
+        q.setUnique(unique);
+        q.setCandidateType(CacheObjectAChild1.class, false);
+
+        return q;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestSJVMCache.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestSJVMCache.java
index 045c4f7..5e49729 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestSJVMCache.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestSJVMCache.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-/**
- * Test data caching across multiple factories in the same JVM, using
- * the single-JVM commit provider to communicate updates..
- */
-public class TestSJVMCache
-    extends CacheTest {
-
-    public TestSJVMCache(String test) {
-        super(test);
-    }
-
-    protected String[] getConfs() {
-        return new String[]{
-            // the second cache is there solely to differentiate between
-            // this PMF and the PMF created from confs2 below
-            "openjpa.DataCache", "true, true(Name=differentiatingProperty1)",
-            "openjpa.QueryCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-
-    protected String[] getConfs2() {
-        return new String[]{
-            // the second cache is there solely to differentiate between
-            // this PMF and the PMF created from confs above
-            "openjpa.DataCache", "true, true(Name=differentiatingProperty2)",
-            "openjpa.QueryCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
-        };
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+/**
+ * Test data caching across multiple factories in the same JVM, using
+ * the single-JVM commit provider to communicate updates..
+ */
+public class TestSJVMCache
+    extends CacheTest {
+
+    public TestSJVMCache(String test) {
+        super(test);
+    }
+
+    protected String[] getConfs() {
+        return new String[]{
+            // the second cache is there solely to differentiate between
+            // this PMF and the PMF created from confs2 below
+            "openjpa.DataCache", "true, true(Name=differentiatingProperty1)",
+            "openjpa.QueryCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+
+    protected String[] getConfs2() {
+        return new String[]{
+            // the second cache is there solely to differentiate between
+            // this PMF and the PMF created from confs above
+            "openjpa.DataCache", "true, true(Name=differentiatingProperty2)",
+            "openjpa.QueryCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+            "openjpa.BrokerImpl", CacheTestBroker.class.getName(),
+        };
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestUniteratedQueryResult.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestUniteratedQueryResult.java
index 7021379..fadaefa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestUniteratedQueryResult.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestUniteratedQueryResult.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestUniteratedQueryResult
-    extends AbstractTestCase {
-
-    public TestUniteratedQueryResult(String test) {
-        super(test, "datacachecactusapp");
-    }
-
-    private EntityManagerFactory _pmf;
-
-    public void setUp() {
-        System.out.println("****Deleted Records "
-            + deleteAll(CacheObjectA.class));
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.DataCache", "true");
-        propsMap.put("openjpa.QueryCache", "true");
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.FetchBatchSize", "0");
-
-        _pmf = getEmf(propsMap);
-    }
-
-    public void test() {
-        CacheObjectA pc1 = new CacheObjectA();
-        pc1.setName("pc1");
-        CacheObjectA pc2 = new CacheObjectA();
-        pc2.setName("pc2");
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) _pmf.createEntityManager();
-        startTx(pm);
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);
-        Object oid1 = pm.getObjectId(pc1);
-        Object oid2 = pm.getObjectId(pc2);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) _pmf.createEntityManager();
-
-        OpenJPAQuery q = pm.createQuery(
-            "select a FROM " + CacheObjectA.class.getSimpleName() +
-                " a where a.name = 'pc1'");
-        List res = (List) q.getResultList();
-
-        OpenJPAEntityManager pm2 =
-            (OpenJPAEntityManager) _pmf.createEntityManager();
-        startTx(pm2);
-        pc1 = (CacheObjectA) pm2.find(CacheObjectA.class, oid1);
-        pc2 = (CacheObjectA) pm2.find(CacheObjectA.class, oid2);
-        pc1.setName("pc2");
-        pc2.setName("pc1");
-        endTx(pm2);
-
-        assertEquals(1, res.size());
-        for (Iterator itr = res.iterator(); itr.hasNext();)
-            assertEquals(oid1, pm2.getObjectId(itr.next()));
-        endEm(pm2);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) _pmf.createEntityManager();
-
-        q = pm.createQuery(
-            "select a FROM " + CacheObjectA.class.getSimpleName() +
-                " a where a.name = 'pc1'");
-        res = (List) q.getResultList();
-
-        assertEquals(oid2, pm.getObjectId(res.iterator().next()));
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestUniteratedQueryResult
+    extends AbstractTestCase {
+
+    public TestUniteratedQueryResult(String test) {
+        super(test, "datacachecactusapp");
+    }
+
+    private EntityManagerFactory _pmf;
+
+    public void setUp() {
+        System.out.println("****Deleted Records "
+            + deleteAll(CacheObjectA.class));
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.QueryCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.FetchBatchSize", "0");
+
+        _pmf = getEmf(propsMap);
+    }
+
+    public void test() {
+        CacheObjectA pc1 = new CacheObjectA();
+        pc1.setName("pc1");
+        CacheObjectA pc2 = new CacheObjectA();
+        pc2.setName("pc2");
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) _pmf.createEntityManager();
+        startTx(pm);
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);
+        Object oid1 = pm.getObjectId(pc1);
+        Object oid2 = pm.getObjectId(pc2);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) _pmf.createEntityManager();
+
+        OpenJPAQuery q = pm.createQuery(
+            "select a FROM " + CacheObjectA.class.getSimpleName() +
+                " a where a.name = 'pc1'");
+        List res = (List) q.getResultList();
+
+        OpenJPAEntityManager pm2 =
+            (OpenJPAEntityManager) _pmf.createEntityManager();
+        startTx(pm2);
+        pc1 = (CacheObjectA) pm2.find(CacheObjectA.class, oid1);
+        pc2 = (CacheObjectA) pm2.find(CacheObjectA.class, oid2);
+        pc1.setName("pc2");
+        pc2.setName("pc1");
+        endTx(pm2);
+
+        assertEquals(1, res.size());
+        for (Iterator itr = res.iterator(); itr.hasNext();)
+            assertEquals(oid1, pm2.getObjectId(itr.next()));
+        endEm(pm2);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) _pmf.createEntityManager();
+
+        q = pm.createQuery(
+            "select a FROM " + CacheObjectA.class.getSimpleName() +
+                " a where a.name = 'pc1'");
+        res = (List) q.getResultList();
+
+        assertEquals(oid2, pm.getObjectId(res.iterator().next()));
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AppIdCacheObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AppIdCacheObject.java
index cbe00c4..b8aca76 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AppIdCacheObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AppIdCacheObject.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class AppIdCacheObject {
-
-    private int id;
-
-    protected AppIdCacheObject() {
-    }
-
-    public AppIdCacheObject(int id) {
-        this.id = id;
-    }
-
-    public int getId() {
-        return id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class AppIdCacheObject {
+
+    private int id;
+
+    protected AppIdCacheObject() {
+    }
+
+    public AppIdCacheObject(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachA.java
index 98efdc7..9f16187 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachA.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachA
-    implements Serializable {
-
-    private String astr;
-    private int aint;
-    private double adbl;
-    private String[] stringArray = new String[0];
-    private AttachE[] attachEArray = new AttachE[0];
-
-    public void setAstr(String astr) {
-        this.astr = astr;
-    }
-
-    public String getAstr() {
-        return this.astr;
-    }
-
-    public void setAint(int aint) {
-        this.aint = aint;
-    }
-
-    public int getAint() {
-        return this.aint;
-    }
-
-    public void setAdbl(double adbl) {
-        this.adbl = adbl;
-    }
-
-    public double getAdbl() {
-        return this.adbl;
-    }
-
-    public void setStringArray(String[] stringArray) {
-        this.stringArray = stringArray;
-    }
-
-    public String[] getStringArray() {
-        return this.stringArray;
-    }
-
-    public void setAttachEArray(AttachE[] attachEArray) {
-        this.attachEArray = attachEArray;
-    }
-
-    public AttachE[] getAttachEArray() {
-        return this.attachEArray;
-    }
-
-    private void writeObject(ObjectOutputStream out)
-        throws IOException {
-        out.defaultWriteObject();
-    }
-
-    private void readObject(ObjectInputStream in)
-        throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachA
+    implements Serializable {
+
+    private String astr;
+    private int aint;
+    private double adbl;
+    private String[] stringArray = new String[0];
+    private AttachE[] attachEArray = new AttachE[0];
+
+    public void setAstr(String astr) {
+        this.astr = astr;
+    }
+
+    public String getAstr() {
+        return this.astr;
+    }
+
+    public void setAint(int aint) {
+        this.aint = aint;
+    }
+
+    public int getAint() {
+        return this.aint;
+    }
+
+    public void setAdbl(double adbl) {
+        this.adbl = adbl;
+    }
+
+    public double getAdbl() {
+        return this.adbl;
+    }
+
+    public void setStringArray(String[] stringArray) {
+        this.stringArray = stringArray;
+    }
+
+    public String[] getStringArray() {
+        return this.stringArray;
+    }
+
+    public void setAttachEArray(AttachE[] attachEArray) {
+        this.attachEArray = attachEArray;
+    }
+
+    public AttachE[] getAttachEArray() {
+        return this.attachEArray;
+    }
+
+    private void writeObject(ObjectOutputStream out)
+        throws IOException {
+        out.defaultWriteObject();
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachB.java
index c067c87..40e393e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachB.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachB
-    extends AttachA {
-
-    private String bstr;
-    private int bint;
-    private double bdbl;
-    private Set ds = new HashSet();
-    private Map stringIntMap = new TreeMap();
-
-    public void setBstr(String bstr) {
-        this.bstr = bstr;
-    }
-
-    public String getBstr() {
-        return this.bstr;
-    }
-
-    public void setBint(int bint) {
-        this.bint = bint;
-    }
-
-    public int getBint() {
-        return this.bint;
-    }
-
-    public void setBdbl(double bdbl) {
-        this.bdbl = bdbl;
-    }
-
-    public double getBdbl() {
-        return this.bdbl;
-    }
-
-    public void setDs(Set ds) {
-        this.ds = ds;
-    }
-
-    public Set getDs() {
-        return this.ds;
-    }
-
-    public void setStringIntMap(Map stringIntMap) {
-        this.stringIntMap = stringIntMap;
-    }
-
-    public Map getStringIntMap() {
-        return this.stringIntMap;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachB
+    extends AttachA {
+
+    private String bstr;
+    private int bint;
+    private double bdbl;
+    private Set ds = new HashSet();
+    private Map stringIntMap = new TreeMap();
+
+    public void setBstr(String bstr) {
+        this.bstr = bstr;
+    }
+
+    public String getBstr() {
+        return this.bstr;
+    }
+
+    public void setBint(int bint) {
+        this.bint = bint;
+    }
+
+    public int getBint() {
+        return this.bint;
+    }
+
+    public void setBdbl(double bdbl) {
+        this.bdbl = bdbl;
+    }
+
+    public double getBdbl() {
+        return this.bdbl;
+    }
+
+    public void setDs(Set ds) {
+        this.ds = ds;
+    }
+
+    public Set getDs() {
+        return this.ds;
+    }
+
+    public void setStringIntMap(Map stringIntMap) {
+        this.stringIntMap = stringIntMap;
+    }
+
+    public Map getStringIntMap() {
+        return this.stringIntMap;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachC.java
index 21f765d..d7d86fd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachC.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.util.LinkedList;
-import java.util.List;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachC
-    extends AttachB {
-
-    private String cstr;
-    private int cint;
-    private double cdbl;
-    private List es = new LinkedList(); // non-DFG
-
-    public void setCstr(String cstr) {
-        this.cstr = cstr;
-    }
-
-    public String getCstr() {
-        return this.cstr;
-    }
-
-    public void setCint(int cint) {
-        this.cint = cint;
-    }
-
-    public int getCint() {
-        return this.cint;
-    }
-
-    public void setCdbl(double cdbl) {
-        this.cdbl = cdbl;
-    }
-
-    public double getCdbl() {
-        return this.cdbl;
-    }
-
-    public void setEs(List es) {
-        this.es = es;
-    }
-
-    public List getEs() {
-        return this.es;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.util.LinkedList;
+import java.util.List;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachC
+    extends AttachB {
+
+    private String cstr;
+    private int cint;
+    private double cdbl;
+    private List es = new LinkedList(); // non-DFG
+
+    public void setCstr(String cstr) {
+        this.cstr = cstr;
+    }
+
+    public String getCstr() {
+        return this.cstr;
+    }
+
+    public void setCint(int cint) {
+        this.cint = cint;
+    }
+
+    public int getCint() {
+        return this.cint;
+    }
+
+    public void setCdbl(double cdbl) {
+        this.cdbl = cdbl;
+    }
+
+    public double getCdbl() {
+        return this.cdbl;
+    }
+
+    public void setEs(List es) {
+        this.es = es;
+    }
+
+    public List getEs() {
+        return this.es;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachD.java
index 9870612..eb8fc55 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachD.java
@@ -1,121 +1,121 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachD
-    implements Serializable {
-
-    private Object version;
-
-    private String dstr;
-    private int dint;
-    private double ddbl;
-    private AttachA a;
-    private Set bs = new HashSet(); // DFG
-    private Map pcStringMap = new HashMap();
-    private TreeMap bigIntegerPCMap = new TreeMap();
-
-    private AttachE embeddedE;
-    private AttachA embeddedA;
-
-    public void setDstr(String dstr) {
-        this.dstr = dstr;
-    }
-
-    public String getDstr() {
-        return this.dstr;
-    }
-
-    public void setDint(int dint) {
-        this.dint = dint;
-    }
-
-    public int getDint() {
-        return this.dint;
-    }
-
-    public void setDdbl(double ddbl) {
-        this.ddbl = ddbl;
-    }
-
-    public double getDdbl() {
-        return this.ddbl;
-    }
-
-    public AttachA getA() {
-        return a;
-    }
-
-    public void setA(AttachA a) {
-        this.a = a;
-    }
-
-    public void setBs(Set bs) {
-        this.bs = bs;
-    }
-
-    public Set getBs() {
-        return this.bs;
-    }
-
-    public void setPcStringMap(Map pcStringMap) {
-        this.pcStringMap = pcStringMap;
-    }
-
-    public Map getPcStringMap() {
-        return this.pcStringMap;
-    }
-
-    public void setBigIntegerPCMap(TreeMap bigIntegerPCMap) {
-        this.bigIntegerPCMap = bigIntegerPCMap;
-    }
-
-    public TreeMap getBigIntegerPCMap() {
-        return this.bigIntegerPCMap;
-    }
-
-    public void setEmbeddedE(AttachE embeddedE) {
-        this.embeddedE = embeddedE;
-    }
-
-    public AttachE getEmbeddedE() {
-        return this.embeddedE;
-    }
-
-    public void setEmbeddedA(AttachA embeddedA) {
-        this.embeddedA = embeddedA;
-    }
-
-    public AttachA getEmbeddedA() {
-        return this.embeddedA;
-    }
-
-    public Object getVersion() {
-        return this.version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachD
+    implements Serializable {
+
+    private Object version;
+
+    private String dstr;
+    private int dint;
+    private double ddbl;
+    private AttachA a;
+    private Set bs = new HashSet(); // DFG
+    private Map pcStringMap = new HashMap();
+    private TreeMap bigIntegerPCMap = new TreeMap();
+
+    private AttachE embeddedE;
+    private AttachA embeddedA;
+
+    public void setDstr(String dstr) {
+        this.dstr = dstr;
+    }
+
+    public String getDstr() {
+        return this.dstr;
+    }
+
+    public void setDint(int dint) {
+        this.dint = dint;
+    }
+
+    public int getDint() {
+        return this.dint;
+    }
+
+    public void setDdbl(double ddbl) {
+        this.ddbl = ddbl;
+    }
+
+    public double getDdbl() {
+        return this.ddbl;
+    }
+
+    public AttachA getA() {
+        return a;
+    }
+
+    public void setA(AttachA a) {
+        this.a = a;
+    }
+
+    public void setBs(Set bs) {
+        this.bs = bs;
+    }
+
+    public Set getBs() {
+        return this.bs;
+    }
+
+    public void setPcStringMap(Map pcStringMap) {
+        this.pcStringMap = pcStringMap;
+    }
+
+    public Map getPcStringMap() {
+        return this.pcStringMap;
+    }
+
+    public void setBigIntegerPCMap(TreeMap bigIntegerPCMap) {
+        this.bigIntegerPCMap = bigIntegerPCMap;
+    }
+
+    public TreeMap getBigIntegerPCMap() {
+        return this.bigIntegerPCMap;
+    }
+
+    public void setEmbeddedE(AttachE embeddedE) {
+        this.embeddedE = embeddedE;
+    }
+
+    public AttachE getEmbeddedE() {
+        return this.embeddedE;
+    }
+
+    public void setEmbeddedA(AttachA embeddedA) {
+        this.embeddedA = embeddedA;
+    }
+
+    public AttachA getEmbeddedA() {
+        return this.embeddedA;
+    }
+
+    public Object getVersion() {
+        return this.version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachE.java
index 871e645..2f636c9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachE.java
@@ -1,85 +1,85 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.io.Serializable;
-import java.util.Date;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachE
-    implements Serializable {
-
-    private Object version;
-
-    private String estr;
-    private int eint;
-    private double edbl;
-    private AttachB b;
-    private AttachF f;
-    private Date date;
-
-    public void setEstr(String estr) {
-        this.estr = estr;
-    }
-
-    public String getEstr() {
-        return this.estr;
-    }
-
-    public void setEint(int eint) {
-        this.eint = eint;
-    }
-
-    public int getEint() {
-        return this.eint;
-    }
-
-    public void setEdbl(double edbl) {
-        this.edbl = edbl;
-    }
-
-    public double getEdbl() {
-        return this.edbl;
-    }
-
-    public void setB(AttachB b) {
-        this.b = b;
-    }
-
-    public AttachB getB() {
-        return this.b;
-    }
-
-    public void setF(AttachF f) {
-        this.f = f;
-    }
-
-    public AttachF getF() {
-        return this.f;
-    }
-
-    public void setDate(Date date) {
-        this.date = date;
-    }
-
-    public Date getDate() {
-        return this.date;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachE
+    implements Serializable {
+
+    private Object version;
+
+    private String estr;
+    private int eint;
+    private double edbl;
+    private AttachB b;
+    private AttachF f;
+    private Date date;
+
+    public void setEstr(String estr) {
+        this.estr = estr;
+    }
+
+    public String getEstr() {
+        return this.estr;
+    }
+
+    public void setEint(int eint) {
+        this.eint = eint;
+    }
+
+    public int getEint() {
+        return this.eint;
+    }
+
+    public void setEdbl(double edbl) {
+        this.edbl = edbl;
+    }
+
+    public double getEdbl() {
+        return this.edbl;
+    }
+
+    public void setB(AttachB b) {
+        this.b = b;
+    }
+
+    public AttachB getB() {
+        return this.b;
+    }
+
+    public void setF(AttachF f) {
+        this.f = f;
+    }
+
+    public AttachF getF() {
+        return this.f;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public Date getDate() {
+        return this.date;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachF.java
index ae093f1..3e5a8f2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/AttachF.java
@@ -1,135 +1,135 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachF
-    implements Serializable {
-
-    private int id1;
-    private String id2;
-
-    private String fstr;
-    private int fint;
-    private double fdbl;
-    private AttachE e;
-    private List strings = new ArrayList();
-
-    private AttachC embeddedC;
-
-    public void setFstr(String fstr) {
-        this.fstr = fstr;
-    }
-
-    public String getFstr() {
-        return this.fstr;
-    }
-
-    public void setFint(int fint) {
-        this.fint = fint;
-    }
-
-    public int getFint() {
-        return this.fint;
-    }
-
-    public void setFdbl(double fdbl) {
-        this.fdbl = fdbl;
-    }
-
-    public double getFdbl() {
-        return this.fdbl;
-    }
-
-    public void setE(AttachE e) {
-        this.e = e;
-    }
-
-    public AttachE getE() {
-        return this.e;
-    }
-
-    public void setStrings(List strings) {
-        this.strings = strings;
-    }
-
-    public List getStrings() {
-        return this.strings;
-    }
-
-    public static class ID {
-
-        public int id1;
-        public String id2;
-
-        public ID() {
-        }
-
-        public ID(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ":");
-            id1 = Integer.parseInt(tok.nextToken());
-            id2 = tok.nextToken();
-        }
-
-        public int hashCode() {
-            return id1 + (id2 == null ? 0 : id2.hashCode());
-        }
-
-        public String toString() {
-            return id1 + ":" + id2;
-        }
-
-        public boolean equals(Object other) {
-            return other instanceof ID
-                && ((ID) other).id1 == id1
-                && (id2 == null ? ((ID) other).id2 == null
-                : id2.equals(((ID) other).id2));
-        }
-    }
-
-    public void setId1(int id1) {
-        this.id1 = id1;
-    }
-
-    public int getId1() {
-        return this.id1;
-    }
-
-    public void setId2(String id2) {
-        this.id2 = id2;
-    }
-
-    public String getId2() {
-        return this.id2;
-    }
-
-    public void setEmbeddedC(AttachC embeddedC) {
-        this.embeddedC = embeddedC;
-    }
-
-    public AttachC getEmbeddedC() {
-        return this.embeddedC;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachF
+    implements Serializable {
+
+    private int id1;
+    private String id2;
+
+    private String fstr;
+    private int fint;
+    private double fdbl;
+    private AttachE e;
+    private List strings = new ArrayList();
+
+    private AttachC embeddedC;
+
+    public void setFstr(String fstr) {
+        this.fstr = fstr;
+    }
+
+    public String getFstr() {
+        return this.fstr;
+    }
+
+    public void setFint(int fint) {
+        this.fint = fint;
+    }
+
+    public int getFint() {
+        return this.fint;
+    }
+
+    public void setFdbl(double fdbl) {
+        this.fdbl = fdbl;
+    }
+
+    public double getFdbl() {
+        return this.fdbl;
+    }
+
+    public void setE(AttachE e) {
+        this.e = e;
+    }
+
+    public AttachE getE() {
+        return this.e;
+    }
+
+    public void setStrings(List strings) {
+        this.strings = strings;
+    }
+
+    public List getStrings() {
+        return this.strings;
+    }
+
+    public static class ID {
+
+        public int id1;
+        public String id2;
+
+        public ID() {
+        }
+
+        public ID(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ":");
+            id1 = Integer.parseInt(tok.nextToken());
+            id2 = tok.nextToken();
+        }
+
+        public int hashCode() {
+            return id1 + (id2 == null ? 0 : id2.hashCode());
+        }
+
+        public String toString() {
+            return id1 + ":" + id2;
+        }
+
+        public boolean equals(Object other) {
+            return other instanceof ID
+                && ((ID) other).id1 == id1
+                && (id2 == null ? ((ID) other).id2 == null
+                : id2.equals(((ID) other).id2));
+        }
+    }
+
+    public void setId1(int id1) {
+        this.id1 = id1;
+    }
+
+    public int getId1() {
+        return this.id1;
+    }
+
+    public void setId2(String id2) {
+        this.id2 = id2;
+    }
+
+    public String getId2() {
+        return this.id2;
+    }
+
+    public void setEmbeddedC(AttachC embeddedC) {
+        this.embeddedC = embeddedC;
+    }
+
+    public AttachC getEmbeddedC() {
+        return this.embeddedC;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectA.java
index fa2989f..2298e47 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectA.java
@@ -1,263 +1,263 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.Locale;
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.jdbc.ContainerTable;
-import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
-import org.apache.openjpa.persistence.jdbc.OrderColumn;
-import org.apache.openjpa.persistence.jdbc.XJoinColumn;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYP")
-@DiscriminatorValue("CACHE_A")
-public class CacheObjectA {
-
-    private String name = null;
-
-    private long age = 0;
-
-    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private CacheObjectA relatedObj = null;
-
-    @PersistentCollection
-    @ContainerTable(name = "CACHE_STRINGCOLL",
-        joinColumns = @XJoinColumn(name = "ID"))
-    @ElementJoinColumn(name = "ELEMENT")
-    /*
-      * @ManyToMany @JoinTable(name="CACHE_STRINGCOLL",
-      * joinColumns=@JoinColumn(name="ID"),
-      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
-      */
-    private Collection<String> stringColl = new LinkedList();
-
-    /*
-      * @ManyToMany @JoinTable(name="CACHE_RELATEDCOLL",
-      * joinColumns=@JoinColumn(name="ID"),
-      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
-      */
-    @PersistentCollection
-    @ContainerTable(name = "CACHE_RELATEDCOLL",
-        joinColumns = @XJoinColumn(name = "ID"))
-    @ElementJoinColumn(name = "ELEMENT")
-    private Collection<CacheObjectA> relatedColl = new LinkedList();
-
-    /*
-      * @PersistentCollection @ContainerTable(name="CACHE_AS",
-      * joinColumns=@XJoinColumn(name="ID")) @ElementJoinColumn(name="ELEMENT")
-      * @OrderColumn(name="ORDR")
-      */
-    @ManyToMany
-    @JoinTable(name = "CACHE_AS", joinColumns = @JoinColumn(name = "ID"),
-        inverseJoinColumns = @JoinColumn(name = "ELEMENT"))
-    private CacheObjectA[] as;
-
-    @PersistentCollection
-    @ContainerTable(name = "CACHE_STRINGARRAY",
-        joinColumns = @XJoinColumn(name = "ID"))
-    @ElementJoinColumn(name = "ELEMENT")
-    @OrderColumn(name = "ORDR")
-    /*
-      * @ManyToMany @JoinTable(name="CACHE_STRINGARRAY",
-      * joinColumns=@JoinColumn(name="ID"),
-      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
-      */
-    private String[] stringArray;
-
-    @PersistentCollection
-    @ContainerTable(name = "CACHE_PRIMITIVEARRAY",
-        joinColumns = @XJoinColumn(name = "ID"))
-    @ElementJoinColumn(name = "ELEMENT")
-    @OrderColumn(name = "ORDR")
-    /*
-      * @ManyToMany @JoinTable(name="CACHE_PRIMITIVEARRAY",
-      * joinColumns=@JoinColumn(name="ID"),
-      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
-      */
-    private float[] primitiveArray;
-
-    @PersistentCollection
-    @ContainerTable(name = "CACHE_DATEARRAY",
-        joinColumns = @XJoinColumn(name = "ID"))
-    @ElementJoinColumn(name = "ELEMENT")
-    @OrderColumn(name = "ORDR")
-    /*
-      * @ManyToMany @JoinTable(name="CACHE_DATEARRAY",
-      * joinColumns=@JoinColumn(name="ID"),
-      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
-      */
-    private Date[] dateArray;
-
-    @Temporal(TemporalType.DATE)
-    private Date date;
-
-    private Locale locale;
-
-    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private CacheObjectB relatedB = null;
-
-    @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
-    private CacheObjectInterface relatedInterface = null;
-
-    public CacheObjectA() {
-    }
-
-    public CacheObjectA(String name, long age) {
-        this.name = name;
-        this.age = age;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public long getAge() {
-        return age;
-    }
-
-    public void setAge(long age) {
-        this.age = age;
-    }
-
-    public CacheObjectA getRelatedObject() {
-        return relatedObj;
-    }
-
-    public void setRelatedObject(CacheObjectA o) {
-        relatedObj = o;
-    }
-
-    public Collection getStringCollection() {
-        return stringColl;
-    }
-
-    public void setStringCollection(Collection coll) {
-        stringColl = coll;
-    }
-
-    public Collection getRelatedCollection() {
-        return relatedColl;
-    }
-
-    public void setRelatedCollection(Collection coll) {
-        relatedColl = coll;
-    }
-
-    public CacheObjectA[] getRelatedArray() {
-        return as;
-    }
-
-    public void setRelatedArray(CacheObjectA[] array) {
-        as = array;
-    }
-
-    public String[] getStringArray() {
-        return stringArray;
-    }
-
-    public void setStringArray(String[] array) {
-        stringArray = array;
-    }
-
-    public void setPrimitiveArray(float[] val) {
-        primitiveArray = val;
-    }
-
-    public float[] getPrimitiveArray() {
-        return primitiveArray;
-    }
-
-    public void setDateArray(Date[] val) {
-        dateArray = val;
-    }
-
-    public Date[] getDateArray() {
-        return dateArray;
-    }
-
-    public void setDate(Date val) {
-        date = val;
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public void setLocale(Locale val) {
-        locale = val;
-    }
-
-    public Locale getLocale() {
-        return locale;
-    }
-
-    public void setRelatedB(CacheObjectB val) {
-        relatedB = val;
-    }
-
-    public CacheObjectB getRelatedB() {
-        return relatedB;
-    }
-
-    public void setRelatedInterface(CacheObjectInterface val) {
-        relatedInterface = val;
-    }
-
-    public CacheObjectInterface getRelatedInterface() {
-        return relatedInterface;
-    }
-
-    public String toString() {
-        try {
-            return "CacheObjectA: " + super.toString() + "; name: " + name
-                + "; age: " + age;
-        }
-        catch (Exception e) {
-            return "CacheObjectA: " + super.toString() + "; "
-                + "Exception in toString(): " + e;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.Locale;
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.jdbc.ContainerTable;
+import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
+import org.apache.openjpa.persistence.jdbc.OrderColumn;
+import org.apache.openjpa.persistence.jdbc.XJoinColumn;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYP")
+@DiscriminatorValue("CACHE_A")
+public class CacheObjectA {
+
+    private String name = null;
+
+    private long age = 0;
+
+    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private CacheObjectA relatedObj = null;
+
+    @PersistentCollection
+    @ContainerTable(name = "CACHE_STRINGCOLL",
+        joinColumns = @XJoinColumn(name = "ID"))
+    @ElementJoinColumn(name = "ELEMENT")
+    /*
+      * @ManyToMany @JoinTable(name="CACHE_STRINGCOLL",
+      * joinColumns=@JoinColumn(name="ID"),
+      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
+      */
+    private Collection<String> stringColl = new LinkedList();
+
+    /*
+      * @ManyToMany @JoinTable(name="CACHE_RELATEDCOLL",
+      * joinColumns=@JoinColumn(name="ID"),
+      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
+      */
+    @PersistentCollection
+    @ContainerTable(name = "CACHE_RELATEDCOLL",
+        joinColumns = @XJoinColumn(name = "ID"))
+    @ElementJoinColumn(name = "ELEMENT")
+    private Collection<CacheObjectA> relatedColl = new LinkedList();
+
+    /*
+      * @PersistentCollection @ContainerTable(name="CACHE_AS",
+      * joinColumns=@XJoinColumn(name="ID")) @ElementJoinColumn(name="ELEMENT")
+      * @OrderColumn(name="ORDR")
+      */
+    @ManyToMany
+    @JoinTable(name = "CACHE_AS", joinColumns = @JoinColumn(name = "ID"),
+        inverseJoinColumns = @JoinColumn(name = "ELEMENT"))
+    private CacheObjectA[] as;
+
+    @PersistentCollection
+    @ContainerTable(name = "CACHE_STRINGARRAY",
+        joinColumns = @XJoinColumn(name = "ID"))
+    @ElementJoinColumn(name = "ELEMENT")
+    @OrderColumn(name = "ORDR")
+    /*
+      * @ManyToMany @JoinTable(name="CACHE_STRINGARRAY",
+      * joinColumns=@JoinColumn(name="ID"),
+      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
+      */
+    private String[] stringArray;
+
+    @PersistentCollection
+    @ContainerTable(name = "CACHE_PRIMITIVEARRAY",
+        joinColumns = @XJoinColumn(name = "ID"))
+    @ElementJoinColumn(name = "ELEMENT")
+    @OrderColumn(name = "ORDR")
+    /*
+      * @ManyToMany @JoinTable(name="CACHE_PRIMITIVEARRAY",
+      * joinColumns=@JoinColumn(name="ID"),
+      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
+      */
+    private float[] primitiveArray;
+
+    @PersistentCollection
+    @ContainerTable(name = "CACHE_DATEARRAY",
+        joinColumns = @XJoinColumn(name = "ID"))
+    @ElementJoinColumn(name = "ELEMENT")
+    @OrderColumn(name = "ORDR")
+    /*
+      * @ManyToMany @JoinTable(name="CACHE_DATEARRAY",
+      * joinColumns=@JoinColumn(name="ID"),
+      * inverseJoinColumns=@JoinColumn(name="ELEMENT"))
+      */
+    private Date[] dateArray;
+
+    @Temporal(TemporalType.DATE)
+    private Date date;
+
+    private Locale locale;
+
+    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private CacheObjectB relatedB = null;
+
+    @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
+    private CacheObjectInterface relatedInterface = null;
+
+    public CacheObjectA() {
+    }
+
+    public CacheObjectA(String name, long age) {
+        this.name = name;
+        this.age = age;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public long getAge() {
+        return age;
+    }
+
+    public void setAge(long age) {
+        this.age = age;
+    }
+
+    public CacheObjectA getRelatedObject() {
+        return relatedObj;
+    }
+
+    public void setRelatedObject(CacheObjectA o) {
+        relatedObj = o;
+    }
+
+    public Collection getStringCollection() {
+        return stringColl;
+    }
+
+    public void setStringCollection(Collection coll) {
+        stringColl = coll;
+    }
+
+    public Collection getRelatedCollection() {
+        return relatedColl;
+    }
+
+    public void setRelatedCollection(Collection coll) {
+        relatedColl = coll;
+    }
+
+    public CacheObjectA[] getRelatedArray() {
+        return as;
+    }
+
+    public void setRelatedArray(CacheObjectA[] array) {
+        as = array;
+    }
+
+    public String[] getStringArray() {
+        return stringArray;
+    }
+
+    public void setStringArray(String[] array) {
+        stringArray = array;
+    }
+
+    public void setPrimitiveArray(float[] val) {
+        primitiveArray = val;
+    }
+
+    public float[] getPrimitiveArray() {
+        return primitiveArray;
+    }
+
+    public void setDateArray(Date[] val) {
+        dateArray = val;
+    }
+
+    public Date[] getDateArray() {
+        return dateArray;
+    }
+
+    public void setDate(Date val) {
+        date = val;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setLocale(Locale val) {
+        locale = val;
+    }
+
+    public Locale getLocale() {
+        return locale;
+    }
+
+    public void setRelatedB(CacheObjectB val) {
+        relatedB = val;
+    }
+
+    public CacheObjectB getRelatedB() {
+        return relatedB;
+    }
+
+    public void setRelatedInterface(CacheObjectInterface val) {
+        relatedInterface = val;
+    }
+
+    public CacheObjectInterface getRelatedInterface() {
+        return relatedInterface;
+    }
+
+    public String toString() {
+        try {
+            return "CacheObjectA: " + super.toString() + "; name: " + name
+                + "; age: " + age;
+        }
+        catch (Exception e) {
+            return "CacheObjectA: " + super.toString() + "; "
+                + "Exception in toString(): " + e;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild1.java
index 6f3e9f5..85b3fa5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild1.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@DiscriminatorValue("CACHE_CHILD1")
-public class CacheObjectAChild1 extends CacheObjectA {
-
-    private String str1 = null;
-
-    protected CacheObjectAChild1() {
-    }
-
-    public CacheObjectAChild1(String s, String name, int age) {
-        super(name, age);
-        this.str1 = s;
-    }
-
-    public String getStr1() {
-        return str1;
-    }
-
-    public void setStr1(String s) {
-        this.str1 = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@DiscriminatorValue("CACHE_CHILD1")
+public class CacheObjectAChild1 extends CacheObjectA {
+
+    private String str1 = null;
+
+    protected CacheObjectAChild1() {
+    }
+
+    public CacheObjectAChild1(String s, String name, int age) {
+        super(name, age);
+        this.str1 = s;
+    }
+
+    public String getStr1() {
+        return str1;
+    }
+
+    public void setStr1(String s) {
+        this.str1 = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild2.java
index 7c1bb28..a71b76d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectAChild2.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.DataCache;
-
-@Entity
-@DiscriminatorValue("CACHE_CHILD2")
-@DataCache(enabled = false)
-public class CacheObjectAChild2 extends CacheObjectA {
-
-    private String str2 = null;
-
-    protected CacheObjectAChild2() {
-    }
-
-    public CacheObjectAChild2(String s, String name, int age) {
-        super(name, age);
-        this.str2 = s;
-    }
-
-    public String getStr2() {
-        return str2;
-    }
-
-    public void setStr2(String s) {
-        this.str2 = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.DataCache;
+
+@Entity
+@DiscriminatorValue("CACHE_CHILD2")
+@DataCache(enabled = false)
+public class CacheObjectAChild2 extends CacheObjectA {
+
+    private String str2 = null;
+
+    protected CacheObjectAChild2() {
+    }
+
+    public CacheObjectAChild2(String s, String name, int age) {
+        super(name, age);
+        this.str2 = s;
+    }
+
+    public String getStr2() {
+        return str2;
+    }
+
+    public void setStr2(String s) {
+        this.str2 = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectB.java
index 8965351..e125056 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectB.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-import org.apache.openjpa.persistence.DataCache;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYP")
-@DataCache(enabled = false)
-public class CacheObjectB {
-
-    private String str = null;
-
-    public CacheObjectB() {
-    }
-
-    public CacheObjectB(String s) {
-        this.str = s;
-    }
-
-    public String getStr() {
-        return str;
-    }
-
-    public void setStr(String s) {
-        this.str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.DataCache;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYP")
+@DataCache(enabled = false)
+public class CacheObjectB {
+
+    private String str = null;
+
+    public CacheObjectB() {
+    }
+
+    public CacheObjectB(String s) {
+        this.str = s;
+    }
+
+    public String getStr() {
+        return str;
+    }
+
+    public void setStr(String s) {
+        this.str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectBChild1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectBChild1.java
index e3e5e27..1b7db9c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectBChild1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectBChild1.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class CacheObjectBChild1
-    extends CacheObjectB {
-
-    private String str1 = null;
-
-    protected CacheObjectBChild1() {
-    }
-
-    public CacheObjectBChild1(String s, String name) {
-        super(name);
-        this.str1 = s;
-    }
-
-    public String getStr1() {
-        return str1;
-    }
-
-    public void setStr1(String s) {
-        this.str1 = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class CacheObjectBChild1
+    extends CacheObjectB {
+
+    private String str1 = null;
+
+    protected CacheObjectBChild1() {
+    }
+
+    public CacheObjectBChild1(String s, String name) {
+        super(name);
+        this.str1 = s;
+    }
+
+    public String getStr1() {
+        return str1;
+    }
+
+    public void setStr1(String s) {
+        this.str1 = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectC.java
index cc99376..53b148b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectC.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-import org.apache.openjpa.persistence.DataCache;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYP")
-@DataCache(name = "not-the-default-cache")
-public class CacheObjectC
-    implements CacheObjectInterface {
-
-    private String str = null;
-
-    public CacheObjectC() {
-    }
-
-    public CacheObjectC(String s) {
-        this.str = s;
-    }
-
-    public String getStr() {
-        return str;
-    }
-
-    public void setStr(String s) {
-        this.str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.DataCache;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYP")
+@DataCache(name = "not-the-default-cache")
+public class CacheObjectC
+    implements CacheObjectInterface {
+
+    private String str = null;
+
+    public CacheObjectC() {
+    }
+
+    public CacheObjectC(String s) {
+        this.str = s;
+    }
+
+    public String getStr() {
+        return str;
+    }
+
+    public void setStr(String s) {
+        this.str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectD.java
index fb82c31..591d0c8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectD.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-import org.apache.openjpa.persistence.DataCache;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYP")
-@DataCache(name = "not-the-default-cache")
-public class CacheObjectD {
-
-    private String str = null;
-
-    public CacheObjectD() {
-    }
-
-    public CacheObjectD(String s) {
-        this.str = s;
-    }
-
-    public String getStr() {
-        return str;
-    }
-
-    public void setStr(String s) {
-        this.str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.DataCache;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYP")
+@DataCache(name = "not-the-default-cache")
+public class CacheObjectD {
+
+    private String str = null;
+
+    public CacheObjectD() {
+    }
+
+    public CacheObjectD(String s) {
+        this.str = s;
+    }
+
+    public String getStr() {
+        return str;
+    }
+
+    public void setStr(String s) {
+        this.str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectE.java
index 4f5b7a6..4291c34 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectE.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYP")
-public class CacheObjectE {
-
-    private String str = null;
-
-    public CacheObjectE() {
-    }
-
-    public CacheObjectE(String s) {
-        this.str = s;
-    }
-
-    public String getStr() {
-        return str;
-    }
-
-    public void setStr(String s) {
-        this.str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYP")
+public class CacheObjectE {
+
+    private String str = null;
+
+    public CacheObjectE() {
+    }
+
+    public CacheObjectE(String s) {
+        this.str = s;
+    }
+
+    public String getStr() {
+        return str;
+    }
+
+    public void setStr(String s) {
+        this.str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectF.java
index 46c11d8..d414c2c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectF.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.DataCache;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@DataCache(timeout = 1000)
-public class CacheObjectF
-    extends CacheObjectE {
-
-    public CacheObjectF() {
-    }
-
-    public CacheObjectF(String s) {
-        super(s);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.DataCache;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@DataCache(timeout = 1000)
+public class CacheObjectF
+    extends CacheObjectE {
+
+    public CacheObjectF() {
+    }
+
+    public CacheObjectF(String s) {
+        super(s);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectG.java
index d86ab12..75f7a06 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectG.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.DataCache;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@DataCache(timeout = 5000)
-public class CacheObjectG
-    extends CacheObjectF {
-
-    public CacheObjectG() {
-    }
-
-    public CacheObjectG(String s) {
-        super(s);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.DataCache;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@DataCache(timeout = 5000)
+public class CacheObjectG
+    extends CacheObjectF {
+
+    public CacheObjectG() {
+    }
+
+    public CacheObjectG(String s) {
+        super(s);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectH.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectH.java
index 3cbaa40..f19557b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectH.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectH.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.DataCache;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@DataCache(timeout = 500)
-public class CacheObjectH
-    extends CacheObjectG {
-
-    public CacheObjectH() {
-    }
-
-    public CacheObjectH(String s) {
-        super(s);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.DataCache;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@DataCache(timeout = 500)
+public class CacheObjectH
+    extends CacheObjectG {
+
+    public CacheObjectH() {
+    }
+
+    public CacheObjectH(String s) {
+        super(s);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectInterface.java
index a050fb6..3b5fa61 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectInterface.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-public interface CacheObjectInterface {
-
-    public void setStr(String val);
-
-    public String getStr();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+public interface CacheObjectInterface {
+
+    public void setStr(String val);
+
+    public String getStr();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectJ.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectJ.java
index 3d5ca57..e15cc44 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectJ.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectJ.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.ManyToOne;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYP")
-public class CacheObjectJ {
-
-    private String str = null;
-    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private CacheObjectE e = null;
-
-    public CacheObjectJ() {
-    }
-
-    public CacheObjectJ(String s, CacheObjectE e) {
-        this.str = s;
-        this.e = e;
-    }
-
-    public String getStr() {
-        return str;
-    }
-
-    public void setStr(String s) {
-        this.str = s;
-    }
-
-    //@Embedded()
-    public CacheObjectE getE() {
-        return e;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYP")
+public class CacheObjectJ {
+
+    private String str = null;
+    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private CacheObjectE e = null;
+
+    public CacheObjectJ() {
+    }
+
+    public CacheObjectJ(String s, CacheObjectE e) {
+        this.str = s;
+        this.e = e;
+    }
+
+    public String getStr() {
+        return str;
+    }
+
+    public void setStr(String s) {
+        this.str = s;
+    }
+
+    //@Embedded()
+    public CacheObjectE getE() {
+        return e;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectWithExternalizedFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectWithExternalizedFields.java
index a025ba4..b5812e7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectWithExternalizedFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/CacheObjectWithExternalizedFields.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-/**
- * A test class for our caching framework that ensures that externalized
- * fields are handled properly.
- */
-public class CacheObjectWithExternalizedFields {
-
-    private Class cls;
-
-    public void setCls(Class cls) {
-        this.cls = cls;
-    }
-
-    public Class getCls() {
-        return this.cls;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+/**
+ * A test class for our caching framework that ensures that externalized
+ * fields are handled properly.
+ */
+public class CacheObjectWithExternalizedFields {
+
+    private Class cls;
+
+    public void setCls(Class cls) {
+        this.cls = cls;
+    }
+
+    public Class getCls() {
+        return this.cls;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddedEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddedEntity.java
index 2530ce5..1402339 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddedEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddedEntity.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Embeddable;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.datacache.TestEmbeddedCollection;
-
-/**
- * Embeddable persistent entity.
- * 
- * Used in {@link TestEmbeddedCollection}.
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-@Embeddable
-public class EmbeddedEntity {
-	private String marker;
-
-	public String getMarker() {
-		return marker;
-	}
-
-	public void setMarker(String marker) {
-		this.marker = marker;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.datacache.TestEmbeddedCollection;
+
+/**
+ * Embeddable persistent entity.
+ * 
+ * Used in {@link TestEmbeddedCollection}.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Embeddable
+public class EmbeddedEntity {
+	private String marker;
+
+	public String getMarker() {
+		return marker;
+	}
+
+	public void setMarker(String marker) {
+		this.marker = marker;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddingOwnerEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddingOwnerEntity.java
index c74faed..d8fea93 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddingOwnerEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/EmbeddingOwnerEntity.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.datacache.TestEmbeddedCollection;
-
-/**
- * Persistent entity that embeds a persistent collection of embeddable.
- *  
- * Used in {@link TestEmbeddedCollection}. 
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class EmbeddingOwnerEntity {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	@PersistentCollection(elementEmbedded = true, 
-			elementType = EmbeddedEntity.class, 
-			fetch = FetchType.LAZY)
-	private List<EmbeddedEntity> members;
-
-	public List<EmbeddedEntity> getMembers() {
-		return members;
-	}
-
-	public void addMember(EmbeddedEntity member) {
-		if (members == null)
-			members = new ArrayList<EmbeddedEntity>();
-		this.members.add(member);
-	}
-	
-	public void removeMember(EmbeddedEntity member) {
-		if (members != null)
-			members.remove(member);
-	}
-	
-	public EmbeddedEntity removeMember(int member) {
-		return (members != null) ? members.remove(member) : null;
-	}
-
-	public long getId() {
-		return id;
-	} 
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.datacache.TestEmbeddedCollection;
+
+/**
+ * Persistent entity that embeds a persistent collection of embeddable.
+ *  
+ * Used in {@link TestEmbeddedCollection}. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class EmbeddingOwnerEntity {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	@PersistentCollection(elementEmbedded = true, 
+			elementType = EmbeddedEntity.class, 
+			fetch = FetchType.LAZY)
+	private List<EmbeddedEntity> members;
+
+	public List<EmbeddedEntity> getMembers() {
+		return members;
+	}
+
+	public void addMember(EmbeddedEntity member) {
+		if (members == null)
+			members = new ArrayList<EmbeddedEntity>();
+		this.members.add(member);
+	}
+	
+	public void removeMember(EmbeddedEntity member) {
+		if (members != null)
+			members.remove(member);
+	}
+	
+	public EmbeddedEntity removeMember(int member) {
+		return (members != null) ? members.remove(member) : null;
+	}
+
+	public long getId() {
+		return id;
+	} 
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/FlushDataCacheObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/FlushDataCacheObject.java
index d2b864f..6531a29 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/FlushDataCacheObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/FlushDataCacheObject.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class FlushDataCacheObject {
-
-    private String string;
-
-    public void setString(String val) {
-        string = val;
-    }
-
-    public String getString() {
-        return string;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class FlushDataCacheObject {
+
+    private String string;
+
+    public void setString(String val) {
+        string = val;
+    }
+
+    public String getString() {
+        return string;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/PObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/PObject.java
index 8d9bf7c..73b9932 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/PObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/PObject.java
@@ -1,57 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-/**
- * A Simple entity for testing. Has a version field for testing optimistic
- * concurrent usage.
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class PObject {
-	@Id
-	@GeneratedValue
-	private long id;
-	private String name;
-	@Version
-	private int version;
-	
-	public String getName() {
-		return name;
-	}
-	
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	public long getId() {
-		return id;
-	}
-	
-	public int getVersion() {
-		return version;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * A Simple entity for testing. Has a version field for testing optimistic
+ * concurrent usage.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class PObject {
+	@Id
+	@GeneratedValue
+	private long id;
+	private String name;
+	@Version
+	private int version;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public long getId() {
+		return id;
+	}
+	
+	public int getVersion() {
+		return version;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest1.java
index b0a7a41..ed5d4bd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest1.java
@@ -1,284 +1,284 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@DiscriminatorValue("dataRt1")
-public class RuntimeTest1
-    implements Serializable {
-
-    public static final String someStaticField = "someField";
-
-    private byte byteField;
-    private boolean booleanField;
-    private char charField;
-    private double doubleField;
-    private float floatField;
-    private int intField;
-    private long longField;
-    private short shortField;
-    private String stringField;
-    private BigInteger bigIntegerField;
-    private BigDecimal bigDecimalField;
-    @Temporal(TemporalType.DATE)
-    private Date dateField;
-    private Locale localeField;
-    private Byte byteObjfield;
-    private Boolean booleanObjField;
-    private Character charObjField;
-    private Double doubleObjField;
-    private Float floatObjField;
-    private Integer intObjField;
-    private Long longObjField;
-    private Short shortObjField;
-
-    // transactional only
-    @OneToOne(fetch = FetchType.LAZY,
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private TransactionalClassPC transField;
-    public String transString;
-
-    // relations
-    @OneToOne(fetch = FetchType.LAZY,
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private RuntimeTest1 selfOneOne;
-
-    @OneToMany(mappedBy = "selfOneOne",
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private Set<RuntimeTest1> selfOneMany = new HashSet<RuntimeTest1>();
-
-    public RuntimeTest1() {
-    }
-
-    public RuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-    }
-
-    public byte getByteField() {
-        return this.byteField;
-    }
-
-    public void setByteField(byte byteField) {
-        this.byteField = byteField;
-    }
-
-    public boolean getBooleanField() {
-        return this.booleanField;
-    }
-
-    public void setBooleanField(boolean booleanField) {
-        this.booleanField = booleanField;
-    }
-
-    public char getCharField() {
-        return this.charField;
-    }
-
-    public void setCharField(char charField) {
-        this.charField = charField;
-    }
-
-    public double getDoubleField() {
-        return this.doubleField;
-    }
-
-    public void setDoubleField(double doubleField) {
-        this.doubleField = doubleField;
-    }
-
-    public float getFloatField() {
-        return this.floatField;
-    }
-
-    public void setFloatField(float floatField) {
-        this.floatField = floatField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public long getLongField() {
-        return this.longField;
-    }
-
-    public void setLongField(long longField) {
-        this.longField = longField;
-    }
-
-    public short getShortField() {
-        return this.shortField;
-    }
-
-    public void setShortField(short shortField) {
-        this.shortField = shortField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public BigInteger getBigIntegerField() {
-        return this.bigIntegerField;
-    }
-
-    public void setBigIntegerField(BigInteger bigIntegerField) {
-        this.bigIntegerField = bigIntegerField;
-    }
-
-    public BigDecimal getBigDecimalField() {
-        return this.bigDecimalField;
-    }
-
-    public void setBigDecimalField(BigDecimal bigDecimalField) {
-        this.bigDecimalField = bigDecimalField;
-    }
-
-    public Date getDateField() {
-        return this.dateField;
-    }
-
-    public void setDateField(Date dateField) {
-        this.dateField = dateField;
-    }
-
-    public Locale getLocaleField() {
-        return this.localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-
-    public Byte getByteObjfield() {
-        return this.byteObjfield;
-    }
-
-    public void setByteObjfield(Byte byteObjfield) {
-        this.byteObjfield = byteObjfield;
-    }
-
-    public Boolean getBooleanObjField() {
-        return this.booleanObjField;
-    }
-
-    public void setBooleanObjField(Boolean booleanObjField) {
-        this.booleanObjField = booleanObjField;
-    }
-
-    public Character getCharObjField() {
-        return this.charObjField;
-    }
-
-    public void setCharObjField(Character charObjField) {
-        this.charObjField = charObjField;
-    }
-
-    public Double getDoubleObjField() {
-        return this.doubleObjField;
-    }
-
-    public void setDoubleObjField(Double doubleObjField) {
-        this.doubleObjField = doubleObjField;
-    }
-
-    public Float getFloatObjField() {
-        return this.floatObjField;
-    }
-
-    public void setFloatObjField(Float floatObjField) {
-        this.floatObjField = floatObjField;
-    }
-
-    public Integer getIntObjField() {
-        return this.intObjField;
-    }
-
-    public void setIntObjField(Integer intObjField) {
-        this.intObjField = intObjField;
-    }
-
-    public Long getLongObjField() {
-        return this.longObjField;
-    }
-
-    public void setLongObjField(Long longObjField) {
-        this.longObjField = longObjField;
-    }
-
-    public Short getShortObjField() {
-        return this.shortObjField;
-    }
-
-    public void setShortObjField(Short shortObjField) {
-        this.shortObjField = shortObjField;
-    }
-
-    public TransactionalClassPC getTransField() {
-        return this.transField;
-    }
-
-    public void setTransField(TransactionalClassPC transField) {
-        this.transField = transField;
-    }
-
-    public RuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@DiscriminatorValue("dataRt1")
+public class RuntimeTest1
+    implements Serializable {
+
+    public static final String someStaticField = "someField";
+
+    private byte byteField;
+    private boolean booleanField;
+    private char charField;
+    private double doubleField;
+    private float floatField;
+    private int intField;
+    private long longField;
+    private short shortField;
+    private String stringField;
+    private BigInteger bigIntegerField;
+    private BigDecimal bigDecimalField;
+    @Temporal(TemporalType.DATE)
+    private Date dateField;
+    private Locale localeField;
+    private Byte byteObjfield;
+    private Boolean booleanObjField;
+    private Character charObjField;
+    private Double doubleObjField;
+    private Float floatObjField;
+    private Integer intObjField;
+    private Long longObjField;
+    private Short shortObjField;
+
+    // transactional only
+    @OneToOne(fetch = FetchType.LAZY,
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private TransactionalClassPC transField;
+    public String transString;
+
+    // relations
+    @OneToOne(fetch = FetchType.LAZY,
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private RuntimeTest1 selfOneOne;
+
+    @OneToMany(mappedBy = "selfOneOne",
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private Set<RuntimeTest1> selfOneMany = new HashSet<RuntimeTest1>();
+
+    public RuntimeTest1() {
+    }
+
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+    }
+
+    public byte getByteField() {
+        return this.byteField;
+    }
+
+    public void setByteField(byte byteField) {
+        this.byteField = byteField;
+    }
+
+    public boolean getBooleanField() {
+        return this.booleanField;
+    }
+
+    public void setBooleanField(boolean booleanField) {
+        this.booleanField = booleanField;
+    }
+
+    public char getCharField() {
+        return this.charField;
+    }
+
+    public void setCharField(char charField) {
+        this.charField = charField;
+    }
+
+    public double getDoubleField() {
+        return this.doubleField;
+    }
+
+    public void setDoubleField(double doubleField) {
+        this.doubleField = doubleField;
+    }
+
+    public float getFloatField() {
+        return this.floatField;
+    }
+
+    public void setFloatField(float floatField) {
+        this.floatField = floatField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public long getLongField() {
+        return this.longField;
+    }
+
+    public void setLongField(long longField) {
+        this.longField = longField;
+    }
+
+    public short getShortField() {
+        return this.shortField;
+    }
+
+    public void setShortField(short shortField) {
+        this.shortField = shortField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public BigInteger getBigIntegerField() {
+        return this.bigIntegerField;
+    }
+
+    public void setBigIntegerField(BigInteger bigIntegerField) {
+        this.bigIntegerField = bigIntegerField;
+    }
+
+    public BigDecimal getBigDecimalField() {
+        return this.bigDecimalField;
+    }
+
+    public void setBigDecimalField(BigDecimal bigDecimalField) {
+        this.bigDecimalField = bigDecimalField;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+
+    public void setDateField(Date dateField) {
+        this.dateField = dateField;
+    }
+
+    public Locale getLocaleField() {
+        return this.localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+
+    public Byte getByteObjfield() {
+        return this.byteObjfield;
+    }
+
+    public void setByteObjfield(Byte byteObjfield) {
+        this.byteObjfield = byteObjfield;
+    }
+
+    public Boolean getBooleanObjField() {
+        return this.booleanObjField;
+    }
+
+    public void setBooleanObjField(Boolean booleanObjField) {
+        this.booleanObjField = booleanObjField;
+    }
+
+    public Character getCharObjField() {
+        return this.charObjField;
+    }
+
+    public void setCharObjField(Character charObjField) {
+        this.charObjField = charObjField;
+    }
+
+    public Double getDoubleObjField() {
+        return this.doubleObjField;
+    }
+
+    public void setDoubleObjField(Double doubleObjField) {
+        this.doubleObjField = doubleObjField;
+    }
+
+    public Float getFloatObjField() {
+        return this.floatObjField;
+    }
+
+    public void setFloatObjField(Float floatObjField) {
+        this.floatObjField = floatObjField;
+    }
+
+    public Integer getIntObjField() {
+        return this.intObjField;
+    }
+
+    public void setIntObjField(Integer intObjField) {
+        this.intObjField = intObjField;
+    }
+
+    public Long getLongObjField() {
+        return this.longObjField;
+    }
+
+    public void setLongObjField(Long longObjField) {
+        this.longObjField = longObjField;
+    }
+
+    public Short getShortObjField() {
+        return this.shortObjField;
+    }
+
+    public void setShortObjField(Short shortObjField) {
+        this.shortObjField = shortObjField;
+    }
+
+    public TransactionalClassPC getTransField() {
+        return this.transField;
+    }
+
+    public void setTransField(TransactionalClassPC transField) {
+        this.transField = transField;
+    }
+
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest2.java
index 35a6cd4..4e1b58a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/RuntimeTest2.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("dataRt2")
-public class RuntimeTest2
-    extends RuntimeTest1 {
-
-    private int intField2;
-
-    public RuntimeTest2() {
-    }
-
-    public RuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("dataRt2")
+public class RuntimeTest2
+    extends RuntimeTest1 {
+
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/ScheduledEviction.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/ScheduledEviction.java
index f360ef1..7ec91ec 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/ScheduledEviction.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/ScheduledEviction.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ScheduledEviction {
-
-    private String stringField;
-
-    public ScheduledEviction(String s) {
-        stringField = s;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ScheduledEviction {
+
+    private String stringField;
+
+    public ScheduledEviction(String s) {
+        stringField = s;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/SelfReferencingCacheTestObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/SelfReferencingCacheTestObject.java
index e9a10f3..6d712ab 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/SelfReferencingCacheTestObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/SelfReferencingCacheTestObject.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.ManyToOne;
-
-@Entity
-public class SelfReferencingCacheTestObject {
-
-    private String str;
-    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private SelfReferencingCacheTestObject o;
-    private CacheObjectAChild1 embedded;
-
-    public SelfReferencingCacheTestObject(String str,
-        SelfReferencingCacheTestObject o) {
-        this.str = str;
-        this.o = o;
-        embedded = new CacheObjectAChild1(str, str, 0);
-    }
-
-    public SelfReferencingCacheTestObject getO() {
-        return o;
-    }
-
-    public String getStr() {
-        return str;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class SelfReferencingCacheTestObject {
+
+    private String str;
+    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private SelfReferencingCacheTestObject o;
+    private CacheObjectAChild1 embedded;
+
+    public SelfReferencingCacheTestObject(String str,
+        SelfReferencingCacheTestObject o) {
+        this.str = str;
+        this.o = o;
+        embedded = new CacheObjectAChild1(str, str, 0);
+    }
+
+    public SelfReferencingCacheTestObject getO() {
+        return o;
+    }
+
+    public String getStr() {
+        return str;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/TransactionalClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/TransactionalClassPC.java
index 19b0519..d3699ca 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/TransactionalClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/common/apps/TransactionalClassPC.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.datacache.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class TransactionalClassPC {
-
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.datacache.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class TransactionalClassPC {
+
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/IntVersionEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/IntVersionEntity.java
new file mode 100644
index 0000000..0b73daf
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/IntVersionEntity.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.detach;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+@Entity
+public class IntVersionEntity {
+    
+    @Id
+    private int id;
+    private String name;
+    
+    @Version
+    private int version;
+    
+    public int getVersion() {
+        return version;
+    }
+
+    @OneToOne(cascade=CascadeType.PERSIST, fetch=FetchType.EAGER)
+    private TimestampVersionEntity e2;
+    
+    public IntVersionEntity(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public TimestampVersionEntity getE2() {
+        return e2;
+    }
+
+    public void setE2(TimestampVersionEntity e2) {
+        this.e2 = e2;
+    }
+
+    public IntVersionEntity() {
+    }
+    
+    public void printE2() {
+        System.out.println("e2 - " + e2);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/NoVersionEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/NoVersionEntity.java
new file mode 100644
index 0000000..9fc7cfb
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/NoVersionEntity.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.detach;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class NoVersionEntity {
+    
+    @Id
+    private int id;
+    private String name;
+    
+    public NoVersionEntity(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public NoVersionEntity() {
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/TestDetachReloadProp.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/TestDetachReloadProp.java
new file mode 100644
index 0000000..ef33bc5
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/TestDetachReloadProp.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.detach;
+
+import org.apache.openjpa.conf.Compatibility;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+public class TestDetachReloadProp extends SQLListenerTestCase {
+    IntVersionEntity intVer;
+    TimestampVersionEntity tsVer;
+    NoVersionEntity noVer;
+    int id;
+    OpenJPAEntityManager em;
+    Compatibility compat;
+    
+    public void setUp() {
+        setUp(org.apache.openjpa.persistence.detach.IntVersionEntity.class, 
+            org.apache.openjpa.persistence.detach.TimestampVersionEntity.class,
+            org.apache.openjpa.persistence.detach.NoVersionEntity.class);
+        compat = emf.getConfiguration().getCompatibilityInstance();
+        id++;
+        create(id);
+        persist();
+    }
+    
+    private void create(int id) {
+        intVer = new IntVersionEntity(id);
+        intVer.setName("xxx");
+        tsVer = new TimestampVersionEntity(id);
+        tsVer.setName("yyy");
+        intVer.setE2(tsVer);
+        noVer = new NoVersionEntity(id);
+        noVer.setName("zzz");
+    }
+    
+    private void persist() {
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(noVer);
+        em.persist(intVer); // also persists referenced tsVer
+        em.getTransaction().commit();
+        em.close();
+    }
+    
+    public void testReloadTrue() {
+        compat.setReloadOnDetach(true);
+        detachProcessing();
+    }
+    
+    public void testReloadFalse() {
+        compat.setReloadOnDetach(false);
+        detachProcessing();
+    }
+    
+    private void detachProcessing() {
+        // Detach individual entities explicitly
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        intVer = em.find(IntVersionEntity.class, id);
+        tsVer = em.find(TimestampVersionEntity.class, id);
+        noVer = em.find(NoVersionEntity.class, id);
+        em.detach(intVer);
+        em.detach(tsVer);
+        em.detach(noVer);
+        em.getTransaction().commit();
+        em.close();
+        
+        // Detach all internal implicitly with close()
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        intVer = em.find(IntVersionEntity.class, id);
+        tsVer = em.find(TimestampVersionEntity.class, id);
+        noVer = em.find(NoVersionEntity.class, id);
+        em.getTransaction().commit();
+        em.close();
+        
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/TimestampVersionEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/TimestampVersionEntity.java
new file mode 100644
index 0000000..284354f
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detach/TimestampVersionEntity.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.detach;
+
+import java.sql.Timestamp;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+@Entity
+public class TimestampVersionEntity {
+    
+    @Id
+    private int id;
+    private String name;
+    
+    @Version
+    private Timestamp version;
+    
+    public Timestamp getVersion() {
+        return version;
+    }
+    
+    public TimestampVersionEntity() {}
+
+    public TimestampVersionEntity(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyChild.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyChild.java
index ac3da2e..2aea112 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyChild.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyChild.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.detachment;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-
-@Entity
-public class DetachmentOneManyChild {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @ManyToOne(optional=false)
-    @JoinColumn(name="PARENT_ID", nullable=false)
-    @ForeignKey
-    private DetachmentOneManyParent parent;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public DetachmentOneManyParent getParent() { 
-        return parent; 
-    }
-
-    public void setParent(DetachmentOneManyParent parent) { 
-        this.parent = parent; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.detachment;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+
+@Entity
+public class DetachmentOneManyChild {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @ManyToOne(optional=false)
+    @JoinColumn(name="PARENT_ID", nullable=false)
+    @ForeignKey
+    private DetachmentOneManyParent parent;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public DetachmentOneManyParent getParent() { 
+        return parent; 
+    }
+
+    public void setParent(DetachmentOneManyParent parent) { 
+        this.parent = parent; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyParent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyParent.java
index 27224fb..7ba8a6e 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyParent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/DetachmentOneManyParent.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.detachment;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.*;
-
-@Entity
-public class DetachmentOneManyParent {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL, 
-        fetch=FetchType.EAGER)
-    @OrderBy("name ASC")
-    private List<DetachmentOneManyChild> children = 
-        new ArrayList<DetachmentOneManyChild>();
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public List<DetachmentOneManyChild> getChildren() { 
-        return children; 
-    }
-
-    public void addChild(DetachmentOneManyChild child) {
-        child.setParent(this);
-        children.add(child);
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.detachment;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.*;
+
+@Entity
+public class DetachmentOneManyParent {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL, 
+        fetch=FetchType.EAGER)
+    @OrderBy("name ASC")
+    private List<DetachmentOneManyChild> children = 
+        new ArrayList<DetachmentOneManyChild>();
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public List<DetachmentOneManyChild> getChildren() { 
+        return children; 
+    }
+
+    public void addChild(DetachmentOneManyChild child) {
+        child.setParent(this);
+        children.add(child);
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java
new file mode 100644
index 0000000..9de2231
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.detachment;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.detachment.model.NoDetachedStateEntityFieldAccess;
+import org.apache.openjpa.persistence.detachment.model.NoDetachedStateEntityPropertyAccess;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestDetachNoStateField extends SingleEMFTestCase {
+
+    @Override
+    protected void setUp(Object... props) {
+        super.setUp(CLEAR_TABLES, "openjpa.DetachState", "loaded(DetachedStateField=false)",
+            NoDetachedStateEntityPropertyAccess.class, NoDetachedStateEntityFieldAccess.class);
+        loadDB();
+    }
+
+    /**
+     * This testcase was added for OPENJPA-1400.
+     */
+    public void testIsDetchedNoStateManagerZeroVersionField() {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        NoDetachedStateEntityPropertyAccess property = em.find(NoDetachedStateEntityPropertyAccess.class, 1);
+        NoDetachedStateEntityFieldAccess field = em.find(NoDetachedStateEntityFieldAccess.class, 1);
+        em.close();
+
+        PersistenceCapable pcProperty = (PersistenceCapable) property;
+        PersistenceCapable pcField = (PersistenceCapable) field;
+
+        assertTrue(pcProperty.pcIsDetached());
+        assertTrue(pcField.pcIsDetached());
+    }
+
+    /**
+     * This testcase was added for OPENJPA-1400.
+     */
+    public void testPersistRelationshipToDetchedEntityZeroVersion() {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        NoDetachedStateEntityPropertyAccess property = em.find(NoDetachedStateEntityPropertyAccess.class, 1);
+        em.close();
+
+        // Make sure we don't hit any exceptions when persisting a relationship to a detached
+        // entity.
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        NoDetachedStateEntityFieldAccess field = em.find(NoDetachedStateEntityFieldAccess.class, 1);
+        field.setRelationship(property);
+        em.getTransaction().commit();
+        em.close();
+
+        // Make sure that the relationship was persisted
+        em = emf.createEntityManager();
+        field = em.find(NoDetachedStateEntityFieldAccess.class, 1);
+        property = field.getRelationship();
+        assertNotNull(property);
+        assertEquals(1, property.getId());
+
+    }
+
+    void loadDB() {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.createNativeQuery("INSERT INTO NoDetachedStateEntityPropertyAccess (ID,VERSION) VALUES (1,0)")
+            .executeUpdate();
+        em.createNativeQuery("INSERT INTO NoDetachedStateEntityFieldAccess (ID,VERSION) VALUES (1,0)")
+            .executeUpdate();
+        em.getTransaction().commit();
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java
new file mode 100644
index 0000000..74f08f4
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.detachment.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class NoDetachedStateEntityFieldAccess {
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	int id;
+	
+	@Version
+	int version;
+	
+	@Basic
+	String string;
+	
+	@ManyToOne
+	NoDetachedStateEntityPropertyAccess relationship;
+	
+	public NoDetachedStateEntityFieldAccess(){
+		
+	}
+	
+	public void setString(String s){
+		string = s;
+	}
+	public void setRelationship(NoDetachedStateEntityPropertyAccess r){
+		relationship = r;
+	}
+	public NoDetachedStateEntityPropertyAccess getRelationship(){
+		return relationship;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java
new file mode 100644
index 0000000..3007fb3
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.detachment.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+@Entity
+public class NoDetachedStateEntityPropertyAccess {
+	int id;
+	int version;
+	String string;
+	public NoDetachedStateEntityPropertyAccess(){
+		
+	}
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+	@Version
+	public int getVersion() {
+		return version;
+	}
+
+	public void setVersion(int version) {
+		this.version = version;
+	}
+	@Basic
+	public String getString() {
+		return string;
+	}
+
+	public void setString(String string) {
+		this.string = string;
+	}
+	
+	
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Address.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Address.java
index a5ba201..0718858 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Address.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Address.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.embed;
-
-import javax.persistence.*;
-
-/**
- * An entity that extends a MappedSuperClass and embeds an entity.
- * 
- * @author Pinaki Poddar 
- *
- */
-@Entity
-public class Address extends BaseEntity {
-    protected String streetAddress, city, state;
-
-    Geocode geocode;
-
-    @Embedded
-    public Geocode getGeocode() {
-        return geocode;
-    }
-
-    public void setGeocode(Geocode geocode) {
-        this.geocode = geocode;
-    }
-
-    public String getStreetAddress() {
-        return streetAddress;
-    }
-
-    public void setStreetAddress(String streetAddress) {
-        this.streetAddress = streetAddress;
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    public void setState(String state) {
-        this.state = state;
-    }
-
-    protected Integer zip;
-
-    public Integer getZip() {
-        return zip;
-    }
-
-    public void setZip(Integer zip) {
-        this.zip = zip;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.embed;
+
+import javax.persistence.*;
+
+/**
+ * An entity that extends a MappedSuperClass and embeds an entity.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+@Entity
+public class Address extends BaseEntity {
+    protected String streetAddress, city, state;
+
+    Geocode geocode;
+
+    @Embedded
+    public Geocode getGeocode() {
+        return geocode;
+    }
+
+    public void setGeocode(Geocode geocode) {
+        this.geocode = geocode;
+    }
+
+    public String getStreetAddress() {
+        return streetAddress;
+    }
+
+    public void setStreetAddress(String streetAddress) {
+        this.streetAddress = streetAddress;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    protected Integer zip;
+
+    public Integer getZip() {
+        return zip;
+    }
+
+    public void setZip(Integer zip) {
+        this.zip = zip;
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/BaseEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/BaseEntity.java
index 621dd95..23bfc97 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/BaseEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/BaseEntity.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.embed;
-
-import javax.persistence.*;
-
-/**
- * Mapped Super Class using auto-generated identity.
- * 
- * @author Pinaki Poddar 
- *
- */
-@MappedSuperclass
-public class BaseEntity {
-    protected Long id;
-
-    @Id
-    @GeneratedValue
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.embed;
+
+import javax.persistence.*;
+
+/**
+ * Mapped Super Class using auto-generated identity.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+@MappedSuperclass
+public class BaseEntity {
+    protected Long id;
+
+    @Id
+    @GeneratedValue
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Geocode.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Geocode.java
index e926b24..5209c5b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Geocode.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/Geocode.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.embed;
-
-import javax.persistence.*;
-
-/**
- * An embedded entity.
- * 
- * @author Pinaki Poddar 
- *
- */
-@Embeddable
-public class Geocode extends BaseEntity {
-    float latitude, longtitude;
-
-    public float getLatitude() {
-        return latitude;
-    }
-
-    public void setLatitude(float latitude) {
-        this.latitude = latitude;
-    }
-
-    public float getLongtitude() {
-        return longtitude;
-    }
-
-    public void setLongtitude(float longtitude) {
-        this.longtitude = longtitude;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.embed;
+
+import javax.persistence.*;
+
+/**
+ * An embedded entity.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+@Embeddable
+public class Geocode extends BaseEntity {
+    float latitude, longtitude;
+
+    public float getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(float latitude) {
+        this.latitude = latitude;
+    }
+
+    public float getLongtitude() {
+        return longtitude;
+    }
+
+    public void setLongtitude(float longtitude) {
+        this.longtitude = longtitude;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java
index bfabe66..520bad3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.embed;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestEmbedded extends SingleEMFTestCase {
-    public void setUp() {
-        super.setUp(BaseEntity.class, Address.class, Geocode.class,
-                CLEAR_TABLES);
-    }
-
-    public void testInsertEmbedded() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Address a = new Address();
-        a.setStreetAddress("123 Main St");
-        a.setCity("Chicago");
-        a.setState("IL");
-        a.setZip(60606);
-        Geocode g = new Geocode();
-        g.setLatitude(1.0f);
-        g.setLongtitude(2.0f);
-        a.setGeocode(g);
-        em.persist(a);
-        em.getTransaction().commit();
-    }
-
-    /*
-     * This variation verifies that an embedded entity can be accessed after
-     * being detached. An entity /w embedded is persisted and then queried. The
-     * em is closed, detaching the entities, and then a getter is called on the
-     * embeddeded. If the embedded is still attached (it should not be) an
-     * IllegalStateException will be thrown.
-     * 
-     * JIRA Ref: OPENJPA-733 Authors: Chris Tillman, Jeremy Bauer
-     */
-    public void testDetachedQueryEmbedded() {
-        Address a = new Address();
-        a.setStreetAddress("456 Main St");
-        a.setCity("New York");
-        a.setState("NY");
-        a.setZip(12955);
-        Geocode g = new Geocode();
-        g.setLatitude(1.0f);
-        g.setLongtitude(2.0f);
-        a.setGeocode(g);
-
-        persistAddress(a);
-
-        Address a2 =
-            queryAddresses(
-                "select address from Address address"
-                    + " where address.streetAddress = '456 Main St'").get(0);
-
-        assertEquals(a2.getGeocode().getLatitude(), 1.0f);
-    }
-
-    private void persistAddress(Address address) {
-        final EntityManager em = emf.createEntityManager();
-        final EntityTransaction tx = em.getTransaction();
-
-        tx.begin();
-
-        try {
-            em.persist(address);
-            tx.commit();
-        } finally {
-            if (tx.isActive()) {
-                tx.rollback();
-            }
-            em.close();
-        }
-        assertEquals(address.getGeocode().getLatitude(), 1.0f);
-    }
-
-    private List<Address> queryAddresses(String query) {
-        final EntityManager em = emf.createEntityManager();
-        final EntityTransaction tx = em.getTransaction();
-
-        tx.begin();
-
-        try {
-            final List<Address> list =
-                (List<Address>) em.createQuery(query).getResultList();
-            tx.commit();
-            return list;
-        } finally {
-            if (tx.isActive()) {
-                tx.rollback();
-            }
-            em.close();
-        }
-    }
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.embed;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestEmbedded extends SingleEMFTestCase {
+    public void setUp() {
+        super.setUp(BaseEntity.class, Address.class, Geocode.class,
+                CLEAR_TABLES);
+    }
+
+    public void testInsertEmbedded() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Address a = new Address();
+        a.setStreetAddress("123 Main St");
+        a.setCity("Chicago");
+        a.setState("IL");
+        a.setZip(60606);
+        Geocode g = new Geocode();
+        g.setLatitude(1.0f);
+        g.setLongtitude(2.0f);
+        a.setGeocode(g);
+        em.persist(a);
+        em.getTransaction().commit();
+    }
+
+    /*
+     * This variation verifies that an embedded entity can be accessed after
+     * being detached. An entity /w embedded is persisted and then queried. The
+     * em is closed, detaching the entities, and then a getter is called on the
+     * embeddeded. If the embedded is still attached (it should not be) an
+     * IllegalStateException will be thrown.
+     * 
+     * JIRA Ref: OPENJPA-733 Authors: Chris Tillman, Jeremy Bauer
+     */
+    public void testDetachedQueryEmbedded() {
+        Address a = new Address();
+        a.setStreetAddress("456 Main St");
+        a.setCity("New York");
+        a.setState("NY");
+        a.setZip(12955);
+        Geocode g = new Geocode();
+        g.setLatitude(1.0f);
+        g.setLongtitude(2.0f);
+        a.setGeocode(g);
+
+        persistAddress(a);
+
+        Address a2 =
+            queryAddresses(
+                "select address from Address address"
+                    + " where address.streetAddress = '456 Main St'").get(0);
+
+        assertEquals(a2.getGeocode().getLatitude(), 1.0f);
+    }
+
+    private void persistAddress(Address address) {
+        final EntityManager em = emf.createEntityManager();
+        final EntityTransaction tx = em.getTransaction();
+
+        tx.begin();
+
+        try {
+            em.persist(address);
+            tx.commit();
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
+            em.close();
+        }
+        assertEquals(address.getGeocode().getLatitude(), 1.0f);
+    }
+
+    private List<Address> queryAddresses(String query) {
+        final EntityManager em = emf.createEntityManager();
+        final EntityTransaction tx = em.getTransaction();
+
+        tx.begin();
+
+        try {
+            final List<Address> list =
+                (List<Address>) em.createQuery(query).getResultList();
+            tx.commit();
+            return list;
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
+            em.close();
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestClone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestClone.java
index ee6c4a4..0502ef4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestClone.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestClone.java
@@ -1,98 +1,98 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance;
-
-
-import org.apache.openjpa.persistence.enhance.common.apps.NoClone;
-import org.apache.openjpa.persistence.enhance.common.apps.PCClone;
-import org.apache.openjpa.persistence.enhance.common.apps.SubclassClone;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestClone
-    extends AbstractTestCase {
-
-    public TestClone(String name) {
-        super(name, "enhancecactusapp");
-    }
-
-    public void setUp() {
-
-        deleteAll(NoClone.class);
-        deleteAll(PCClone.class);
-        deleteAll(SubclassClone.class);
-    }
-
-    /**
-     * test no clone method declared.
-     */
-    public void testNoClone() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        NoClone orig = new NoClone("test");
-        pm.persist(orig);
-        endTx(pm);
-        pm.refresh(orig);
-        NoClone copy = orig.safeClone();
-        assertEquals("test", copy.getString());
-        assertTrue(pm.isPersistent(orig));
-        assertFalse(pm.isPersistent(copy));
-        endEm(pm);
-    }
-
-    /**
-     * test subclass which we cannot handle safely
-     */
-    public void testSubclassClone() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        SubclassClone orig = new SubclassClone("test");
-        pm.persist(orig);
-        endTx(pm);
-        pm.refresh(orig);
-        SubclassClone copy = orig.safeClone();
-        assertEquals("test", copy.getString());
-        assertTrue(pm.isPersistent(orig));
-        // this should be true since the sm should be VM copied.
-        // as we intentionally don't handle this case.
-        assertTrue(pm.isPersistent(copy));
-        endEm(pm);
-    }
-
-    /**
-     * test explicit clone call
-     */
-    public void testPCClone() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        PCClone orig = new PCClone("test");
-        pm.persist(orig);
-        endTx(pm);
-        pm.refresh(orig);
-        PCClone copy = (PCClone) orig.clone();
-        assertEquals("test", copy.getString());
-        assertTrue(pm.isPersistent(orig));
-        assertFalse(pm.isPersistent(copy));
-        endEm(pm);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance;
+
+
+import org.apache.openjpa.persistence.enhance.common.apps.NoClone;
+import org.apache.openjpa.persistence.enhance.common.apps.PCClone;
+import org.apache.openjpa.persistence.enhance.common.apps.SubclassClone;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestClone
+    extends AbstractTestCase {
+
+    public TestClone(String name) {
+        super(name, "enhancecactusapp");
+    }
+
+    public void setUp() {
+
+        deleteAll(NoClone.class);
+        deleteAll(PCClone.class);
+        deleteAll(SubclassClone.class);
+    }
+
+    /**
+     * test no clone method declared.
+     */
+    public void testNoClone() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        NoClone orig = new NoClone("test");
+        pm.persist(orig);
+        endTx(pm);
+        pm.refresh(orig);
+        NoClone copy = orig.safeClone();
+        assertEquals("test", copy.getString());
+        assertTrue(pm.isPersistent(orig));
+        assertFalse(pm.isPersistent(copy));
+        endEm(pm);
+    }
+
+    /**
+     * test subclass which we cannot handle safely
+     */
+    public void testSubclassClone() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        SubclassClone orig = new SubclassClone("test");
+        pm.persist(orig);
+        endTx(pm);
+        pm.refresh(orig);
+        SubclassClone copy = orig.safeClone();
+        assertEquals("test", copy.getString());
+        assertTrue(pm.isPersistent(orig));
+        // this should be true since the sm should be VM copied.
+        // as we intentionally don't handle this case.
+        assertTrue(pm.isPersistent(copy));
+        endEm(pm);
+    }
+
+    /**
+     * test explicit clone call
+     */
+    public void testPCClone() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        PCClone orig = new PCClone("test");
+        pm.persist(orig);
+        endTx(pm);
+        pm.refresh(orig);
+        PCClone copy = (PCClone) orig.clone();
+        assertEquals("test", copy.getString());
+        assertTrue(pm.isPersistent(orig));
+        assertFalse(pm.isPersistent(copy));
+        endEm(pm);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestDynamicStorageGenerator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestDynamicStorageGenerator.java
index b4021e9..5cf43a4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestDynamicStorageGenerator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestDynamicStorageGenerator.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance;
-
-import java.util.Date;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.enhance.DynamicStorage;
-import org.apache.openjpa.enhance.DynamicStorageGenerator;
-import org.apache.openjpa.meta.JavaTypes;
-
-public class TestDynamicStorageGenerator
-    extends AbstractTestCase {
-
-    public TestDynamicStorageGenerator(String s) {
-        super(s, "enhancecactusapp");
-    }
-
-    public void testStorage()
-        throws Exception {
-
-        DynamicStorageGenerator gen = new DynamicStorageGenerator();
-        int[] types = new int[]{
-            JavaTypes.BOOLEAN,
-            JavaTypes.BYTE,
-            JavaTypes.CHAR,
-            JavaTypes.INT,
-            JavaTypes.SHORT,
-            JavaTypes.LONG,
-            JavaTypes.FLOAT,
-            JavaTypes.DOUBLE,
-            JavaTypes.STRING,
-            JavaTypes.OBJECT
-        };
-        DynamicStorage storage = gen.generateStorage(types,
-            "org.apache.openjpa.enhance.Test");
-        storage = storage.newInstance();
-
-        storage.setBoolean(0, true);
-        storage.setByte(1, (byte) 1);
-        storage.setChar(2, 'f');
-        storage.setInt(3, 3);
-        storage.setShort(4, (short) 4);
-        storage.setLong(5, 5);
-        storage.setFloat(6, (float) 6.6);
-        storage.setDouble(7, 7.7);
-        storage.setObject(8, "field8");
-        Date date = new Date();
-        storage.setObject(9, date);
-
-        assertTrue(storage.getBoolean(0));
-        assertEquals(1, storage.getByte(1));
-        assertEquals('f', storage.getChar(2));
-        assertEquals(3, storage.getInt(3));
-        assertEquals(4, storage.getShort(4));
-        assertEquals(5, storage.getLong(5));
-        assertTrue(6.59 < storage.getFloat(6) && 6.61 > storage.getFloat(6));
-        assertTrue(7.69 < storage.getDouble(7)
-            && 7.71 > storage.getDouble(7));
-        assertEquals("field8", storage.getObject(8));
-        assertEquals(date, storage.getObject(9));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance;
+
+import java.util.Date;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.enhance.DynamicStorage;
+import org.apache.openjpa.enhance.DynamicStorageGenerator;
+import org.apache.openjpa.meta.JavaTypes;
+
+public class TestDynamicStorageGenerator
+    extends AbstractTestCase {
+
+    public TestDynamicStorageGenerator(String s) {
+        super(s, "enhancecactusapp");
+    }
+
+    public void testStorage()
+        throws Exception {
+
+        DynamicStorageGenerator gen = new DynamicStorageGenerator();
+        int[] types = new int[]{
+            JavaTypes.BOOLEAN,
+            JavaTypes.BYTE,
+            JavaTypes.CHAR,
+            JavaTypes.INT,
+            JavaTypes.SHORT,
+            JavaTypes.LONG,
+            JavaTypes.FLOAT,
+            JavaTypes.DOUBLE,
+            JavaTypes.STRING,
+            JavaTypes.OBJECT
+        };
+        DynamicStorage storage = gen.generateStorage(types,
+            "org.apache.openjpa.enhance.Test");
+        storage = storage.newInstance();
+
+        storage.setBoolean(0, true);
+        storage.setByte(1, (byte) 1);
+        storage.setChar(2, 'f');
+        storage.setInt(3, 3);
+        storage.setShort(4, (short) 4);
+        storage.setLong(5, 5);
+        storage.setFloat(6, (float) 6.6);
+        storage.setDouble(7, 7.7);
+        storage.setObject(8, "field8");
+        Date date = new Date();
+        storage.setObject(9, date);
+
+        assertTrue(storage.getBoolean(0));
+        assertEquals(1, storage.getByte(1));
+        assertEquals('f', storage.getChar(2));
+        assertEquals(3, storage.getInt(3));
+        assertEquals(4, storage.getShort(4));
+        assertEquals(5, storage.getLong(5));
+        assertTrue(6.59 < storage.getFloat(6) && 6.61 > storage.getFloat(6));
+        assertTrue(7.69 < storage.getDouble(7)
+            && 7.71 > storage.getDouble(7));
+        assertEquals("field8", storage.getObject(8));
+        assertEquals(date, storage.getObject(9));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestNoNoArgs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestNoNoArgs.java
index afed28f..c78838b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestNoNoArgs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestNoNoArgs.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance;
-
-import java.io.IOException;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.enhance.PCEnhancer;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.util.OpenJPAException;
-
-public class TestNoNoArgs
-    extends AbstractTestCase {
-
-    OpenJPAConfiguration conf;
-    MetaDataRepository repos;
-    ClassLoader loader;
-    private PCEnhancer.Flags flags = new PCEnhancer.Flags();
-
-    public TestNoNoArgs(String s) {
-        super(s, "enhancecactusapp");
-    }
-
-    public void setUp() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        conf = ((OpenJPAEntityManagerSPI) em).getConfiguration();
-        repos = conf.newMetaDataRepositoryInstance();
-        loader = em.getClassLoader();
-        endEm(em);
-    }
-
-    public void testNoNoArgs()
-        throws IOException {
-        PCEnhancer.run((OpenJPAConfiguration) conf,
-            new String[]{ },
-            flags, repos, null, loader);
-    }
-
-    public void testNo2NoArgs()
-        throws IOException {
-        flags.addDefaultConstructor = false;
-        boolean caughtException = false;
-        try {
-            PCEnhancer.run((OpenJPAConfiguration) conf, new String[]{ },
-                flags, repos, null, loader);
-        } catch (OpenJPAException e) {
-            caughtException = true;
-        }
-        assertTrue(caughtException);
-    }
-
-    public void testNo3NoArgs()
-        throws IOException {
-        PCEnhancer.run((OpenJPAConfiguration) conf,
-            new String[]{ "persistence.enhance.common.apps.Entity1" },
-            flags, repos, null, loader);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance;
+
+import java.io.IOException;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.enhance.PCEnhancer;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.util.OpenJPAException;
+
+public class TestNoNoArgs
+    extends AbstractTestCase {
+
+    OpenJPAConfiguration conf;
+    MetaDataRepository repos;
+    ClassLoader loader;
+    private PCEnhancer.Flags flags = new PCEnhancer.Flags();
+
+    public TestNoNoArgs(String s) {
+        super(s, "enhancecactusapp");
+    }
+
+    public void setUp() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        conf = ((OpenJPAEntityManagerSPI) em).getConfiguration();
+        repos = conf.newMetaDataRepositoryInstance();
+        loader = em.getClassLoader();
+        endEm(em);
+    }
+
+    public void testNoNoArgs()
+        throws IOException {
+        PCEnhancer.run((OpenJPAConfiguration) conf,
+            new String[]{ },
+            flags, repos, null, loader);
+    }
+
+    public void testNo2NoArgs()
+        throws IOException {
+        flags.addDefaultConstructor = false;
+        boolean caughtException = false;
+        try {
+            PCEnhancer.run((OpenJPAConfiguration) conf, new String[]{ },
+                flags, repos, null, loader);
+        } catch (OpenJPAException e) {
+            caughtException = true;
+        }
+        assertTrue(caughtException);
+    }
+
+    public void testNo3NoArgs()
+        throws IOException {
+        PCEnhancer.run((OpenJPAConfiguration) conf,
+            new String[]{ "persistence.enhance.common.apps.Entity1" },
+            flags, repos, null, loader);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestSubclassedBehavior.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestSubclassedBehavior.java
index 652d5a5..d45a0fa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestSubclassedBehavior.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestSubclassedBehavior.java
@@ -1,559 +1,559 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.enhance.common.apps.BackingFieldNameMismatchInstance;
-import org.apache.openjpa.persistence.enhance.common.apps.BaseEntity;
-import org.apache.openjpa.persistence.enhance.common.apps.BasicSubclassInstance;
-import org.apache.openjpa.persistence.enhance.common.apps.DerivedEntity;
-import org.apache.openjpa.persistence.enhance.common.apps.Entity1;
-import org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance;
-import org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance2;
-import org.apache.openjpa.persistence.enhance.common.apps.SubclassTestInstance;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.AssertionFailedError;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.util.ExceptionInfo;
-import org.apache.openjpa.util.ImplHelper;
-
-public class TestSubclassedBehavior extends AbstractTestCase {
-
-    public TestSubclassedBehavior(String name) {
-        super(name, "enhancecactusapp");
-    }
-
-
-    public void setUp() {
-        deleteAll(BasicSubclassInstance.class);
-        deleteAll(BackingFieldNameMismatchInstance.class);
-        deleteAll(BaseEntity.class);
-        deleteAll(ManagedInverseTestInstance.class);
-        deleteAll(ManagedInverseTestInstance2.class);
-    }
-
-    public void testInheritance() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        DerivedEntity de = (DerivedEntity) newInstance(pm, DerivedEntity.class);
-        BasicSubclassInstance basic = (BasicSubclassInstance) newInstance(pm,
-            BasicSubclassInstance.class);
-        basic.setStringField("basic one-to-one");
-        de.setOneToOne(basic);
-        Object oid = persistenceOperations(pm, de, false);
-
-        // ##### need a test case for JDOHelper.createEntityManager() for
-        // subclass
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(pm, de.getClass());
-        assertEquals(BaseEntity.class, meta.getPCSuperclass());
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-
-        Object o = pm.find(DerivedEntity.class, oid);
-        assertTrue(o instanceof DerivedEntity);
-        de = (DerivedEntity) o;
-        Broker b = JPAFacadeHelper.toBroker(pm);
-        OpenJPAStateManager sm = b.getStateManager(de);
-        // we use getLoaded() here because isLoaded() always returns true.
-        assertFalse(sm.getLoaded().get(
-            sm.getMetaData().getField("oneToOne").getIndex()));
-        assertEquals("basic one-to-one", de.getOneToOne().getStringField());
-        assertTrue(sm.getLoaded().get(sm.getMetaData()
-            .getField("oneToOne").getIndex()));
-
-        startTx(pm);
-        pm.remove(de);
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testBasicSubclassPersistenceOperations()
-        throws ClassNotFoundException {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BasicSubclassInstance o = (BasicSubclassInstance) newInstance(pm,
-            BasicSubclassInstance.class);
-        persistenceOperations(pm, o, true);
-    }
-
-    public void testBackingFieldNameMismatch() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BackingFieldNameMismatchInstance o = (BackingFieldNameMismatchInstance)
-            newInstance(pm, BackingFieldNameMismatchInstance.class);
-        persistenceOperations(pm, o, true);
-    }
-
-    private Object newInstance(OpenJPAEntityManager pm, Class cls) {
-        return pm.createInstance(cls);
-    }
-
-    private Object createInstance(EntityManager em, Class cls) {
-        return ((OpenJPAEntityManager) em).createInstance(cls);
-    }
-
-    private Object persistenceOperations(OpenJPAEntityManager pm,
-        SubclassTestInstance o, boolean delete) {
-        startTx(pm);
-        pm.persist(o);
-        o.setStringField("new persistent instance");
-        endTx(pm);
-        Object oid = pm.getObjectId(o);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        o = (SubclassTestInstance) pm.find(SubclassTestInstance.class, oid);
-
-        assertEquals("new persistent instance", o.getStringField());
-        startTx(pm);
-        o.setStringField("modified persistent instance");
-        endTx(pm);
-        endEm(pm);
-
-        if (delete) {
-            pm = (OpenJPAEntityManager) currentEntityManager();
-            o = (SubclassTestInstance) pm.find(SubclassTestInstance.class, oid);
-            assertEquals("modified persistent instance", o.getStringField());
-            startTx(pm);
-            pm.remove(o);
-            endTx(pm);
-            endEm(pm);
-            return null;
-        } else {
-            return oid;
-        }
-    }
-
-    public void testPolymorphicQueries() {
-        deleteAll(BaseEntity.class);
-        deleteAll(BasicSubclassInstance.class);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-
-        BaseEntity be = (BaseEntity) newInstance(pm, BaseEntity.class);
-        be.setShortField((short) 0);
-        pm.persist(be);
-
-        be = (BaseEntity) newInstance(pm, BaseEntity.class);
-        be.setShortField((short) 1);
-        pm.persist(be);
-
-        DerivedEntity de = (DerivedEntity) newInstance(pm, DerivedEntity.class);
-        de.setShortField((short) 2);
-        de.setOneToOne((BasicSubclassInstance) newInstance(pm,
-            BasicSubclassInstance.class));
-        pm.persist(de);
-
-        de = (DerivedEntity) newInstance(pm, DerivedEntity.class);
-        de.setShortField((short) 3);
-        de.setOneToOne((BasicSubclassInstance) newInstance(pm,
-            BasicSubclassInstance.class));
-        pm.persist(de);
-
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        OpenJPAQuery q =
-            pm.createQuery("SELECT a FROM BaseEntity a "
-                + "ORDER BY a.shortField ASC");
-        List l = (List) q.getResultList();
-        assertEquals(4, l.size());
-        assertEquals(0, ((BaseEntity) l.get(0)).getShortField());
-        assertEquals(1, ((BaseEntity) l.get(1)).getShortField());
-        assertEquals(2, ((BaseEntity) l.get(2)).getShortField());
-        assertEquals(3, ((BaseEntity) l.get(3)).getShortField());
-        assertTrue(l.get(2) instanceof DerivedEntity);
-        assertTrue(l.get(3) instanceof DerivedEntity);
-        endEm(pm);
-    }
-
-    public void testEnhancedClassChangesOutsideTxWithoutNTW() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        deleteAll(Entity1.class);
-        endTx(pm);
-        Entity1 o = new Entity1(8, "pk 8", 4);
-        startTx(pm);
-        pm.persist(o);
-        endTx(pm);
-        Object oid = pm.getObjectId(o);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        o = (Entity1) pm.find(Entity1.class, oid);
-
-        try {
-            o.setStringField("hello");
-            fail("non-transactional write should not be allowed");
-        } catch (Exception e) {
-            // expected
-        } finally {
-            endEm(pm);
-        }
-    }
-
-    public void testSubclassChangesOutsideTxWithoutNTW() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BasicSubclassInstance basic = (BasicSubclassInstance) newInstance(pm,
-            BasicSubclassInstance.class);
-        basic.setStringField("foo");
-        startTx(pm);
-        pm.persist(basic);
-        endTx(pm);
-        Object oid = pm.getObjectId(basic);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        basic =
-            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
-
-        try {
-            basic.setStringField("hello");
-            fail("non-transactional write should not be allowed");
-        } catch (Exception e) {
-            // expected
-        } finally {
-            endEm(pm);
-        }
-    }
-
-    public void testBasicPMUses() {
-        // retain so we don't reload in the reads after the tx commit
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        Broker broker = JPAFacadeHelper.toBroker(pm);
-        startTx(pm);
-
-        // register a new instance with the PM
-        BasicSubclassInstance basic = (BasicSubclassInstance) newInstance
-            (pm, BasicSubclassInstance.class);
-        assertTrue(ImplHelper.isManageable(basic));
-        basic.setStringField("foo");
-        pm.persist(basic);
-        assertTrue(broker.isNew(basic));
-        assertTrue(broker.isPersistent(basic));
-
-        // commit. this should cause the data to be written.
-        // ### should check SQL count
-        endTx(pm);
-
-        assertFalse(broker.isNew(basic));
-
-        OpenJPAStateManager sm = broker.getStateManager(basic);
-        assertNotNull(sm);
-        assertEquals(sm.getManagedInstance(), basic);
-
-        FieldMetaData fmd = sm.getMetaData().getField("stringField");
-        assertEquals("foo", sm.fetch(fmd.getIndex()));
-        assertTrue(sm.getLoaded().get(fmd.getIndex()));
-
-        pm.evict(basic);
-        assertFalse(sm.getLoaded().get(fmd.getIndex()));
-        // lazy loading
-        assertNotNull(basic.getStringField());
-        assertEquals("foo", sm.fetch(fmd.getIndex()));
-        assertEquals("foo", basic.getStringField());
-        assertTrue(sm.getLoaded().get(fmd.getIndex()));
-
-        startTx(pm);
-        basic.setStringField("bar");
-        assertTrue(broker.isDirty(basic));
-        endTx(pm);
-        Object oid = broker.getObjectId(basic);
-        assertNotNull(oid);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        basic =
-            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
-        assertEquals("bar", basic.getStringField());
-
-        startTx(pm);
-        pm.remove(basic);
-        assertTrue(JPAFacadeHelper.toBroker(pm).isDeleted(basic));
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testGetObjectId() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BasicSubclassInstance basic = new BasicSubclassInstance();
-        basic.setStringField("foo");
-        startTx(pm);
-        pm.persist(basic);
-        endTx(pm);
-        Object oid = null;
-        try {
-            assertNotNull(oid = pm.getObjectId(basic));
-        } catch (Exception e) {
-            fail("object id lookup failed: " + e.getMessage());
-        }
-
-        startTx(pm);
-        pm.remove(basic);
-        // before committing, id should exist still
-        assertNotNull(pm.getObjectId(basic));
-
-        endTx(pm);
-        assertNull(pm.getObjectId(basic));
-        endEm(pm);
-
-        // looking up the instance by id in a new PM should fail.
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        try {
-            pm.find(BasicSubclassInstance.class, oid);
-            fail("instance should have been deleted!");
-        } catch (Exception e) {
-            // expected
-        }
-        endEm(pm);
-    }
-
-    public void testChangesOutsideTxWithNTW() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BasicSubclassInstance basic = new BasicSubclassInstance();
-        basic.setStringField("foo");
-        startTx(pm);
-        pm.persist(basic);
-        endTx(pm);
-        Object oid = pm.getObjectId(basic);
-        endEm(pm);
-
-        pm = getNTWPM();
-        basic =
-            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
-        basic.setStringField("hello");
-        startTx(pm);
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        basic =
-            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
-        try {
-            assertEquals("hello", basic.getStringField());
-        } catch (AssertionFailedError afe) {
-            bug(1205, afe, "JDO 2-style NTW not supported.");
-        }
-    }
-
-    public void testChangesOutsideTxWithoutNTW() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BasicSubclassInstance basic = new BasicSubclassInstance();
-        basic.setStringField("foo");
-        startTx(pm);
-        pm.persist(basic);
-        endTx(pm);
-
-        try {
-            basic.setStringField("hello");
-            fail("should not be able to write outside tx without NTW");
-        } catch (RuntimeException re) {
-            // expected case
-            Object failed = ((ExceptionInfo) re).getFailedObject();
-            assertNotNull(failed);
-            assertSame(basic, failed);
-        } finally {
-            endEm(pm);
-        }
-    }
-
-    private OpenJPAEntityManager getNTWPM() {
-        EntityManagerFactory pmf = getEmf();
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) pmf.createEntityManager();
-        em.setNontransactionalWrite(true);
-        return em;
-    }
-
-    /*
-     public void testCallbacks ()
-     {
-         fail ("##### unimplemented test");
-     }
-
-
-     public void testTransactionListeners ()
-     {
-         fail ("#####");
-     }
-
-
-     public void testRemoteCommitListeners ()
-     {
-         fail ("#####");
-     }
-
-
-     public void testCaching ()
-     {
-         fail ("#####");
-     }
-
-
-     public void testRemote ()
-     {
-         fail ("#####");
-     }
-     */
-
-    public void testVersionIncrementAndIdField() {
-        // make sure that version increments happen correctly, and are
-        // visible in the user-visible instance.
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        BasicSubclassInstance basic = new BasicSubclassInstance();
-        basic.setStringField("foo");
-        startTx(pm);
-        pm.persist(basic);
-        endTx(pm);
-
-        assertEquals(1, basic.getVersion());
-        long id = basic.getId();
-        assertNotEquals(0, id);
-
-        startTx(pm);
-        basic.setStringField("bar");
-        endTx(pm);
-        assertEquals(2, basic.getVersion());
-        endEm(pm);
-    }
-
-    /*
-     public void testAutoAssignedFields ()
-     {
-         // make sure that auto-assigned field values get into the user-visible
-         // instance.
-         fail ("#####");
-     }
-     */
-
-    public void testJPABasics() {
-        EntityManager em = currentEntityManager();
-        BasicSubclassInstance basic = (BasicSubclassInstance) createInstance(
-            em, BasicSubclassInstance.class);
-        basic.setStringField("hello");
-        startTx(em);
-        em.persist(basic);
-        endTx(em);
-        endEm(em);
-    }
-
-    /*
-     public void testDetachmentAndAttachemnt ()
-     {
-         fail ("#####");
-     }
-
-
-     public void testEmbeddedNonEnhanced ()
-     {
-         fail ("#####");
-     }
-
-
-     public void testTransactionalNonEnhanced ()
-     {
-         fail ("#####");
-     }
-
-
-     public void testBulkTransactionalNonEnhanced ()
-     {
-         fail ("#####");
-     }
-     */
-
-    public void testSingleValuedInverseManagement() {
-        Map map = new HashMap();
-        map.put("openjpa.InverseManager", "true");
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)
-            getEmf(map).createEntityManager();
-        ManagedInverseTestInstance managed = (ManagedInverseTestInstance)
-            newInstance(pm, ManagedInverseTestInstance.class);
-        ManagedInverseTestInstance2 managed2 = (ManagedInverseTestInstance2)
-            newInstance(pm, ManagedInverseTestInstance2.class);
-        managed.setStringField("managed");
-        managed2.setStringField("managed2");
-        managed.setManaged2(managed2);
-
-        startTx(pm);
-        pm.persist(managed);
-        endTx(pm);
-
-        assertSame(managed, managed2.getManaged());
-    }
-
-    public void testBackingFieldConfigurationWithTwoFactories() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        // this causes DerivedEntity.class to get loaded into PCRegistry
-        newInstance(pm, DerivedEntity.class);
-        Map map = new HashMap();
-        map.put("openjpa.Log", "DiagnosticContext=subclass-two-factories-test");
-        pm = (OpenJPAEntityManager) getEmf(map).createEntityManager();
-        newInstance(pm, DerivedEntity.class);
-
-        // this second new-instance creation will result in the metadata
-        // defaults being loaded from the PCRegistry instead of via reflection.
-        // Make sure that things still work as expected from the
-        // registry-parsing code.
-        ClassMetaData meta = getConfiguration()
-            .getMetaDataRepositoryInstance().
-            getMetaData(DerivedEntity.class, null, false);
-        assertTrue("meta's access should be ACCESS_PROPERTY",
-            meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY);
-        FieldMetaData[] fmds = meta.getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            assertEquals(Method.class, fmds[i].getBackingMember().getClass());
-
-            // make sure that the fields are defined in the right part of the
-            // hierarchy
-            if (fmds[i].getName().equals("intField") ||
-                fmds[i].getName().equals("oneToOne")) {
-                assertEquals(DerivedEntity.class,
-                    fmds[i].getDefiningMetaData().getDescribedType());
-            } else {
-                assertEquals(BaseEntity.class,
-                    fmds[i].getDefiningMetaData().getDescribedType());
-            }
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.enhance.common.apps.BackingFieldNameMismatchInstance;
+import org.apache.openjpa.persistence.enhance.common.apps.BaseEntity;
+import org.apache.openjpa.persistence.enhance.common.apps.BasicSubclassInstance;
+import org.apache.openjpa.persistence.enhance.common.apps.DerivedEntity;
+import org.apache.openjpa.persistence.enhance.common.apps.Entity1;
+import org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance;
+import org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance2;
+import org.apache.openjpa.persistence.enhance.common.apps.SubclassTestInstance;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.util.ExceptionInfo;
+import org.apache.openjpa.util.ImplHelper;
+
+public class TestSubclassedBehavior extends AbstractTestCase {
+
+    public TestSubclassedBehavior(String name) {
+        super(name, "enhancecactusapp");
+    }
+
+
+    public void setUp() {
+        deleteAll(BasicSubclassInstance.class);
+        deleteAll(BackingFieldNameMismatchInstance.class);
+        deleteAll(BaseEntity.class);
+        deleteAll(ManagedInverseTestInstance.class);
+        deleteAll(ManagedInverseTestInstance2.class);
+    }
+
+    public void testInheritance() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        DerivedEntity de = (DerivedEntity) newInstance(pm, DerivedEntity.class);
+        BasicSubclassInstance basic = (BasicSubclassInstance) newInstance(pm,
+            BasicSubclassInstance.class);
+        basic.setStringField("basic one-to-one");
+        de.setOneToOne(basic);
+        Object oid = persistenceOperations(pm, de, false);
+
+        // ##### need a test case for JDOHelper.createEntityManager() for
+        // subclass
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(pm, de.getClass());
+        assertEquals(BaseEntity.class, meta.getPCSuperclass());
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+
+        Object o = pm.find(DerivedEntity.class, oid);
+        assertTrue(o instanceof DerivedEntity);
+        de = (DerivedEntity) o;
+        Broker b = JPAFacadeHelper.toBroker(pm);
+        OpenJPAStateManager sm = b.getStateManager(de);
+        // we use getLoaded() here because isLoaded() always returns true.
+        assertFalse(sm.getLoaded().get(
+            sm.getMetaData().getField("oneToOne").getIndex()));
+        assertEquals("basic one-to-one", de.getOneToOne().getStringField());
+        assertTrue(sm.getLoaded().get(sm.getMetaData()
+            .getField("oneToOne").getIndex()));
+
+        startTx(pm);
+        pm.remove(de);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testBasicSubclassPersistenceOperations()
+        throws ClassNotFoundException {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BasicSubclassInstance o = (BasicSubclassInstance) newInstance(pm,
+            BasicSubclassInstance.class);
+        persistenceOperations(pm, o, true);
+    }
+
+    public void testBackingFieldNameMismatch() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BackingFieldNameMismatchInstance o = (BackingFieldNameMismatchInstance)
+            newInstance(pm, BackingFieldNameMismatchInstance.class);
+        persistenceOperations(pm, o, true);
+    }
+
+    private Object newInstance(OpenJPAEntityManager pm, Class cls) {
+        return pm.createInstance(cls);
+    }
+
+    private Object createInstance(EntityManager em, Class cls) {
+        return ((OpenJPAEntityManager) em).createInstance(cls);
+    }
+
+    private Object persistenceOperations(OpenJPAEntityManager pm,
+        SubclassTestInstance o, boolean delete) {
+        startTx(pm);
+        pm.persist(o);
+        o.setStringField("new persistent instance");
+        endTx(pm);
+        Object oid = pm.getObjectId(o);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        o = (SubclassTestInstance) pm.find(SubclassTestInstance.class, oid);
+
+        assertEquals("new persistent instance", o.getStringField());
+        startTx(pm);
+        o.setStringField("modified persistent instance");
+        endTx(pm);
+        endEm(pm);
+
+        if (delete) {
+            pm = (OpenJPAEntityManager) currentEntityManager();
+            o = (SubclassTestInstance) pm.find(SubclassTestInstance.class, oid);
+            assertEquals("modified persistent instance", o.getStringField());
+            startTx(pm);
+            pm.remove(o);
+            endTx(pm);
+            endEm(pm);
+            return null;
+        } else {
+            return oid;
+        }
+    }
+
+    public void testPolymorphicQueries() {
+        deleteAll(BaseEntity.class);
+        deleteAll(BasicSubclassInstance.class);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+
+        BaseEntity be = (BaseEntity) newInstance(pm, BaseEntity.class);
+        be.setShortField((short) 0);
+        pm.persist(be);
+
+        be = (BaseEntity) newInstance(pm, BaseEntity.class);
+        be.setShortField((short) 1);
+        pm.persist(be);
+
+        DerivedEntity de = (DerivedEntity) newInstance(pm, DerivedEntity.class);
+        de.setShortField((short) 2);
+        de.setOneToOne((BasicSubclassInstance) newInstance(pm,
+            BasicSubclassInstance.class));
+        pm.persist(de);
+
+        de = (DerivedEntity) newInstance(pm, DerivedEntity.class);
+        de.setShortField((short) 3);
+        de.setOneToOne((BasicSubclassInstance) newInstance(pm,
+            BasicSubclassInstance.class));
+        pm.persist(de);
+
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        OpenJPAQuery q =
+            pm.createQuery("SELECT a FROM BaseEntity a "
+                + "ORDER BY a.shortField ASC");
+        List l = (List) q.getResultList();
+        assertEquals(4, l.size());
+        assertEquals(0, ((BaseEntity) l.get(0)).getShortField());
+        assertEquals(1, ((BaseEntity) l.get(1)).getShortField());
+        assertEquals(2, ((BaseEntity) l.get(2)).getShortField());
+        assertEquals(3, ((BaseEntity) l.get(3)).getShortField());
+        assertTrue(l.get(2) instanceof DerivedEntity);
+        assertTrue(l.get(3) instanceof DerivedEntity);
+        endEm(pm);
+    }
+
+    public void testEnhancedClassChangesOutsideTxWithoutNTW() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        deleteAll(Entity1.class);
+        endTx(pm);
+        Entity1 o = new Entity1(8, "pk 8", 4);
+        startTx(pm);
+        pm.persist(o);
+        endTx(pm);
+        Object oid = pm.getObjectId(o);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        o = (Entity1) pm.find(Entity1.class, oid);
+
+        try {
+            o.setStringField("hello");
+            fail("non-transactional write should not be allowed");
+        } catch (Exception e) {
+            // expected
+        } finally {
+            endEm(pm);
+        }
+    }
+
+    public void testSubclassChangesOutsideTxWithoutNTW() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BasicSubclassInstance basic = (BasicSubclassInstance) newInstance(pm,
+            BasicSubclassInstance.class);
+        basic.setStringField("foo");
+        startTx(pm);
+        pm.persist(basic);
+        endTx(pm);
+        Object oid = pm.getObjectId(basic);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        basic =
+            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
+
+        try {
+            basic.setStringField("hello");
+            fail("non-transactional write should not be allowed");
+        } catch (Exception e) {
+            // expected
+        } finally {
+            endEm(pm);
+        }
+    }
+
+    public void testBasicPMUses() {
+        // retain so we don't reload in the reads after the tx commit
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        Broker broker = JPAFacadeHelper.toBroker(pm);
+        startTx(pm);
+
+        // register a new instance with the PM
+        BasicSubclassInstance basic = (BasicSubclassInstance) newInstance
+            (pm, BasicSubclassInstance.class);
+        assertTrue(ImplHelper.isManageable(basic));
+        basic.setStringField("foo");
+        pm.persist(basic);
+        assertTrue(broker.isNew(basic));
+        assertTrue(broker.isPersistent(basic));
+
+        // commit. this should cause the data to be written.
+        // ### should check SQL count
+        endTx(pm);
+
+        assertFalse(broker.isNew(basic));
+
+        OpenJPAStateManager sm = broker.getStateManager(basic);
+        assertNotNull(sm);
+        assertEquals(sm.getManagedInstance(), basic);
+
+        FieldMetaData fmd = sm.getMetaData().getField("stringField");
+        assertEquals("foo", sm.fetch(fmd.getIndex()));
+        assertTrue(sm.getLoaded().get(fmd.getIndex()));
+
+        pm.evict(basic);
+        assertFalse(sm.getLoaded().get(fmd.getIndex()));
+        // lazy loading
+        assertNotNull(basic.getStringField());
+        assertEquals("foo", sm.fetch(fmd.getIndex()));
+        assertEquals("foo", basic.getStringField());
+        assertTrue(sm.getLoaded().get(fmd.getIndex()));
+
+        startTx(pm);
+        basic.setStringField("bar");
+        assertTrue(broker.isDirty(basic));
+        endTx(pm);
+        Object oid = broker.getObjectId(basic);
+        assertNotNull(oid);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        basic =
+            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
+        assertEquals("bar", basic.getStringField());
+
+        startTx(pm);
+        pm.remove(basic);
+        assertTrue(JPAFacadeHelper.toBroker(pm).isDeleted(basic));
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testGetObjectId() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BasicSubclassInstance basic = new BasicSubclassInstance();
+        basic.setStringField("foo");
+        startTx(pm);
+        pm.persist(basic);
+        endTx(pm);
+        Object oid = null;
+        try {
+            assertNotNull(oid = pm.getObjectId(basic));
+        } catch (Exception e) {
+            fail("object id lookup failed: " + e.getMessage());
+        }
+
+        startTx(pm);
+        pm.remove(basic);
+        // before committing, id should exist still
+        assertNotNull(pm.getObjectId(basic));
+
+        endTx(pm);
+        assertNull(pm.getObjectId(basic));
+        endEm(pm);
+
+        // looking up the instance by id in a new PM should fail.
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        try {
+            pm.find(BasicSubclassInstance.class, oid);
+            fail("instance should have been deleted!");
+        } catch (Exception e) {
+            // expected
+        }
+        endEm(pm);
+    }
+
+    public void testChangesOutsideTxWithNTW() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BasicSubclassInstance basic = new BasicSubclassInstance();
+        basic.setStringField("foo");
+        startTx(pm);
+        pm.persist(basic);
+        endTx(pm);
+        Object oid = pm.getObjectId(basic);
+        endEm(pm);
+
+        pm = getNTWPM();
+        basic =
+            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
+        basic.setStringField("hello");
+        startTx(pm);
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        basic =
+            (BasicSubclassInstance) pm.find(BasicSubclassInstance.class, oid);
+        try {
+            assertEquals("hello", basic.getStringField());
+        } catch (AssertionFailedError afe) {
+            bug(1205, afe, "JDO 2-style NTW not supported.");
+        }
+    }
+
+    public void testChangesOutsideTxWithoutNTW() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BasicSubclassInstance basic = new BasicSubclassInstance();
+        basic.setStringField("foo");
+        startTx(pm);
+        pm.persist(basic);
+        endTx(pm);
+
+        try {
+            basic.setStringField("hello");
+            fail("should not be able to write outside tx without NTW");
+        } catch (RuntimeException re) {
+            // expected case
+            Object failed = ((ExceptionInfo) re).getFailedObject();
+            assertNotNull(failed);
+            assertSame(basic, failed);
+        } finally {
+            endEm(pm);
+        }
+    }
+
+    private OpenJPAEntityManager getNTWPM() {
+        EntityManagerFactory pmf = getEmf();
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) pmf.createEntityManager();
+        em.setNontransactionalWrite(true);
+        return em;
+    }
+
+    /*
+     public void testCallbacks ()
+     {
+         fail ("##### unimplemented test");
+     }
+
+
+     public void testTransactionListeners ()
+     {
+         fail ("#####");
+     }
+
+
+     public void testRemoteCommitListeners ()
+     {
+         fail ("#####");
+     }
+
+
+     public void testCaching ()
+     {
+         fail ("#####");
+     }
+
+
+     public void testRemote ()
+     {
+         fail ("#####");
+     }
+     */
+
+    public void testVersionIncrementAndIdField() {
+        // make sure that version increments happen correctly, and are
+        // visible in the user-visible instance.
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        BasicSubclassInstance basic = new BasicSubclassInstance();
+        basic.setStringField("foo");
+        startTx(pm);
+        pm.persist(basic);
+        endTx(pm);
+
+        assertEquals(1, basic.getVersion());
+        long id = basic.getId();
+        assertNotEquals(0, id);
+
+        startTx(pm);
+        basic.setStringField("bar");
+        endTx(pm);
+        assertEquals(2, basic.getVersion());
+        endEm(pm);
+    }
+
+    /*
+     public void testAutoAssignedFields ()
+     {
+         // make sure that auto-assigned field values get into the user-visible
+         // instance.
+         fail ("#####");
+     }
+     */
+
+    public void testJPABasics() {
+        EntityManager em = currentEntityManager();
+        BasicSubclassInstance basic = (BasicSubclassInstance) createInstance(
+            em, BasicSubclassInstance.class);
+        basic.setStringField("hello");
+        startTx(em);
+        em.persist(basic);
+        endTx(em);
+        endEm(em);
+    }
+
+    /*
+     public void testDetachmentAndAttachemnt ()
+     {
+         fail ("#####");
+     }
+
+
+     public void testEmbeddedNonEnhanced ()
+     {
+         fail ("#####");
+     }
+
+
+     public void testTransactionalNonEnhanced ()
+     {
+         fail ("#####");
+     }
+
+
+     public void testBulkTransactionalNonEnhanced ()
+     {
+         fail ("#####");
+     }
+     */
+
+    public void testSingleValuedInverseManagement() {
+        Map map = new HashMap();
+        map.put("openjpa.InverseManager", "true");
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)
+            getEmf(map).createEntityManager();
+        ManagedInverseTestInstance managed = (ManagedInverseTestInstance)
+            newInstance(pm, ManagedInverseTestInstance.class);
+        ManagedInverseTestInstance2 managed2 = (ManagedInverseTestInstance2)
+            newInstance(pm, ManagedInverseTestInstance2.class);
+        managed.setStringField("managed");
+        managed2.setStringField("managed2");
+        managed.setManaged2(managed2);
+
+        startTx(pm);
+        pm.persist(managed);
+        endTx(pm);
+
+        assertSame(managed, managed2.getManaged());
+    }
+
+    public void testBackingFieldConfigurationWithTwoFactories() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        // this causes DerivedEntity.class to get loaded into PCRegistry
+        newInstance(pm, DerivedEntity.class);
+        Map map = new HashMap();
+        map.put("openjpa.Log", "DiagnosticContext=subclass-two-factories-test");
+        pm = (OpenJPAEntityManager) getEmf(map).createEntityManager();
+        newInstance(pm, DerivedEntity.class);
+
+        // this second new-instance creation will result in the metadata
+        // defaults being loaded from the PCRegistry instead of via reflection.
+        // Make sure that things still work as expected from the
+        // registry-parsing code.
+        ClassMetaData meta = getConfiguration()
+            .getMetaDataRepositoryInstance().
+            getMetaData(DerivedEntity.class, null, false);
+        assertTrue("meta's access should be ACCESS_PROPERTY",
+            meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY);
+        FieldMetaData[] fmds = meta.getFields();
+        for (int i = 0; i < fmds.length; i++) {
+            assertEquals(Method.class, fmds[i].getBackingMember().getClass());
+
+            // make sure that the fields are defined in the right part of the
+            // hierarchy
+            if (fmds[i].getName().equals("intField") ||
+                fmds[i].getName().equals("oneToOne")) {
+                assertEquals(DerivedEntity.class,
+                    fmds[i].getDefiningMetaData().getDescribedType());
+            } else {
+                assertEquals(BaseEntity.class,
+                    fmds[i].getDefiningMetaData().getDescribedType());
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BackingFieldNameMismatchInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BackingFieldNameMismatchInstance.java
index aed9682..e76c1d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BackingFieldNameMismatchInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BackingFieldNameMismatchInstance.java
@@ -1,68 +1,68 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-/**
- * Backing field names do not match up with the property accessor names, and
- * we use package-protected method access (which is not supported by JPA),
- *
- * @see TestPCSubclasser
- */
-@Entity
-@Table(name = "BACKINGMISMATCH")
-public class BackingFieldNameMismatchInstance
-    implements SubclassTestInstance {
-
-    protected long _id; // protected since we don't have a setter
-    private int _version;
-    private String _s;
-
-    @Id
-    @GeneratedValue
-    public long getId() {
-        return _id;
-    }
-
-    public void setId(long id) {
-        _id = id;
-    }
-
-    @Version
-    public int getVersion() {
-        return _version;
-    }
-
-    public void setVersion(int v) {
-        _version = v;
-    }
-
-    public String getStringField() {
-        return _s;
-    }
-
-    public void setStringField(String s) {
-        _s = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+/**
+ * Backing field names do not match up with the property accessor names, and
+ * we use package-protected method access (which is not supported by JPA),
+ *
+ * @see TestPCSubclasser
+ */
+@Entity
+@Table(name = "BACKINGMISMATCH")
+public class BackingFieldNameMismatchInstance
+    implements SubclassTestInstance {
+
+    protected long _id; // protected since we don't have a setter
+    private int _version;
+    private String _s;
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return _id;
+    }
+
+    public void setId(long id) {
+        _id = id;
+    }
+
+    @Version
+    public int getVersion() {
+        return _version;
+    }
+
+    public void setVersion(int v) {
+        _version = v;
+    }
+
+    public String getStringField() {
+        return _s;
+    }
+
+    public void setStringField(String s) {
+        _s = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BaseEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BaseEntity.java
index 10f475a..00ea60f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BaseEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BaseEntity.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Version;
-
-/**
- * @see TestPCSubclasser
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class BaseEntity
-    implements SubclassTestInstance {
-
-    private long _id;
-    private int _version;
-    private String _s;
-    private short _short;
-
-    @Id
-    @GeneratedValue
-    public long getId() {
-        return _id;
-    }
-
-    public void setId(long id) {
-        _id = id;
-    }
-
-    @Version
-    public int getVersion() {
-        return _version;
-    }
-
-    public void setVersion(int version) {
-        _version = version;
-    }
-
-    public void setStringField(String s) {
-        _s = s;
-    }
-
-    public String getStringField() {
-        return _s;
-    }
-
-    public short getShortField() {
-        return _short;
-    }
-
-    public void setShortField(short aShort) {
-        _short = aShort;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Version;
+
+/**
+ * @see TestPCSubclasser
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class BaseEntity
+    implements SubclassTestInstance {
+
+    private long _id;
+    private int _version;
+    private String _s;
+    private short _short;
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return _id;
+    }
+
+    public void setId(long id) {
+        _id = id;
+    }
+
+    @Version
+    public int getVersion() {
+        return _version;
+    }
+
+    public void setVersion(int version) {
+        _version = version;
+    }
+
+    public void setStringField(String s) {
+        _s = s;
+    }
+
+    public String getStringField() {
+        return _s;
+    }
+
+    public short getShortField() {
+        return _short;
+    }
+
+    public void setShortField(short aShort) {
+        _short = aShort;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BasicSubclassInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BasicSubclassInstance.java
index 701db45..a8d96fc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BasicSubclassInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/BasicSubclassInstance.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-/**
- * @see TestPCSubclasser
- */
-@Entity
-public class BasicSubclassInstance
-    implements SubclassTestInstance {
-
-    private long id;
-    private int version;
-    private String stringField;
-
-    @Id
-    @GeneratedValue
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    @Version
-    public int getVersion() {
-        return version;
-    }
-
-    public void setVersion(int v) {
-        version = v;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String str) {
-        stringField = str;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * @see TestPCSubclasser
+ */
+@Entity
+public class BasicSubclassInstance
+    implements SubclassTestInstance {
+
+    private long id;
+    private int version;
+    private String stringField;
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @Version
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int v) {
+        version = v;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String str) {
+        stringField = str;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DerivedEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DerivedEntity.java
index f4c45b7..624b393 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DerivedEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DerivedEntity.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToOne;
-
-/**
- * @see TestPCSubclasser
- */
-@Entity
-public class DerivedEntity
-    extends BaseEntity {
-
-    private int _i;
-    private BasicSubclassInstance _basic;
-
-    public int getIntField() {
-        return _i;
-    }
-
-    public void setIntField(int i) {
-        _i = i;
-    }
-
-    @OneToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
-    public BasicSubclassInstance getOneToOne() {
-        return _basic;
-    }
-
-    public void setOneToOne(BasicSubclassInstance basic) {
-        // ##### this should be throwing an exception, but clashes with
-        // delete behavior.
-        //#####if (basic == null)
-        //#####throw new NullPointerException ();
-        _basic = basic;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToOne;
+
+/**
+ * @see TestPCSubclasser
+ */
+@Entity
+public class DerivedEntity
+    extends BaseEntity {
+
+    private int _i;
+    private BasicSubclassInstance _basic;
+
+    public int getIntField() {
+        return _i;
+    }
+
+    public void setIntField(int i) {
+        _i = i;
+    }
+
+    @OneToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
+    public BasicSubclassInstance getOneToOne() {
+        return _basic;
+    }
+
+    public void setOneToOne(BasicSubclassInstance basic) {
+        // ##### this should be throwing an exception, but clashes with
+        // delete behavior.
+        //#####if (basic == null)
+        //#####throw new NullPointerException ();
+        _basic = basic;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachablePC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachablePC.java
index b9930fc..057dc92 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachablePC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachablePC.java
@@ -1,30 +1,30 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-
-@Entity
-public class DetachablePC
-    implements Serializable {
-
-    private long id;
-    private String val;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+
+@Entity
+public class DetachablePC
+    implements Serializable {
+
+    private long id;
+    private String val;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachableVersionedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachableVersionedPC.java
index 9c8bc3d..3e86379 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachableVersionedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/DetachableVersionedPC.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-
-@Entity
-public class DetachableVersionedPC
-    implements Serializable {
-
-    private long id;
-    private String val;
-    private int version;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+
+@Entity
+public class DetachableVersionedPC
+    implements Serializable {
+
+    private long id;
+    private String val;
+    private int version;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity1.java
index da1f336..e4bd48e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity1.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name = "entity_1")
-@Inheritance(strategy = InheritanceType.JOINED)
-@SqlResultSetMapping(name = "NativeTestResult",
-    entities = @EntityResult(entityClass = Entity1.class))
-public class Entity1 implements Serializable {
-
-    private static final long serialVersionUID = 2882935803066041165L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
-    protected Entity2 entity2Field;
-
-    @Version
-    protected int versionField;
-
-    public Entity1() {
-    }
-
-    public Entity1(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setEntity2Field(Entity2 val) {
-        entity2Field = val;
-    }
-
-    public Entity2 getEntity2Field() {
-        return entity2Field;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "entity_1")
+@Inheritance(strategy = InheritanceType.JOINED)
+@SqlResultSetMapping(name = "NativeTestResult",
+    entities = @EntityResult(entityClass = Entity1.class))
+public class Entity1 implements Serializable {
+
+    private static final long serialVersionUID = 2882935803066041165L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
+    protected Entity2 entity2Field;
+
+    @Version
+    protected int versionField;
+
+    public Entity1() {
+    }
+
+    public Entity1(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setEntity2Field(Entity2 val) {
+        entity2Field = val;
+    }
+
+    public Entity2 getEntity2Field() {
+        return entity2Field;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity2.java
index 928cb24..b450371 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/Entity2.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-//@Entity(name="entity2ExplicitName")
-
-//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-/**
- * FIX-ME
- * <p/>
- * It should complain if i uncomment the above strategies...but it does
- */
-@Entity
-public class Entity2 implements Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 4723739219953167343L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    public Entity2() {
-    }
-
-    public Entity2(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+//@Entity(name="entity2ExplicitName")
+
+//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+/**
+ * FIX-ME
+ * <p/>
+ * It should complain if i uncomment the above strategies...but it does
+ */
+@Entity
+public class Entity2 implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4723739219953167343L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    public Entity2() {
+    }
+
+    public Entity2(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance.java
index 279d7e2..4cda6ca 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name = "MGDINVERSE")
-public class ManagedInverseTestInstance {
-
-    private long id;
-    private int version;
-    private String stringField;
-    private ManagedInverseTestInstance2 managed2;
-
-    @Id
-    @GeneratedValue
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    @OneToOne(cascade = CascadeType.PERSIST)
-    public ManagedInverseTestInstance2 getManaged2() {
-        return managed2;
-    }
-
-    public void setManaged2(ManagedInverseTestInstance2 managed2) {
-        this.managed2 = managed2;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    @Version
-    public int getVersion() {
-        return version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "MGDINVERSE")
+public class ManagedInverseTestInstance {
+
+    private long id;
+    private int version;
+    private String stringField;
+    private ManagedInverseTestInstance2 managed2;
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @OneToOne(cascade = CascadeType.PERSIST)
+    public ManagedInverseTestInstance2 getManaged2() {
+        return managed2;
+    }
+
+    public void setManaged2(ManagedInverseTestInstance2 managed2) {
+        this.managed2 = managed2;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    @Version
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance2.java
index ccecabf..2dacbe2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/ManagedInverseTestInstance2.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name = "MGDINVERSE_2")
-public class ManagedInverseTestInstance2 {
-
-    private long id;
-    private int version;
-    private String stringField;
-    private ManagedInverseTestInstance managed;
-
-    @Id
-    @GeneratedValue
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    @OneToOne(cascade = CascadeType.PERSIST, mappedBy = "managed2")
-    public ManagedInverseTestInstance getManaged() {
-        return managed;
-    }
-
-    public void setManaged(ManagedInverseTestInstance managed) {
-        this.managed = managed;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    @Version
-    public int getVersion() {
-        return version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "MGDINVERSE_2")
+public class ManagedInverseTestInstance2 {
+
+    private long id;
+    private int version;
+    private String stringField;
+    private ManagedInverseTestInstance managed;
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @OneToOne(cascade = CascadeType.PERSIST, mappedBy = "managed2")
+    public ManagedInverseTestInstance getManaged() {
+        return managed;
+    }
+
+    public void setManaged(ManagedInverseTestInstance managed) {
+        this.managed = managed;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    @Version
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No2NoArgs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No2NoArgs.java
index 0b2be8e..c2423e1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No2NoArgs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No2NoArgs.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class No2NoArgs {
-
-    private String name;
-
-    public No2NoArgs(String n) {
-        name = n;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class No2NoArgs {
+
+    private String name;
+
+    public No2NoArgs(String n) {
+        name = n;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No3NoArgs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No3NoArgs.java
index be6d6f4..586a976 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No3NoArgs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/No3NoArgs.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public final class No3NoArgs {
-
-    private String name;
-
-    public No3NoArgs(String n) {
-        name = n;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public final class No3NoArgs {
+
+    private String name;
+
+    public No3NoArgs(String n) {
+        name = n;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoClone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoClone.java
index 55fda0a..3073a23 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoClone.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoClone.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class NoClone implements Cloneable {
-
-    private String string;
-
-    public NoClone(String str) {
-        this.string = str;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public NoClone safeClone() {
-        try {
-            return (NoClone) clone();
-        } catch (CloneNotSupportedException cnfe) {
-            return null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class NoClone implements Cloneable {
+
+    private String string;
+
+    public NoClone(String str) {
+        this.string = str;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public NoClone safeClone() {
+        try {
+            return (NoClone) clone();
+        } catch (CloneNotSupportedException cnfe) {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoNoArgs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoNoArgs.java
index ca67978..21abd09 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoNoArgs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NoNoArgs.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class NoNoArgs {
-
-    private String name;
-
-    public NoNoArgs(String n) {
-        name = n;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class NoNoArgs {
+
+    private String name;
+
+    public NoNoArgs(String n) {
+        name = n;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NonPCClone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NonPCClone.java
index 3fc4fe2..43abc91 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NonPCClone.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/NonPCClone.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class NonPCClone {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class NonPCClone {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/PCClone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/PCClone.java
index a79253a..8f64518 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/PCClone.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/PCClone.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class PCClone implements Cloneable {
-
-    private String string;
-
-    public PCClone(String str) {
-        this.string = str;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public Object clone() {
-        try {
-            return (PCClone) super.clone();
-        } catch (CloneNotSupportedException cnfe) {
-            return null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class PCClone implements Cloneable {
+
+    private String string;
+
+    public PCClone(String str) {
+        this.string = str;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public Object clone() {
+        try {
+            return (PCClone) super.clone();
+        } catch (CloneNotSupportedException cnfe) {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassClone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassClone.java
index df027d8..3711aa5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassClone.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassClone.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class SubclassClone extends NonPCClone implements Cloneable {
-
-    private String string;
-
-    public SubclassClone(String str) {
-        this.string = str;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public SubclassClone safeClone() {
-        try {
-            return (SubclassClone) super.clone();
-        } catch (CloneNotSupportedException cnfe) {
-            return null;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class SubclassClone extends NonPCClone implements Cloneable {
+
+    private String string;
+
+    public SubclassClone(String str) {
+        this.string = str;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public SubclassClone safeClone() {
+        try {
+            return (SubclassClone) super.clone();
+        } catch (CloneNotSupportedException cnfe) {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassTestInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassTestInstance.java
index 0d9a9f7..0d63101 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassTestInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/SubclassTestInstance.java
@@ -1,30 +1,30 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.enhance.common.apps;
-
-/**
- * The various subclass test classes that we use all implement this interface,
- * to allow reuse in some of the unit tests.
- */
-public interface SubclassTestInstance {
-
-    public void setStringField(String s);
-
-    public String getStringField();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.enhance.common.apps;
+
+/**
+ * The various subclass test classes that we use all implement this interface,
+ * to allow reuse in some of the unit tests.
+ */
+public interface SubclassTestInstance {
+
+    public void setStringField(String s);
+
+    public String getStringField();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java
index ad78ee8..167b64e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java
@@ -1,1142 +1,1142 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.entityoperation;
-
-
-import org.apache.openjpa.persistence.entityoperation.common.apps.CascadesEntity;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * <p>Test EJB persistence cascade options.</p>
- *
- * @author Abe White
- */
-public class TestCascades extends AbstractTestCase {
-
-    public TestCascades(String name) {
-        super(name, "entityopcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(CascadesEntity.class);
-    }
-
-    public void testNoCascadePersist ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setNone (rel);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         assertTrue (em.isPersistent (ent));
-         assertFalse (em.isPersistent (rel));
-         rollbackTx(em);
-         endEm(em);
-     }
-
-
-     public void testCascadePersistIsImmediate ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel1 = new CascadesEntity ();
-         CascadesEntity rel2 = new CascadesEntity ();
-         ent.setAll (rel1);
-         ent.getAllCollection ().add (rel2);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         assertTrue (em.isPersistent (ent));
-         assertTrue (em.isPersistent (rel1));
-         assertTrue (em.isPersistent (rel2));
-         rollbackTx(em);
-         endEm(em);
-     }
-
-
-     public void testNoCascadePersistFlushWithDeletedCausesException ()
-     {
-         CascadesEntity rel = new CascadesEntity ();
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (rel);
-         endTx(em);
-         long id = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         rel = em.find (CascadesEntity.class, id);
-         assertNotNull (rel);
-         CascadesEntity ent = new CascadesEntity ();
-         ent.setNone (rel);
-         startTx(em);
-         em.remove (rel);
-         em.persist (ent);
-         try
-         {
-             endTx(em);
-             fail ("Allowed flush with deleted object in non-cascade-persist "
-                 + "relation field");
-         }
-         catch (RuntimeException re)
-         {
-         }
-         catch (Exception e)
-         {}
-
-         assertTrue (!em.getTransaction().isActive ());
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         rel = em.find (CascadesEntity.class, id);
-         assertNotNull (rel);
-         ent = new CascadesEntity ();
-         ent.getNoneCollection ().add (rel);
-         startTx(em);
-         em.remove (rel);
-         em.persist (ent);
-         try
-         {
-             endTx(em);
-             fail ("Allowed flush with deleted object in non-cascade-persist "
-                 + "relation field");
-         }
-         catch (RuntimeException re)
-         {
-         }
-         catch (Exception re)
-         {
-         }
-         assertTrue (!em.getTransaction().isActive ());
-
-         endEm(em);
-     }
-
-
-     public void testCascadePersistFlushWithDeleted ()
-     {
-         CascadesEntity rel = new CascadesEntity ();
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (rel);
-         endTx(em);
-         long id = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         rel = em.find (CascadesEntity.class, id);
-         assertNotNull (rel);
-         CascadesEntity ent = new CascadesEntity ();
-         ent.setAll (rel);
-         startTx(em);
-         em.remove (rel);
-         em.persist (ent);
-         endTx(em);
-         assertTrue (!em.getTransaction().isActive ());
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         rel = em.find (CascadesEntity.class, id);
-         assertNotNull (rel);
-         ent = new CascadesEntity ();
-         ent.getAllCollection ().add (rel);
-         startTx(em);
-         em.remove (rel);
-         em.persist (ent);
-         endTx(em);
-         assertTrue (!em.getTransaction().isActive ());
-
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         rel = em.find (CascadesEntity.class, id);
-         assertNotNull (rel);
-         endEm(em);
-     }
-
-
-     public void testNoCascadePersistFlushWithTransientCausesException ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setNone (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         try
-         {
-             endTx(em);
-             fail ("Allowed flush with transient object in non-cascade-persist "
-                 + "relation field");
-         }
-         catch (RuntimeException re)
-         {
-         }
-         catch (Exception re)
-         {
-         }
-
-
-         assertTrue (!em.getTransaction().isActive ());
-         endEm(em);
-
-         ent = new CascadesEntity ();
-         rel = new CascadesEntity ();
-         ent.getNoneCollection ().add (rel);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         try
-         {
-             endTx(em);
-             fail ("Allowed flush with transient object in non-cascade-persist "
-                 + "relation field");
-         }
-         catch (RuntimeException re)
-         {
-         }
-         catch (Exception re)
-         {
-         }
-         assertTrue (!em.getTransaction().isActive ());
-         endEm(em);
-     }
-
-
-     public void testNoCascadePersistFlushWithPersistent ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setNone (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         assertFalse(em.isPersistent (rel));
-         em.persist (rel);
-         endTx(em);
-         long id = rel.getId ();
-         endEm(em);
-
-         ent = new CascadesEntity ();
-         rel = new CascadesEntity ();
-         ent.getNoneCollection ().add (rel);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNotNull (em.find (CascadesEntity.class, id));
-         startTx(em);
-         em.persist (ent);
-         assertFalse (em.isPersistent (rel));
-         em.persist (rel);
-         endTx(em);
-         id = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNotNull (em.find (CascadesEntity.class, id));
-         endEm(em);
-     }
-
-
-     public void testCascadePersistFlushWithTransient ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         ent.setAll (rel);
-         assertFalse (em.isPersistent (rel));
-         endTx(em);
-         long id = rel.getId ();
-         endEm(em);
-
-         ent = new CascadesEntity ();
-         rel = new CascadesEntity ();
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNotNull (em.find (CascadesEntity.class, id));
-         startTx(em);
-         em.persist (ent);
-         ent.getAllCollection ().add (rel);
-         assertFalse (em.isPersistent (rel));
-         endTx(em);
-         id = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNotNull (em.find (CascadesEntity.class, id));
-         endEm(em);
-     }
-
-
-     public void testCascadePersistFlushWithPersistent ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setAll (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         assertTrue (em.isPersistent (rel));
-         endTx(em);
-         long id = rel.getId ();
-         endEm(em);
-
-         ent = new CascadesEntity ();
-         rel = new CascadesEntity ();
-         ent.getAllCollection ().add (rel);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNotNull (em.find (CascadesEntity.class, id));
-         startTx(em);
-         em.persist (ent);
-         assertTrue (em.isPersistent (rel));
-         endTx(em);
-         id = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNotNull (em.find (CascadesEntity.class, id));
-         endEm(em);
-     }
-
-
-     public void testCascadeCircleThroughPersistent ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         endTx(em);
-         long id = ent.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         CascadesEntity top = new CascadesEntity ();
-         top.setAll (ent);
-         CascadesEntity rel = new CascadesEntity ();
-
-         startTx(em);
-         ent.setAll (rel);
-         rel.setAll (top);
-         em.persist (top);
-         assertTrue (em.isPersistent (top));
-         assertTrue (em.isPersistent (ent));
-         assertTrue (em.isPersistent (rel));
-         rollbackTx(em);
-         endEm(em);
-     }
-
-
-     public void testNoCascadeDelete ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         CascadesEntity depend = new CascadesEntity ();
-         ent.setNone (rel);
-         ent.setDependent (depend);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, rel, depend);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         long dependId = depend.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         rel = ent.getNone ();
-         depend = ent.getDependent ();
-         assertEquals (relId, rel.getId ());
-         assertEquals (dependId, depend.getId ());
-         assertEquals (1, ent.getNoneCollection ().size ());
-         assertEquals (relId, ent.getNoneCollection ().iterator ().next ().getId ());
-
-         startTx(em);
-         em.remove (ent);
-         assertTrue (em.isRemoved (ent));
-         assertFalse (em.isRemoved (rel));
-         assertFalse (em.isRemoved (depend));
-         endTx(em);
-         assertFalse (em.isPersistent (ent));
-         assertTrue (em.isPersistent (rel));
-         assertFalse (em.isPersistent (depend));
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNull (em.find (CascadesEntity.class, id));
-         assertNotNull (em.find (CascadesEntity.class, relId));
-         assertNull (em.find (CascadesEntity.class, dependId));
-         endEm(em);
-     }
-
-
-     public void testDeepCascadeDelete ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel1 = new CascadesEntity ();
-         CascadesEntity rel2 = new CascadesEntity ();
-         CascadesEntity depend = new CascadesEntity ();
-         CascadesEntity deep1 = new CascadesEntity ();
-         CascadesEntity deep2 = new CascadesEntity ();
-         CascadesEntity deep3 = new CascadesEntity ();
-         ent.setAll (rel1);
-         rel1.setAll (deep1);
-         ent.getAllCollection ().add (rel2);
-         rel2.getAllCollection ().add (deep2);
-         ent.setDependent (depend);
-         depend.setAll (deep3);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, depend);
-         endTx(em);
-         long id = ent.getId ();
-         long rel1Id = rel1.getId ();
-         long rel2Id = rel2.getId ();
-         long deep1Id = deep1.getId ();
-         long deep2Id = deep2.getId ();
-         long deep3Id = deep3.getId ();
-         long dependId = depend.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         rel1 = ent.getAll ();
-         assertEquals (rel1Id, rel1.getId ());
-         deep1 = rel1.getAll ();
-         assertEquals (deep1Id, deep1.getId ());
-         assertEquals (1, ent.getAllCollection ().size ());
-         rel2 = ent.getAllCollection ().iterator ().next ();
-         assertEquals (rel2Id, rel2.getId ());
-         assertEquals (1, rel2.getAllCollection ().size ());
-         deep2 = rel2.getAllCollection ().iterator ().next ();
-         assertEquals (deep2Id, deep2.getId ());
-         depend = ent.getDependent ();
-         assertEquals (dependId, depend.getId ());
-         deep3 = depend.getAll ();
-         assertEquals (deep3Id, deep3.getId ());
-
-         startTx(em);
-         em.remove (ent);
-         assertTrue (em.isRemoved (ent));
-         assertTrue (em.isRemoved (rel1));
-         assertTrue (em.isRemoved (rel2));
-         assertTrue (em.isRemoved (deep1));
-         assertTrue (em.isRemoved (deep2));
-         assertFalse (em.isRemoved (depend));
-         assertFalse (em.isRemoved (deep3));
-         endTx(em);
-         assertFalse (em.isPersistent (ent));
-         assertFalse (em.isPersistent (rel1));
-         assertFalse (em.isPersistent (rel2));
-         assertFalse (em.isPersistent (deep1));
-         assertFalse (em.isPersistent (depend));
-         assertFalse (em.isPersistent (deep2));
-         assertFalse(em.isPersistent (deep3));
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNull (em.find (CascadesEntity.class, id));
-         assertNull (em.find (CascadesEntity.class, rel1Id));
-         assertNull (em.find (CascadesEntity.class, rel2Id));
-         assertNull (em.find (CascadesEntity.class, deep1Id));
-         assertNull (em.find (CascadesEntity.class, deep2Id));
-         assertNull (em.find (CascadesEntity.class, deep3Id));
-         assertNull (em.find (CascadesEntity.class, dependId));
-         endEm(em);
-     }
-
-
-     public void testCircularCascadeDelete ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setAll (rel);
-         ent.getAllCollection ().add (rel);
-         rel.setAll (ent);
-         rel.getAllCollection ().add (ent);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         rel = ent.getAll ();
-         assertEquals (relId, rel.getId ());
-         assertEquals (rel, ent.getAllCollection ().iterator ().next ());
-         assertEquals (ent, rel.getAllCollection ().iterator ().next ());
-
-         startTx(em);
-         em.remove (ent);
-         assertTrue (em.isRemoved (ent));
-         assertTrue (em.isRemoved (rel));
-         endTx(em);
-         assertFalse (em.isPersistent (ent));
-         assertFalse (em.isPersistent (rel));
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNull (em.find (CascadesEntity.class, id));
-         assertNull (em.find (CascadesEntity.class, relId));
-         endEm(em);
-     }
-
-
-     public void testNoCascadeRefresh ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setNone (rel);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, rel);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         rel = ent.getNone ();
-         assertEquals (relId, rel.getId ());
-
-         startTx(em);
-         assertNull (ent.getDependent ());
-         assertNull (rel.getDependent ());
-         ent.setDependent (new CascadesEntity ());
-         rel.setDependent (new CascadesEntity ());
-         em.persist (ent.getDependent ());
-         em.persist (rel.getDependent ());
-         em.refresh (ent);
-         assertNull (ent.getDependent ());
-         assertNotNull (rel.getDependent ());
-         endTx(em);
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         assertNull (em.find (CascadesEntity.class, id).getDependent ());
-         assertNotNull (em.find (CascadesEntity.class, relId).getDependent ());
-         endEm(em);
-     }
-
-
-     public void testCircularCascadeRefresh ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setAll (rel);
-         rel.setAll (ent);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         rel = ent.getAll ();
-         assertEquals (relId, rel.getId ());
-         assertEquals (ent, rel.getAll ());
-
-         startTx(em);
-         assertNull (ent.getDependent ());
-         assertNull (rel.getDependent ());
-         ent.setDependent (new CascadesEntity ());
-         rel.setDependent (new CascadesEntity ());
-         em.persist (ent.getDependent ());
-         em.persist (rel.getDependent ());
-         em.refresh (ent);
-         assertNull (ent.getDependent ());
-         assertNull (rel.getDependent ());
-         endTx(em);
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         assertEquals (relId, ent.getAll ().getId ());
-         assertNull (ent.getDependent ());
-         assertNull (em.find (CascadesEntity.class, relId).getDependent ());
-         endEm(em);
-
-         ent = new CascadesEntity ();
-         rel = new CascadesEntity ();
-         CascadesEntity deep = new CascadesEntity ();
-         ent.getAllCollection ().add (rel);
-         rel.getAllCollection ().add (ent);
-         rel.getAllCollection ().add (deep);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         endTx(em);
-         id = ent.getId ();
-         relId = rel.getId ();
-         long deepId = deep.getId ();
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         rel = ent.getAllCollection ().iterator ().next ();
-         assertEquals (relId, rel.getId ());
-         assertEquals (2, rel.getAllCollection ().size ());
-         deep = null;
-         for (CascadesEntity elem : rel.getAllCollection ())
-             if (elem != ent)
-                 deep = elem;
-         assertEquals (deepId, deep.getId ());
-
-         startTx(em);
-         assertNull (ent.getDependent ());
-         assertNull (rel.getDependent ());
-         assertNull (deep.getDependent ());
-         ent.setDependent (new CascadesEntity ());
-         ent.getAllCollection ().add (new CascadesEntity ());
-         rel.setDependent (new CascadesEntity ());
-         deep.setDependent (new CascadesEntity ());
-         em.persistAll (ent.getAllCollection ());
-         em.persist (ent.getDependent ());
-         em.persist (rel.getDependent ());
-         em.persist (deep.getDependent ());
-         em.refresh (ent);
-         assertNull (ent.getDependent ());
-         assertEquals (1, ent.getAllCollection ().size ());
-         assertTrue (ent.getAllCollection ().contains (rel));
-         assertNull (rel.getDependent ());
-         assertEquals (2, rel.getAllCollection ().size ());
-         assertTrue (rel.getAllCollection ().contains (ent));
-         assertTrue (rel.getAllCollection ().contains (deep));
-         assertNull (deep.getDependent ());
-         endTx(em);
-         endEm(em);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         ent = em.find (CascadesEntity.class, id);
-         assertEquals (1, ent.getAllCollection ().size ());
-         assertEquals (relId, ent.getAllCollection ().iterator ().next ().
-             getId ());
-         assertNull (ent.getDependent ());
-         assertNull (em.find (CascadesEntity.class, relId).getDependent ());
-         assertNull (em.find (CascadesEntity.class, deepId).getDependent ());
-         endEm(em);
-     }
-
-
-     public void testNoCascadeAttachClean ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setName ("ent");
-         rel.setName ("rel");
-         ent.setNone (rel);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, rel);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         endEm(em);
-
-         assertEquals ("ent", ent.getName ());
-         assertEquals ("rel", rel.getName ());
-         assertEquals (rel, ent.getNone ());
-         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         ent = em.merge (ent);
-         assertTrue (!em.isDirty (ent));
-         assertEquals ("ent", ent.getName ());
-         assertEquals (id, ent.getId ());
-         assertTrue (ent.getNone () != rel);
-         rel = ent.getNone ();
-         assertNotNull (rel);
-         assertTrue (!em.isDirty (rel));
-         assertEquals (1, ent.getNoneCollection ().size ());
-         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
-
-         assertTrue (em.isPersistent (rel));
-         assertEquals (relId, rel.getId ());
-         assertEquals ("rel", rel.getName ());
-         endTx(em);
-         endEm(em);
-     }
-
-
-     public void testCascadeAttachClean ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel1 = new CascadesEntity ();
-         CascadesEntity rel2 = new CascadesEntity ();
-         ent.setName ("ent");
-         rel1.setName ("rel1");
-         ent.setAll (rel1);
-         rel2.setName ("rel2");
-         ent.getAllCollection ().add (rel2);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         endTx(em);
-         long id = ent.getId ();
-         long rel1Id = rel1.getId ();
-         long rel2Id = rel2.getId ();
-         endEm(em);
-
-         assertEquals ("ent", ent.getName ());
-         assertEquals ("rel1", rel1.getName ());
-         assertEquals ("rel2", rel2.getName ());
-         assertEquals (rel1, ent.getAll ());
-         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         ent = em.merge (ent);
-         assertTrue (!em.isDirty (ent));
-         assertEquals ("ent", ent.getName ());
-         assertEquals (id, ent.getId ());
-         assertTrue (rel1 != ent.getAll ());
-         rel1 = ent.getAll ();
-         assertTrue (!em.isDirty (rel1));
-         assertEquals (1, ent.getAllCollection ().size ());
-         rel2 = ent.getAllCollection ().iterator ().next ();
-         assertTrue (!em.isDirty (rel2));
-
-         assertTrue (em.isPersistent (rel1));
-         assertEquals (rel1Id, rel1.getId ());
-         assertEquals ("rel1", rel1.getName ());
-         assertTrue (em.isPersistent (rel2));
-         assertEquals (rel2Id, rel2.getId ());
-         assertEquals ("rel2", rel2.getName ());
-         endTx(em);
-         endEm(em);
-     }
-
-
-     public void testNoCascadeAttachDirtyFields ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         ent.setName ("ent");
-         rel.setName ("rel");
-         ent.setNone (rel);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, rel);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         endEm(em);
-
-         assertEquals ("ent", ent.getName ());
-         assertEquals ("rel", rel.getName ());
-         assertEquals (rel, ent.getNone ());
-         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
-         rel.setName ("foo");
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         ent = em.merge (ent);
-         assertTrue (!em.isDirty (ent));
-         assertEquals ("ent", ent.getName ());
-         assertEquals (id, ent.getId ());
-         assertTrue (ent.getNone () != rel);
-         rel = ent.getNone ();
-         assertNotNull (rel);
-         assertTrue (!em.isDirty (rel));
-         assertEquals (relId, rel.getId ());
-         assertEquals (1, ent.getNoneCollection ().size ());
-         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
-
-         assertTrue (em.isPersistent (rel));
-         assertEquals (relId, rel.getId ());
-         assertEquals ("rel", rel.getName ());
-         endTx(em);
-         endEm(em);
-     }
-
-
-     public void testCascadeAttachDirtyFields ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel1 = new CascadesEntity ();
-         CascadesEntity rel2 = new CascadesEntity ();
-         ent.setName ("ent");
-         rel1.setName ("rel1");
-         ent.setAll (rel1);
-         rel2.setName ("rel2");
-         ent.getAllCollection ().add (rel2);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persist (ent);
-         endTx(em);
-         long id = ent.getId ();
-         long rel1Id = rel1.getId ();
-         long rel2Id = rel2.getId ();
-         endEm(em);
-
-         assertEquals ("ent", ent.getName ());
-         assertEquals ("rel1", rel1.getName ());
-         assertEquals ("rel2", rel2.getName ());
-         assertEquals (rel1, ent.getAll ());
-         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
-         rel1.setName ("foo");
-         rel2.setName ("bar");
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         ent = em.merge (ent);
-         assertEquals ("ent", ent.getName ());
-         assertTrue (!em.isDirty (ent));
-         assertEquals (id, ent.getId ());
-         assertTrue (rel1 != ent.getAll ());
-         rel1 = ent.getAll ();
-         assertTrue (em.isDirty (rel1));
-         assertEquals (1, ent.getAllCollection ().size ());
-         rel2 = ent.getAllCollection ().iterator ().next ();
-         assertTrue (em.isDirty (rel2));
-
-         assertTrue (em.isPersistent (rel1));
-         assertEquals (rel1Id, rel1.getId ());
-         assertEquals ("foo", rel1.getName ());
-         assertTrue (em.isPersistent (rel2));
-         assertEquals (rel2Id, rel2.getId ());
-         assertEquals ("bar", rel2.getName ());
-         endTx(em);
-         endEm(em);
-     }
-
-
-     public void testNoCascadeAttachDirtyRelations ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         CascadesEntity other = new CascadesEntity ();
-         ent.setName ("ent");
-         rel.setName ("rel");
-         other.setName ("other");
-         ent.setNone (rel);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, rel, other);
-         endTx(em);
-         long id = ent.getId ();
-         long relId = rel.getId ();
-         long otherId = other.getId ();
-         endEm(em);
-
-         assertEquals ("ent", ent.getName ());
-         assertEquals ("rel", rel.getName ());
-         assertEquals ("other", other.getName ());
-         assertEquals (rel, ent.getNone ());
-         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
-         other.setName ("foo");
-         ent.setNone (other);
-         ent.getNoneCollection ().remove (rel);
-         ent.getNoneCollection ().add (other);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         ent = em.merge (ent);
-         assertTrue (em.isDirty (ent));
-         assertEquals ("ent", ent.getName ());
-         assertEquals (id, ent.getId ());
-         assertTrue (ent.getNone () != rel);
-         assertTrue (ent.getNone () != other);
-         other = ent.getNone ();
-         assertNotNull (other);
-         assertTrue (!em.isDirty (other));
-         assertEquals (otherId, other.getId ());
-         assertEquals (1, ent.getNoneCollection ().size ());
-         assertEquals (other, ent.getNoneCollection ().iterator ().next ());
-
-         assertTrue (em.isPersistent (other));
-         assertFalse (em.isPersistent (rel));
-         assertEquals (otherId, other.getId ());
-         assertEquals ("other", other.getName ());
-         endTx(em);
-         endEm(em);
-     }
-
-
-     public void testCascadeAttachDirtyRelations ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel1 = new CascadesEntity ();
-         CascadesEntity rel2 = new CascadesEntity ();
-         CascadesEntity other1 = new CascadesEntity ();
-         CascadesEntity other2 = new CascadesEntity ();
-         ent.setName ("ent");
-         rel1.setName ("rel1");
-         ent.setAll (rel1);
-         rel2.setName ("rel2");
-         ent.getAllCollection ().add (rel2);
-         other1.setName ("other1");
-         other2.setName ("other2");
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, other1, other2);
-         endTx(em);
-         long id = ent.getId ();
-         long rel1Id = rel1.getId ();
-         long rel2Id = rel2.getId ();
-         long other1Id = other1.getId ();
-         long other2Id = other2.getId ();
-         endEm(em);
-
-         assertEquals ("ent", ent.getName ());
-         assertEquals ("rel1", rel1.getName ());
-         assertEquals ("rel2", rel2.getName ());
-         assertEquals (rel1, ent.getAll ());
-         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
-         assertEquals ("other1", other1.getName ());
-         other1.setName ("foo");
-         assertEquals ("other2", other2.getName ());
-         other2.setName ("bar");
-         ent.setAll (other1);
-         ent.getAllCollection ().remove (rel2);
-         ent.getAllCollection ().add (other2);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         ent = em.merge (ent);
-         assertEquals ("ent", ent.getName ());
-         assertTrue (em.isDirty (ent));
-         assertEquals (id, ent.getId ());
-         assertTrue (rel1 != ent.getAll ());
-         assertTrue (other1 != ent.getAll ());
-         other1 = ent.getAll ();
-         assertTrue (em.isDirty (other1));
-         assertEquals (1, ent.getAllCollection ().size ());
-         other2 = ent.getAllCollection ().iterator ().next ();
-         assertTrue (em.isDirty (other2));
-
-         assertTrue (em.isPersistent (other1));
-         assertEquals (other1Id, other1.getId ());
-         assertEquals ("foo", other1.getName ());
-         assertTrue (em.isPersistent (other2));
-         assertEquals (other2Id, other2.getId ());
-         assertEquals ("bar", other2.getName ());
-         endTx(em);
-         endEm(em);
-     }
-
-
-     public void testNoCascadeReferenceIsPreLoadedReference ()
-     {
-         CascadesEntity ent = new CascadesEntity ();
-         CascadesEntity rel = new CascadesEntity ();
-         CascadesEntity other = new CascadesEntity ();
-         ent.setName ("ent");
-         rel.setName ("rel");
-         other.setName ("other");
-         ent.setNone (rel);
-         ent.getNoneCollection ().add (rel);
-
-         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         em.persistAll (ent, rel, other);
-         endTx(em);
-         long otherId = other.getId ();
-         endEm(em);
-
-         ent.setNone (other);
-         ent.getNoneCollection ().remove (rel);
-         ent.getNoneCollection ().add (other);
-
-         em = (OpenJPAEntityManager)currentEntityManager();
-         startTx(em);
-         other = em.find (CascadesEntity.class, otherId);
-         ent = em.merge (ent);
-         assertEquals (other, ent.getNone ());
-         assertEquals (other, ent.getNoneCollection ().iterator ().next ());
-         endTx(em);
-         endEm(em);
-     }
-
-    public void testNoCascadeNewCausesException() {
-        CascadesEntity ent = new CascadesEntity();
-        CascadesEntity rel = new CascadesEntity();
-        ent.setNone(rel);
-
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        em.persistAll(ent, rel);
-        endTx(em);
-        endEm(em);
-
-        CascadesEntity other = new CascadesEntity();
-        ent.setNone(other);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        try {
-            ent = em.merge(ent);
-            fail("Allowed merge of new instance in non-cascading relation.");
-        }
-        catch (RuntimeException re) {
-            if (isActiveTx(em))
-                rollbackTx(em);
-        }
-        endEm(em);
-
-        ent = new CascadesEntity();
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        em.persist(ent);
-        endTx(em);
-        endEm(em);
-
-        other = new CascadesEntity();
-        ent.getNoneCollection().add(other);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        try {
-            ent = em.merge(ent);
-            fail("Allowed merge of new instance in non-cascading relation.");
-        }
-        catch (RuntimeException re) {
-            if (isActiveTx(em))
-                rollbackTx(em);
-        }
-        endEm(em);
-    }
-
-	public void testCascadeNewPersisted ()
-	{
-		CascadesEntity ent = new CascadesEntity ();
-		CascadesEntity rel1 = new CascadesEntity ();
-		CascadesEntity rel2 = new CascadesEntity ();
-		ent.setName ("ent");
-		rel1.setName ("rel1");
-		ent.setAll (rel1);
-		rel2.setName ("rel2");
-		ent.getAllCollection ().add (rel2);
-
-		OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-		startTx(em);
-		em.persist (ent);
-		endTx(em);
-		endEm(em);
-
-		CascadesEntity other1 = new CascadesEntity ();
-		CascadesEntity other2 = new CascadesEntity ();
-		other1.setName ("other1");
-		other2.setName ("other2");
-
-		ent.setAll (other1);
-		ent.getAllCollection ().remove (rel2);
-		ent.getAllCollection ().add (other2);
-
-		em = (OpenJPAEntityManager)currentEntityManager();
-		startTx(em);
-		ent = em.merge (ent);
-		assertTrue (em.isDirty (ent));
-		assertTrue (rel1 != ent.getAll ());
-		assertTrue (other1 != ent.getAll ());
-		other1 = ent.getAll ();
-		assertEquals ("other1", other1.getName ());
-		assertTrue (em.isNewlyPersistent (other1));
-		assertEquals (1, ent.getAllCollection ().size ());
-		other2 = ent.getAllCollection ().iterator ().next ();
-		assertEquals ("other2", other2.getName ());
-		assertTrue (em.isNewlyPersistent (other2));
-		endTx(em);
-		endEm(em);
-	}
-
-
-	public void testCascadesDeleteNonPersistent ()
-	{
-		CascadesEntity all = new CascadesEntity ();
-		CascadesEntity none = new CascadesEntity ();
-		CascadesEntity manyAll = new CascadesEntity ();
-		CascadesEntity manyNone = new CascadesEntity ();
-		OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-		startTx(em);
-		em.persist (all);
-		em.persist (none);
-		em.persist (manyAll);
-		em.persist (manyNone);
-		endTx(em);
-		long allId = all.getId ();
-		long noneId = none.getId ();
-		long manyAllId = manyAll.getId ();
-		long manyNoneId = manyNone.getId ();
-		endEm(em);
-
-		em = (OpenJPAEntityManager) currentEntityManager();
-		startTx(em);
-		CascadesEntity ent = new CascadesEntity ();
-		ent.setAll (em.find (CascadesEntity.class, allId));
-		ent.setNone (em.find (CascadesEntity.class, noneId));
-		ent.getAllCollection ().add (em.find (CascadesEntity.class, manyAllId));
-		ent.getNoneCollection ().add (em.find (CascadesEntity.class, manyNoneId));
-		em.remove (ent);
-		assertTrue (em.isRemoved (ent.getAll ()));
-		assertFalse (em.isRemoved (ent.getNone ()));
-		for (CascadesEntity rel : ent.getAllCollection ())
-		assertTrue (em.isRemoved (rel));
-		for (CascadesEntity rel : ent.getNoneCollection ())
-			assertFalse (em.isRemoved (rel));
-		assertFalse (em.contains (ent));
-		endTx(em);
-		endEm(em);
-
-		em = (OpenJPAEntityManager) currentEntityManager();
-		assertNull (em.find (CascadesEntity.class, allId));
-		assertNotNull (em.find (CascadesEntity.class, noneId));
-		assertNull (em.find (CascadesEntity.class, manyAllId));
-		assertNotNull (em.find (CascadesEntity.class, manyNoneId));
-		endEm(em);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.entityoperation;
+
+
+import org.apache.openjpa.persistence.entityoperation.common.apps.CascadesEntity;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * <p>Test EJB persistence cascade options.</p>
+ *
+ * @author Abe White
+ */
+public class TestCascades extends AbstractTestCase {
+
+    public TestCascades(String name) {
+        super(name, "entityopcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(CascadesEntity.class);
+    }
+
+    public void testNoCascadePersist ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (ent));
+         assertFalse (em.isPersistent (rel));
+         rollbackTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadePersistIsImmediate ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         ent.setAll (rel1);
+         ent.getAllCollection ().add (rel2);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (ent));
+         assertTrue (em.isPersistent (rel1));
+         assertTrue (em.isPersistent (rel2));
+         rollbackTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadePersistFlushWithDeletedCausesException ()
+     {
+         CascadesEntity rel = new CascadesEntity ();
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (rel);
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         CascadesEntity ent = new CascadesEntity ();
+         ent.setNone (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with deleted object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception e)
+         {}
+
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         ent = new CascadesEntity ();
+         ent.getNoneCollection ().add (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with deleted object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception re)
+         {
+         }
+         assertTrue (!em.getTransaction().isActive ());
+
+         endEm(em);
+     }
+
+
+     public void testCascadePersistFlushWithDeleted ()
+     {
+         CascadesEntity rel = new CascadesEntity ();
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (rel);
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         CascadesEntity ent = new CascadesEntity ();
+         ent.setAll (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         endTx(em);
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         ent = new CascadesEntity ();
+         ent.getAllCollection ().add (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         endTx(em);
+         assertTrue (!em.getTransaction().isActive ());
+
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         endEm(em);
+     }
+
+
+     public void testNoCascadePersistFlushWithTransientCausesException ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with transient object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception re)
+         {
+         }
+
+
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         ent.getNoneCollection ().add (rel);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with transient object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception re)
+         {
+         }
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+     }
+
+
+     public void testNoCascadePersistFlushWithPersistent ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertFalse(em.isPersistent (rel));
+         em.persist (rel);
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         ent.getNoneCollection ().add (rel);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         startTx(em);
+         em.persist (ent);
+         assertFalse (em.isPersistent (rel));
+         em.persist (rel);
+         endTx(em);
+         id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         endEm(em);
+     }
+
+
+     public void testCascadePersistFlushWithTransient ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         ent.setAll (rel);
+         assertFalse (em.isPersistent (rel));
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         startTx(em);
+         em.persist (ent);
+         ent.getAllCollection ().add (rel);
+         assertFalse (em.isPersistent (rel));
+         endTx(em);
+         id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         endEm(em);
+     }
+
+
+     public void testCascadePersistFlushWithPersistent ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setAll (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (rel));
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         ent.getAllCollection ().add (rel);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (rel));
+         endTx(em);
+         id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         endEm(em);
+     }
+
+
+     public void testCascadeCircleThroughPersistent ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         CascadesEntity top = new CascadesEntity ();
+         top.setAll (ent);
+         CascadesEntity rel = new CascadesEntity ();
+
+         startTx(em);
+         ent.setAll (rel);
+         rel.setAll (top);
+         em.persist (top);
+         assertTrue (em.isPersistent (top));
+         assertTrue (em.isPersistent (ent));
+         assertTrue (em.isPersistent (rel));
+         rollbackTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeDelete ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         CascadesEntity depend = new CascadesEntity ();
+         ent.setNone (rel);
+         ent.setDependent (depend);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel, depend);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         long dependId = depend.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getNone ();
+         depend = ent.getDependent ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (dependId, depend.getId ());
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (relId, ent.getNoneCollection ().iterator ().next ().getId ());
+
+         startTx(em);
+         em.remove (ent);
+         assertTrue (em.isRemoved (ent));
+         assertFalse (em.isRemoved (rel));
+         assertFalse (em.isRemoved (depend));
+         endTx(em);
+         assertFalse (em.isPersistent (ent));
+         assertTrue (em.isPersistent (rel));
+         assertFalse (em.isPersistent (depend));
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id));
+         assertNotNull (em.find (CascadesEntity.class, relId));
+         assertNull (em.find (CascadesEntity.class, dependId));
+         endEm(em);
+     }
+
+
+     public void testDeepCascadeDelete ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         CascadesEntity depend = new CascadesEntity ();
+         CascadesEntity deep1 = new CascadesEntity ();
+         CascadesEntity deep2 = new CascadesEntity ();
+         CascadesEntity deep3 = new CascadesEntity ();
+         ent.setAll (rel1);
+         rel1.setAll (deep1);
+         ent.getAllCollection ().add (rel2);
+         rel2.getAllCollection ().add (deep2);
+         ent.setDependent (depend);
+         depend.setAll (deep3);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, depend);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         long deep1Id = deep1.getId ();
+         long deep2Id = deep2.getId ();
+         long deep3Id = deep3.getId ();
+         long dependId = depend.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel1 = ent.getAll ();
+         assertEquals (rel1Id, rel1.getId ());
+         deep1 = rel1.getAll ();
+         assertEquals (deep1Id, deep1.getId ());
+         assertEquals (1, ent.getAllCollection ().size ());
+         rel2 = ent.getAllCollection ().iterator ().next ();
+         assertEquals (rel2Id, rel2.getId ());
+         assertEquals (1, rel2.getAllCollection ().size ());
+         deep2 = rel2.getAllCollection ().iterator ().next ();
+         assertEquals (deep2Id, deep2.getId ());
+         depend = ent.getDependent ();
+         assertEquals (dependId, depend.getId ());
+         deep3 = depend.getAll ();
+         assertEquals (deep3Id, deep3.getId ());
+
+         startTx(em);
+         em.remove (ent);
+         assertTrue (em.isRemoved (ent));
+         assertTrue (em.isRemoved (rel1));
+         assertTrue (em.isRemoved (rel2));
+         assertTrue (em.isRemoved (deep1));
+         assertTrue (em.isRemoved (deep2));
+         assertFalse (em.isRemoved (depend));
+         assertFalse (em.isRemoved (deep3));
+         endTx(em);
+         assertFalse (em.isPersistent (ent));
+         assertFalse (em.isPersistent (rel1));
+         assertFalse (em.isPersistent (rel2));
+         assertFalse (em.isPersistent (deep1));
+         assertFalse (em.isPersistent (depend));
+         assertFalse (em.isPersistent (deep2));
+         assertFalse(em.isPersistent (deep3));
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id));
+         assertNull (em.find (CascadesEntity.class, rel1Id));
+         assertNull (em.find (CascadesEntity.class, rel2Id));
+         assertNull (em.find (CascadesEntity.class, deep1Id));
+         assertNull (em.find (CascadesEntity.class, deep2Id));
+         assertNull (em.find (CascadesEntity.class, deep3Id));
+         assertNull (em.find (CascadesEntity.class, dependId));
+         endEm(em);
+     }
+
+
+     public void testCircularCascadeDelete ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setAll (rel);
+         ent.getAllCollection ().add (rel);
+         rel.setAll (ent);
+         rel.getAllCollection ().add (ent);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getAll ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (rel, ent.getAllCollection ().iterator ().next ());
+         assertEquals (ent, rel.getAllCollection ().iterator ().next ());
+
+         startTx(em);
+         em.remove (ent);
+         assertTrue (em.isRemoved (ent));
+         assertTrue (em.isRemoved (rel));
+         endTx(em);
+         assertFalse (em.isPersistent (ent));
+         assertFalse (em.isPersistent (rel));
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id));
+         assertNull (em.find (CascadesEntity.class, relId));
+         endEm(em);
+     }
+
+
+     public void testNoCascadeRefresh ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getNone ();
+         assertEquals (relId, rel.getId ());
+
+         startTx(em);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         ent.setDependent (new CascadesEntity ());
+         rel.setDependent (new CascadesEntity ());
+         em.persist (ent.getDependent ());
+         em.persist (rel.getDependent ());
+         em.refresh (ent);
+         assertNull (ent.getDependent ());
+         assertNotNull (rel.getDependent ());
+         endTx(em);
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id).getDependent ());
+         assertNotNull (em.find (CascadesEntity.class, relId).getDependent ());
+         endEm(em);
+     }
+
+
+     public void testCircularCascadeRefresh ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setAll (rel);
+         rel.setAll (ent);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getAll ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (ent, rel.getAll ());
+
+         startTx(em);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         ent.setDependent (new CascadesEntity ());
+         rel.setDependent (new CascadesEntity ());
+         em.persist (ent.getDependent ());
+         em.persist (rel.getDependent ());
+         em.refresh (ent);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         endTx(em);
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         assertEquals (relId, ent.getAll ().getId ());
+         assertNull (ent.getDependent ());
+         assertNull (em.find (CascadesEntity.class, relId).getDependent ());
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         CascadesEntity deep = new CascadesEntity ();
+         ent.getAllCollection ().add (rel);
+         rel.getAllCollection ().add (ent);
+         rel.getAllCollection ().add (deep);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         id = ent.getId ();
+         relId = rel.getId ();
+         long deepId = deep.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getAllCollection ().iterator ().next ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (2, rel.getAllCollection ().size ());
+         deep = null;
+         for (CascadesEntity elem : rel.getAllCollection ())
+             if (elem != ent)
+                 deep = elem;
+         assertEquals (deepId, deep.getId ());
+
+         startTx(em);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         assertNull (deep.getDependent ());
+         ent.setDependent (new CascadesEntity ());
+         ent.getAllCollection ().add (new CascadesEntity ());
+         rel.setDependent (new CascadesEntity ());
+         deep.setDependent (new CascadesEntity ());
+         em.persistAll (ent.getAllCollection ());
+         em.persist (ent.getDependent ());
+         em.persist (rel.getDependent ());
+         em.persist (deep.getDependent ());
+         em.refresh (ent);
+         assertNull (ent.getDependent ());
+         assertEquals (1, ent.getAllCollection ().size ());
+         assertTrue (ent.getAllCollection ().contains (rel));
+         assertNull (rel.getDependent ());
+         assertEquals (2, rel.getAllCollection ().size ());
+         assertTrue (rel.getAllCollection ().contains (ent));
+         assertTrue (rel.getAllCollection ().contains (deep));
+         assertNull (deep.getDependent ());
+         endTx(em);
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         assertEquals (1, ent.getAllCollection ().size ());
+         assertEquals (relId, ent.getAllCollection ().iterator ().next ().
+             getId ());
+         assertNull (ent.getDependent ());
+         assertNull (em.find (CascadesEntity.class, relId).getDependent ());
+         assertNull (em.find (CascadesEntity.class, deepId).getDependent ());
+         endEm(em);
+     }
+
+
+     public void testNoCascadeAttachClean ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel", rel.getName ());
+         assertEquals (rel, ent.getNone ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (!em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (ent.getNone () != rel);
+         rel = ent.getNone ();
+         assertNotNull (rel);
+         assertTrue (!em.isDirty (rel));
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+
+         assertTrue (em.isPersistent (rel));
+         assertEquals (relId, rel.getId ());
+         assertEquals ("rel", rel.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadeAttachClean ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         ent.setName ("ent");
+         rel1.setName ("rel1");
+         ent.setAll (rel1);
+         rel2.setName ("rel2");
+         ent.getAllCollection ().add (rel2);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel1", rel1.getName ());
+         assertEquals ("rel2", rel2.getName ());
+         assertEquals (rel1, ent.getAll ());
+         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (!em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (rel1 != ent.getAll ());
+         rel1 = ent.getAll ();
+         assertTrue (!em.isDirty (rel1));
+         assertEquals (1, ent.getAllCollection ().size ());
+         rel2 = ent.getAllCollection ().iterator ().next ();
+         assertTrue (!em.isDirty (rel2));
+
+         assertTrue (em.isPersistent (rel1));
+         assertEquals (rel1Id, rel1.getId ());
+         assertEquals ("rel1", rel1.getName ());
+         assertTrue (em.isPersistent (rel2));
+         assertEquals (rel2Id, rel2.getId ());
+         assertEquals ("rel2", rel2.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeAttachDirtyFields ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel", rel.getName ());
+         assertEquals (rel, ent.getNone ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+         rel.setName ("foo");
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (!em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (ent.getNone () != rel);
+         rel = ent.getNone ();
+         assertNotNull (rel);
+         assertTrue (!em.isDirty (rel));
+         assertEquals (relId, rel.getId ());
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+
+         assertTrue (em.isPersistent (rel));
+         assertEquals (relId, rel.getId ());
+         assertEquals ("rel", rel.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadeAttachDirtyFields ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         ent.setName ("ent");
+         rel1.setName ("rel1");
+         ent.setAll (rel1);
+         rel2.setName ("rel2");
+         ent.getAllCollection ().add (rel2);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel1", rel1.getName ());
+         assertEquals ("rel2", rel2.getName ());
+         assertEquals (rel1, ent.getAll ());
+         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
+         rel1.setName ("foo");
+         rel2.setName ("bar");
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertEquals ("ent", ent.getName ());
+         assertTrue (!em.isDirty (ent));
+         assertEquals (id, ent.getId ());
+         assertTrue (rel1 != ent.getAll ());
+         rel1 = ent.getAll ();
+         assertTrue (em.isDirty (rel1));
+         assertEquals (1, ent.getAllCollection ().size ());
+         rel2 = ent.getAllCollection ().iterator ().next ();
+         assertTrue (em.isDirty (rel2));
+
+         assertTrue (em.isPersistent (rel1));
+         assertEquals (rel1Id, rel1.getId ());
+         assertEquals ("foo", rel1.getName ());
+         assertTrue (em.isPersistent (rel2));
+         assertEquals (rel2Id, rel2.getId ());
+         assertEquals ("bar", rel2.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeAttachDirtyRelations ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         CascadesEntity other = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         other.setName ("other");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel, other);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         long otherId = other.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel", rel.getName ());
+         assertEquals ("other", other.getName ());
+         assertEquals (rel, ent.getNone ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+         other.setName ("foo");
+         ent.setNone (other);
+         ent.getNoneCollection ().remove (rel);
+         ent.getNoneCollection ().add (other);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (ent.getNone () != rel);
+         assertTrue (ent.getNone () != other);
+         other = ent.getNone ();
+         assertNotNull (other);
+         assertTrue (!em.isDirty (other));
+         assertEquals (otherId, other.getId ());
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (other, ent.getNoneCollection ().iterator ().next ());
+
+         assertTrue (em.isPersistent (other));
+         assertFalse (em.isPersistent (rel));
+         assertEquals (otherId, other.getId ());
+         assertEquals ("other", other.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadeAttachDirtyRelations ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         CascadesEntity other1 = new CascadesEntity ();
+         CascadesEntity other2 = new CascadesEntity ();
+         ent.setName ("ent");
+         rel1.setName ("rel1");
+         ent.setAll (rel1);
+         rel2.setName ("rel2");
+         ent.getAllCollection ().add (rel2);
+         other1.setName ("other1");
+         other2.setName ("other2");
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, other1, other2);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         long other1Id = other1.getId ();
+         long other2Id = other2.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel1", rel1.getName ());
+         assertEquals ("rel2", rel2.getName ());
+         assertEquals (rel1, ent.getAll ());
+         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
+         assertEquals ("other1", other1.getName ());
+         other1.setName ("foo");
+         assertEquals ("other2", other2.getName ());
+         other2.setName ("bar");
+         ent.setAll (other1);
+         ent.getAllCollection ().remove (rel2);
+         ent.getAllCollection ().add (other2);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertEquals ("ent", ent.getName ());
+         assertTrue (em.isDirty (ent));
+         assertEquals (id, ent.getId ());
+         assertTrue (rel1 != ent.getAll ());
+         assertTrue (other1 != ent.getAll ());
+         other1 = ent.getAll ();
+         assertTrue (em.isDirty (other1));
+         assertEquals (1, ent.getAllCollection ().size ());
+         other2 = ent.getAllCollection ().iterator ().next ();
+         assertTrue (em.isDirty (other2));
+
+         assertTrue (em.isPersistent (other1));
+         assertEquals (other1Id, other1.getId ());
+         assertEquals ("foo", other1.getName ());
+         assertTrue (em.isPersistent (other2));
+         assertEquals (other2Id, other2.getId ());
+         assertEquals ("bar", other2.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeReferenceIsPreLoadedReference ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         CascadesEntity other = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         other.setName ("other");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel, other);
+         endTx(em);
+         long otherId = other.getId ();
+         endEm(em);
+
+         ent.setNone (other);
+         ent.getNoneCollection ().remove (rel);
+         ent.getNoneCollection ().add (other);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         other = em.find (CascadesEntity.class, otherId);
+         ent = em.merge (ent);
+         assertEquals (other, ent.getNone ());
+         assertEquals (other, ent.getNoneCollection ().iterator ().next ());
+         endTx(em);
+         endEm(em);
+     }
+
+    public void testNoCascadeNewCausesException() {
+        CascadesEntity ent = new CascadesEntity();
+        CascadesEntity rel = new CascadesEntity();
+        ent.setNone(rel);
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persistAll(ent, rel);
+        endTx(em);
+        endEm(em);
+
+        CascadesEntity other = new CascadesEntity();
+        ent.setNone(other);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        try {
+            ent = em.merge(ent);
+            fail("Allowed merge of new instance in non-cascading relation.");
+        }
+        catch (RuntimeException re) {
+            if (isActiveTx(em))
+                rollbackTx(em);
+        }
+        endEm(em);
+
+        ent = new CascadesEntity();
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persist(ent);
+        endTx(em);
+        endEm(em);
+
+        other = new CascadesEntity();
+        ent.getNoneCollection().add(other);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        try {
+            ent = em.merge(ent);
+            fail("Allowed merge of new instance in non-cascading relation.");
+        }
+        catch (RuntimeException re) {
+            if (isActiveTx(em))
+                rollbackTx(em);
+        }
+        endEm(em);
+    }
+
+	public void testCascadeNewPersisted ()
+	{
+		CascadesEntity ent = new CascadesEntity ();
+		CascadesEntity rel1 = new CascadesEntity ();
+		CascadesEntity rel2 = new CascadesEntity ();
+		ent.setName ("ent");
+		rel1.setName ("rel1");
+		ent.setAll (rel1);
+		rel2.setName ("rel2");
+		ent.getAllCollection ().add (rel2);
+
+		OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+		startTx(em);
+		em.persist (ent);
+		endTx(em);
+		endEm(em);
+
+		CascadesEntity other1 = new CascadesEntity ();
+		CascadesEntity other2 = new CascadesEntity ();
+		other1.setName ("other1");
+		other2.setName ("other2");
+
+		ent.setAll (other1);
+		ent.getAllCollection ().remove (rel2);
+		ent.getAllCollection ().add (other2);
+
+		em = (OpenJPAEntityManager)currentEntityManager();
+		startTx(em);
+		ent = em.merge (ent);
+		assertTrue (em.isDirty (ent));
+		assertTrue (rel1 != ent.getAll ());
+		assertTrue (other1 != ent.getAll ());
+		other1 = ent.getAll ();
+		assertEquals ("other1", other1.getName ());
+		assertTrue (em.isNewlyPersistent (other1));
+		assertEquals (1, ent.getAllCollection ().size ());
+		other2 = ent.getAllCollection ().iterator ().next ();
+		assertEquals ("other2", other2.getName ());
+		assertTrue (em.isNewlyPersistent (other2));
+		endTx(em);
+		endEm(em);
+	}
+
+
+	public void testCascadesDeleteNonPersistent ()
+	{
+		CascadesEntity all = new CascadesEntity ();
+		CascadesEntity none = new CascadesEntity ();
+		CascadesEntity manyAll = new CascadesEntity ();
+		CascadesEntity manyNone = new CascadesEntity ();
+		OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+		startTx(em);
+		em.persist (all);
+		em.persist (none);
+		em.persist (manyAll);
+		em.persist (manyNone);
+		endTx(em);
+		long allId = all.getId ();
+		long noneId = none.getId ();
+		long manyAllId = manyAll.getId ();
+		long manyNoneId = manyNone.getId ();
+		endEm(em);
+
+		em = (OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+		CascadesEntity ent = new CascadesEntity ();
+		ent.setAll (em.find (CascadesEntity.class, allId));
+		ent.setNone (em.find (CascadesEntity.class, noneId));
+		ent.getAllCollection ().add (em.find (CascadesEntity.class, manyAllId));
+		ent.getNoneCollection ().add (em.find (CascadesEntity.class, manyNoneId));
+		em.remove (ent);
+		assertTrue (em.isRemoved (ent.getAll ()));
+		assertFalse (em.isRemoved (ent.getNone ()));
+		for (CascadesEntity rel : ent.getAllCollection ())
+		assertTrue (em.isRemoved (rel));
+		for (CascadesEntity rel : ent.getNoneCollection ())
+			assertFalse (em.isRemoved (rel));
+		assertFalse (em.contains (ent));
+		endTx(em);
+		endEm(em);
+
+		em = (OpenJPAEntityManager) currentEntityManager();
+		assertNull (em.find (CascadesEntity.class, allId));
+		assertNotNull (em.find (CascadesEntity.class, noneId));
+		assertNull (em.find (CascadesEntity.class, manyAllId));
+		assertNotNull (em.find (CascadesEntity.class, manyNoneId));
+		endEm(em);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java
index a33a9e5..70bfa21 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java
@@ -1,112 +1,112 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.entityoperation.common.apps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.Dependent;
-
-@Entity
-public class CascadesEntity {
-
-    private long id;
-    private String name;
-    private CascadesEntity none;
-    private CascadesEntity all;
-    private CascadesEntity dependent;
-    private Collection<CascadesEntity> noneCollection = new ArrayList();
-    private Collection<CascadesEntity> allCollection = new ArrayList();
-
-    @Id
-    @GeneratedValue
-    public long getId() {
-        return this.id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    @ManyToOne
-    public CascadesEntity getNone() {
-        return this.none;
-    }
-
-    public void setNone(CascadesEntity none) {
-        this.none = none;
-    }
-
-    @ManyToOne(cascade = CascadeType.ALL)
-    public CascadesEntity getAll() {
-        return this.all;
-    }
-
-    public void setAll(CascadesEntity all) {
-        this.all = all;
-    }
-
-    @ManyToMany
-    @JoinTable(name = "CASCADES_NONE_COLL",
-        joinColumns = @JoinColumn(name = "owner"))
-    public Collection<CascadesEntity> getNoneCollection() {
-        return this.noneCollection;
-    }
-
-    public void setNoneCollection(Collection<CascadesEntity> noneCollection) {
-        this.noneCollection = noneCollection;
-    }
-
-    @ManyToMany(cascade = CascadeType.ALL)
-    @JoinTable(name = "CASCADES_ALL_COLL",
-        joinColumns = @JoinColumn(name = "owner"))
-    public Collection<CascadesEntity> getAllCollection() {
-        return this.allCollection;
-    }
-
-    public void setAllCollection(Collection<CascadesEntity> allCollection) {
-        this.allCollection = allCollection;
-    }
-
-    @ManyToOne
-    @Dependent
-    public CascadesEntity getDependent() {
-        return this.dependent;
-    }
-
-    public void setDependent(CascadesEntity dependent) {
-        this.dependent = dependent;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.entityoperation.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.Dependent;
+
+@Entity
+public class CascadesEntity {
+
+    private long id;
+    private String name;
+    private CascadesEntity none;
+    private CascadesEntity all;
+    private CascadesEntity dependent;
+    private Collection<CascadesEntity> noneCollection = new ArrayList();
+    private Collection<CascadesEntity> allCollection = new ArrayList();
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @ManyToOne
+    public CascadesEntity getNone() {
+        return this.none;
+    }
+
+    public void setNone(CascadesEntity none) {
+        this.none = none;
+    }
+
+    @ManyToOne(cascade = CascadeType.ALL)
+    public CascadesEntity getAll() {
+        return this.all;
+    }
+
+    public void setAll(CascadesEntity all) {
+        this.all = all;
+    }
+
+    @ManyToMany
+    @JoinTable(name = "CASCADES_NONE_COLL",
+        joinColumns = @JoinColumn(name = "owner"))
+    public Collection<CascadesEntity> getNoneCollection() {
+        return this.noneCollection;
+    }
+
+    public void setNoneCollection(Collection<CascadesEntity> noneCollection) {
+        this.noneCollection = noneCollection;
+    }
+
+    @ManyToMany(cascade = CascadeType.ALL)
+    @JoinTable(name = "CASCADES_ALL_COLL",
+        joinColumns = @JoinColumn(name = "owner"))
+    public Collection<CascadesEntity> getAllCollection() {
+        return this.allCollection;
+    }
+
+    public void setAllCollection(Collection<CascadesEntity> allCollection) {
+        this.allCollection = allCollection;
+    }
+
+    @ManyToOne
+    @Dependent
+    public CascadesEntity getDependent() {
+        return this.dependent;
+    }
+
+    public void setDependent(CascadesEntity dependent) {
+        this.dependent = dependent;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java
index a88f124..cab5b09 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.ObjectMessage;
-import javax.jms.Session;
-import javax.jms.Topic;
-import javax.jms.TopicConnection;
-import javax.jms.TopicConnectionFactory;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.event.JMSRemoteCommitProvider;
-
-/**
- * So named to prevent the autobuild from running this -- we don't
- * have a JMS provider up and running in the autobuild currently.
- */
-public class JMSRemoteEventsTest
-    extends RemoteEventBase {
-
-    public JMSRemoteEventsTest(String s) {
-        super(s);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testJMSEvents() {
-        doTest(JMSRemoteCommitProvider.class,
-            "Topic=topic/KodoCommitProviderTopic",
-            "Topic=topic/KodoCommitProviderTopic");
-    }
-
-    public static void main(String[] args)
-        throws Exception {
-        Context ctx = new InitialContext();
-        TopicConnectionFactory tcf =
-            (TopicConnectionFactory) ctx.lookup("java:/ConnectionFactory");
-        Topic topic = (Topic) ctx.lookup("topic/KodoCommitProviderTopic");
-        ctx.close();
-
-        TopicConnection connection = tcf.createTopicConnection();
-
-        // false == not transacted.
-        TopicSession session = connection.createTopicSession
-            (false, Session.AUTO_ACKNOWLEDGE);
-
-        // create a subscriber.
-        TopicSubscriber s = session.createSubscriber(topic, null,
-            /* noLocal: */ false);
-        s.setMessageListener(new DebugMessageListener());
-        connection.start();
-        System.out.println
-            ("started listening on topic/KodoCommitProviderTopic");
-    }
-
-    private static class DebugMessageListener
-        implements MessageListener {
-
-        public void onMessage(Message m) {
-            try {
-                if (m instanceof ObjectMessage) {
-                    ObjectMessage om = (ObjectMessage) m;
-                    System.out.println("received object: " + om.getObject());
-                } else {
-                    System.out.println("received bad message: " + m);
-                }
-            }
-            catch (JMSException e) {
-                System.out.println("Exception while processing message");
-                e.printStackTrace(System.out);
-            }
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.JMSRemoteCommitProvider;
+
+/**
+ * So named to prevent the autobuild from running this -- we don't
+ * have a JMS provider up and running in the autobuild currently.
+ */
+public class JMSRemoteEventsTest
+    extends RemoteEventBase {
+
+    public JMSRemoteEventsTest(String s) {
+        super(s);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testJMSEvents() {
+        doTest(JMSRemoteCommitProvider.class,
+            "Topic=topic/KodoCommitProviderTopic",
+            "Topic=topic/KodoCommitProviderTopic");
+    }
+
+    public static void main(String[] args)
+        throws Exception {
+        Context ctx = new InitialContext();
+        TopicConnectionFactory tcf =
+            (TopicConnectionFactory) ctx.lookup("java:/ConnectionFactory");
+        Topic topic = (Topic) ctx.lookup("topic/KodoCommitProviderTopic");
+        ctx.close();
+
+        TopicConnection connection = tcf.createTopicConnection();
+
+        // false == not transacted.
+        TopicSession session = connection.createTopicSession
+            (false, Session.AUTO_ACKNOWLEDGE);
+
+        // create a subscriber.
+        TopicSubscriber s = session.createSubscriber(topic, null,
+            /* noLocal: */ false);
+        s.setMessageListener(new DebugMessageListener());
+        connection.start();
+        System.out.println
+            ("started listening on topic/KodoCommitProviderTopic");
+    }
+
+    private static class DebugMessageListener
+        implements MessageListener {
+
+        public void onMessage(Message m) {
+            try {
+                if (m instanceof ObjectMessage) {
+                    ObjectMessage om = (ObjectMessage) m;
+                    System.out.println("received object: " + om.getObject());
+                } else {
+                    System.out.println("received bad message: " + m);
+                }
+            }
+            catch (JMSException e) {
+                System.out.println("Exception while processing message");
+                e.printStackTrace(System.out);
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java
index 47b7129..baff3c4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java
@@ -1,249 +1,249 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.StoreCache;
-import org.apache.openjpa.util.Id;
-
-public class RemoteEventBase extends AbstractTestCase {
-
-    public Id roid;
-    public StoreCache datacatch;
-
-    public RemoteEventBase(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        datacatch.evictAll();
-    }
-
-    public void tearDown() throws Exception {
-        ((OpenJPAEntityManagerSPI) OpenJPAPersistence
-            .cast(currentEntityManager())).getConfiguration()
-            .getRemoteCommitEventManager().close();
-    }
-
-    protected void doTest(Class providerClass, String classProps1,
-        String classProps2) {
-        String transmit = "TransmitPersistedObjectIds=true";
-        if (classProps1 == null || classProps1.length() == 0)
-            classProps1 = transmit;
-        else
-            classProps1 += "," + transmit;
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.RemoteCommitProvider",
-            Configurations.getPlugin(providerClass.getName(), classProps1));
-        propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup1");
-        propsMap.put("openjpa.DataCache", "true");
-        OpenJPAEntityManagerFactory factory1 = getEmf(propsMap);
-
-        TriggerRemoteCommitListener listener1 =
-            new TriggerRemoteCommitListener();
-        ((OpenJPAEntityManagerFactorySPI) factory1).getConfiguration()
-            .getRemoteCommitEventManager().addListener(listener1);
-
-        if (classProps2 == null || classProps2.length() == 0)
-            classProps2 = transmit;
-        else
-            classProps2 += ", " + transmit;
-
-        propsMap = new HashMap();
-        propsMap.put("openjpa.RemoteCommitProvider",
-            Configurations.getPlugin(providerClass.getName(), classProps2));
-        propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup2");
-        propsMap.put("openjpa.DataCache", "true");
-        OpenJPAEntityManagerFactory factory2 = getEmf(propsMap);
-
-        RemoteCommitListenerTestImpl listener2 =
-            new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) factory2).getConfiguration()
-            .getRemoteCommitEventManager().addListener(listener2);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) factory1.createEntityManager();
-        datacatch = pm.getEntityManagerFactory().getStoreCache();
-        // get an object id
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        pm.persist(t1);
-        Object oid = pm.getObjectId(t1);
-        roid = Id.newInstance(RuntimeTest1.class, oid);
-        endTx(pm);
-
-        try {
-            Thread.currentThread().sleep(250);
-        }
-        catch (InterruptedException ie) {
-        }
-
-        // ensure that the commit info was not propagated to factory1.
-        assertFalse(listener1.commitNotificationReceived);
-
-        // ensure that the commit info propagated to the
-        // factories correctly.
-        assertNotNull(listener2.added);
-        assertNotNull(listener2.updated);
-        assertNotNull(listener2.deleted);
-
-        boolean pass = false;
-        for (Iterator iter = listener2.added.iterator(); iter.hasNext();) {
-            Id roid = Id.newInstance(RuntimeTest1.class, oid);
-            Id it = (Id) iter.next();
-            System.out.println("===ROID: " + roid.getId() + " +++== ITER: " +
-                it.getId() + " Content: " + listener2.added + "ROID Cont: " +
-                roid);
-            System.out.println("Result of COMP " + it.equals(roid));
-            //FixMe --det. why it.equals(roid) fails when the are actually equal
-            if (it.toString().equals(roid.toString())) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue("pass = " + pass, pass);
-        assertTrue(listener2.updated.size() == 0);
-        assertTrue(listener2.deleted.size() == 0);
-
-        // modify an object
-        startTx(pm);
-        t1.setStringField("baz");
-        endTx(pm);
-
-        try {
-            Thread.currentThread().sleep(250);
-        }
-        catch (InterruptedException ie) {
-        }
-
-        // ensure that the commit info was not propagated to factory1.
-        assertFalse(listener1.commitNotificationReceived);
-
-        // ensure that the commit info propagated to the remote
-        // factories correctly.
-        assertNotNull(listener2.added);
-        assertNotNull(listener2.updated);
-        assertNotNull(listener2.deleted);
-
-        pass = false;
-        for (Iterator iter = listener2.updated.iterator(); iter.hasNext();) {
-            Id it = (Id) iter.next();
-            System.out.println("===ROID: " + roid.getId() + "+++== ITER: " +
-                it.getId() + "Content: " + listener2.added);
-            System.out.println("Result of COMP " + it.equals(roid));
-
-            if (it.toString().equals(roid.toString())) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue(pass);
-        assertTrue(listener2.added.size() == 0);
-        assertTrue(listener2.deleted.size() == 0);
-
-        // delete an object
-        startTx(pm);
-        pm.remove(t1);
-        endTx(pm);
-
-        try {
-            Thread.currentThread().sleep(250);
-        }
-        catch (InterruptedException ie) {
-        }
-
-        // ensure that the commit info was not propagated to factory1.
-        assertFalse(listener1.commitNotificationReceived);
-
-        // ensure that the commit info propagated to the remote
-        // factories correctly.
-        assertNotNull(listener2.added);
-        assertNotNull(listener2.updated);
-        assertNotNull(listener2.deleted);
-
-        pass = false;
-        for (Iterator iter = listener2.deleted.iterator(); iter.hasNext();) {
-            Id it = (Id) iter.next();
-            System.out.println("===ROID: " + roid.getId() + "+++== ITER: " +
-                it.getId() + "Content: " + listener2.added);
-            System.out.println("Result of COMP " + it.equals(roid));
-
-            if (it.toString().equals(roid.toString())) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue(pass);
-        assertTrue(listener2.added.size() == 0);
-        assertTrue(listener2.updated.size() == 0);
-    }
-
-    protected static class RemoteCommitListenerTestImpl implements
-        RemoteCommitListener {
-
-        transient Collection added;
-
-        transient Collection updated;
-
-        transient Collection deleted;
-
-        public void afterCommit(RemoteCommitEvent event) {
-            this.added = event.getPersistedObjectIds();
-            this.updated = event.getUpdatedObjectIds();
-            this.deleted = event.getDeletedObjectIds();
-        }
-
-        public void close() {
-        }
-    }
-
-    protected static class TriggerRemoteCommitListener
-        implements RemoteCommitListener {
-
-        boolean commitNotificationReceived = false;
-
-        public void afterCommit(RemoteCommitEvent event) {
-            commitNotificationReceived = true;
-        }
-
-        public void close() {
-        }
-    }
-}
-// looks like this might be creating another factory that is
-// connecting to the same ports, causing the failure. Should
-// probably debug by putting a third conf in RemoteEventBase.
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.StoreCache;
+import org.apache.openjpa.util.Id;
+
+public class RemoteEventBase extends AbstractTestCase {
+
+    public Id roid;
+    public StoreCache datacatch;
+
+    public RemoteEventBase(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        datacatch.evictAll();
+    }
+
+    public void tearDown() throws Exception {
+        ((OpenJPAEntityManagerSPI) OpenJPAPersistence
+            .cast(currentEntityManager())).getConfiguration()
+            .getRemoteCommitEventManager().close();
+    }
+
+    protected void doTest(Class providerClass, String classProps1,
+        String classProps2) {
+        String transmit = "TransmitPersistedObjectIds=true";
+        if (classProps1 == null || classProps1.length() == 0)
+            classProps1 = transmit;
+        else
+            classProps1 += "," + transmit;
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.RemoteCommitProvider",
+            Configurations.getPlugin(providerClass.getName(), classProps1));
+        propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup1");
+        propsMap.put("openjpa.DataCache", "true");
+        OpenJPAEntityManagerFactory factory1 = getEmf(propsMap);
+
+        TriggerRemoteCommitListener listener1 =
+            new TriggerRemoteCommitListener();
+        ((OpenJPAEntityManagerFactorySPI) factory1).getConfiguration()
+            .getRemoteCommitEventManager().addListener(listener1);
+
+        if (classProps2 == null || classProps2.length() == 0)
+            classProps2 = transmit;
+        else
+            classProps2 += ", " + transmit;
+
+        propsMap = new HashMap();
+        propsMap.put("openjpa.RemoteCommitProvider",
+            Configurations.getPlugin(providerClass.getName(), classProps2));
+        propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup2");
+        propsMap.put("openjpa.DataCache", "true");
+        OpenJPAEntityManagerFactory factory2 = getEmf(propsMap);
+
+        RemoteCommitListenerTestImpl listener2 =
+            new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) factory2).getConfiguration()
+            .getRemoteCommitEventManager().addListener(listener2);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) factory1.createEntityManager();
+        datacatch = pm.getEntityManagerFactory().getStoreCache();
+        // get an object id
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        pm.persist(t1);
+        Object oid = pm.getObjectId(t1);
+        roid = Id.newInstance(RuntimeTest1.class, oid);
+        endTx(pm);
+
+        try {
+            Thread.currentThread().sleep(250);
+        }
+        catch (InterruptedException ie) {
+        }
+
+        // ensure that the commit info was not propagated to factory1.
+        assertFalse(listener1.commitNotificationReceived);
+
+        // ensure that the commit info propagated to the
+        // factories correctly.
+        assertNotNull(listener2.added);
+        assertNotNull(listener2.updated);
+        assertNotNull(listener2.deleted);
+
+        boolean pass = false;
+        for (Iterator iter = listener2.added.iterator(); iter.hasNext();) {
+            Id roid = Id.newInstance(RuntimeTest1.class, oid);
+            Id it = (Id) iter.next();
+            System.out.println("===ROID: " + roid.getId() + " +++== ITER: " +
+                it.getId() + " Content: " + listener2.added + "ROID Cont: " +
+                roid);
+            System.out.println("Result of COMP " + it.equals(roid));
+            //FixMe --det. why it.equals(roid) fails when the are actually equal
+            if (it.toString().equals(roid.toString())) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue("pass = " + pass, pass);
+        assertTrue(listener2.updated.size() == 0);
+        assertTrue(listener2.deleted.size() == 0);
+
+        // modify an object
+        startTx(pm);
+        t1.setStringField("baz");
+        endTx(pm);
+
+        try {
+            Thread.currentThread().sleep(250);
+        }
+        catch (InterruptedException ie) {
+        }
+
+        // ensure that the commit info was not propagated to factory1.
+        assertFalse(listener1.commitNotificationReceived);
+
+        // ensure that the commit info propagated to the remote
+        // factories correctly.
+        assertNotNull(listener2.added);
+        assertNotNull(listener2.updated);
+        assertNotNull(listener2.deleted);
+
+        pass = false;
+        for (Iterator iter = listener2.updated.iterator(); iter.hasNext();) {
+            Id it = (Id) iter.next();
+            System.out.println("===ROID: " + roid.getId() + "+++== ITER: " +
+                it.getId() + "Content: " + listener2.added);
+            System.out.println("Result of COMP " + it.equals(roid));
+
+            if (it.toString().equals(roid.toString())) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(listener2.added.size() == 0);
+        assertTrue(listener2.deleted.size() == 0);
+
+        // delete an object
+        startTx(pm);
+        pm.remove(t1);
+        endTx(pm);
+
+        try {
+            Thread.currentThread().sleep(250);
+        }
+        catch (InterruptedException ie) {
+        }
+
+        // ensure that the commit info was not propagated to factory1.
+        assertFalse(listener1.commitNotificationReceived);
+
+        // ensure that the commit info propagated to the remote
+        // factories correctly.
+        assertNotNull(listener2.added);
+        assertNotNull(listener2.updated);
+        assertNotNull(listener2.deleted);
+
+        pass = false;
+        for (Iterator iter = listener2.deleted.iterator(); iter.hasNext();) {
+            Id it = (Id) iter.next();
+            System.out.println("===ROID: " + roid.getId() + "+++== ITER: " +
+                it.getId() + "Content: " + listener2.added);
+            System.out.println("Result of COMP " + it.equals(roid));
+
+            if (it.toString().equals(roid.toString())) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(listener2.added.size() == 0);
+        assertTrue(listener2.updated.size() == 0);
+    }
+
+    protected static class RemoteCommitListenerTestImpl implements
+        RemoteCommitListener {
+
+        transient Collection added;
+
+        transient Collection updated;
+
+        transient Collection deleted;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+        }
+
+        public void close() {
+        }
+    }
+
+    protected static class TriggerRemoteCommitListener
+        implements RemoteCommitListener {
+
+        boolean commitNotificationReceived = false;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            commitNotificationReceived = true;
+        }
+
+        public void close() {
+        }
+    }
+}
+// looks like this might be creating another factory that is
+// connecting to the same ports, causing the failure. Should
+// probably debug by putting a third conf in RemoteEventBase.
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java
index 58a2a6d..a11f8c0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java
@@ -1,256 +1,256 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.Collections;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.event.TransactionEvent;
-import org.apache.openjpa.event.TransactionListener;
-import org.apache.openjpa.persistence.CallbackMode;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-
-public class TestEvents
-    extends AbstractTestCase {
-
-    private TransactionEventListenerTestImpl transactionListener;
-
-    public TestEvents(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        transactionListener = new TransactionEventListenerTestImpl();
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testCommit() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        ((OpenJPAEntityManagerSPI) pm)
-            .addTransactionListener(transactionListener);
-
-        assertEquals(0, transactionListener.status);
-
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED,
-            transactionListener.status);
-
-        pm.persist(t1);
-
-        endTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED |
-            TransactionEventListenerTestImpl.COMMIT_BEGUN |
-            TransactionEventListenerTestImpl.COMMITTED,
-            transactionListener.status);
-    }
-
-    public void testRollback() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        ((OpenJPAEntityManagerSPI) pm)
-            .addTransactionListener(transactionListener);
-
-        assertEquals(0, transactionListener.status);
-
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED,
-            transactionListener.status);
-
-        pm.persist(t1);
-
-        rollbackTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED |
-            TransactionEventListenerTestImpl.ROLLEDBACK,
-            transactionListener.status);
-    }
-
-    public void testObjectChanges() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        ((OpenJPAEntityManagerSPI) pm)
-            .addTransactionListener(transactionListener);
-
-        // add a couple new object
-        RuntimeTest1 t1 = new RuntimeTest1("t1", 0);
-        RuntimeTest1 t2 = new RuntimeTest1("t2", 1);
-        startTx(pm);
-        pm.persist(t1);
-        pm.persist(t2);
-        endTx(pm);
-
-        // now do some modifications
-        transactionListener.status = 0;
-        startTx(pm);
-        RuntimeTest1 t3 = new RuntimeTest1("t3", 3);
-        pm.persist(t3);
-        t1.setStringField("baz");
-        pm.remove(t2);
-        endTx(pm);
-
-        assertEquals(3, transactionListener.trans.size());
-        assertTrue(transactionListener.trans.contains(t1));
-        assertTrue(transactionListener.trans.contains(t2));
-        assertTrue(transactionListener.trans.contains(t3));
-    }
-
-    public void testIgnoreCallbackModeExceptionConsumed() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        ((OpenJPAEntityManagerSPI) pm)
-            .addTransactionListener(transactionListener);
-        //FIXME need to find an alternative
-        ((OpenJPAEntityManagerSPI) pm)
-            .setTransactionListenerCallbackMode(CallbackMode.IGNORE);
-        transactionListener.exception = transactionListener.EXCEPTION;
-
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED,
-            transactionListener.status);
-        pm.persist(t1);
-        endTx(pm);
-        endEm(pm);
-
-        assertEquals(TransactionEventListenerTestImpl.STARTED |
-            TransactionEventListenerTestImpl.COMMIT_BEGUN |
-            TransactionEventListenerTestImpl.COMMITTED,
-            transactionListener.status);
-    }
-
-    public void testExceptionCausesRollback() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        ((OpenJPAEntityManagerSPI) pm)
-            .addTransactionListener(transactionListener);
-        transactionListener.exception = transactionListener.EXCEPTION;
-
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED,
-            transactionListener.status);
-        pm.persist(t1);
-
-        try {
-            endTx(pm);
-            fail("Commit should have caused exception.");
-        } catch (AssertionFailedError afe) {
-            bug(1139, afe, "Listener exceptions being swallowed");
-            return;
-        } catch (Exception je) {
-            assertEquals("xxx", je.getMessage());
-        }
-        assertTrue(!(isActiveTx(pm)));
-        endEm(pm);
-
-        assertEquals(TransactionEventListenerTestImpl.STARTED |
-            TransactionEventListenerTestImpl.COMMIT_BEGUN |
-            TransactionEventListenerTestImpl.ROLLEDBACK,
-            transactionListener.status);
-    }
-
-    public void testExceptionAfterCommitThrown() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        ((OpenJPAEntityManagerSPI) pm)
-            .addTransactionListener(transactionListener);
-        transactionListener.exception = transactionListener.EXCEPTION_AFTER;
-
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        assertEquals(TransactionEventListenerTestImpl.STARTED,
-            transactionListener.status);
-        pm.persist(t1);
-
-        try {
-            endTx(pm);
-            fail("Commit should have caused exception.");
-        } catch (AssertionFailedError afe) {
-            bug(1139, afe, "Listener exceptions being swallowed");
-        } catch (Exception je) {
-            assertEquals("xxx", je.getMessage());
-        }
-        assertFalse(isActiveTx(pm));
-        endEm(pm);
-
-        assertEquals(TransactionEventListenerTestImpl.STARTED |
-            TransactionEventListenerTestImpl.COMMIT_BEGUN |
-            TransactionEventListenerTestImpl.COMMITTED,
-            transactionListener.status);
-    }
-
-    private static class TransactionEventListenerTestImpl
-        implements TransactionListener {
-
-        static int STARTED = 1;
-        static int COMMITTED = 2;
-        static int ROLLEDBACK = 4;
-        static int COMMIT_BEGUN = 8;
-        static int EXCEPTION = 1;
-        static int EXCEPTION_AFTER = 2;
-
-        int exception;
-        int status;
-        Collection trans = Collections.EMPTY_LIST;
-
-        public void afterBegin(TransactionEvent event) {
-            status |= STARTED;
-        }
-
-        public void beforeFlush(TransactionEvent event) {
-        }
-
-        public void afterFlush(TransactionEvent event) {
-        }
-
-        public void beforeCommit(TransactionEvent event) {
-            status |= COMMIT_BEGUN;
-            trans = event.getTransactionalObjects();
-            if (exception == EXCEPTION)
-                throw new RuntimeException("xxx");
-        }
-
-        public void afterCommit(TransactionEvent event) {
-            status |= COMMITTED;
-            if (exception == EXCEPTION_AFTER)
-                throw new RuntimeException("xxx");
-        }
-
-        public void afterRollback(TransactionEvent event) {
-            status |= ROLLEDBACK;
-        }
-
-        public void afterStateTransitions(TransactionEvent event) {
-        }
-
-        public void afterCommitComplete(TransactionEvent event) {
-        }
-
-        public void afterRollbackComplete(TransactionEvent event) {
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.Collections;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.event.TransactionListener;
+import org.apache.openjpa.persistence.CallbackMode;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+
+public class TestEvents
+    extends AbstractTestCase {
+
+    private TransactionEventListenerTestImpl transactionListener;
+
+    public TestEvents(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        transactionListener = new TransactionEventListenerTestImpl();
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testCommit() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+
+        assertEquals(0, transactionListener.status);
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+
+        pm.persist(t1);
+
+        endTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.COMMITTED,
+            transactionListener.status);
+    }
+
+    public void testRollback() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+
+        assertEquals(0, transactionListener.status);
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+
+        pm.persist(t1);
+
+        rollbackTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.ROLLEDBACK,
+            transactionListener.status);
+    }
+
+    public void testObjectChanges() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+
+        // add a couple new object
+        RuntimeTest1 t1 = new RuntimeTest1("t1", 0);
+        RuntimeTest1 t2 = new RuntimeTest1("t2", 1);
+        startTx(pm);
+        pm.persist(t1);
+        pm.persist(t2);
+        endTx(pm);
+
+        // now do some modifications
+        transactionListener.status = 0;
+        startTx(pm);
+        RuntimeTest1 t3 = new RuntimeTest1("t3", 3);
+        pm.persist(t3);
+        t1.setStringField("baz");
+        pm.remove(t2);
+        endTx(pm);
+
+        assertEquals(3, transactionListener.trans.size());
+        assertTrue(transactionListener.trans.contains(t1));
+        assertTrue(transactionListener.trans.contains(t2));
+        assertTrue(transactionListener.trans.contains(t3));
+    }
+
+    public void testIgnoreCallbackModeExceptionConsumed() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+        //FIXME need to find an alternative
+        ((OpenJPAEntityManagerSPI) pm)
+            .setTransactionListenerCallbackMode(CallbackMode.IGNORE);
+        transactionListener.exception = transactionListener.EXCEPTION;
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+        pm.persist(t1);
+        endTx(pm);
+        endEm(pm);
+
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.COMMITTED,
+            transactionListener.status);
+    }
+
+    public void testExceptionCausesRollback() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+        transactionListener.exception = transactionListener.EXCEPTION;
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+        pm.persist(t1);
+
+        try {
+            endTx(pm);
+            fail("Commit should have caused exception.");
+        } catch (AssertionFailedError afe) {
+            bug(1139, afe, "Listener exceptions being swallowed");
+            return;
+        } catch (Exception je) {
+            assertEquals("xxx", je.getMessage());
+        }
+        assertTrue(!(isActiveTx(pm)));
+        endEm(pm);
+
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.ROLLEDBACK,
+            transactionListener.status);
+    }
+
+    public void testExceptionAfterCommitThrown() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+        transactionListener.exception = transactionListener.EXCEPTION_AFTER;
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+        pm.persist(t1);
+
+        try {
+            endTx(pm);
+            fail("Commit should have caused exception.");
+        } catch (AssertionFailedError afe) {
+            bug(1139, afe, "Listener exceptions being swallowed");
+        } catch (Exception je) {
+            assertEquals("xxx", je.getMessage());
+        }
+        assertFalse(isActiveTx(pm));
+        endEm(pm);
+
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.COMMITTED,
+            transactionListener.status);
+    }
+
+    private static class TransactionEventListenerTestImpl
+        implements TransactionListener {
+
+        static int STARTED = 1;
+        static int COMMITTED = 2;
+        static int ROLLEDBACK = 4;
+        static int COMMIT_BEGUN = 8;
+        static int EXCEPTION = 1;
+        static int EXCEPTION_AFTER = 2;
+
+        int exception;
+        int status;
+        Collection trans = Collections.EMPTY_LIST;
+
+        public void afterBegin(TransactionEvent event) {
+            status |= STARTED;
+        }
+
+        public void beforeFlush(TransactionEvent event) {
+        }
+
+        public void afterFlush(TransactionEvent event) {
+        }
+
+        public void beforeCommit(TransactionEvent event) {
+            status |= COMMIT_BEGUN;
+            trans = event.getTransactionalObjects();
+            if (exception == EXCEPTION)
+                throw new RuntimeException("xxx");
+        }
+
+        public void afterCommit(TransactionEvent event) {
+            status |= COMMITTED;
+            if (exception == EXCEPTION_AFTER)
+                throw new RuntimeException("xxx");
+        }
+
+        public void afterRollback(TransactionEvent event) {
+            status |= ROLLEDBACK;
+        }
+
+        public void afterStateTransitions(TransactionEvent event) {
+        }
+
+        public void afterCommitComplete(TransactionEvent event) {
+        }
+
+        public void afterRollbackComplete(TransactionEvent event) {
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java
index 1dbfc19..8025572 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java
@@ -1,226 +1,226 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.event.AbstractRemoteCommitProvider;
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.util.Id;
-
-public class TestFakeRemoteEvents extends AbstractTestCase {
-
-    /*
-      * The most recently set provider, and a lock to control access to it. This
-      * is rather hacky.
-      */
-    private static Object currentProviderLock = new Object();
-
-    private static RemoteCommitProviderTestImpl currentProvider;
-
-    public TestFakeRemoteEvents(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testListener() {
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-        propsMap.put("openjpa.DataCache", "true");
-        OpenJPAEntityManagerFactory factory = getEmf(propsMap);
-
-        RemoteCommitListenerTestImpl transactionListener =
-            new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
-            .getRemoteCommitEventManager().addListener(
-            transactionListener);
-
-        OpenJPAEntityManager pm = (OpenJPAEntityManager) factory
-            .createEntityManager();
-
-        // get an object id
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        pm.persist(t1);
-        Object oid = pm.getObjectId(t1);
-        rollbackTx(pm);
-
-        // simulate an add
-        Set s = new HashSet();
-        s.add(oid);
-        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
-            .getRemoteCommitEventManager().fireEvent(
-            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
-                s, null, null, null));
-
-        boolean pass = false;
-        for (Iterator iter = transactionListener.added.iterator(); iter
-            .hasNext();) {
-            if (iter.next().equals(oid)) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue(pass);
-        assertTrue(transactionListener.updated.size() == 0);
-        assertTrue(transactionListener.deleted.size() == 0);
-
-        // simulate modifications
-        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
-            .getRemoteCommitEventManager().fireEvent(
-            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
-                null, null, s, null));
-
-        pass = false;
-        for (Iterator iter = transactionListener.updated.iterator(); iter
-            .hasNext();) {
-            if (iter.next().equals(oid)) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue(pass);
-        assertTrue(transactionListener.added.size() == 0);
-        assertTrue(transactionListener.deleted.size() == 0);
-
-        // simulate a delete
-        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
-            .getRemoteCommitEventManager().fireEvent(
-            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
-                null, null, null, s));
-
-        pass = false;
-        for (Iterator iter = transactionListener.deleted.iterator(); iter
-            .hasNext();) {
-            if (iter.next().equals(oid)) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue(pass);
-        assertTrue(transactionListener.added.size() == 0);
-        assertTrue(transactionListener.updated.size() == 0);
-    }
-
-    public void testProvider() {
-        RemoteCommitProviderTestImpl provider;
-        OpenJPAEntityManager pm;
-        synchronized (currentProviderLock) {
-            Map propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider",
-                RemoteCommitProviderTestImpl.class.getName()
-                    + "(TransmitPersistedObjectIds=true)");
-            propsMap.put("openjpa.DataCache", "true");
-            OpenJPAEntityManagerFactory factory = getEmf(propsMap);
-
-            pm = (OpenJPAEntityManager) factory.createEntityManager();
-            provider = currentProvider;
-        }
-
-        // get an object id
-        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
-        startTx(pm);
-        pm.persist(t1);
-        Object oid = pm.getObjectId(t1);
-        endTx(pm);
-
-        boolean pass = false;
-        for (Iterator iter = provider.added.iterator(); iter.hasNext();) {
-            Object added = iter.next();
-            if (equals(added, oid)) {
-                pass = true;
-                break;
-            }
-        }
-        assertTrue(pass);
-        assertTrue(provider.updated.size() == 0);
-        assertTrue(provider.deleted.size() == 0);
-    }
-
-    boolean equals(Object added, Object oid) {
-        if (added.equals(oid))
-            return true;
-        if (added instanceof Id)
-            return ((Id) added).getIdObject().equals(oid);
-        return false;
-    }
-
-    private static class RemoteCommitListenerTestImpl implements
-        RemoteCommitListener {
-
-        transient Collection added;
-
-        transient Collection updated;
-
-        transient Collection deleted;
-
-        public void afterCommit(RemoteCommitEvent event) {
-            this.added = event.getPersistedObjectIds();
-            this.updated = event.getUpdatedObjectIds();
-            this.deleted = event.getDeletedObjectIds();
-        }
-
-        public void close() {
-        }
-    }
-
-    public static class RemoteCommitProviderTestImpl extends
-        AbstractRemoteCommitProvider {
-
-        Collection added;
-
-        Collection updated;
-
-        Collection deleted;
-
-        public RemoteCommitProviderTestImpl() {
-            synchronized (currentProviderLock) {
-                currentProvider = this;
-            }
-        }
-
-        // ---------- RemoteCommitProvider implementation ----------
-
-        public void broadcast(RemoteCommitEvent event) {
-            this.added = event.getPersistedObjectIds();
-            this.updated = event.getUpdatedObjectIds();
-            this.deleted = event.getDeletedObjectIds();
-        }
-
-        public void close() {
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.AbstractRemoteCommitProvider;
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.util.Id;
+
+public class TestFakeRemoteEvents extends AbstractTestCase {
+
+    /*
+      * The most recently set provider, and a lock to control access to it. This
+      * is rather hacky.
+      */
+    private static Object currentProviderLock = new Object();
+
+    private static RemoteCommitProviderTestImpl currentProvider;
+
+    public TestFakeRemoteEvents(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testListener() {
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.DataCache", "true");
+        OpenJPAEntityManagerFactory factory = getEmf(propsMap);
+
+        RemoteCommitListenerTestImpl transactionListener =
+            new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().addListener(
+            transactionListener);
+
+        OpenJPAEntityManager pm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+
+        // get an object id
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        pm.persist(t1);
+        Object oid = pm.getObjectId(t1);
+        rollbackTx(pm);
+
+        // simulate an add
+        Set s = new HashSet();
+        s.add(oid);
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().fireEvent(
+            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
+                s, null, null, null));
+
+        boolean pass = false;
+        for (Iterator iter = transactionListener.added.iterator(); iter
+            .hasNext();) {
+            if (iter.next().equals(oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(transactionListener.updated.size() == 0);
+        assertTrue(transactionListener.deleted.size() == 0);
+
+        // simulate modifications
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().fireEvent(
+            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
+                null, null, s, null));
+
+        pass = false;
+        for (Iterator iter = transactionListener.updated.iterator(); iter
+            .hasNext();) {
+            if (iter.next().equals(oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(transactionListener.added.size() == 0);
+        assertTrue(transactionListener.deleted.size() == 0);
+
+        // simulate a delete
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().fireEvent(
+            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
+                null, null, null, s));
+
+        pass = false;
+        for (Iterator iter = transactionListener.deleted.iterator(); iter
+            .hasNext();) {
+            if (iter.next().equals(oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(transactionListener.added.size() == 0);
+        assertTrue(transactionListener.updated.size() == 0);
+    }
+
+    public void testProvider() {
+        RemoteCommitProviderTestImpl provider;
+        OpenJPAEntityManager pm;
+        synchronized (currentProviderLock) {
+            Map propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider",
+                RemoteCommitProviderTestImpl.class.getName()
+                    + "(TransmitPersistedObjectIds=true)");
+            propsMap.put("openjpa.DataCache", "true");
+            OpenJPAEntityManagerFactory factory = getEmf(propsMap);
+
+            pm = (OpenJPAEntityManager) factory.createEntityManager();
+            provider = currentProvider;
+        }
+
+        // get an object id
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        pm.persist(t1);
+        Object oid = pm.getObjectId(t1);
+        endTx(pm);
+
+        boolean pass = false;
+        for (Iterator iter = provider.added.iterator(); iter.hasNext();) {
+            Object added = iter.next();
+            if (equals(added, oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(provider.updated.size() == 0);
+        assertTrue(provider.deleted.size() == 0);
+    }
+
+    boolean equals(Object added, Object oid) {
+        if (added.equals(oid))
+            return true;
+        if (added instanceof Id)
+            return ((Id) added).getIdObject().equals(oid);
+        return false;
+    }
+
+    private static class RemoteCommitListenerTestImpl implements
+        RemoteCommitListener {
+
+        transient Collection added;
+
+        transient Collection updated;
+
+        transient Collection deleted;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+        }
+
+        public void close() {
+        }
+    }
+
+    public static class RemoteCommitProviderTestImpl extends
+        AbstractRemoteCommitProvider {
+
+        Collection added;
+
+        Collection updated;
+
+        Collection deleted;
+
+        public RemoteCommitProviderTestImpl() {
+            synchronized (currentProviderLock) {
+                currentProvider = this;
+            }
+        }
+
+        // ---------- RemoteCommitProvider implementation ----------
+
+        public void broadcast(RemoteCommitEvent event) {
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+        }
+
+        public void close() {
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java
index b7dcea3..caeccd3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java
@@ -1,222 +1,222 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest4;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.event.LifecycleEventManager;
-import org.apache.openjpa.event.LoadListener;
-import org.apache.openjpa.event.StoreListener;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-/**
- * <p>Test the {@link LifecycleEventManager}.</p>
- *
- * @author Abe White
- */
-public class TestLifecycleEventManager
-    extends AbstractTestCase {
-
-    public TestLifecycleEventManager(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void testAllClassListener() {
-        MetaDataRepository repos =
-            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
-                OpenJPAPersistence.createEntityManagerFactory("TestConv2", "")))
-                .
-                    getConfiguration().getMetaDataRepositoryInstance();
-        ClassMetaData meta = repos.getMetaData(RuntimeTest2.class, null, true);
-        LifecycleEventManager mgr = new LifecycleEventManager();
-        RuntimeTest2 pc = new RuntimeTest2();
-        Listener listener = new Listener();
-
-        assertFalse(mgr.hasLoadListeners(pc, meta));
-        assertFalse(mgr.hasStoreListeners(pc, meta));
-
-        mgr.addListener(listener, null);
-        assertEquals(0, listener.load);
-        assertEquals(0, listener.store);
-        assertTrue(mgr.hasLoadListeners(pc, meta));
-        assertTrue(mgr.hasStoreListeners(pc, meta));
-        assertFalse(mgr.hasDirtyListeners(pc, meta));
-        assertEquals(0, listener.load);
-        assertEquals(0, listener.store);
-
-        Listener listener2 = new Listener();
-        mgr.addListener(listener2, null);
-        assertTrue(mgr.hasLoadListeners(pc, meta));
-        assertTrue(mgr.hasStoreListeners(pc, meta));
-        assertFalse(mgr.hasDirtyListeners(pc, meta));
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
-        assertEquals(1, listener.load);
-        assertEquals(0, listener.store);
-        assertEquals(0, listener.preStore);
-        assertEquals(1, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.removeListener(listener2);
-        assertTrue(mgr.hasLoadListeners(pc, meta));
-        assertTrue(mgr.hasStoreListeners(pc, meta));
-        assertFalse(mgr.hasDirtyListeners(pc, meta));
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
-        assertEquals(2, listener.load);
-        assertEquals(0, listener.store);
-        assertEquals(0, listener.preStore);
-        assertEquals(1, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
-        assertEquals(2, listener.load);
-        assertEquals(1, listener.store);
-        assertEquals(0, listener.preStore);
-        assertEquals(1, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.BEFORE_STORE);
-        assertEquals(2, listener.load);
-        assertEquals(2, listener.store);
-        assertEquals(1, listener.preStore);
-        assertEquals(1, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_DIRTY);
-        assertEquals(2, listener.load);
-        assertEquals(2, listener.store);
-
-        mgr.removeListener(listener);
-        assertFalse(mgr.hasLoadListeners(pc, meta));
-        assertFalse(mgr.hasStoreListeners(pc, meta));
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
-        assertEquals(2, listener.load);
-        assertEquals(2, listener.store);
-    }
-
-    public void testBaseClassListener() {
-        MetaDataRepository repos =
-            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
-                OpenJPAPersistence.createEntityManagerFactory("TestConv2", "")))
-                .
-                    getConfiguration().getMetaDataRepositoryInstance();
-        ClassMetaData meta = repos.getMetaData(RuntimeTest2.class, null, true);
-
-        LifecycleEventManager mgr = new LifecycleEventManager();
-        RuntimeTest2 pc = new RuntimeTest2();
-        Listener listener = new Listener();
-
-        assertFalse(mgr.hasLoadListeners(pc, meta));
-        assertFalse(mgr.hasStoreListeners(pc, meta));
-
-        mgr.addListener(listener, new Class[]{ RuntimeTest1.class });
-        assertEquals(0, listener.load);
-        assertEquals(0, listener.store);
-        assertTrue(mgr.hasLoadListeners(pc, meta));
-        assertTrue(mgr.hasStoreListeners(pc, meta));
-        assertFalse(mgr.hasDirtyListeners(pc, meta));
-        assertFalse(mgr.hasLoadListeners(new RuntimeTest4("foo"), meta));
-        assertEquals(0, listener.load);
-        assertEquals(0, listener.store);
-
-        Listener listener2 = new Listener();
-        mgr.addListener(listener2, new Class[]{ RuntimeTest2.class });
-        assertTrue(mgr.hasLoadListeners(pc, meta));
-        assertTrue(mgr.hasStoreListeners(pc, meta));
-        assertFalse(mgr.hasDirtyListeners(pc, meta));
-        assertFalse(mgr.hasLoadListeners(new RuntimeTest4("foo"), meta));
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
-        assertEquals(1, listener.load);
-        assertEquals(0, listener.store);
-        assertEquals(1, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
-        assertEquals(2, listener.load);
-        assertEquals(0, listener.store);
-        assertEquals(2, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.fireEvent(new RuntimeTest1(), meta, LifecycleEvent.AFTER_LOAD);
-        assertEquals(3, listener.load);
-        assertEquals(0, listener.store);
-        assertEquals(2, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.removeListener(listener2);
-        assertTrue(mgr.hasLoadListeners(pc, meta));
-        assertTrue(mgr.hasStoreListeners(pc, meta));
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
-        assertEquals(3, listener.load);
-        assertEquals(1, listener.store);
-        assertEquals(2, listener2.load);
-        assertEquals(0, listener2.store);
-
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_DIRTY);
-        assertEquals(3, listener.load);
-        assertEquals(1, listener.store);
-
-        mgr.fireEvent(new RuntimeTest4("foo"), meta,
-            LifecycleEvent.AFTER_STORE);
-        assertEquals(3, listener.load);
-        assertEquals(1, listener.store);
-
-        mgr.removeListener(listener);
-        assertFalse(mgr.hasLoadListeners(pc, meta));
-        assertFalse(mgr.hasStoreListeners(pc, meta));
-        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
-        assertEquals(3, listener.load);
-        assertEquals(1, listener.store);
-    }
-
-    private static class Listener
-        implements LoadListener, StoreListener {
-
-        public int load = 0;
-        public int preStore = 0;
-        public int store = 0;
-
-        public void afterLoad(LifecycleEvent ev) {
-            load++;
-        }
-
-        public void afterRefresh(LifecycleEvent ev) {
-            // TODO
-        }
-
-        public void beforeStore(LifecycleEvent ev) {
-            preStore++;
-            store++;
-        }
-
-        public void afterStore(LifecycleEvent ev) {
-            store++;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest4;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.LifecycleEventManager;
+import org.apache.openjpa.event.LoadListener;
+import org.apache.openjpa.event.StoreListener;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/**
+ * <p>Test the {@link LifecycleEventManager}.</p>
+ *
+ * @author Abe White
+ */
+public class TestLifecycleEventManager
+    extends AbstractTestCase {
+
+    public TestLifecycleEventManager(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void testAllClassListener() {
+        MetaDataRepository repos =
+            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
+                OpenJPAPersistence.createEntityManagerFactory("TestConv2", "")))
+                .
+                    getConfiguration().getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(RuntimeTest2.class, null, true);
+        LifecycleEventManager mgr = new LifecycleEventManager();
+        RuntimeTest2 pc = new RuntimeTest2();
+        Listener listener = new Listener();
+
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+
+        mgr.addListener(listener, null);
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+
+        Listener listener2 = new Listener();
+        mgr.addListener(listener2, null);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(1, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(0, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.removeListener(listener2);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(2, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(0, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(2, listener.load);
+        assertEquals(1, listener.store);
+        assertEquals(0, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.BEFORE_STORE);
+        assertEquals(2, listener.load);
+        assertEquals(2, listener.store);
+        assertEquals(1, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_DIRTY);
+        assertEquals(2, listener.load);
+        assertEquals(2, listener.store);
+
+        mgr.removeListener(listener);
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(2, listener.load);
+        assertEquals(2, listener.store);
+    }
+
+    public void testBaseClassListener() {
+        MetaDataRepository repos =
+            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
+                OpenJPAPersistence.createEntityManagerFactory("TestConv2", "")))
+                .
+                    getConfiguration().getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(RuntimeTest2.class, null, true);
+
+        LifecycleEventManager mgr = new LifecycleEventManager();
+        RuntimeTest2 pc = new RuntimeTest2();
+        Listener listener = new Listener();
+
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+
+        mgr.addListener(listener, new Class[]{ RuntimeTest1.class });
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+        assertFalse(mgr.hasLoadListeners(new RuntimeTest4("foo"), meta));
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+
+        Listener listener2 = new Listener();
+        mgr.addListener(listener2, new Class[]{ RuntimeTest2.class });
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+        assertFalse(mgr.hasLoadListeners(new RuntimeTest4("foo"), meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(1, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(2, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(2, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(new RuntimeTest1(), meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(3, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(2, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.removeListener(listener2);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+        assertEquals(2, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_DIRTY);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+
+        mgr.fireEvent(new RuntimeTest4("foo"), meta,
+            LifecycleEvent.AFTER_STORE);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+
+        mgr.removeListener(listener);
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+    }
+
+    private static class Listener
+        implements LoadListener, StoreListener {
+
+        public int load = 0;
+        public int preStore = 0;
+        public int store = 0;
+
+        public void afterLoad(LifecycleEvent ev) {
+            load++;
+        }
+
+        public void afterRefresh(LifecycleEvent ev) {
+            // TODO
+        }
+
+        public void beforeStore(LifecycleEvent ev) {
+            preStore++;
+            store++;
+        }
+
+        public void afterStore(LifecycleEvent ev) {
+            store++;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java
index 409069b..e30dd4f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.event.SingleJVMRemoteCommitProvider;
-
-public class TestLocalRemoteEvents
-    extends RemoteEventBase {
-
-    public TestLocalRemoteEvents(String s) {
-        super(s);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testLocalEvents() {
-        doTest(SingleJVMRemoteCommitProvider.class, "", "");
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.SingleJVMRemoteCommitProvider;
+
+public class TestLocalRemoteEvents
+    extends RemoteEventBase {
+
+    public TestLocalRemoteEvents(String s) {
+        super(s);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testLocalEvents() {
+        doTest(SingleJVMRemoteCommitProvider.class, "", "");
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java
index f652efd..a84491e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java
@@ -1,136 +1,136 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.HashMap;
-import java.util.Map;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.common.utils.BufferedLogFactory;
-
-import org.apache.openjpa.event.OrphanedKeyAction;
-import org.apache.openjpa.persistence.EntityNotFoundException;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.util.OpenJPAException;
-
-/**
- * <p>Test the {@link OrphanedKeyAction} plugin.</p>
- *
- * @author Abe White
- */
-public class TestOrphanedKeyAction
-    extends AbstractTestCase {
-
-    private Object _oid = null;
-
-    public TestOrphanedKeyAction(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        RuntimeTest1 pc = new RuntimeTest1();
-        pc.setIntField(1);
-        RuntimeTest1 pc2 = new RuntimeTest1();
-        pc2.setIntField(2);
-        pc.setSelfOneOne(pc2);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        endTx(pm);
-        _oid = pm.getObjectId(pc);
-
-        startTx(pm);
-        pm.remove(pc2);
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testLog() {
-        Map map = getOrphanedKeyConfiguration("log(Level=FATAL)");
-
-        OpenJPAEntityManagerFactory pmf = getEmf(map);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        BufferedLogFactory logFactory = (BufferedLogFactory)
-            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
-        logFactory.clear();
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        logFactory.assertNoLogMessage("*orphan*");
-        assertNull(pc.getSelfOneOne());
-        logFactory.assertLogMessage("*orphan*");
-        endEm(pm);
-        pmf.close();
-    }
-
-    public void testException() {
-        Map map = getOrphanedKeyConfiguration("exception");
-        OpenJPAEntityManagerFactory pmf = getEmf(map);
-
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        BufferedLogFactory logFactory = (BufferedLogFactory)
-            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
-        logFactory.clear();
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        try {
-            pc.getSelfOneOne();
-            fail("Did not throw expected exception for orphaned key.");
-        } catch (EntityNotFoundException onfe) {
-            logFactory.assertNoLogMessage("*orphan*");
-        } catch (OpenJPAException ke) {
-            bug(1138, ke, "Wrong exception type.");
-        }
-        endEm(pm);
-        pmf.close();
-    }
-
-    public void testNone() {
-        Map map = getOrphanedKeyConfiguration("none");
-        OpenJPAEntityManagerFactory pmf = getEmf(map);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        BufferedLogFactory logFactory = (BufferedLogFactory)
-            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
-        logFactory.clear();
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        assertNull(pc.getSelfOneOne());
-        logFactory.assertNoLogMessage("*orphan*");
-        endEm(pm);
-        pmf.close();
-    }
-
-    Map getOrphanedKeyConfiguration(String orphanKeyAction) {
-        Map map = new HashMap();
-        map.put("openjpa.Log", BufferedLogFactory.class.getName());
-        if (orphanKeyAction != null)
-            map.put("openjpa.OrphanedKeyAction", orphanKeyAction);
-        return map;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.common.utils.BufferedLogFactory;
+
+import org.apache.openjpa.event.OrphanedKeyAction;
+import org.apache.openjpa.persistence.EntityNotFoundException;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.util.OpenJPAException;
+
+/**
+ * <p>Test the {@link OrphanedKeyAction} plugin.</p>
+ *
+ * @author Abe White
+ */
+public class TestOrphanedKeyAction
+    extends AbstractTestCase {
+
+    private Object _oid = null;
+
+    public TestOrphanedKeyAction(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        RuntimeTest1 pc = new RuntimeTest1();
+        pc.setIntField(1);
+        RuntimeTest1 pc2 = new RuntimeTest1();
+        pc2.setIntField(2);
+        pc.setSelfOneOne(pc2);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        _oid = pm.getObjectId(pc);
+
+        startTx(pm);
+        pm.remove(pc2);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testLog() {
+        Map map = getOrphanedKeyConfiguration("log(Level=FATAL)");
+
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        BufferedLogFactory logFactory = (BufferedLogFactory)
+            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
+        logFactory.clear();
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        logFactory.assertNoLogMessage("*orphan*");
+        assertNull(pc.getSelfOneOne());
+        logFactory.assertLogMessage("*orphan*");
+        endEm(pm);
+        pmf.close();
+    }
+
+    public void testException() {
+        Map map = getOrphanedKeyConfiguration("exception");
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        BufferedLogFactory logFactory = (BufferedLogFactory)
+            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
+        logFactory.clear();
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        try {
+            pc.getSelfOneOne();
+            fail("Did not throw expected exception for orphaned key.");
+        } catch (EntityNotFoundException onfe) {
+            logFactory.assertNoLogMessage("*orphan*");
+        } catch (OpenJPAException ke) {
+            bug(1138, ke, "Wrong exception type.");
+        }
+        endEm(pm);
+        pmf.close();
+    }
+
+    public void testNone() {
+        Map map = getOrphanedKeyConfiguration("none");
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        BufferedLogFactory logFactory = (BufferedLogFactory)
+            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
+        logFactory.clear();
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        assertNull(pc.getSelfOneOne());
+        logFactory.assertNoLogMessage("*orphan*");
+        endEm(pm);
+        pmf.close();
+    }
+
+    Map getOrphanedKeyConfiguration(String orphanKeyAction) {
+        Map map = new HashMap();
+        map.put("openjpa.Log", BufferedLogFactory.class.getName());
+        if (orphanKeyAction != null)
+            map.put("openjpa.OrphanedKeyAction", orphanKeyAction);
+        return map;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java
index 030bf8f..8445541 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java
@@ -1,273 +1,273 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.event.common.apps.Duration;
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.event.TCPRemoteCommitProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public class TestTCPRemoteClassChanges
-    extends AbstractTestCase {
-
-    public TestTCPRemoteClassChanges(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void tearDownTestClass()
-        throws Exception {
-        //super.tearDownTestClass();
-    }
-
-    private static final int NUM_OBJECTS = 4;
-
-    private void pause(double seconds) {
-        try {
-            Thread.currentThread().yield();
-            Thread.currentThread().sleep((int) seconds * 1000);
-        } catch (Exception e) {
-        }
-    }
-
-    public void testAddedClasses() {
-        // Create two pmfs in a cluster that are using RCPTCP.
-        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
-        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
-
-        // Register a RCEListener with the RCEM. Our RCEListener will
-        // record the total number of a,d, and u recevied from each
-        // RCE as the sending PM performs commits.
-        RemoteCommitListenerTestImpl listenerAtReceiver
-            = new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-
-        OpenJPAEntityManager pmSender = (OpenJPAEntityManager)
-            pmfSender.createEntityManager();
-
-        System.out.println("-------------------");
-        System.out.println(
-            "2 PMFs created, acting as a cluster using ports 5636 and 6636");
-        System.out.println(
-            "Testing scenario:");
-        System.out.println(
-            "  - tx of inserts (normal trans)\n" +
-                "  - tx of inserts (large trans)\n" +
-                "  - tx of inserts,updates, dels (large trans)");
-        System.out.println(
-            "Remote commit event will transmit classes.");
-
-        // Perform transaction that adds objects.
-        // Noraml transaction
-        performAdds(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the receiver can get the event.
-        pause(1);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
-
-        // largeTransaction
-        //pmSender.setLargeTransaction(true);
-        pmSender.setTrackChangesByType(true);
-        performAdds(pmSender, NUM_OBJECTS);
-        pause(1);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
-        assertEquals(0, listenerAtReceiver.totalUpdatedClasses);
-        assertEquals(0, listenerAtReceiver.totalDeletedClasses);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.receivedExtentEvCount);
-
-        // Still in large trans mode, perform updates and deletes of
-        // check that class names are communicated
-
-        //pmSender.setLargeTransaction(true);
-        pmSender.setTrackChangesByType(true);
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-        pause(1);
-        assertEquals(3 * NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdatedClasses);
-        // all deletes then a commit
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeletedClasses);
-        assertEquals(4 * NUM_OBJECTS,
-            listenerAtReceiver.receivedExtentEvCount);
-        assertEquals(0, listenerAtReceiver.totalOidUpdated);
-        assertEquals(0, listenerAtReceiver.totalOidDeleted);
-        assertEquals(0, listenerAtReceiver.totalOidAdded);
-
-        // shutdown
-        pmSender.close();
-        pmfSender.close();
-        pmfReceiver.close();
-    }
-
-    protected double performAdds(EntityManager pm,
-        int numObjects) {
-        // Perform a transaction that will trigger adds
-        Duration timeToAMD = new Duration(
-            "Adds, " + numObjects + " objects.");
-        timeToAMD.start();
-
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, i);
-        }
-
-        // add them, a commit per object
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            pm.persist(persistables[i]);
-            endTx(pm);
-        }
-
-        timeToAMD.stop();
-        return timeToAMD.getDurationAsSeconds();
-    }
-
-    protected void performAddsModifiesDeletes(EntityManager pm,
-        int numObjects) {
-        // Perform a series of transactions that will trigger adds,
-        // deletes, and udpates
-
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, i);
-        }
-
-        // add them
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            pm.persist(persistables[i]);
-            endTx(pm);
-        }
-
-        // modify them
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            persistables[i].setStringField("bazzed" + i);
-            endTx(pm);
-        }
-
-        // delete them
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            pm.remove(persistables[i]);
-            endTx(pm);
-        }
-    }
-
-    static int _fetchGroupSerial = 0;
-
-    protected OpenJPAEntityManagerFactory createDistinctFactory(
-        Class providerClass, String classProps1) {
-        Map propsMap;
-
-        if (providerClass != null) {
-
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
-                getPlugin(providerClass.getName(), classProps1));
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        } else {
-            // No RCP
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        }
-        _fetchGroupSerial += 1;
-
-        return (OpenJPAEntityManagerFactory) getEmf(propsMap);
-    }
-
-    protected static class RemoteCommitListenerTestImpl
-        implements RemoteCommitListener {
-
-        Collection updated;
-        Collection deleted;
-        int totalAddedClasses = 0;
-        int totalUpdatedClasses = 0;
-        int totalDeletedClasses = 0;
-
-        int totalOidAdded = 0;
-        int totalOidUpdated = 0;
-        int totalOidDeleted = 0;
-
-        int receivedExtentEvCount = 0;
-
-        public synchronized void afterCommit(RemoteCommitEvent event) {
-            totalAddedClasses += event.getPersistedTypeNames().size();
-            if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
-                receivedExtentEvCount += 1;
-                totalUpdatedClasses += event.getUpdatedTypeNames().size();
-                totalDeletedClasses += event.getDeletedTypeNames().size();
-            } else {
-                if (event.getPayloadType() ==
-                    RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS)
-                    totalOidAdded = event.getPersistedObjectIds().size();
-                this.updated = event.getUpdatedObjectIds();
-                this.deleted = event.getDeletedObjectIds();
-                totalOidUpdated += updated.size();
-                totalOidDeleted += deleted.size();
-            }
-        }
-
-        public void resetCounts() {
-            totalAddedClasses = 0;
-            totalUpdatedClasses = 0;
-            totalDeletedClasses = 0;
-            totalOidAdded = 0;
-            totalOidUpdated = 0;
-            totalOidDeleted = 0;
-        }
-
-        public void close() {
-        }
-
-        public String toString() {
-            String returnString = "Clsses add=" + totalAddedClasses + " dels=" +
-                totalDeletedClasses + " ups=" + totalUpdatedClasses;
-            returnString = returnString + "Oids add=" + totalAddedClasses +
-                " dels=" + totalDeletedClasses + " ups=" + totalUpdatedClasses;
-            return returnString;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteClassChanges
+    extends AbstractTestCase {
+
+    public TestTCPRemoteClassChanges(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    private static final int NUM_OBJECTS = 4;
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testAddedClasses() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. Our RCEListener will
+        // record the total number of a,d, and u recevied from each
+        // RCE as the sending PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        OpenJPAEntityManager pmSender = (OpenJPAEntityManager)
+            pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println(
+            "2 PMFs created, acting as a cluster using ports 5636 and 6636");
+        System.out.println(
+            "Testing scenario:");
+        System.out.println(
+            "  - tx of inserts (normal trans)\n" +
+                "  - tx of inserts (large trans)\n" +
+                "  - tx of inserts,updates, dels (large trans)");
+        System.out.println(
+            "Remote commit event will transmit classes.");
+
+        // Perform transaction that adds objects.
+        // Noraml transaction
+        performAdds(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the receiver can get the event.
+        pause(1);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
+
+        // largeTransaction
+        //pmSender.setLargeTransaction(true);
+        pmSender.setTrackChangesByType(true);
+        performAdds(pmSender, NUM_OBJECTS);
+        pause(1);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
+        assertEquals(0, listenerAtReceiver.totalUpdatedClasses);
+        assertEquals(0, listenerAtReceiver.totalDeletedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.receivedExtentEvCount);
+
+        // Still in large trans mode, perform updates and deletes of
+        // check that class names are communicated
+
+        //pmSender.setLargeTransaction(true);
+        pmSender.setTrackChangesByType(true);
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+        pause(1);
+        assertEquals(3 * NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdatedClasses);
+        // all deletes then a commit
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeletedClasses);
+        assertEquals(4 * NUM_OBJECTS,
+            listenerAtReceiver.receivedExtentEvCount);
+        assertEquals(0, listenerAtReceiver.totalOidUpdated);
+        assertEquals(0, listenerAtReceiver.totalOidDeleted);
+        assertEquals(0, listenerAtReceiver.totalOidAdded);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected double performAdds(EntityManager pm,
+        int numObjects) {
+        // Perform a transaction that will trigger adds
+        Duration timeToAMD = new Duration(
+            "Adds, " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them, a commit per object
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    protected void performAddsModifiesDeletes(EntityManager pm,
+        int numObjects) {
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            persistables[i].setStringField("bazzed" + i);
+            endTx(pm);
+        }
+
+        // delete them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.remove(persistables[i]);
+            endTx(pm);
+        }
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        Map propsMap;
+
+        if (providerClass != null) {
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return (OpenJPAEntityManagerFactory) getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection updated;
+        Collection deleted;
+        int totalAddedClasses = 0;
+        int totalUpdatedClasses = 0;
+        int totalDeletedClasses = 0;
+
+        int totalOidAdded = 0;
+        int totalOidUpdated = 0;
+        int totalOidDeleted = 0;
+
+        int receivedExtentEvCount = 0;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+            totalAddedClasses += event.getPersistedTypeNames().size();
+            if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
+                receivedExtentEvCount += 1;
+                totalUpdatedClasses += event.getUpdatedTypeNames().size();
+                totalDeletedClasses += event.getDeletedTypeNames().size();
+            } else {
+                if (event.getPayloadType() ==
+                    RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS)
+                    totalOidAdded = event.getPersistedObjectIds().size();
+                this.updated = event.getUpdatedObjectIds();
+                this.deleted = event.getDeletedObjectIds();
+                totalOidUpdated += updated.size();
+                totalOidDeleted += deleted.size();
+            }
+        }
+
+        public void resetCounts() {
+            totalAddedClasses = 0;
+            totalUpdatedClasses = 0;
+            totalDeletedClasses = 0;
+            totalOidAdded = 0;
+            totalOidUpdated = 0;
+            totalOidDeleted = 0;
+        }
+
+        public void close() {
+        }
+
+        public String toString() {
+            String returnString = "Clsses add=" + totalAddedClasses + " dels=" +
+                totalDeletedClasses + " ups=" + totalUpdatedClasses;
+            returnString = returnString + "Oids add=" + totalAddedClasses +
+                " dels=" + totalDeletedClasses + " ups=" + totalUpdatedClasses;
+            return returnString;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java
index 67ebe78..ba3f219 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.event.TCPRemoteCommitProvider;
-
-public class TestTCPRemoteEvents
-    extends RemoteEventBase {
-
-    public TestTCPRemoteEvents(String s) {
-        super(s);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testEvents() {
-        doTest(TCPRemoteCommitProvider.class,
-            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636",
-            "Port=6636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+
+public class TestTCPRemoteEvents
+    extends RemoteEventBase {
+
+    public TestTCPRemoteEvents(String s) {
+        super(s);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testEvents() {
+        doTest(TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636",
+            "Port=6636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java
index f5d6145..c28fed6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java
@@ -1,278 +1,278 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.event.common.apps.Duration;
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.event.TCPRemoteCommitProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public class TestTCPRemoteEventsDuration
-    extends AbstractTestCase {
-
-    public TestTCPRemoteEventsDuration(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void tearDownTestClass()
-        throws Exception {
-        //super.tearDownTestClass();
-    }
-
-    // FYI For 1000 objects with MySQL -- 1005 transactions,
-    // doTransactions () takes 45 seconds
-    private static final int NUM_OBJECTS = 200;
-    private static final int NUM_TO_AVERAGE = 3;
-    private static final int NUM_CONCURRENT = 3;
-
-    public void testDurationDifference() {
-        // create a non-cluserted, single pmf
-        OpenJPAEntityManagerFactory factorySingle = createDistinctFactory(
-            null, "");
-        EntityManager pmSingle = factorySingle.createEntityManager();
-
-        // Create 2 pmfs that are using RCPTCP. run same benachmark of
-        // transactions
-        OpenJPAEntityManagerFactory senderFactory1TCP =
-            createDistinctFactory(TCPRemoteCommitProvider.class,
-                "MaxActive=4, RecoveryTimeMillis=1000, Port=5636, " +
-                    "Addresses=127.0.0.1:5636;127.0.0.1:6636");
-        OpenJPAEntityManagerFactory factory2TCP = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
-
-        // Register a RCEListener with the RCEM. The RCEListener
-        // will record the number of
-        // a,d, and u recevied when the sender PM performs commits.
-        RemoteCommitListenerTestImpl listenerAtReceiver
-            = new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) factory2TCP).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-
-        System.out.println("-------------------");
-        System.out.println("3 PMFs created, 1 as standalone, and 2 acting " +
-            "as a cluster using ports 5636 and 6636");
-        // This call is a "throw away" run to seed caches, etc.
-        doTransactions(pmSingle, NUM_OBJECTS);
-
-        double benchmarkSingle = 0.0;
-        for (int i = 0; i < NUM_TO_AVERAGE; i++) {
-            benchmarkSingle += doTransactions(pmSingle, NUM_OBJECTS);
-        }
-        benchmarkSingle /= NUM_TO_AVERAGE;
-
-        EntityManager pmOneThread =
-            senderFactory1TCP.createEntityManager();
-        double benchmarkClusterOneThread = doTransactions(pmOneThread,
-            NUM_OBJECTS);
-        pmOneThread.close();
-
-        Duration timeThreaded = new Duration("For " + NUM_CONCURRENT +
-            " concurrent threads performing Adds, removes, and dletes for " +
-            NUM_OBJECTS + " objects.");
-
-        Thread[] concurrentThreads = new Thread[NUM_CONCURRENT];
-        timeThreaded.start();
-        for (int i = 0; i < NUM_CONCURRENT; i++) {
-            Worker worker = new Worker
-                (senderFactory1TCP.createEntityManager());
-            concurrentThreads[i] = new Thread(worker);
-            concurrentThreads[i].start();
-        }
-        // Wait for all threads to finish
-        for (int i = 0; i < NUM_CONCURRENT; i++) {
-            try {
-                concurrentThreads[i].join();
-            } catch (Exception e) {
-                assertTrue(false);
-                break;
-            }
-        }
-        timeThreaded.stop();
-        double benchmarkCluster = timeThreaded.getDurationAsSeconds();
-
-        System.out.println("For " + NUM_OBJECTS + " objects, and " +
-            NUM_CONCURRENT + " concurrent threads, the receiving pmf of the " +
-            "cluster received :" +
-            listenerAtReceiver.totalAddedClasses + " claases adds, " +
-            listenerAtReceiver.totalDeleted + " deletes, " +
-            listenerAtReceiver.totalUpdated + " updates");
-        System.out.println(
-            "\nSingle pmf - " + benchmarkSingle +
-                "(s).\n Clustered pmfs (one worker thread) -"
-                + benchmarkClusterOneThread +
-                "(s).\n Clustered pmfs (" + NUM_CONCURRENT
-                + " threads - " + benchmarkCluster + "(s).\n");
-
-        Thread.currentThread().yield();
-        try {
-            Thread.currentThread().sleep((int) 500);
-        } catch (InterruptedException e) {
-            fail("unexecpted exception during pause");
-        }
-        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
-            listenerAtReceiver.totalAddedClasses);
-        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
-            listenerAtReceiver.totalDeleted);
-        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
-            listenerAtReceiver.totalUpdated);
-
-        // shutdown
-        pmSingle.close();
-        factorySingle.close();
-
-        factory2TCP.close();
-        senderFactory1TCP.close();
-    }
-
-    /*
-      *	Worker thread that takes ownership of a PM to perform
-      *	transactions. Once transactions are complete the tread
-      *	will close the PM and end.
-      */
-    private class Worker
-        implements Runnable {
-
-        private EntityManager _pm;
-
-        public Worker(EntityManager pm) {
-            _pm = pm;
-        }
-
-        public void run() {
-            doTransactions(_pm, NUM_OBJECTS);
-            endEm(_pm);
-        }
-    }
-
-    protected double doTransactions(EntityManager pm, int numObjects) {
-        // Perform a series of transactions  that will trigger
-        // adds, deletes, and udpates
-        Duration timeToAMD = new Duration(
-            "Adds, removes, and dletes for " + numObjects + " objects.");
-        timeToAMD.start();
-
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, i);
-        }
-
-        // add them
-        // This will generate a larger number of transaction in a very
-        // short amount of time (old socket-per-transaction would
-        // exhaust jvm socket pool)
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            pm.persist(persistables[i]);
-            endTx(pm);
-        }
-
-        // modify them
-        startTx(pm);
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i].setStringField("bazzed" + i);
-        }
-        endTx(pm);
-
-        // delete them
-        startTx(pm);
-        for (int i = 0; i < persistables.length; i++) {
-            pm.remove(persistables[i]);
-        }
-        endTx(pm);
-
-        timeToAMD.stop();
-        return timeToAMD.getDurationAsSeconds();
-    }
-
-    static int _fetchGroupSerial = 0;
-
-    protected OpenJPAEntityManagerFactory createDistinctFactory(
-        Class providerClass, String classProps1) {
-        String transmit = "TransmitPersistedObjectIds=true";
-        if (classProps1 == null || classProps1.length() == 0)
-            classProps1 = transmit;
-        else
-            classProps1 += "," + transmit;
-
-        Map propsMap;
-        if (providerClass != null) {
-
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
-                getPlugin(providerClass.getName(), classProps1));
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        } else {
-            // No RCP
-
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider",
-                "sjvm(TransmitPersistedObjectIds=true)");
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        }
-        _fetchGroupSerial += 1;
-
-        return getEmf(propsMap);
-    }
-
-    protected static class RemoteCommitListenerTestImpl
-        implements RemoteCommitListener {
-
-        Collection addClasses;
-        Collection added;
-        Collection updated;
-        Collection deleted;
-        int totalAddedClasses;
-        int totalUpdated;
-        int totalDeleted;
-
-        public synchronized void afterCommit(RemoteCommitEvent event) {
-            this.addClasses = event.getPersistedTypeNames();
-            this.updated = event.getUpdatedObjectIds();
-            this.deleted = event.getDeletedObjectIds();
-
-            totalAddedClasses += addClasses.size();
-            totalUpdated += updated.size();
-            totalDeleted += deleted.size();
-        }
-
-        public void close() {
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteEventsDuration
+    extends AbstractTestCase {
+
+    public TestTCPRemoteEventsDuration(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    // FYI For 1000 objects with MySQL -- 1005 transactions,
+    // doTransactions () takes 45 seconds
+    private static final int NUM_OBJECTS = 200;
+    private static final int NUM_TO_AVERAGE = 3;
+    private static final int NUM_CONCURRENT = 3;
+
+    public void testDurationDifference() {
+        // create a non-cluserted, single pmf
+        OpenJPAEntityManagerFactory factorySingle = createDistinctFactory(
+            null, "");
+        EntityManager pmSingle = factorySingle.createEntityManager();
+
+        // Create 2 pmfs that are using RCPTCP. run same benachmark of
+        // transactions
+        OpenJPAEntityManagerFactory senderFactory1TCP =
+            createDistinctFactory(TCPRemoteCommitProvider.class,
+                "MaxActive=4, RecoveryTimeMillis=1000, Port=5636, " +
+                    "Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory factory2TCP = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. The RCEListener
+        // will record the number of
+        // a,d, and u recevied when the sender PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) factory2TCP).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        System.out.println("-------------------");
+        System.out.println("3 PMFs created, 1 as standalone, and 2 acting " +
+            "as a cluster using ports 5636 and 6636");
+        // This call is a "throw away" run to seed caches, etc.
+        doTransactions(pmSingle, NUM_OBJECTS);
+
+        double benchmarkSingle = 0.0;
+        for (int i = 0; i < NUM_TO_AVERAGE; i++) {
+            benchmarkSingle += doTransactions(pmSingle, NUM_OBJECTS);
+        }
+        benchmarkSingle /= NUM_TO_AVERAGE;
+
+        EntityManager pmOneThread =
+            senderFactory1TCP.createEntityManager();
+        double benchmarkClusterOneThread = doTransactions(pmOneThread,
+            NUM_OBJECTS);
+        pmOneThread.close();
+
+        Duration timeThreaded = new Duration("For " + NUM_CONCURRENT +
+            " concurrent threads performing Adds, removes, and dletes for " +
+            NUM_OBJECTS + " objects.");
+
+        Thread[] concurrentThreads = new Thread[NUM_CONCURRENT];
+        timeThreaded.start();
+        for (int i = 0; i < NUM_CONCURRENT; i++) {
+            Worker worker = new Worker
+                (senderFactory1TCP.createEntityManager());
+            concurrentThreads[i] = new Thread(worker);
+            concurrentThreads[i].start();
+        }
+        // Wait for all threads to finish
+        for (int i = 0; i < NUM_CONCURRENT; i++) {
+            try {
+                concurrentThreads[i].join();
+            } catch (Exception e) {
+                assertTrue(false);
+                break;
+            }
+        }
+        timeThreaded.stop();
+        double benchmarkCluster = timeThreaded.getDurationAsSeconds();
+
+        System.out.println("For " + NUM_OBJECTS + " objects, and " +
+            NUM_CONCURRENT + " concurrent threads, the receiving pmf of the " +
+            "cluster received :" +
+            listenerAtReceiver.totalAddedClasses + " claases adds, " +
+            listenerAtReceiver.totalDeleted + " deletes, " +
+            listenerAtReceiver.totalUpdated + " updates");
+        System.out.println(
+            "\nSingle pmf - " + benchmarkSingle +
+                "(s).\n Clustered pmfs (one worker thread) -"
+                + benchmarkClusterOneThread +
+                "(s).\n Clustered pmfs (" + NUM_CONCURRENT
+                + " threads - " + benchmarkCluster + "(s).\n");
+
+        Thread.currentThread().yield();
+        try {
+            Thread.currentThread().sleep((int) 500);
+        } catch (InterruptedException e) {
+            fail("unexecpted exception during pause");
+        }
+        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
+            listenerAtReceiver.totalAddedClasses);
+        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
+            listenerAtReceiver.totalDeleted);
+        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
+            listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSingle.close();
+        factorySingle.close();
+
+        factory2TCP.close();
+        senderFactory1TCP.close();
+    }
+
+    /*
+      *	Worker thread that takes ownership of a PM to perform
+      *	transactions. Once transactions are complete the tread
+      *	will close the PM and end.
+      */
+    private class Worker
+        implements Runnable {
+
+        private EntityManager _pm;
+
+        public Worker(EntityManager pm) {
+            _pm = pm;
+        }
+
+        public void run() {
+            doTransactions(_pm, NUM_OBJECTS);
+            endEm(_pm);
+        }
+    }
+
+    protected double doTransactions(EntityManager pm, int numObjects) {
+        // Perform a series of transactions  that will trigger
+        // adds, deletes, and udpates
+        Duration timeToAMD = new Duration(
+            "Adds, removes, and dletes for " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        // This will generate a larger number of transaction in a very
+        // short amount of time (old socket-per-transaction would
+        // exhaust jvm socket pool)
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setStringField("bazzed" + i);
+        }
+        endTx(pm);
+
+        // delete them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            pm.remove(persistables[i]);
+        }
+        endTx(pm);
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        String transmit = "TransmitPersistedObjectIds=true";
+        if (classProps1 == null || classProps1.length() == 0)
+            classProps1 = transmit;
+        else
+            classProps1 += "," + transmit;
+
+        Map propsMap;
+        if (providerClass != null) {
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider",
+                "sjvm(TransmitPersistedObjectIds=true)");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection addClasses;
+        Collection added;
+        Collection updated;
+        Collection deleted;
+        int totalAddedClasses;
+        int totalUpdated;
+        int totalDeleted;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+            this.addClasses = event.getPersistedTypeNames();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+
+            totalAddedClasses += addClasses.size();
+            totalUpdated += updated.size();
+            totalDeleted += deleted.size();
+        }
+
+        public void close() {
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java
index e36647a..947623d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java
@@ -1,327 +1,327 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.event.common.apps.Duration;
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.event.TCPRemoteCommitProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public class TestTCPRemoteRecovery
-    extends AbstractTestCase {
-
-    public TestTCPRemoteRecovery(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void tearDownTestClass()
-        throws Exception {
-        //super.tearDownTestClass();
-    }
-
-    private static final int NUM_OBJECTS = 1;
-
-    private void pause(double seconds) {
-        try {
-            Thread.currentThread().yield();
-            Thread.currentThread().sleep((int) seconds * 1000);
-        } catch (Exception e) {
-        }
-    }
-
-    public void testReceiverRecovers() {
-        // Create two pmfs in a cluster that are using RCPTCP.
-        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
-        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
-
-        // Register a RCEListener with the RCEM. Our RCEListener will
-        // record the total number of a,d, and u recevied from each
-        // RCE as the sending PM performs commits.
-        RemoteCommitListenerTestImpl listenerAtReceiver
-            = new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-
-        EntityManager pmSender = pmfSender.createEntityManager();
-
-        System.out.println("-------------------");
-        System.out.println("2 PMFs created, acting as a cluster using ports " +
-            "5636 and 6636");
-        System.out.println("Testing scenario where receiver is failed, then " +
-            "recovered ");
-        System.out.println("after two timeouts all the while with the " +
-            "sending pm continuing");
-        System.out.println("to send.");
-
-        // Perform a set of transactions. Events will be communicated
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the receiver can get the event.
-        pause(1);
-        // Now Fail the receiver in the cluster
-        System.out.println("About to close the receiving pmf.");
-        pmfReceiver.close();
-        // Wait for a bit longer so the listener's threads all
-        // get closed out.
-        pause(1);
-        assertEquals(1, listenerAtReceiver.totalAddedClasses);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        System.out.println("You should now see 1 WARN triggered as the " +
-            "sender-pmf tries to send.");
-        // Perform second set of transactions. This will trigger a single
-        // log WARN as the pmf won't be able to communciate events to the
-        // second member of the cluster.
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a recoverytime, try transactions again, this will
-        // trigger an INFO
-        pause(15.1);
-        System.out.println("Waited for a while. Should see 1 INFO for next " +
-            "transaction.");
-
-        // This will trigger a single log INFO
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-        // This delay should ensure this second sent of
-        // transmissions is dropped as expected. If we
-        // don't pause, the new pmf can be created, then the
-        // events will be sent by the worker threads, and
-        // the new pmf will receive this messages (which
-        // are supposed to be dropped)
-        pause(1.1);
-
-        // -----
-        // Now recovery the Receiver and test that messages
-        // resume being delivered.
-        // -----
-
-        System.out.println("Recovering receiver pmf.");
-        // Recreate the listener pmf of the cluster.
-        pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
-        pause(1.0);
-        // reRegister the same listener
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-        assertEquals(1, listenerAtReceiver.totalAddedClasses);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        System.out.println("Now waiting a recoverytime so that the sender");
-        System.out.println("will resume trying to connect to the receiver.");
-        pause(15.1);
-
-        // These events should get communicated.
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a last little bit so the listener thread in
-        // the receiver PMF can get all messages.
-        pause(1.0);
-        assertEquals(2, listenerAtReceiver.totalAddedClasses);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        // shutdown
-        pmSender.close();
-        pmfSender.close();
-        pmfReceiver.close();
-    }
-
-    public void testSenderRecovers() {
-        // Create two pmfs in a cluster that are using RCPTCP.
-        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
-        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6637, Addresses=127.0.0.1:6637;127.0.0.1:5637");
-
-        RemoteCommitListenerTestImpl listenerAtReceiver
-            = new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-
-        EntityManager pmSender = pmfSender.createEntityManager();
-
-        System.out.println("-------------------");
-        System.out.println("2 PMFs created, acting as a cluster using ports " +
-            "5637 and 6637");
-        System.out.println("Testing scenario where sender fails and then " +
-            "later recovers.");
-        System.out.println("All the while the receiving pm stays up and " +
-            "should receive");
-        System.out.println("Events (both before and after the sender's " +
-            "failure).");
-
-        // Perform a set of transactions. Events in the cluster will be
-        // communicated
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the sockets in our sender PMF can fully transmit
-        // their Event messages to the receiver PMF.
-        pause(2.1);
-        // Fail the Sender in our cluster
-        System.out.println("Sender pmf closed.");
-        pmSender.close();
-        pmfSender.close();
-
-        // Wait for a while, try again, this will let close exception propagate
-        pause(4.1);
-        System.out.println("Waited for a while.");
-        System.out.println("Recovering the sender pmf.");
-
-        pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
-        pmSender = pmfSender.createEntityManager();
-        // Perform a second set of transactions. Events in the cluster will be
-        // communicated
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the listener thread in the receiver PMF can get all
-        // messages.
-        pause(4.1);
-        assertEquals(2, listenerAtReceiver.totalAddedClasses);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        // shutdown
-        pmSender.close();
-        pmfSender.close();
-        pmfReceiver.close();
-    }
-
-    protected double performAddsModifiesDeletes(EntityManager pm,
-        int numObjects) {
-        // Perform a series of transactions that will trigger adds,
-        // deletes, and udpates
-        Duration timeToAMD = new Duration(
-            "Adds, removes, and dletes for " + numObjects + " objects.");
-        timeToAMD.start();
-
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, i);
-        }
-
-        // add them
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            pm.persist(persistables[i]);
-            endTx(pm);
-        }
-
-        // modify them
-        startTx(pm);
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i].setStringField("bazzed" + i);
-        }
-        endTx(pm);
-
-        // delete them
-        startTx(pm);
-        for (int i = 0; i < persistables.length; i++) {
-            pm.remove(persistables[i]);
-        }
-        endTx(pm);
-
-        timeToAMD.stop();
-        return timeToAMD.getDurationAsSeconds();
-    }
-
-    static int _fetchGroupSerial = 0;
-
-    protected OpenJPAEntityManagerFactory createDistinctFactory(
-        Class providerClass, String classProps1) {
-        Map propsMap;
-
-        if (providerClass != null) {
-
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
-                getPlugin(providerClass.getName(), classProps1));
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        } else {
-            // No RCP
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        }
-        _fetchGroupSerial += 1;
-
-        return getEmf(propsMap);
-    }
-
-    protected static class RemoteCommitListenerTestImpl
-        implements RemoteCommitListener {
-
-        Collection updated;
-        Collection deleted;
-        int totalAddedClasses;
-        int totalUpdated;
-        int totalDeleted;
-
-        public synchronized void afterCommit(RemoteCommitEvent event) {
-            this.updated = event.getUpdatedObjectIds();
-            this.deleted = event.getDeletedObjectIds();
-
-            totalAddedClasses += event.getPersistedTypeNames().size();
-            totalUpdated += updated.size();
-            totalDeleted += deleted.size();
-            System.out.println("Aftercommit " + this);
-        }
-
-        public void close() {
-        }
-
-        public String toString() {
-            String returnString = "Added clsses " + totalAddedClasses +
-                " Dels " + totalDeleted + " Ups " + totalUpdated;
-            return returnString;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteRecovery
+    extends AbstractTestCase {
+
+    public TestTCPRemoteRecovery(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    private static final int NUM_OBJECTS = 1;
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testReceiverRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. Our RCEListener will
+        // record the total number of a,d, and u recevied from each
+        // RCE as the sending PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5636 and 6636");
+        System.out.println("Testing scenario where receiver is failed, then " +
+            "recovered ");
+        System.out.println("after two timeouts all the while with the " +
+            "sending pm continuing");
+        System.out.println("to send.");
+
+        // Perform a set of transactions. Events will be communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the receiver can get the event.
+        pause(1);
+        // Now Fail the receiver in the cluster
+        System.out.println("About to close the receiving pmf.");
+        pmfReceiver.close();
+        // Wait for a bit longer so the listener's threads all
+        // get closed out.
+        pause(1);
+        assertEquals(1, listenerAtReceiver.totalAddedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("You should now see 1 WARN triggered as the " +
+            "sender-pmf tries to send.");
+        // Perform second set of transactions. This will trigger a single
+        // log WARN as the pmf won't be able to communciate events to the
+        // second member of the cluster.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a recoverytime, try transactions again, this will
+        // trigger an INFO
+        pause(15.1);
+        System.out.println("Waited for a while. Should see 1 INFO for next " +
+            "transaction.");
+
+        // This will trigger a single log INFO
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+        // This delay should ensure this second sent of
+        // transmissions is dropped as expected. If we
+        // don't pause, the new pmf can be created, then the
+        // events will be sent by the worker threads, and
+        // the new pmf will receive this messages (which
+        // are supposed to be dropped)
+        pause(1.1);
+
+        // -----
+        // Now recovery the Receiver and test that messages
+        // resume being delivered.
+        // -----
+
+        System.out.println("Recovering receiver pmf.");
+        // Recreate the listener pmf of the cluster.
+        pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+        pause(1.0);
+        // reRegister the same listener
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+        assertEquals(1, listenerAtReceiver.totalAddedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("Now waiting a recoverytime so that the sender");
+        System.out.println("will resume trying to connect to the receiver.");
+        pause(15.1);
+
+        // These events should get communicated.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a last little bit so the listener thread in
+        // the receiver PMF can get all messages.
+        pause(1.0);
+        assertEquals(2, listenerAtReceiver.totalAddedClasses);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    public void testSenderRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6637, Addresses=127.0.0.1:6637;127.0.0.1:5637");
+
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5637 and 6637");
+        System.out.println("Testing scenario where sender fails and then " +
+            "later recovers.");
+        System.out.println("All the while the receiving pm stays up and " +
+            "should receive");
+        System.out.println("Events (both before and after the sender's " +
+            "failure).");
+
+        // Perform a set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the sockets in our sender PMF can fully transmit
+        // their Event messages to the receiver PMF.
+        pause(2.1);
+        // Fail the Sender in our cluster
+        System.out.println("Sender pmf closed.");
+        pmSender.close();
+        pmfSender.close();
+
+        // Wait for a while, try again, this will let close exception propagate
+        pause(4.1);
+        System.out.println("Waited for a while.");
+        System.out.println("Recovering the sender pmf.");
+
+        pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        pmSender = pmfSender.createEntityManager();
+        // Perform a second set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the listener thread in the receiver PMF can get all
+        // messages.
+        pause(4.1);
+        assertEquals(2, listenerAtReceiver.totalAddedClasses);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected double performAddsModifiesDeletes(EntityManager pm,
+        int numObjects) {
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+        Duration timeToAMD = new Duration(
+            "Adds, removes, and dletes for " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setStringField("bazzed" + i);
+        }
+        endTx(pm);
+
+        // delete them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            pm.remove(persistables[i]);
+        }
+        endTx(pm);
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        Map propsMap;
+
+        if (providerClass != null) {
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection updated;
+        Collection deleted;
+        int totalAddedClasses;
+        int totalUpdated;
+        int totalDeleted;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+
+            totalAddedClasses += event.getPersistedTypeNames().size();
+            totalUpdated += updated.size();
+            totalDeleted += deleted.size();
+            System.out.println("Aftercommit " + this);
+        }
+
+        public void close() {
+        }
+
+        public String toString() {
+            String returnString = "Added clsses " + totalAddedClasses +
+                " Dels " + totalDeleted + " Ups " + totalUpdated;
+            return returnString;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java
index 9225258..56bfbb5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java
@@ -1,335 +1,335 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.event.common.apps.Duration;
-import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.event.RemoteCommitEvent;
-import org.apache.openjpa.event.RemoteCommitListener;
-import org.apache.openjpa.event.TCPRemoteCommitProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public class TestTCPRemoteRecoveryTransmitAdds
-    extends AbstractTestCase {
-
-    public TestTCPRemoteRecoveryTransmitAdds(String s) {
-        super(s, "eventcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void tearDownTestClass()
-        throws Exception {
-        //super.tearDownTestClass();
-    }
-
-    private static final int NUM_OBJECTS = 1;
-
-    private void pause(double seconds) {
-        try {
-            Thread.currentThread().yield();
-            Thread.currentThread().sleep((int) seconds * 1000);
-        } catch (Exception e) {
-        }
-    }
-
-    public void testReceiverRecovers() {
-        // Create two pmfs in a cluster that are using RCPTCP.
-        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
-        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
-
-        // Register a RCEListener with the RCEM. Our RCEListener will
-        // record the total number of a,d, and u recevied from each
-        // RCE as the sending PM performs commits.
-        RemoteCommitListenerTestImpl listenerAtReceiver
-            = new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-
-        EntityManager pmSender = pmfSender.createEntityManager();
-
-        System.out.println("-------------------");
-        System.out.println("2 PMFs created, acting as a cluster using ports " +
-            "5636 and 6636");
-        System.out.println("Testing scenario where receiver is failed, then " +
-            "recovered ");
-        System.out.println("after two timeouts all the while with the " +
-            "sending pm continuing");
-        System.out.println("to send.");
-
-        // Perform a set of transactions. Events will be communicated
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the receiver can get the event.
-        pause(3);
-        // Now Fail the receiver in the cluster
-        System.out.println("About to close the receiving pmf.");
-        pmfReceiver.close();
-        // Wait for a bit longer so the listener's threads all
-        // get closed out.
-        pause(3);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAdded);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        System.out.println("You should now see 1 WARN triggered as the " +
-            "sender-pmf tries to send.");
-        // Perform second set of transactions. This will trigger a single
-        // log WARN as the pmf won't be able to communciate events to the
-        // second member of the cluster.
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a recoverytime, try transactions again, this will
-        // trigger an INFO
-        pause(15.1);
-        System.out.println("Waited for a while. Should see 1 INFO for next " +
-            "transaction.");
-
-        // This will trigger a single log INFO
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-        // This delay should ensure this second sent of
-        // transmissions is dropped as expected. If we
-        // don't pause, the new pmf can be created, then the
-        // events will be sent by the worker threads, and
-        // the new pmf will receive this messages (which
-        // are supposed to be dropped)
-        pause(1.1);
-
-        // -----
-        // Now recovery the Receiver and test that messages
-        // resume being delivered.
-        // -----
-
-        System.out.println("Recovering receiver pmf.");
-        // Recreate the listener pmf of the cluster.
-        pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
-        pause(1.0);
-        // reRegister the same listener
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAdded);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        System.out.println("Now waiting a recoverytime so that the sender");
-        System.out.println("will resume trying to connect to the receiver.");
-        pause(15.1);
-
-        // These events should get communicated.
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a last little bit so the listener thread in
-        // the receiver PMF can get all messages.
-        pause(1.0);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAdded);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        // shutdown
-        pmSender.close();
-        pmfSender.close();
-        pmfReceiver.close();
-    }
-
-    public void testSenderRecovers() {
-        // Create two pmfs in a cluster that are using RCPTCP.
-        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
-        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=6637, Addresses=127.0.0.1:6637;127.0.0.1:5637");
-
-        RemoteCommitListenerTestImpl listenerAtReceiver
-            = new RemoteCommitListenerTestImpl();
-        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
-            .getRemoteCommitEventManager().
-            addListener(listenerAtReceiver);
-
-        EntityManager pmSender = pmfSender.createEntityManager();
-
-        System.out.println("-------------------");
-        System.out.println("2 PMFs created, acting as a cluster using ports " +
-            "5637 and 6637");
-        System.out.println("Testing scenario where sender fails and then " +
-            "later recovers.");
-        System.out.println("All the while the receiving pm stays up and " +
-            "should receive");
-        System.out.println("Events (both before and after the sender's " +
-            "failure).");
-
-        // Perform a set of transactions. Events in the cluster will be
-        // communicated
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the sockets in our sender PMF can fully transmit
-        // their Event messages to the receiver PMF.
-        pause(2.1);
-        // Fail the Sender in our cluster
-        System.out.println("Sender pmf closed.");
-        pmSender.close();
-        pmfSender.close();
-
-        // Wait for a while, try again, this will let close exception propagate
-        pause(4.1);
-        System.out.println("Waited for a while.");
-        System.out.println("Recovering the sender pmf.");
-
-        pmfSender = createDistinctFactory(
-            TCPRemoteCommitProvider.class,
-            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
-        pmSender = pmfSender.createEntityManager();
-        // Perform a second set of transactions. Events in the cluster will be
-        // communicated
-        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
-
-        // Wait for a bit so the listener thread in the receiver PMF can get all
-        // messages.
-        pause(4.1);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAdded);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
-        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
-
-        // shutdown
-        pmSender.close();
-        pmfSender.close();
-        pmfReceiver.close();
-    }
-
-    protected double performAddsModifiesDeletes(EntityManager pm,
-        int numObjects) {
-        // Perform a series of transactions that will trigger adds,
-        // deletes, and udpates
-        Duration timeToAMD = new Duration(
-            "Adds, removes, and dletes for " + numObjects + " objects.");
-        timeToAMD.start();
-
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, i);
-        }
-
-        // add them
-        for (int i = 0; i < persistables.length; i++) {
-            startTx(pm);
-            pm.persist(persistables[i]);
-            endTx(pm);
-        }
-
-        // modify them
-        startTx(pm);
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i].setStringField("bazzed" + i);
-        }
-        endTx(pm);
-
-        // delete them
-        startTx(pm);
-        for (int i = 0; i < persistables.length; i++) {
-            pm.remove(persistables[i]);
-        }
-        endTx(pm);
-
-        timeToAMD.stop();
-        return timeToAMD.getDurationAsSeconds();
-    }
-
-    static int _fetchGroupSerial = 0;
-
-    protected OpenJPAEntityManagerFactory createDistinctFactory(
-        Class providerClass, String classProps1) {
-        String transmit = "TransmitPersistedObjectIds=true";
-        if (classProps1 == null || classProps1.length() == 0)
-            classProps1 = transmit;
-        else
-            classProps1 += "," + transmit;
-
-        Map propsMap;
-        if (providerClass != null) {
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
-                getPlugin(providerClass.getName(), classProps1));
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        } else {
-            // No RCP
-
-            propsMap = new HashMap();
-            propsMap.put("openjpa.RemoteCommitProvider",
-                "sjvm(TransmitPersistedObjectIds=true)");
-            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial);
-        }
-        _fetchGroupSerial += 1;
-
-        return getEmf(propsMap);
-    }
-
-    protected static class RemoteCommitListenerTestImpl
-        implements RemoteCommitListener {
-
-        Collection added;
-        Collection updated;
-        Collection deleted;
-        int totalAdded;
-        int totalUpdated;
-        int totalDeleted;
-
-        public synchronized void afterCommit(RemoteCommitEvent event) {
-
-            this.added = event.getPersistedObjectIds();
-            this.updated = event.getUpdatedObjectIds();
-            this.deleted = event.getDeletedObjectIds();
-
-            totalAdded += added.size();
-            totalUpdated += updated.size();
-            totalDeleted += deleted.size();
-        }
-
-        public void close() {
-        }
-
-        public String toString() {
-            String returnString = "Adds " + totalAdded + " Dels " +
-                totalDeleted + " Ups " + totalUpdated;
-            return returnString;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteRecoveryTransmitAdds
+    extends AbstractTestCase {
+
+    public TestTCPRemoteRecoveryTransmitAdds(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    private static final int NUM_OBJECTS = 1;
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testReceiverRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. Our RCEListener will
+        // record the total number of a,d, and u recevied from each
+        // RCE as the sending PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5636 and 6636");
+        System.out.println("Testing scenario where receiver is failed, then " +
+            "recovered ");
+        System.out.println("after two timeouts all the while with the " +
+            "sending pm continuing");
+        System.out.println("to send.");
+
+        // Perform a set of transactions. Events will be communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the receiver can get the event.
+        pause(3);
+        // Now Fail the receiver in the cluster
+        System.out.println("About to close the receiving pmf.");
+        pmfReceiver.close();
+        // Wait for a bit longer so the listener's threads all
+        // get closed out.
+        pause(3);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("You should now see 1 WARN triggered as the " +
+            "sender-pmf tries to send.");
+        // Perform second set of transactions. This will trigger a single
+        // log WARN as the pmf won't be able to communciate events to the
+        // second member of the cluster.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a recoverytime, try transactions again, this will
+        // trigger an INFO
+        pause(15.1);
+        System.out.println("Waited for a while. Should see 1 INFO for next " +
+            "transaction.");
+
+        // This will trigger a single log INFO
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+        // This delay should ensure this second sent of
+        // transmissions is dropped as expected. If we
+        // don't pause, the new pmf can be created, then the
+        // events will be sent by the worker threads, and
+        // the new pmf will receive this messages (which
+        // are supposed to be dropped)
+        pause(1.1);
+
+        // -----
+        // Now recovery the Receiver and test that messages
+        // resume being delivered.
+        // -----
+
+        System.out.println("Recovering receiver pmf.");
+        // Recreate the listener pmf of the cluster.
+        pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+        pause(1.0);
+        // reRegister the same listener
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("Now waiting a recoverytime so that the sender");
+        System.out.println("will resume trying to connect to the receiver.");
+        pause(15.1);
+
+        // These events should get communicated.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a last little bit so the listener thread in
+        // the receiver PMF can get all messages.
+        pause(1.0);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    public void testSenderRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6637, Addresses=127.0.0.1:6637;127.0.0.1:5637");
+
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5637 and 6637");
+        System.out.println("Testing scenario where sender fails and then " +
+            "later recovers.");
+        System.out.println("All the while the receiving pm stays up and " +
+            "should receive");
+        System.out.println("Events (both before and after the sender's " +
+            "failure).");
+
+        // Perform a set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the sockets in our sender PMF can fully transmit
+        // their Event messages to the receiver PMF.
+        pause(2.1);
+        // Fail the Sender in our cluster
+        System.out.println("Sender pmf closed.");
+        pmSender.close();
+        pmfSender.close();
+
+        // Wait for a while, try again, this will let close exception propagate
+        pause(4.1);
+        System.out.println("Waited for a while.");
+        System.out.println("Recovering the sender pmf.");
+
+        pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        pmSender = pmfSender.createEntityManager();
+        // Perform a second set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the listener thread in the receiver PMF can get all
+        // messages.
+        pause(4.1);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected double performAddsModifiesDeletes(EntityManager pm,
+        int numObjects) {
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+        Duration timeToAMD = new Duration(
+            "Adds, removes, and dletes for " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setStringField("bazzed" + i);
+        }
+        endTx(pm);
+
+        // delete them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            pm.remove(persistables[i]);
+        }
+        endTx(pm);
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        String transmit = "TransmitPersistedObjectIds=true";
+        if (classProps1 == null || classProps1.length() == 0)
+            classProps1 = transmit;
+        else
+            classProps1 += "," + transmit;
+
+        Map propsMap;
+        if (providerClass != null) {
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider",
+                "sjvm(TransmitPersistedObjectIds=true)");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection added;
+        Collection updated;
+        Collection deleted;
+        int totalAdded;
+        int totalUpdated;
+        int totalDeleted;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+
+            totalAdded += added.size();
+            totalUpdated += updated.size();
+            totalDeleted += deleted.size();
+        }
+
+        public void close() {
+        }
+
+        public String toString() {
+            String returnString = "Adds " + totalAdded + " Dels " +
+                totalDeleted + " Ups " + totalUpdated;
+            return returnString;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java
index db3718b..e7777bb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java
@@ -1,236 +1,236 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-
-/*
-
-    Millisecond (only) accuracy timer.
-
-    Java 1.4 supposedly has sun.misc.Perf.
-
-    Java 1.5 has System.nanoTime (JSR 166)
-
-*/
-
-public class Duration
-
-    implements Cloneable {
-
-    private String _name;
-
-    private boolean _started;
-
-    private boolean _running;
-
-    private long _startTime;        // millis
-
-    private long _stopTime;        // millis
-
-    // NYI clock time of day at start
-
-    public Duration(String name) {
-
-        _name = name;
-
-        _started = false;
-
-        _running = false;
-    }
-
-    public String getName() {
-
-        return _name;
-    }
-
-    public synchronized void start() {
-
-        if (_started) {
-
-            throw new RuntimeException("Duration was already started.");
-        }
-
-        _startTime = System.currentTimeMillis();
-
-        _started = true;
-
-        _running = true;
-    }
-
-    public synchronized void stop() {
-
-        if (!_started) {
-
-            throw new RuntimeException("Duration was never started.");
-        }
-
-        if (!_running) {
-
-            throw new RuntimeException("Duration was already stopped.");
-        }
-
-        _stopTime = System.currentTimeMillis();
-
-        _running = false;
-    }
-
-    protected Object clone()
-
-        throws CloneNotSupportedException {
-
-        return super.clone();
-    }
-
-    /*
-
-        Returns a new Duration object from a currently running timer
-
-        as a snapshot of this object.
-
-        The returned timer is stopped, while this object continue on.
-
-    */
-
-    public synchronized Duration getCurrentDuration() {
-
-        if (!_started) {
-
-            throw new RuntimeException("Duration was never started.");
-        }
-
-        if (!_running) {
-
-            throw new RuntimeException("Duration is not running.");
-        }
-
-        long now = System.currentTimeMillis();
-
-        Duration currentDuration;
-
-        try {
-
-            currentDuration = (Duration) this.clone();
-        } catch (Exception e) {
-
-            currentDuration = new Duration("");
-        }
-
-        currentDuration._stopTime = now;
-
-        currentDuration._running = false;
-
-        return currentDuration;
-    }
-
-    /* Obtain the duration that this timer has run (in seconds)	*/
-
-    public synchronized double getDurationAsSeconds() {
-
-        if (!_started) {
-
-            throw new RuntimeException("Duration was never started.");
-        }
-
-        if (_running) {
-
-            // snapshot
-
-            Duration snapshot = getCurrentDuration();
-
-            return (1000.0 * (snapshot._stopTime - snapshot._startTime));
-        }
-
-        // Return a double value. Someday this class may make use of
-
-        // higher precision timing services (e.g. java 1.5)
-
-        return ((_stopTime - _startTime) / (double) 1000.0);
-    }
-
-    public synchronized boolean isRunning() {
-
-        return _running;
-    }
-
-    public synchronized boolean wasStarted() {
-
-        return _started;
-    }
-
-    public String toString() {
-
-        double time = 0.0;
-
-        StringBuffer buf = new StringBuffer(256);
-
-        if (wasStarted()) {
-
-            if (isRunning()) {
-
-                Duration snapshot = getCurrentDuration();
-
-                time = snapshot.getDurationAsSeconds();
-            } else {
-
-                time = getDurationAsSeconds();
-            }
-
-            buf.append("Duration for '" + _name + "' is " + time + " (s).");
-        } else {
-
-            buf.append("Duration for '" + _name +
-
-                "' has not yet been started.");
-        }
-
-        return buf.toString();
-    }
-
-/* Example usage:
-
-       public static void main (String[] args)
-
-        throws Exception
-
-    {
-
-        Duration test = new Duration ("hello, count to 1 million");
-
-        System.out.println (test);
-
-        test.start ();
-
-        for (int i = 0; i < 1000000000; i++)
-
-            {
-
-            }
-
-        test.stop ();
-
-        System.out.println (test);
-
-    }
-
-    */
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+
+/*
+
+    Millisecond (only) accuracy timer.
+
+    Java 1.4 supposedly has sun.misc.Perf.
+
+    Java 1.5 has System.nanoTime (JSR 166)
+
+*/
+
+public class Duration
+
+    implements Cloneable {
+
+    private String _name;
+
+    private boolean _started;
+
+    private boolean _running;
+
+    private long _startTime;        // millis
+
+    private long _stopTime;        // millis
+
+    // NYI clock time of day at start
+
+    public Duration(String name) {
+
+        _name = name;
+
+        _started = false;
+
+        _running = false;
+    }
+
+    public String getName() {
+
+        return _name;
+    }
+
+    public synchronized void start() {
+
+        if (_started) {
+
+            throw new RuntimeException("Duration was already started.");
+        }
+
+        _startTime = System.currentTimeMillis();
+
+        _started = true;
+
+        _running = true;
+    }
+
+    public synchronized void stop() {
+
+        if (!_started) {
+
+            throw new RuntimeException("Duration was never started.");
+        }
+
+        if (!_running) {
+
+            throw new RuntimeException("Duration was already stopped.");
+        }
+
+        _stopTime = System.currentTimeMillis();
+
+        _running = false;
+    }
+
+    protected Object clone()
+
+        throws CloneNotSupportedException {
+
+        return super.clone();
+    }
+
+    /*
+
+        Returns a new Duration object from a currently running timer
+
+        as a snapshot of this object.
+
+        The returned timer is stopped, while this object continue on.
+
+    */
+
+    public synchronized Duration getCurrentDuration() {
+
+        if (!_started) {
+
+            throw new RuntimeException("Duration was never started.");
+        }
+
+        if (!_running) {
+
+            throw new RuntimeException("Duration is not running.");
+        }
+
+        long now = System.currentTimeMillis();
+
+        Duration currentDuration;
+
+        try {
+
+            currentDuration = (Duration) this.clone();
+        } catch (Exception e) {
+
+            currentDuration = new Duration("");
+        }
+
+        currentDuration._stopTime = now;
+
+        currentDuration._running = false;
+
+        return currentDuration;
+    }
+
+    /* Obtain the duration that this timer has run (in seconds)	*/
+
+    public synchronized double getDurationAsSeconds() {
+
+        if (!_started) {
+
+            throw new RuntimeException("Duration was never started.");
+        }
+
+        if (_running) {
+
+            // snapshot
+
+            Duration snapshot = getCurrentDuration();
+
+            return (1000.0 * (snapshot._stopTime - snapshot._startTime));
+        }
+
+        // Return a double value. Someday this class may make use of
+
+        // higher precision timing services (e.g. java 1.5)
+
+        return ((_stopTime - _startTime) / (double) 1000.0);
+    }
+
+    public synchronized boolean isRunning() {
+
+        return _running;
+    }
+
+    public synchronized boolean wasStarted() {
+
+        return _started;
+    }
+
+    public String toString() {
+
+        double time = 0.0;
+
+        StringBuffer buf = new StringBuffer(256);
+
+        if (wasStarted()) {
+
+            if (isRunning()) {
+
+                Duration snapshot = getCurrentDuration();
+
+                time = snapshot.getDurationAsSeconds();
+            } else {
+
+                time = getDurationAsSeconds();
+            }
+
+            buf.append("Duration for '" + _name + "' is " + time + " (s).");
+        } else {
+
+            buf.append("Duration for '" + _name +
+
+                "' has not yet been started.");
+        }
+
+        return buf.toString();
+    }
+
+/* Example usage:
+
+       public static void main (String[] args)
+
+        throws Exception
+
+    {
+
+        Duration test = new Duration ("hello, count to 1 million");
+
+        System.out.println (test);
+
+        test.start ();
+
+        for (int i = 0; i < 1000000000; i++)
+
+            {
+
+            }
+
+        test.stop ();
+
+        System.out.println (test);
+
+    }
+
+    */
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java
index c46cf2e..9a5935d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java
@@ -1,279 +1,279 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event.common.apps;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToOne;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-public class RuntimeTest1
-    implements Serializable {
-
-    public static final String someStaticField = "someField";
-
-    private byte byteField;
-    private boolean booleanField;
-    private char charField;
-    private double doubleField = 1.0;
-    private float floatField = 1.0f;
-    private int intField;
-    private long longField;
-    private short shortField;
-    private String stringField;
-    private BigInteger bigIntegerField;
-    private BigDecimal bigDecimalField;
-    private Date dateField;
-    private Locale localeField;
-    private Byte byteObjfield;
-    private Boolean booleanObjField;
-    private Character charObjField;
-    private Double doubleObjField;
-    private Float floatObjField = 1.0F;
-    private Integer intObjField;
-    private Long longObjField;
-    private Short shortObjField;
-
-    // transactional only
-    private TransactionalClassPC transField;
-    public String transString;
-
-    // relations
-    @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
-    private RuntimeTest1 selfOneOne;
-    @PersistentCollection
-    private Set selfOneMany = new HashSet();
-
-    public RuntimeTest1() {
-    }
-
-    public RuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-
-        //FIXME Seetha Oct 25,2006
-        //mySQL 0.0 float issue
-        floatField = 1.0f;
-    }
-
-    public byte getByteField() {
-        return this.byteField;
-    }
-
-    public void setByteField(byte byteField) {
-        this.byteField = byteField;
-    }
-
-    public boolean getBooleanField() {
-        return this.booleanField;
-    }
-
-    public void setBooleanField(boolean booleanField) {
-        this.booleanField = booleanField;
-    }
-
-    public char getCharField() {
-        return this.charField;
-    }
-
-    public void setCharField(char charField) {
-        this.charField = charField;
-    }
-
-    public double getDoubleField() {
-        return this.doubleField;
-    }
-
-    public void setDoubleField(double doubleField) {
-        this.doubleField = doubleField;
-    }
-
-    public float getFloatField() {
-        return this.floatField;
-    }
-
-    public void setFloatField(float floatField) {
-        this.floatField = floatField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public long getLongField() {
-        return this.longField;
-    }
-
-    public void setLongField(long longField) {
-        this.longField = longField;
-    }
-
-    public short getShortField() {
-        return this.shortField;
-    }
-
-    public void setShortField(short shortField) {
-        this.shortField = shortField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public BigInteger getBigIntegerField() {
-        return this.bigIntegerField;
-    }
-
-    public void setBigIntegerField(BigInteger bigIntegerField) {
-        this.bigIntegerField = bigIntegerField;
-    }
-
-    public BigDecimal getBigDecimalField() {
-        return this.bigDecimalField;
-    }
-
-    public void setBigDecimalField(BigDecimal bigDecimalField) {
-        this.bigDecimalField = bigDecimalField;
-    }
-
-    public Date getDateField() {
-        return this.dateField;
-    }
-
-    public void setDateField(Date dateField) {
-        this.dateField = dateField;
-    }
-
-    public Locale getLocaleField() {
-        return this.localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-
-    public Byte getByteObjfield() {
-        return this.byteObjfield;
-    }
-
-    public void setByteObjfield(Byte byteObjfield) {
-        this.byteObjfield = byteObjfield;
-    }
-
-    public Boolean getBooleanObjField() {
-        return this.booleanObjField;
-    }
-
-    public void setBooleanObjField(Boolean booleanObjField) {
-        this.booleanObjField = booleanObjField;
-    }
-
-    public Character getCharObjField() {
-        return this.charObjField;
-    }
-
-    public void setCharObjField(Character charObjField) {
-        this.charObjField = charObjField;
-    }
-
-    public Double getDoubleObjField() {
-        return this.doubleObjField;
-    }
-
-    public void setDoubleObjField(Double doubleObjField) {
-        this.doubleObjField = doubleObjField;
-    }
-
-    public Float getFloatObjField() {
-        return this.floatObjField;
-    }
-
-    public void setFloatObjField(Float floatObjField) {
-        this.floatObjField = floatObjField;
-    }
-
-    public Integer getIntObjField() {
-        return this.intObjField;
-    }
-
-    public void setIntObjField(Integer intObjField) {
-        this.intObjField = intObjField;
-    }
-
-    public Long getLongObjField() {
-        return this.longObjField;
-    }
-
-    public void setLongObjField(Long longObjField) {
-        this.longObjField = longObjField;
-    }
-
-    public Short getShortObjField() {
-        return this.shortObjField;
-    }
-
-    public void setShortObjField(Short shortObjField) {
-        this.shortObjField = shortObjField;
-    }
-
-    public TransactionalClassPC getTransField() {
-        return this.transField;
-    }
-
-    public void setTransField(TransactionalClassPC transField) {
-        this.transField = transField;
-    }
-
-    public RuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event.common.apps;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToOne;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+public class RuntimeTest1
+    implements Serializable {
+
+    public static final String someStaticField = "someField";
+
+    private byte byteField;
+    private boolean booleanField;
+    private char charField;
+    private double doubleField = 1.0;
+    private float floatField = 1.0f;
+    private int intField;
+    private long longField;
+    private short shortField;
+    private String stringField;
+    private BigInteger bigIntegerField;
+    private BigDecimal bigDecimalField;
+    private Date dateField;
+    private Locale localeField;
+    private Byte byteObjfield;
+    private Boolean booleanObjField;
+    private Character charObjField;
+    private Double doubleObjField;
+    private Float floatObjField = 1.0F;
+    private Integer intObjField;
+    private Long longObjField;
+    private Short shortObjField;
+
+    // transactional only
+    private TransactionalClassPC transField;
+    public String transString;
+
+    // relations
+    @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
+    private RuntimeTest1 selfOneOne;
+    @PersistentCollection
+    private Set selfOneMany = new HashSet();
+
+    public RuntimeTest1() {
+    }
+
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+
+        //FIXME Seetha Oct 25,2006
+        //mySQL 0.0 float issue
+        floatField = 1.0f;
+    }
+
+    public byte getByteField() {
+        return this.byteField;
+    }
+
+    public void setByteField(byte byteField) {
+        this.byteField = byteField;
+    }
+
+    public boolean getBooleanField() {
+        return this.booleanField;
+    }
+
+    public void setBooleanField(boolean booleanField) {
+        this.booleanField = booleanField;
+    }
+
+    public char getCharField() {
+        return this.charField;
+    }
+
+    public void setCharField(char charField) {
+        this.charField = charField;
+    }
+
+    public double getDoubleField() {
+        return this.doubleField;
+    }
+
+    public void setDoubleField(double doubleField) {
+        this.doubleField = doubleField;
+    }
+
+    public float getFloatField() {
+        return this.floatField;
+    }
+
+    public void setFloatField(float floatField) {
+        this.floatField = floatField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public long getLongField() {
+        return this.longField;
+    }
+
+    public void setLongField(long longField) {
+        this.longField = longField;
+    }
+
+    public short getShortField() {
+        return this.shortField;
+    }
+
+    public void setShortField(short shortField) {
+        this.shortField = shortField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public BigInteger getBigIntegerField() {
+        return this.bigIntegerField;
+    }
+
+    public void setBigIntegerField(BigInteger bigIntegerField) {
+        this.bigIntegerField = bigIntegerField;
+    }
+
+    public BigDecimal getBigDecimalField() {
+        return this.bigDecimalField;
+    }
+
+    public void setBigDecimalField(BigDecimal bigDecimalField) {
+        this.bigDecimalField = bigDecimalField;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+
+    public void setDateField(Date dateField) {
+        this.dateField = dateField;
+    }
+
+    public Locale getLocaleField() {
+        return this.localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+
+    public Byte getByteObjfield() {
+        return this.byteObjfield;
+    }
+
+    public void setByteObjfield(Byte byteObjfield) {
+        this.byteObjfield = byteObjfield;
+    }
+
+    public Boolean getBooleanObjField() {
+        return this.booleanObjField;
+    }
+
+    public void setBooleanObjField(Boolean booleanObjField) {
+        this.booleanObjField = booleanObjField;
+    }
+
+    public Character getCharObjField() {
+        return this.charObjField;
+    }
+
+    public void setCharObjField(Character charObjField) {
+        this.charObjField = charObjField;
+    }
+
+    public Double getDoubleObjField() {
+        return this.doubleObjField;
+    }
+
+    public void setDoubleObjField(Double doubleObjField) {
+        this.doubleObjField = doubleObjField;
+    }
+
+    public Float getFloatObjField() {
+        return this.floatObjField;
+    }
+
+    public void setFloatObjField(Float floatObjField) {
+        this.floatObjField = floatObjField;
+    }
+
+    public Integer getIntObjField() {
+        return this.intObjField;
+    }
+
+    public void setIntObjField(Integer intObjField) {
+        this.intObjField = intObjField;
+    }
+
+    public Long getLongObjField() {
+        return this.longObjField;
+    }
+
+    public void setLongObjField(Long longObjField) {
+        this.longObjField = longObjField;
+    }
+
+    public Short getShortObjField() {
+        return this.shortObjField;
+    }
+
+    public void setShortObjField(Short shortObjField) {
+        this.shortObjField = shortObjField;
+    }
+
+    public TransactionalClassPC getTransField() {
+        return this.transField;
+    }
+
+    public void setTransField(TransactionalClassPC transField) {
+        this.transField = transField;
+    }
+
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java
index bf27ba1..73b7b2a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-public class RuntimeTest2
-    extends RuntimeTest1 {
-
-    private int intField2;
-
-    public RuntimeTest2() {
-    }
-
-    public RuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+public class RuntimeTest2
+    extends RuntimeTest1 {
+
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java
index 1750c8e..a3616c8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event.common.apps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.persistence.Entity;
-
-@Entity
-public class RuntimeTest4 {
-
-    private String name;
-    private Collection runtimeTest5s = new ArrayList();
-
-    public RuntimeTest4(String str) {
-        name = str;
-    }
-
-    public void setName(String val) {
-        name = val;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Collection getRuntimeTest5s() {
-        return runtimeTest5s;
-    }
-
-    public void setRuntimeTest5s(Collection c) {
-        runtimeTest5s = c;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest4 {
+
+    private String name;
+    private Collection runtimeTest5s = new ArrayList();
+
+    public RuntimeTest4(String str) {
+        name = str;
+    }
+
+    public void setName(String val) {
+        name = val;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Collection getRuntimeTest5s() {
+        return runtimeTest5s;
+    }
+
+    public void setRuntimeTest5s(Collection c) {
+        runtimeTest5s = c;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java
index 1ea5cc6..f61aa78 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.event.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class TransactionalClassPC {
-
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.event.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class TransactionalClassPC {
+
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/PObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/PObject.java
index 9239d14..01ce72a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/PObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/PObject.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.exception;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-/**
- * A Simple entity for testing. Has a version field for testing optimistic
- * concurrent usage.
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class PObject {
-	@Id
-	private long id;
-	private String name;
-	@Version
-	private int version;
-	
-	public String getName() {
-		return name;
-	}
-	
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	public void setId(long id) {
-		this.id = id;
-	}
-
-	public long getId() {
-		return id;
-	}
-	
-	public int getVersion() {
-		return version;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.exception;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * A Simple entity for testing. Has a version field for testing optimistic
+ * concurrent usage.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class PObject {
+	@Id
+	private long id;
+	private String name;
+	@Version
+	private int version;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public long getId() {
+		return id;
+	}
+	
+	public int getVersion() {
+		return version;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/TestException.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/TestException.java
index 33ebe56..40c1b5f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/TestException.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/TestException.java
@@ -1,197 +1,198 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.exception;
-
-import java.io.InputStream;
-import java.sql.SQLException;
-import java.util.List;
-
-import javax.persistence.EntityExistsException;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityNotFoundException;
-import javax.persistence.OptimisticLockException;
-import javax.persistence.TransactionRequiredException;
-
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.jdbc.sql.SQLErrorCodeReader;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests proper JPA exceptions are raised by the implementation. 
- * Actual runtime type of the raised exception is a subclass of JPA-defined 
- * exception.
- * The raised exception may nest the expected exception. 
- * 
- * @author Pinaki Poddar
- */
-public class TestException extends SingleEMFTestCase {
-	private static long ID_COUNTER = System.currentTimeMillis();
-    
-	public void setUp() {
-        super.setUp(PObject.class, CLEAR_TABLES);
-    }
-    
-	/**
-	 * Tests that when Optimistic transaction consistency is violated, the
-	 * exception thrown is an instance of javax.persistence.OptimisticException.
-	 */
-	public void testThrowsOptimisticException() {
-		EntityManager em1 = emf.createEntityManager();
-		EntityManager em2 = emf.createEntityManager();
-		assertNotEquals(em1, em2);
-		
-		em1.getTransaction().begin();
-		PObject pc = new PObject();
-		long id = ++ID_COUNTER;
-		pc.setId(id);
-		em1.persist(pc);
-		em1.getTransaction().commit();
-		em1.clear();
-		
-		em1.getTransaction().begin();
-		em2.getTransaction().begin();
-		
-		PObject pc1 = em1.find(PObject.class, id);
-		PObject pc2 = em2.find(PObject.class, id);
-		
-		assertTrue(pc1 != pc2);
-		
-		pc1.setName("Modified in TXN1");
-		em1.flush();
-		try {
-			pc2.setName("Modified in TXN2");
-			em2.flush();
-			fail("Expected " + OptimisticLockException.class);
-		} catch (Throwable t) {
-			assertException(t, OptimisticLockException.class);
-		}
-		
-		em1.getTransaction().commit();
-		try {
-			em2.getTransaction().commit();
-			fail("Expected " + OptimisticLockException.class);
-		} catch (Throwable t) {
-			assertException(t, OptimisticLockException.class);
-		}
-	}
-	
-	public void testThrowsEntityExistsException() {
-		EntityManager em = emf.createEntityManager();
-		
-		em.getTransaction().begin();
-		PObject pc = new PObject();
-		long id = ++ID_COUNTER;
-		pc.setId(id);
-		em.persist(pc);
-		em.getTransaction().commit();
-		em.clear();
-		
-		em.getTransaction().begin();
-		PObject pc2 = new PObject();
-		pc2.setId(id);
-		em.persist(pc2);
-		try {
-			em.getTransaction().commit();
-			fail("Expected " + EntityExistsException.class);
-		} catch (Throwable t) {
-			assertException(t, EntityExistsException.class);
-		}
-	}
-	
-	public void testThrowsEntityNotFoundException() {
-		EntityManager em = emf.createEntityManager();
-		
-		em.getTransaction().begin();
-		PObject pc = new PObject();
-		long id = ++ID_COUNTER;
-		pc.setId(id);
-		em.persist(pc);
-		em.getTransaction().commit();
-		
-		EntityManager em2 = emf.createEntityManager();
-		em2.getTransaction().begin();
-		PObject pc2 = em2.find(PObject.class, id);
-		assertNotNull(pc2);
-		em2.remove(pc2);
-		em2.getTransaction().commit();
-		
-		try {
-			em.refresh(pc);
-			fail("Expected " + EntityNotFoundException.class);
-		} catch (Throwable t) {
-			assertException(t, EntityNotFoundException.class);
-		}
-	}
-	
-	public void testErrorCodeConfigurationHasAllKnownDictionaries() {
-		SQLErrorCodeReader reader = new SQLErrorCodeReader();
-		InputStream in = DBDictionary.class.getResourceAsStream
-			("sql-error-state-codes.xml");
-		assertNotNull(in);
-		List<String> names = reader.getDictionaries(in);
-		assertTrue(names.size()>=18);
-		for (String name:names) {
-			try {
-				Class.forName(name, false, Thread.currentThread()
-							.getContextClassLoader());
-			} catch (Throwable t) {
-				fail("DB dictionary " + name + " can not be loaded");
-				t.printStackTrace();
-			}
-		}
-	}
-	
-	/**
-	 * Asserts that the given expected type of the exception is equal to or a
-	 * subclass of the given throwable or any of its nested exception.
-	 * Otherwise fails assertion and prints the given throwable and its nested
-	 * exception on the console. 
-	 */
-	void assertException(Throwable t, Class expectedType) {
-		if (!isExpectedException(t, expectedType)) {
-			t.printStackTrace();
-			print(t, 0);
-			fail(t + " or its cause is not instanceof " + expectedType);
-		}
-	}
-	
-	/**
-	 * Affirms if the given expected type of the exception is equal to or a
-	 * subclass of the given throwable or any of its nested exception.
-	 */
-	boolean isExpectedException(Throwable t, Class expectedType) {
-		if (t == null) 
-			return false;
-		if (expectedType.isAssignableFrom(t.getClass()))
-				return true;
-		return isExpectedException(t.getCause(), expectedType);
-	}
-	
-	void print(Throwable t, int tab) {
-		if (t == null) return;
-		for (int i=0; i<tab*4;i++) System.out.print(" ");
-		String sqlState = (t instanceof SQLException) ? 
-			"(SQLState=" + ((SQLException)t).getSQLState() + ":" 
-				+ t.getMessage() + ")" : "";
-		System.out.println(t.getClass().getName() + sqlState);
-		if (t.getCause() == t) 
-			return;
-		print(t.getCause(), tab+1);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.exception;
+
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.List;
+
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.OptimisticLockException;
+import javax.persistence.TransactionRequiredException;
+
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.SQLErrorCodeReader;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests proper JPA exceptions are raised by the implementation. 
+ * Actual runtime type of the raised exception is a subclass of JPA-defined 
+ * exception.
+ * The raised exception may nest the expected exception. 
+ * 
+ * @author Pinaki Poddar
+ */
+public class TestException extends SingleEMFTestCase {
+	private static long ID_COUNTER = System.currentTimeMillis();
+    
+	public void setUp() {
+        super.setUp(PObject.class, CLEAR_TABLES);
+    }
+    
+	/**
+	 * <p>Tests that when Optimistic transaction consistency is violated, the
+	 * exception thrown is an instance of javax.persistence.OptimisticException.</p>
+	 * <p>Disabled pending resolution of OPENJPA-991</p>
+	 */
+	public void disabledTestThrowsOptimisticException() {
+		EntityManager em1 = emf.createEntityManager();
+		EntityManager em2 = emf.createEntityManager();
+		assertNotEquals(em1, em2);
+		
+		em1.getTransaction().begin();
+		PObject pc = new PObject();
+		long id = ++ID_COUNTER;
+		pc.setId(id);
+		em1.persist(pc);
+		em1.getTransaction().commit();
+		em1.clear();
+		
+		em1.getTransaction().begin();
+		em2.getTransaction().begin();
+		
+		PObject pc1 = em1.find(PObject.class, id);
+		PObject pc2 = em2.find(PObject.class, id);
+		
+		assertTrue(pc1 != pc2);
+		
+		pc1.setName("Modified in TXN1");
+		em1.flush();
+		try {
+			pc2.setName("Modified in TXN2");
+			em2.flush();
+			fail("Expected " + OptimisticLockException.class);
+		} catch (Throwable t) {
+			assertException(t, OptimisticLockException.class);
+		}
+		
+		em1.getTransaction().commit();
+		try {
+			em2.getTransaction().commit();
+			fail("Expected " + OptimisticLockException.class);
+		} catch (Throwable t) {
+			assertException(t, OptimisticLockException.class);
+		}
+	}
+	
+	public void testThrowsEntityExistsException() {
+		EntityManager em = emf.createEntityManager();
+		
+		em.getTransaction().begin();
+		PObject pc = new PObject();
+		long id = ++ID_COUNTER;
+		pc.setId(id);
+		em.persist(pc);
+		em.getTransaction().commit();
+		em.clear();
+		
+		em.getTransaction().begin();
+		PObject pc2 = new PObject();
+		pc2.setId(id);
+		em.persist(pc2);
+		try {
+			em.getTransaction().commit();
+			fail("Expected " + EntityExistsException.class);
+		} catch (Throwable t) {
+			assertException(t, EntityExistsException.class);
+		}
+	}
+	
+	public void testThrowsEntityNotFoundException() {
+		EntityManager em = emf.createEntityManager();
+		
+		em.getTransaction().begin();
+		PObject pc = new PObject();
+		long id = ++ID_COUNTER;
+		pc.setId(id);
+		em.persist(pc);
+		em.getTransaction().commit();
+		
+		EntityManager em2 = emf.createEntityManager();
+		em2.getTransaction().begin();
+		PObject pc2 = em2.find(PObject.class, id);
+		assertNotNull(pc2);
+		em2.remove(pc2);
+		em2.getTransaction().commit();
+		
+		try {
+			em.refresh(pc);
+			fail("Expected " + EntityNotFoundException.class);
+		} catch (Throwable t) {
+			assertException(t, EntityNotFoundException.class);
+		}
+	}
+	
+	public void testErrorCodeConfigurationHasAllKnownDictionaries() {
+		SQLErrorCodeReader reader = new SQLErrorCodeReader();
+		InputStream in = DBDictionary.class.getResourceAsStream
+			("sql-error-state-codes.xml");
+		assertNotNull(in);
+		List<String> names = reader.getDictionaries(in);
+		assertTrue(names.size()>=18);
+		for (String name:names) {
+			try {
+				Class.forName(name, false, Thread.currentThread()
+							.getContextClassLoader());
+			} catch (Throwable t) {
+				fail("DB dictionary " + name + " can not be loaded");
+				t.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 * Asserts that the given expected type of the exception is equal to or a
+	 * subclass of the given throwable or any of its nested exception.
+	 * Otherwise fails assertion and prints the given throwable and its nested
+	 * exception on the console. 
+	 */
+	void assertException(Throwable t, Class expectedType) {
+		if (!isExpectedException(t, expectedType)) {
+			t.printStackTrace();
+			print(t, 0);
+			fail(t + " or its cause is not instanceof " + expectedType);
+		}
+	}
+	
+	/**
+	 * Affirms if the given expected type of the exception is equal to or a
+	 * subclass of the given throwable or any of its nested exception.
+	 */
+	boolean isExpectedException(Throwable t, Class expectedType) {
+		if (t == null) 
+			return false;
+		if (expectedType.isAssignableFrom(t.getClass()))
+				return true;
+		return isExpectedException(t.getCause(), expectedType);
+	}
+	
+	void print(Throwable t, int tab) {
+		if (t == null) return;
+		for (int i=0; i<tab*4;i++) System.out.print(" ");
+		String sqlState = (t instanceof SQLException) ? 
+			"(SQLState=" + ((SQLException)t).getSQLState() + ":" 
+				+ t.getMessage() + ")" : "";
+		System.out.println(t.getClass().getName() + sqlState);
+		if (t.getCause() == t) 
+			return;
+		print(t.getCause(), tab+1);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGAddress.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGAddress.java
index aa5d0b5..f24944b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGAddress.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGAddress.java
@@ -1,105 +1,105 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.fetchgroups;
-
-import javax.persistence.Basic;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class FGAddress {
-    @Id
-    private int id;
-
-    @Basic
-    private String street;
-
-    @Basic
-    private String city;
-
-    @Basic
-    private String state;
-
-    @Basic
-    private int zip;
-
-    public FGAddress() {
-
-    }
-
-    public FGAddress(int id, String street, String city, String state, int zip) {
-        this.id = id;
-        this.street = street;
-        this.city = city;
-        this.state = state;
-        this.zip = zip;
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    public void setState(String state) {
-        this.state = state;
-    }
-
-    public String getStreet() {
-        return street;
-    }
-
-    public void setStreet(String street) {
-        this.street = street;
-    }
-
-    public int getZip() {
-        return zip;
-    }
-
-    public void setZip(int zip) {
-        this.zip = zip;
-    }
-
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append("FGAddress(id=").append(this.id).append(")");
-        sb.append(": street=").append(getStreet());
-        sb.append(": city=").append(getCity());
-        sb.append(": state=").append(getState());
-        sb.append(": zip=").append(getZip());
-
-        return new String(sb);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.fetchgroups;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class FGAddress {
+    @Id
+    private int id;
+
+    @Basic
+    private String street;
+
+    @Basic
+    private String city;
+
+    @Basic
+    private String state;
+
+    @Basic
+    private int zip;
+
+    public FGAddress() {
+
+    }
+
+    public FGAddress(int id, String street, String city, String state, int zip) {
+        this.id = id;
+        this.street = street;
+        this.city = city;
+        this.state = state;
+        this.zip = zip;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getStreet() {
+        return street;
+    }
+
+    public void setStreet(String street) {
+        this.street = street;
+    }
+
+    public int getZip() {
+        return zip;
+    }
+
+    public void setZip(int zip) {
+        this.zip = zip;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("FGAddress(id=").append(this.id).append(")");
+        sb.append(": street=").append(getStreet());
+        sb.append(": city=").append(getCity());
+        sb.append(": state=").append(getState());
+        sb.append(": zip=").append(getZip());
+
+        return new String(sb);
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGDepartment.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGDepartment.java
index 38bc351..fdb7a21 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGDepartment.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGDepartment.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.fetchgroups;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class FGDepartment {
-    @Id
-    private int id;
-
-    private String name;
-
-    public FGDepartment() {
-
-    }
-
-    public FGDepartment(int id, String name) {
-        this.id = id;
-        this.name = name;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String toString() {
-        return new String("FGDepartment(id=" + this.id + ")");
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.fetchgroups;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class FGDepartment {
+    @Id
+    private int id;
+
+    private String name;
+
+    public FGDepartment() {
+
+    }
+
+    public FGDepartment(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return new String("FGDepartment(id=" + this.id + ")");
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGEmployee.java
index 5145709..242a09c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGEmployee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGEmployee.java
@@ -1,174 +1,174 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.fetchgroups;
-
-import javax.persistence.Basic;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-import org.apache.openjpa.persistence.LoadFetchGroup;
-
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-// Default inheritance strategy
-@DiscriminatorColumn(name = "EMP_TYPE", discriminatorType = DiscriminatorType.INTEGER)
-@DiscriminatorValue("0")
-@FetchGroups( {
-        @FetchGroup(name = "AddressFetchGroup", attributes = { @FetchAttribute(name = "address") }),
-        @FetchGroup(name = "RatingFetchGroup", attributes = { @FetchAttribute(name = "rating") }),
-        @FetchGroup(name = "ManagerFetchGroup1A", attributes = { @FetchAttribute(name = "manager", recursionDepth = 1) }),
-        @FetchGroup(name = "ManagerFetchGroup1B", attributes = { @FetchAttribute(name = "manager", recursionDepth = -1) }),
-        @FetchGroup(name = "ManagerFetchGroup2", attributes = { @FetchAttribute(name = "manager", recursionDepth = 2) }),
-        @FetchGroup(name = "DescFetchGroup", attributes = { @FetchAttribute(name = "description") }),
-
-        @FetchGroup(name = "DepartmentFetchGroup", attributes = { @FetchAttribute(name = "dept") }),
-
-        @FetchGroup(name = "AggregateEmployeeFetchGroup1", attributes = {
-                @FetchAttribute(name = "dept"),
-                @FetchAttribute(name = "address"),
-                @FetchAttribute(name = "manager", recursionDepth = 1) }),
-        @FetchGroup(name = "AggregateEmployeeFetchGroup2", fetchGroups = { "AggregateEmployeeFetchGroup1" }),
-        @FetchGroup(name = "AggregateEmployeeFetchGroup3", fetchGroups = {
-                "DepartmentFetchGroup", "AddressFetchGroup",
-                "ManagerFetchGroup1A" }),
-        @FetchGroup(name = "AggregateEmployeeFetchGroup4", attributes = {
-                @FetchAttribute(name = "dept"),
-                @FetchAttribute(name = "address") }, fetchGroups = { "ManagerFetchGroup1A" }) })
-public class FGEmployee {
-    @Id
-    private int id;
-
-    private String lastName;
-
-    private String firstName;
-
-    @Basic(fetch = FetchType.LAZY)
-    private String description;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    private FGDepartment dept;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    private FGAddress address;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    private FGManager manager;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("AddressFetchGroup")
-    private String rating;
-
-    public FGEmployee() {
-
-    }
-
-    public FGEmployee(int id, String firstName, String lastName, String desc,
-            FGDepartment dept, FGAddress address, FGManager manager,
-            String rating) {
-        this.id = id;
-        this.lastName = lastName;
-        this.firstName = firstName;
-        this.description = desc;
-        this.dept = dept;
-        this.address = address;
-        this.manager = manager;
-        this.rating = rating;
-    }
-
-    public FGAddress getAddress() {
-        return address;
-    }
-
-    public void setAddress(FGAddress address) {
-        this.address = address;
-    }
-
-    public FGDepartment getDept() {
-        return dept;
-    }
-
-    public void setDept(FGDepartment dept) {
-        this.dept = dept;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String desc) {
-        this.description = desc;
-    }
-
-    public String getFirstName() {
-        return firstName;
-    }
-
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getLastName() {
-        return lastName;
-    }
-
-    public void setLastName(String lastName) {
-        this.lastName = lastName;
-    }
-
-    public FGManager getManager() {
-        return manager;
-    }
-
-    public void setManager(FGManager manager) {
-        this.manager = manager;
-    }
-
-    public String getRating() {
-        return rating;
-    }
-
-    public void setRating(String rating) {
-        this.rating = rating;
-    }
-
-    public String toString() {
-        return new String(this.getClass().getSimpleName() + "(id=" + this.id
-                + ")");
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.fetchgroups;
+
+import javax.persistence.Basic;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+import org.apache.openjpa.persistence.LoadFetchGroup;
+
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+// Default inheritance strategy
+@DiscriminatorColumn(name = "EMP_TYPE", discriminatorType = DiscriminatorType.INTEGER)
+@DiscriminatorValue("0")
+@FetchGroups( {
+        @FetchGroup(name = "AddressFetchGroup", attributes = { @FetchAttribute(name = "address") }),
+        @FetchGroup(name = "RatingFetchGroup", attributes = { @FetchAttribute(name = "rating") }),
+        @FetchGroup(name = "ManagerFetchGroup1A", attributes = { @FetchAttribute(name = "manager", recursionDepth = 1) }),
+        @FetchGroup(name = "ManagerFetchGroup1B", attributes = { @FetchAttribute(name = "manager", recursionDepth = -1) }),
+        @FetchGroup(name = "ManagerFetchGroup2", attributes = { @FetchAttribute(name = "manager", recursionDepth = 2) }),
+        @FetchGroup(name = "DescFetchGroup", attributes = { @FetchAttribute(name = "description") }),
+
+        @FetchGroup(name = "DepartmentFetchGroup", attributes = { @FetchAttribute(name = "dept") }),
+
+        @FetchGroup(name = "AggregateEmployeeFetchGroup1", attributes = {
+                @FetchAttribute(name = "dept"),
+                @FetchAttribute(name = "address"),
+                @FetchAttribute(name = "manager", recursionDepth = 1) }),
+        @FetchGroup(name = "AggregateEmployeeFetchGroup2", fetchGroups = { "AggregateEmployeeFetchGroup1" }),
+        @FetchGroup(name = "AggregateEmployeeFetchGroup3", fetchGroups = {
+                "DepartmentFetchGroup", "AddressFetchGroup",
+                "ManagerFetchGroup1A" }),
+        @FetchGroup(name = "AggregateEmployeeFetchGroup4", attributes = {
+                @FetchAttribute(name = "dept"),
+                @FetchAttribute(name = "address") }, fetchGroups = { "ManagerFetchGroup1A" }) })
+public class FGEmployee {
+    @Id
+    private int id;
+
+    private String lastName;
+
+    private String firstName;
+
+    @Basic(fetch = FetchType.LAZY)
+    private String description;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    private FGDepartment dept;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    private FGAddress address;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    private FGManager manager;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("AddressFetchGroup")
+    private String rating;
+
+    public FGEmployee() {
+
+    }
+
+    public FGEmployee(int id, String firstName, String lastName, String desc,
+            FGDepartment dept, FGAddress address, FGManager manager,
+            String rating) {
+        this.id = id;
+        this.lastName = lastName;
+        this.firstName = firstName;
+        this.description = desc;
+        this.dept = dept;
+        this.address = address;
+        this.manager = manager;
+        this.rating = rating;
+    }
+
+    public FGAddress getAddress() {
+        return address;
+    }
+
+    public void setAddress(FGAddress address) {
+        this.address = address;
+    }
+
+    public FGDepartment getDept() {
+        return dept;
+    }
+
+    public void setDept(FGDepartment dept) {
+        this.dept = dept;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String desc) {
+        this.description = desc;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public FGManager getManager() {
+        return manager;
+    }
+
+    public void setManager(FGManager manager) {
+        this.manager = manager;
+    }
+
+    public String getRating() {
+        return rating;
+    }
+
+    public void setRating(String rating) {
+        this.rating = rating;
+    }
+
+    public String toString() {
+        return new String(this.getClass().getSimpleName() + "(id=" + this.id
+                + ")");
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGManager.java
index 8c69edf..ec2f506 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fetchgroups/FGManager.java
@@ -1,72 +1,72 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.fetchgroups;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import javax.persistence.Basic;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-@Entity
-@DiscriminatorValue("1")
-@FetchGroups( {
-        @FetchGroup(name = "MDataFetchGroup", attributes = { @FetchAttribute(name = "mData") }),
-        @FetchGroup(name = "EmployeesFetchGroup", attributes = { @FetchAttribute(name = "employees") }) })
-public class FGManager extends FGEmployee {
-    @OneToMany(mappedBy = "manager", fetch = FetchType.LAZY)
-    Collection<FGEmployee> employees;
-
-    @Basic(fetch = FetchType.LAZY)
-    private String mData;
-
-    public FGManager() {
-        super();
-        employees = new ArrayList<FGEmployee>();
-    }
-
-    public FGManager(int id, String firstName, String lastName, String desc,
-            FGDepartment dept, FGAddress address, FGManager manager,
-            String rating, Collection<FGEmployee> employees, String mData) {
-        super(id, firstName, lastName, desc, dept, address, manager, rating);
-        this.employees = new ArrayList<FGEmployee>();
-        this.employees.addAll(employees);
-        this.mData = mData;
-    }
-
-    public String getMData() {
-        return mData;
-    }
-
-    public void setMData(String data) {
-        mData = data;
-    }
-
-    public Collection<FGEmployee> getEmployees() {
-        return employees;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.fetchgroups;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.Basic;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+@Entity
+@DiscriminatorValue("1")
+@FetchGroups( {
+        @FetchGroup(name = "MDataFetchGroup", attributes = { @FetchAttribute(name = "mData") }),
+        @FetchGroup(name = "EmployeesFetchGroup", attributes = { @FetchAttribute(name = "employees") }) })
+public class FGManager extends FGEmployee {
+    @OneToMany(mappedBy = "manager", fetch = FetchType.LAZY)
+    Collection<FGEmployee> employees;
+
+    @Basic(fetch = FetchType.LAZY)
+    private String mData;
+
+    public FGManager() {
+        super();
+        employees = new ArrayList<FGEmployee>();
+    }
+
+    public FGManager(int id, String firstName, String lastName, String desc,
+            FGDepartment dept, FGAddress address, FGManager manager,
+            String rating, Collection<FGEmployee> employees, String mData) {
+        super(id, firstName, lastName, desc, dept, address, manager, rating);
+        this.employees = new ArrayList<FGEmployee>();
+        this.employees.addAll(employees);
+        this.mData = mData;
+    }
+
+    public String getMData() {
+        return mData;
+    }
+
+    public void setMData(String data) {
+        mData = data;
+    }
+
+    public Collection<FGEmployee> getEmployees() {
+        return employees;
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumFieldType.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumFieldType.java
index d18f176..e9d4b99 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumFieldType.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumFieldType.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.fields;
-
-import java.util.List;
-import java.util.ArrayList;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.DetachedState;
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.kernel.common.apps.PCDirectory;
-
-@Entity
-//@DetachedState(enabled = false) // ##### shouldn't need this
-public class EnumFieldType {
-    @Id
-    @GeneratedValue
-    private int intField;
-
-    private SampleEnum enumField;
-
-    @PersistentCollection
-    private List<SampleEnum> enumList = new ArrayList<SampleEnum>();
-
-    // for OpenJPA
-    protected EnumFieldType() {
-    }
-
-    public EnumFieldType(int intField, SampleEnum enumField) {
-        this.intField = intField;
-        this.enumField = enumField;
-    }
-
-    public void setEnumField(SampleEnum enumField) {
-        this.enumField = enumField;
-    }
-
-    public SampleEnum getEnumField() {
-        return enumField;
-    }
-
-    public List<SampleEnum> getEnumList() {
-        return enumList;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.fields;
+
+import java.util.List;
+import java.util.ArrayList;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.DetachedState;
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.kernel.common.apps.PCDirectory;
+
+@Entity
+//@DetachedState(enabled = false) // ##### shouldn't need this
+public class EnumFieldType {
+    @Id
+    @GeneratedValue
+    private int intField;
+
+    private SampleEnum enumField;
+
+    @PersistentCollection
+    private List<SampleEnum> enumList = new ArrayList<SampleEnum>();
+
+    // for OpenJPA
+    protected EnumFieldType() {
+    }
+
+    public EnumFieldType(int intField, SampleEnum enumField) {
+        this.intField = intField;
+        this.enumField = enumField;
+    }
+
+    public void setEnumField(SampleEnum enumField) {
+        this.enumField = enumField;
+    }
+
+    public SampleEnum getEnumField() {
+        return enumField;
+    }
+
+    public List<SampleEnum> getEnumList() {
+        return enumList;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumSetOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumSetOwner.java
index 6d395f3..8b1bc08 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumSetOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/EnumSetOwner.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.fields;
-
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.Set;
-import javax.persistence.Id;
-import javax.persistence.Version;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.Persistent;
-import org.apache.openjpa.persistence.Externalizer;
-
-@Entity
-public class EnumSetOwner {
-
-    @Id
-    private int id;
-
-    @Version
-    private int version;
-
-    @Persistent
-    @Externalizer("externalizer")
-    private EnumSetHolder enumSetHolder;
-
-    public Set<SampleEnum> getEnumSet() {
-        return Collections.unmodifiableSet(enumSetHolder.enumSet);
-    }
-
-    public void setEnumSet(EnumSet<SampleEnum> enumSet) {
-        enumSetHolder = new EnumSetHolder(enumSet);
-    }
-
-    public static class EnumSetHolder {
-
-        private final EnumSet<SampleEnum> enumSet;
-
-        public EnumSetHolder(String externalizedValue) {
-            // this implementation can only handle the special form created
-            // by the externalizer above
-            if (!"all".equals(externalizedValue))
-                throw new IllegalStateException(externalizedValue);
-
-            enumSet = EnumSet.allOf(SampleEnum.class);
-        }
-
-        private EnumSetHolder(EnumSet<SampleEnum> enumSet) {
-            this.enumSet = enumSet;
-        }
-
-        public String externalizer() {
-            // this implementation always externalizes to a special
-            // representation of all the values.
-            return "all";
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.fields;
+
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.Set;
+import javax.persistence.Id;
+import javax.persistence.Version;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.Persistent;
+import org.apache.openjpa.persistence.Externalizer;
+
+@Entity
+public class EnumSetOwner {
+
+    @Id
+    private int id;
+
+    @Version
+    private int version;
+
+    @Persistent
+    @Externalizer("externalizer")
+    private EnumSetHolder enumSetHolder;
+
+    public Set<SampleEnum> getEnumSet() {
+        return Collections.unmodifiableSet(enumSetHolder.enumSet);
+    }
+
+    public void setEnumSet(EnumSet<SampleEnum> enumSet) {
+        enumSetHolder = new EnumSetHolder(enumSet);
+    }
+
+    public static class EnumSetHolder {
+
+        private final EnumSet<SampleEnum> enumSet;
+
+        public EnumSetHolder(String externalizedValue) {
+            // this implementation can only handle the special form created
+            // by the externalizer above
+            if (!"all".equals(externalizedValue))
+                throw new IllegalStateException(externalizedValue);
+
+            enumSet = EnumSet.allOf(SampleEnum.class);
+        }
+
+        private EnumSetHolder(EnumSet<SampleEnum> enumSet) {
+            this.enumSet = enumSet;
+        }
+
+        public String externalizer() {
+            // this implementation always externalizes to a special
+            // representation of all the values.
+            return "all";
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/SampleEnum.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/SampleEnum.java
index 23efa42..5912f6f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/SampleEnum.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/SampleEnum.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.fields;
-
-public enum SampleEnum {
-    FOO, BAR, BAZ, QUUX
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.fields;
+
+public enum SampleEnum {
+    FOO, BAR, BAZ, QUUX
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumQueryConstructor.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumQueryConstructor.java
index 85b8dde..d0a1fe9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumQueryConstructor.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumQueryConstructor.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.fields;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-
-public class TestEnumQueryConstructor
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(EnumFieldType.class, CLEAR_TABLES);
-
-        EnumFieldType e = new EnumFieldType();
-        e.setEnumField(SampleEnum.FOO);
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(e);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testEnumQueryConstructor() {
-        Query q = em.createQuery(
-            "select new EnumFieldType(e.intField, e.enumField) " +
-                "from EnumFieldType e");
-        EnumFieldType e = (EnumFieldType) q.getSingleResult();
-        assertEquals(SampleEnum.FOO, e.getEnumField());
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.fields;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+public class TestEnumQueryConstructor
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(EnumFieldType.class, CLEAR_TABLES);
+
+        EnumFieldType e = new EnumFieldType();
+        e.setEnumField(SampleEnum.FOO);
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(e);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testEnumQueryConstructor() {
+        Query q = em.createQuery(
+            "select new EnumFieldType(e.intField, e.enumField) " +
+                "from EnumFieldType e");
+        EnumFieldType e = (EnumFieldType) q.getSingleResult();
+        assertEquals(SampleEnum.FOO, e.getEnumField());
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumSets.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumSets.java
index 876f2ec..aec9b9c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumSets.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumSets.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.fields;
-
-import java.util.EnumSet;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestEnumSets
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(EnumSetOwner.class, CLEAR_TABLES);
-    }
-
-    public void testExternalizedEnumSet() {
-        // test that inserting works
-        EnumSetOwner o = new EnumSetOwner();
-        o.setEnumSet(EnumSet.allOf(SampleEnum.class));
-
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        Object oid = em.getObjectId(o);
-        em.close();
-
-        // ... and that loading works, with a new EM
-        em = emf.createEntityManager();
-        o = em.find(EnumSetOwner.class, oid);
-        assertEquals(EnumSet.allOf(SampleEnum.class), o.getEnumSet());
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.fields;
+
+import java.util.EnumSet;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestEnumSets
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(EnumSetOwner.class, CLEAR_TABLES);
+    }
+
+    public void testExternalizedEnumSet() {
+        // test that inserting works
+        EnumSetOwner o = new EnumSetOwner();
+        o.setEnumSet(EnumSet.allOf(SampleEnum.class));
+
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        Object oid = em.getObjectId(o);
+        em.close();
+
+        // ... and that loading works, with a new EM
+        em = emf.createEntityManager();
+        o = em.find(EnumSetOwner.class, oid);
+        assertEquals(EnumSet.allOf(SampleEnum.class), o.getEnumSet());
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumsInJPQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumsInJPQL.java
index d86635b..c950d9e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumsInJPQL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestEnumsInJPQL.java
@@ -1,128 +1,128 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.fields;
-
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestEnumsInJPQL
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(EnumFieldType.class, CLEAR_TABLES);
-
-        EnumFieldType o = new EnumFieldType();
-        o.setEnumField(SampleEnum.BAR);
-        o.getEnumList().add(SampleEnum.FOO);
-
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-        em = emf.createEntityManager();
-    }
-
-    public void testEnumLiteralInSelect() {
-        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
-            "o.enumField = " +
-            "org.apache.openjpa.persistence.fields.SampleEnum.BAR");
-        assertEquals(1, ((Number) q.getSingleResult()).intValue());
-    }
-
-    public void testEnumLiteralInSetInUpdate() {
-        testEnumLiteralInSelect();
-        em.getTransaction().begin();
-        Query q = em.createQuery("update EnumFieldType o set " +
-            "o.enumField = " +
-            "org.apache.openjpa.persistence.fields.SampleEnum.BAZ");
-        assertEquals(1, ((Number) q.executeUpdate()).intValue());
-        em.getTransaction().commit();
-        postUpdateCheck(true);
-    }
-
-    public void testEnumLiteralInWhereInUpdate() {
-        testEnumLiteralInSelect();
-        em.getTransaction().begin();
-        Query q = em.createQuery("update EnumFieldType o set o.intField = 3 " +
-            "where o.enumField = " +
-            "org.apache.openjpa.persistence.fields.SampleEnum.BAR");
-        assertEquals(1, ((Number) q.executeUpdate()).intValue());
-        em.getTransaction().commit();
-        postUpdateCheck(false);
-    }
-
-    private void postUpdateCheck(boolean wasEnumModified) {
-        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
-            "o.enumField = " +
-            "org.apache.openjpa.persistence.fields.SampleEnum.BAR");
-        assertEquals(wasEnumModified ? 0 : 1,
-            ((Number) q.getSingleResult()).intValue());
-
-        q = em.createQuery("select count(o) from EnumFieldType o where " +
-            "o.enumField = " +
-            "org.apache.openjpa.persistence.fields.SampleEnum.BAZ");
-        assertEquals(wasEnumModified ? 1 : 0,
-            ((Number) q.getSingleResult()).intValue());
-    }
-
-    public void testEnumPositionalParamInSelect() {
-        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
-            "o.enumField = ?1");
-        q.setParameter(1, SampleEnum.BAR);
-        assertEquals(1, ((Number) q.getSingleResult()).intValue());
-    }
-
-    public void testEnumNamedParamInSelect() {
-        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
-            "o.enumField = :e");
-        q.setParameter("e", SampleEnum.BAR);
-        assertEquals(1, ((Number) q.getSingleResult()).intValue());
-    }
-
-    public void testEnumParamInSetInUpdate() {
-        testEnumLiteralInSelect();
-        em.getTransaction().begin();
-        Query q = em.createQuery("update EnumFieldType o set o.enumField = :e");
-        q.setParameter("e", SampleEnum.BAZ);
-        assertEquals(1, ((Number) q.executeUpdate()).intValue());
-        em.getTransaction().commit();
-        postUpdateCheck(true);
-    }
-
-    public void testEnumParamInWhereInUpdate() {
-        testEnumLiteralInSelect();
-        em.getTransaction().begin();
-        Query q = em.createQuery("update EnumFieldType o set o.intField = 3 " +
-            "where o.enumField = :e");
-        q.setParameter("e", SampleEnum.BAR);
-        assertEquals(1, ((Number) q.executeUpdate()).intValue());
-        em.getTransaction().commit();
-        postUpdateCheck(false);
-    }
-
-    public void testMemberOf() {
-        assertEquals(Long.valueOf(1),
-            em.createQuery("select count(o) from EnumFieldType o where " +
-                "(:param member of o.enumList or :param2 member of o.enumList)")
-                .setParameter("param", SampleEnum.FOO)
-                .setParameter("param2", SampleEnum.BAR)
-                .getSingleResult());
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.fields;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestEnumsInJPQL
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(EnumFieldType.class, CLEAR_TABLES);
+
+        EnumFieldType o = new EnumFieldType();
+        o.setEnumField(SampleEnum.BAR);
+        o.getEnumList().add(SampleEnum.FOO);
+
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+        em = emf.createEntityManager();
+    }
+
+    public void testEnumLiteralInSelect() {
+        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
+            "o.enumField = " +
+            "org.apache.openjpa.persistence.fields.SampleEnum.BAR");
+        assertEquals(1, ((Number) q.getSingleResult()).intValue());
+    }
+
+    public void testEnumLiteralInSetInUpdate() {
+        testEnumLiteralInSelect();
+        em.getTransaction().begin();
+        Query q = em.createQuery("update EnumFieldType o set " +
+            "o.enumField = " +
+            "org.apache.openjpa.persistence.fields.SampleEnum.BAZ");
+        assertEquals(1, ((Number) q.executeUpdate()).intValue());
+        em.getTransaction().commit();
+        postUpdateCheck(true);
+    }
+
+    public void testEnumLiteralInWhereInUpdate() {
+        testEnumLiteralInSelect();
+        em.getTransaction().begin();
+        Query q = em.createQuery("update EnumFieldType o set o.intField = 3 " +
+            "where o.enumField = " +
+            "org.apache.openjpa.persistence.fields.SampleEnum.BAR");
+        assertEquals(1, ((Number) q.executeUpdate()).intValue());
+        em.getTransaction().commit();
+        postUpdateCheck(false);
+    }
+
+    private void postUpdateCheck(boolean wasEnumModified) {
+        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
+            "o.enumField = " +
+            "org.apache.openjpa.persistence.fields.SampleEnum.BAR");
+        assertEquals(wasEnumModified ? 0 : 1,
+            ((Number) q.getSingleResult()).intValue());
+
+        q = em.createQuery("select count(o) from EnumFieldType o where " +
+            "o.enumField = " +
+            "org.apache.openjpa.persistence.fields.SampleEnum.BAZ");
+        assertEquals(wasEnumModified ? 1 : 0,
+            ((Number) q.getSingleResult()).intValue());
+    }
+
+    public void testEnumPositionalParamInSelect() {
+        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
+            "o.enumField = ?1");
+        q.setParameter(1, SampleEnum.BAR);
+        assertEquals(1, ((Number) q.getSingleResult()).intValue());
+    }
+
+    public void testEnumNamedParamInSelect() {
+        Query q = em.createQuery("select count(o) from EnumFieldType o where " +
+            "o.enumField = :e");
+        q.setParameter("e", SampleEnum.BAR);
+        assertEquals(1, ((Number) q.getSingleResult()).intValue());
+    }
+
+    public void testEnumParamInSetInUpdate() {
+        testEnumLiteralInSelect();
+        em.getTransaction().begin();
+        Query q = em.createQuery("update EnumFieldType o set o.enumField = :e");
+        q.setParameter("e", SampleEnum.BAZ);
+        assertEquals(1, ((Number) q.executeUpdate()).intValue());
+        em.getTransaction().commit();
+        postUpdateCheck(true);
+    }
+
+    public void testEnumParamInWhereInUpdate() {
+        testEnumLiteralInSelect();
+        em.getTransaction().begin();
+        Query q = em.createQuery("update EnumFieldType o set o.intField = 3 " +
+            "where o.enumField = :e");
+        q.setParameter("e", SampleEnum.BAR);
+        assertEquals(1, ((Number) q.executeUpdate()).intValue());
+        em.getTransaction().commit();
+        postUpdateCheck(false);
+    }
+
+    public void testMemberOf() {
+        assertEquals(Long.valueOf(1),
+            em.createQuery("select count(o) from EnumFieldType o where " +
+                "(:param member of o.enumList or :param2 member of o.enumList)")
+                .setParameter("param", SampleEnum.FOO)
+                .setParameter("param2", SampleEnum.BAR)
+                .getSingleResult());
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/CustomSeq.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/CustomSeq.java
index 3e138bd..ca20eae 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/CustomSeq.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/CustomSeq.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.generationtype;
-
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.meta.ClassMetaData;
-
-public class CustomSeq implements Seq {
-
-    private int i = 1;
-
-    public void setType(int type) {
-        if (type == Seq.TYPE_TRANSACTIONAL)
-            throw new UnsupportedOperationException();
-    }
-
-    public Object next(StoreContext ctx, ClassMetaData cls) {
-        return i++;
-    }
-
-    public Object current(StoreContext ctx, ClassMetaData cls) {
-        return i;
-    }
-
-    public void allocate(int additional, StoreContext ctx, ClassMetaData cls) {
-    }
-
-    public void close() {
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.meta.ClassMetaData;
+
+public class CustomSeq implements Seq {
+
+    private int i = 1;
+
+    public void setType(int type) {
+        if (type == Seq.TYPE_TRANSACTIONAL)
+            throw new UnsupportedOperationException();
+    }
+
+    public Object next(StoreContext ctx, ClassMetaData cls) {
+        return i++;
+    }
+
+    public Object current(StoreContext ctx, ClassMetaData cls) {
+        return i;
+    }
+
+    public void allocate(int additional, StoreContext ctx, ClassMetaData cls) {
+    }
+
+    public void close() {
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable3.java
index 83c2ad8..7e30bcc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable3.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.generationtype;
-
-import java.io.*;
-import javax.persistence.*;
-
-/**
- * Extension of Animal class illustrating inheritance.
- */
-@Entity(name = "DogTable3")
-@Table(name = "DOGTABLES", schema = "SCHEMA3")
-public class DogTable3 implements Serializable
-
-{
-    @Id
-    @TableGenerator(name = "Dog_Gen3", table = "ID_Gen3", schema="SCHEMA3G",
-            pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", 
-            pkColumnValue = "ID2", initialValue = 100, allocationSize = 10)
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "Dog_Gen3")
-    private int id2;
-
-    private String name;
-
-    private float price;
-
-    private boolean domestic;
-
-    public DogTable3() {
-        super();
-
-    }
-
-    public DogTable3(String name) {
-        this.name = name;
-
-    }
-
-    public int getId2() {
-        return id2;
-    }
-
-    public void setId2(int id) {
-        this.id2 = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public float getPrice() {
-        return price;
-    }
-
-    public void setPrice(float price) {
-
-        this.price = price;
-    }
-
-    public boolean isDomestic() {
-        return domestic;
-    }
-
-    public void setDomestic(boolean domestic) {
-        this.domestic = domestic;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import java.io.*;
+import javax.persistence.*;
+
+/**
+ * Extension of Animal class illustrating inheritance.
+ */
+@Entity(name = "DogTable3")
+@Table(name = "DOGTABLES", schema = "SCHEMA3")
+public class DogTable3 implements Serializable
+
+{
+    @Id
+    @TableGenerator(name = "Dog_Gen3", table = "ID_Gen3", schema="SCHEMA3G",
+            pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", 
+            pkColumnValue = "ID2", initialValue = 100, allocationSize = 10)
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "Dog_Gen3")
+    private int id2;
+
+    private String name;
+
+    private float price;
+
+    private boolean domestic;
+
+    public DogTable3() {
+        super();
+
+    }
+
+    public DogTable3(String name) {
+        this.name = name;
+
+    }
+
+    public int getId2() {
+        return id2;
+    }
+
+    public void setId2(int id) {
+        this.id2 = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public float getPrice() {
+        return price;
+    }
+
+    public void setPrice(float price) {
+
+        this.price = price;
+    }
+
+    public boolean isDomestic() {
+        return domestic;
+    }
+
+    public void setDomestic(boolean domestic) {
+        this.domestic = domestic;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable4.java
index 8d08cd3..68009ba 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable4.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.generationtype;
-
-import java.io.*;
-import javax.persistence.*;
-
-/**
- * Extension of Animal class illustrating inheritance.
- */
-@Entity(name = "DogTable4")
-@Table(name = "DOGTABLES4")
-public class DogTable4 implements Serializable
-
-{
-    @Id
-    @TableGenerator(name = "Dog_Gen4", table = "ID_Gen4", schema="SCHEMA4G",
-            pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", 
-            pkColumnValue = "ID2", initialValue = 100, allocationSize = 10)
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "Dog_Gen4")
-    private int id2;
-
-    private String name;
-
-    private float price;
-
-    private boolean domestic;
-
-    public DogTable4() {
-        super();
-
-    }
-
-    public DogTable4(String name) {
-        this.name = name;
-
-    }
-
-    public int getId2() {
-        return id2;
-    }
-
-    public void setId2(int id) {
-        this.id2 = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public float getPrice() {
-        return price;
-    }
-
-    public void setPrice(float price) {
-
-        this.price = price;
-    }
-
-    public boolean isDomestic() {
-        return domestic;
-    }
-
-    public void setDomestic(boolean domestic) {
-        this.domestic = domestic;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import java.io.*;
+import javax.persistence.*;
+
+/**
+ * Extension of Animal class illustrating inheritance.
+ */
+@Entity(name = "DogTable4")
+@Table(name = "DOGTABLES4")
+public class DogTable4 implements Serializable
+
+{
+    @Id
+    @TableGenerator(name = "Dog_Gen4", table = "ID_Gen4", schema="SCHEMA4G",
+            pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", 
+            pkColumnValue = "ID2", initialValue = 100, allocationSize = 10)
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "Dog_Gen4")
+    private int id2;
+
+    private String name;
+
+    private float price;
+
+    private boolean domestic;
+
+    public DogTable4() {
+        super();
+
+    }
+
+    public DogTable4(String name) {
+        this.name = name;
+
+    }
+
+    public int getId2() {
+        return id2;
+    }
+
+    public void setId2(int id) {
+        this.id2 = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public float getPrice() {
+        return price;
+    }
+
+    public void setPrice(float price) {
+
+        this.price = price;
+    }
+
+    public boolean isDomestic() {
+        return domestic;
+    }
+
+    public void setDomestic(boolean domestic) {
+        this.domestic = domestic;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/GeneratedValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/GeneratedValues.java
index 27cf555..91957c4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/GeneratedValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/GeneratedValues.java
@@ -1,128 +1,128 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.generationtype;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.SequenceGenerator;
-
-@Entity
-public class GeneratedValues {
-    @Id
-    @GeneratedValue
-    private int id;
-
-    @GeneratedValue
-    private long field;
-
-//    @GeneratedValue(strategy= GenerationType.SEQUENCE,
-//        generator="org.apache.openjpa.persistence.generationtype.CustomSeq")
-//    private int customSeqField;
-
-    @GeneratedValue(strategy= GenerationType.SEQUENCE,
-        generator="GeneratedValues.SequenceGeneratorCustomSeq")
-    @SequenceGenerator(name="GeneratedValues.SequenceGeneratorCustomSeq",
-        sequenceName="org.apache.openjpa.persistence.generationtype.CustomSeq()")
-    private int customSeqWithIndirectionField;
-
-    @GeneratedValue(generator="uuid-hex")
-    private String uuidhex;
-
-    @GeneratedValue(generator="uuid-string")
-    private String uuidstring;
-
-    @GeneratedValue(generator="uuid-type4-hex")
-    private String uuidT4hex;
-
-    @GeneratedValue(generator="uuid-type4-string")
-    private String uuidT4string;
-    
-    public GeneratedValues() {
-        super();
-    }
-    
-    public GeneratedValues(int id, long field, String uh, String us,
-        String ut4h, String ut4s) {
-        super();
-        this.id = id;
-        this.field = field;
-        this.uuidhex = uh;
-        this.uuidstring = us;
-        this.uuidT4hex = ut4h;
-        this.uuidT4string = ut4s;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public long getField() {
-        return field;
-    }
-
-    public void setField(long field) {
-        this.field = field;
-    }
-
-//    public int getCustomSeqField() {
-//        return customSeqField;
-//    }
-
-    public int getCustomSeqWithIndirectionField() {
-        return customSeqWithIndirectionField;
-    }
-    
-    public void setUuidhex(String uuidhex) {
-        this.uuidhex = uuidhex;
-    }
-
-    public String getUuidhex() {
-        return uuidhex;
-    }
-
-    public void setUuidstring(String uuidstring) {
-        this.uuidstring = uuidstring;
-    }
-
-    public String getUuidstring() {
-        return uuidstring;
-    }
-
-    public void setUuidT4hex(String uuidT4hex) {
-        this.uuidT4hex = uuidT4hex;
-    }
-
-    public String getUuidT4hex() {
-        return uuidT4hex;
-    }
-
-    public void setUuidT4string(String uuidT4string) {
-        this.uuidT4string = uuidT4string;
-    }
-
-    public String getUuidT4string() {
-        return uuidT4string;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+
+@Entity
+public class GeneratedValues {
+    @Id
+    @GeneratedValue
+    private int id;
+
+    @GeneratedValue
+    private long field;
+
+//    @GeneratedValue(strategy= GenerationType.SEQUENCE,
+//        generator="org.apache.openjpa.persistence.generationtype.CustomSeq")
+//    private int customSeqField;
+
+    @GeneratedValue(strategy= GenerationType.SEQUENCE,
+        generator="GeneratedValues.SequenceGeneratorCustomSeq")
+    @SequenceGenerator(name="GeneratedValues.SequenceGeneratorCustomSeq",
+        sequenceName="org.apache.openjpa.persistence.generationtype.CustomSeq()")
+    private int customSeqWithIndirectionField;
+
+    @GeneratedValue(generator="uuid-hex")
+    private String uuidhex;
+
+    @GeneratedValue(generator="uuid-string")
+    private String uuidstring;
+
+    @GeneratedValue(generator="uuid-type4-hex")
+    private String uuidT4hex;
+
+    @GeneratedValue(generator="uuid-type4-string")
+    private String uuidT4string;
+    
+    public GeneratedValues() {
+        super();
+    }
+    
+    public GeneratedValues(int id, long field, String uh, String us,
+        String ut4h, String ut4s) {
+        super();
+        this.id = id;
+        this.field = field;
+        this.uuidhex = uh;
+        this.uuidstring = us;
+        this.uuidT4hex = ut4h;
+        this.uuidT4string = ut4s;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public long getField() {
+        return field;
+    }
+
+    public void setField(long field) {
+        this.field = field;
+    }
+
+//    public int getCustomSeqField() {
+//        return customSeqField;
+//    }
+
+    public int getCustomSeqWithIndirectionField() {
+        return customSeqWithIndirectionField;
+    }
+    
+    public void setUuidhex(String uuidhex) {
+        this.uuidhex = uuidhex;
+    }
+
+    public String getUuidhex() {
+        return uuidhex;
+    }
+
+    public void setUuidstring(String uuidstring) {
+        this.uuidstring = uuidstring;
+    }
+
+    public String getUuidstring() {
+        return uuidstring;
+    }
+
+    public void setUuidT4hex(String uuidT4hex) {
+        this.uuidT4hex = uuidT4hex;
+    }
+
+    public String getUuidT4hex() {
+        return uuidT4hex;
+    }
+
+    public void setUuidT4string(String uuidT4string) {
+        this.uuidT4string = uuidT4string;
+    }
+
+    public String getUuidT4string() {
+        return uuidT4string;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestGeneratedValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestGeneratedValues.java
index 7e90cb0..0a7f6dc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestGeneratedValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestGeneratedValues.java
@@ -1,218 +1,218 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.generationtype;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityExistsException;
-
-import org.apache.openjpa.persistence.InvalidStateException;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestGeneratedValues extends SingleEMFTestCase {
-    
-    public void setUp() { 
-        setUp(GeneratedValues.class, CLEAR_TABLES);
-    }
-
-    public void testDefaultValues() { 
-        EntityManager em = emf.createEntityManager();
-
-        GeneratedValues gv = new GeneratedValues();
-        GeneratedValues gv2 = new GeneratedValues();
-
-        em.getTransaction().begin();
-        em.persist(gv);
-        em.persist(gv2);
-        em.getTransaction().commit();
-
-        em.refresh(gv);
-        em.refresh(gv2);
-
-        assertFalse(gv.getId() == gv2.getId());
-        assertFalse(gv.getField() == gv2.getField());
-        assertFalse(gv.getUuidstring().equals(gv2.getUuidstring()));
-        assertFalse(gv.getUuidhex().equals(gv2.getUuidhex()));
-        assertFalse(gv.getUuidT4hex().equals(gv2.getUuidT4hex()));
-        assertFalse(gv.getUuidT4string().equals(gv2.getUuidT4string()));
-    }
-    
-    public void testInitialValues() { 
-        EntityManager em = emf.createEntityManager();
-
-        GeneratedValues gv = new GeneratedValues(7, 9, "a", "b", "c", "d");
-
-        try {
-            em.getTransaction().begin();
-            em.persist(gv);
-            em.getTransaction().commit();
-        } catch (InvalidStateException ise) {
-            // expected result
-            return;
-        }  catch (EntityExistsException eee) {
-            // also ok
-            return;
-        }
-        
-        // should not get here...
-        fail();
-    }
-    
-    public void testIdSetter() { 
-        EntityManager em = emf.createEntityManager();
-
-        GeneratedValues gv = new GeneratedValues();
-        gv.setId(3);
-
-        try {
-            em.getTransaction().begin();
-            em.persist(gv);
-            em.getTransaction().commit();
-        } catch (InvalidStateException ise) {
-            // expected result
-            return;
-        }  catch (EntityExistsException eee) {
-            // also ok
-            return;
-        }
-        
-        // should not get here...
-        fail();
-    }
-    
-    public void testFieldSetter() { 
-        EntityManager em = emf.createEntityManager();
-
-        GeneratedValues gv = new GeneratedValues();
-        gv.setField(5);
-
-        try {
-            em.getTransaction().begin();
-            em.persist(gv);
-            em.getTransaction().commit();
-        } catch (InvalidStateException ise) {
-            // expected result
-            return;
-        }
-        
-        // should not get here...
-        fail();
-    }
-
-//    public void testCustomSequenceGenerator() {
-//        EntityManager em = emf.createEntityManager();
-//
-//        GeneratedValues gv = new GeneratedValues();
-//
-//        em.getTransaction().begin();
-//        em.persist(gv);
-//        em.getTransaction().commit();
-//
-//        assertNotEquals(0, gv.getCustomSeqField());
-//    }
-
-    public void testCustomSequenceGeneratorWithIndirection() {
-        EntityManager em = emf.createEntityManager();
-
-        GeneratedValues gv = new GeneratedValues();
-
-        em.getTransaction().begin();
-        em.persist(gv);
-        em.getTransaction().commit();
-
-        assertNotEquals(0, gv.getCustomSeqWithIndirectionField());
-    }
-    
-    public void testUUIDGenerators() {
-        EntityManager em = emf.createEntityManager();
-
-        GeneratedValues gv = new GeneratedValues();
-        em.getTransaction().begin();
-        em.persist(gv);
-        em.getTransaction().commit();
-        
-        int id = gv.getId();
-
-        assertTrue(isStringUUID(gv.getUuidT4string(), 4));
-        assertTrue(isStringUUID(gv.getUuidstring(), 1));
-        assertTrue(isHexUUID(gv.getUuidhex(), 1));
-        assertTrue(isHexUUID(gv.getUuidT4hex(), 4));     
-        
-        em.clear();
-        
-        GeneratedValues gv2 = em.find(GeneratedValues.class, id);  
-        assertNotNull(gv2);
-        // The string value could contain null values and such so length
-        // calculations may be non-deterministic.  For string generators, 
-        // simply ensure the fields are populated (not null). 
-        assertNotNull(gv2.getUuidstring());
-        assertTrue(isHexUUID(gv2.getUuidhex(), 1));
-        assertNotNull(gv2.getUuidT4string());
-        assertTrue(isHexUUID(gv2.getUuidT4hex(), 4));     
-        
-        // Compare original hex values with new values.  They should be equal.
-        // Note: UUID 'string' values are not compared.  In most cases they will
-        // be the same, but in an environment where data is converted to
-        // a considerably different character encoding of the database (ex.
-        // Unicode -> EBCDIC) upon persistence, the uuid string returned by the 
-        // database may not be equal to the original value.  This is a common 
-        // issue with string data, but even more likely for a uuids given that 
-        // uuid strings are produced from pseudo-random byte arrays, which yield 
-        // all sorts of variant characters.
-        assertTrue(gv.getId() == gv2.getId());
-        assertTrue(gv.getField() == gv2.getField());
-        assertTrue(gv.getUuidhex().equals(gv2.getUuidhex()));
-        assertTrue(gv.getUuidT4hex().equals(gv2.getUuidT4hex()));
-    }
-                
-    /*
-     * Verify a uuid string is 16 characters long and is the expected type.
-     */
-    private boolean isStringUUID(String value, int type) {
-        if (value.length() != 16)
-            return false;
-        byte version = (byte)(value.charAt(6) >>> 4);
-        if (type != version) return false;
-        return true;
-    }
-    
-    /*
-     * Verify a uuid hex string value is 32 characters long, consists entirely
-     * of hex digits and is the correct version.
-     */
-    private boolean isHexUUID(String value, int type) {
-        if (value.length() != 32) 
-            return false;
-        char[] chArr = value.toCharArray();
-        for (int i = 0; i < 32; i++)
-        {                
-            char ch = chArr[i];
-            if (!(Character.isDigit(ch) ||
-                (ch >= 'a' && ch <= 'f') ||
-                (ch >= 'A' && ch <= 'F')))
-                return false;
-            if (i == 12) {
-                if (type == 1 && ch != '1')
-                    return false;
-                if (type == 4 && ch != '4')
-                    return false;
-            }
-        }
-        return true;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityExistsException;
+
+import org.apache.openjpa.persistence.InvalidStateException;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestGeneratedValues extends SingleEMFTestCase {
+    
+    public void setUp() { 
+        setUp(GeneratedValues.class, CLEAR_TABLES);
+    }
+
+    public void testDefaultValues() { 
+        EntityManager em = emf.createEntityManager();
+
+        GeneratedValues gv = new GeneratedValues();
+        GeneratedValues gv2 = new GeneratedValues();
+
+        em.getTransaction().begin();
+        em.persist(gv);
+        em.persist(gv2);
+        em.getTransaction().commit();
+
+        em.refresh(gv);
+        em.refresh(gv2);
+
+        assertFalse(gv.getId() == gv2.getId());
+        assertFalse(gv.getField() == gv2.getField());
+        assertFalse(gv.getUuidstring().equals(gv2.getUuidstring()));
+        assertFalse(gv.getUuidhex().equals(gv2.getUuidhex()));
+        assertFalse(gv.getUuidT4hex().equals(gv2.getUuidT4hex()));
+        assertFalse(gv.getUuidT4string().equals(gv2.getUuidT4string()));
+    }
+    
+    public void testInitialValues() { 
+        EntityManager em = emf.createEntityManager();
+
+        GeneratedValues gv = new GeneratedValues(7, 9, "a", "b", "c", "d");
+
+        try {
+            em.getTransaction().begin();
+            em.persist(gv);
+            em.getTransaction().commit();
+        } catch (InvalidStateException ise) {
+            // expected result
+            return;
+        }  catch (EntityExistsException eee) {
+            // also ok
+            return;
+        }
+        
+        // should not get here...
+        fail();
+    }
+    
+    public void testIdSetter() { 
+        EntityManager em = emf.createEntityManager();
+
+        GeneratedValues gv = new GeneratedValues();
+        gv.setId(3);
+
+        try {
+            em.getTransaction().begin();
+            em.persist(gv);
+            em.getTransaction().commit();
+        } catch (InvalidStateException ise) {
+            // expected result
+            return;
+        }  catch (EntityExistsException eee) {
+            // also ok
+            return;
+        }
+        
+        // should not get here...
+        fail();
+    }
+    
+    public void testFieldSetter() { 
+        EntityManager em = emf.createEntityManager();
+
+        GeneratedValues gv = new GeneratedValues();
+        gv.setField(5);
+
+        try {
+            em.getTransaction().begin();
+            em.persist(gv);
+            em.getTransaction().commit();
+        } catch (InvalidStateException ise) {
+            // expected result
+            return;
+        }
+        
+        // should not get here...
+        fail();
+    }
+
+//    public void testCustomSequenceGenerator() {
+//        EntityManager em = emf.createEntityManager();
+//
+//        GeneratedValues gv = new GeneratedValues();
+//
+//        em.getTransaction().begin();
+//        em.persist(gv);
+//        em.getTransaction().commit();
+//
+//        assertNotEquals(0, gv.getCustomSeqField());
+//    }
+
+    public void testCustomSequenceGeneratorWithIndirection() {
+        EntityManager em = emf.createEntityManager();
+
+        GeneratedValues gv = new GeneratedValues();
+
+        em.getTransaction().begin();
+        em.persist(gv);
+        em.getTransaction().commit();
+
+        assertNotEquals(0, gv.getCustomSeqWithIndirectionField());
+    }
+    
+    public void testUUIDGenerators() {
+        EntityManager em = emf.createEntityManager();
+
+        GeneratedValues gv = new GeneratedValues();
+        em.getTransaction().begin();
+        em.persist(gv);
+        em.getTransaction().commit();
+        
+        int id = gv.getId();
+
+        assertTrue(isStringUUID(gv.getUuidT4string(), 4));
+        assertTrue(isStringUUID(gv.getUuidstring(), 1));
+        assertTrue(isHexUUID(gv.getUuidhex(), 1));
+        assertTrue(isHexUUID(gv.getUuidT4hex(), 4));     
+        
+        em.clear();
+        
+        GeneratedValues gv2 = em.find(GeneratedValues.class, id);  
+        assertNotNull(gv2);
+        // The string value could contain null values and such so length
+        // calculations may be non-deterministic.  For string generators, 
+        // simply ensure the fields are populated (not null). 
+        assertNotNull(gv2.getUuidstring());
+        assertTrue(isHexUUID(gv2.getUuidhex(), 1));
+        assertNotNull(gv2.getUuidT4string());
+        assertTrue(isHexUUID(gv2.getUuidT4hex(), 4));     
+        
+        // Compare original hex values with new values.  They should be equal.
+        // Note: UUID 'string' values are not compared.  In most cases they will
+        // be the same, but in an environment where data is converted to
+        // a considerably different character encoding of the database (ex.
+        // Unicode -> EBCDIC) upon persistence, the uuid string returned by the 
+        // database may not be equal to the original value.  This is a common 
+        // issue with string data, but even more likely for a uuids given that 
+        // uuid strings are produced from pseudo-random byte arrays, which yield 
+        // all sorts of variant characters.
+        assertTrue(gv.getId() == gv2.getId());
+        assertTrue(gv.getField() == gv2.getField());
+        assertTrue(gv.getUuidhex().equals(gv2.getUuidhex()));
+        assertTrue(gv.getUuidT4hex().equals(gv2.getUuidT4hex()));
+    }
+                
+    /*
+     * Verify a uuid string is 16 characters long and is the expected type.
+     */
+    private boolean isStringUUID(String value, int type) {
+        if (value.length() != 16)
+            return false;
+        byte version = (byte)(value.charAt(6) >>> 4);
+        if (type != version) return false;
+        return true;
+    }
+    
+    /*
+     * Verify a uuid hex string value is 32 characters long, consists entirely
+     * of hex digits and is the correct version.
+     */
+    private boolean isHexUUID(String value, int type) {
+        if (value.length() != 32) 
+            return false;
+        char[] chArr = value.toCharArray();
+        for (int i = 0; i < 32; i++)
+        {                
+            char ch = chArr[i];
+            if (!(Character.isDigit(ch) ||
+                (ch >= 'a' && ch <= 'f') ||
+                (ch >= 'A' && ch <= 'F')))
+                return false;
+            if (i == 12) {
+                if (type == 1 && ch != '1')
+                    return false;
+                if (type == 4 && ch != '4')
+                    return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFieldDuplicates.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFieldDuplicates.java
index 179aa5c..7e624c2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFieldDuplicates.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFieldDuplicates.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.hugariannotation;
-
-import javax.persistence.Entity;
-
-/**
- * Created by IntelliJ IDEA.
- * User: Ben
- * Date: 02-Nov-2007
- * Time: 22:44:47
- */
-@Entity
-public class HungarianNotationFieldDuplicates {
-
-    private String strFooBar;
-    private Integer intFooBar;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.hugariannotation;
+
+import javax.persistence.Entity;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Ben
+ * Date: 02-Nov-2007
+ * Time: 22:44:47
+ */
+@Entity
+public class HungarianNotationFieldDuplicates {
+
+    private String strFooBar;
+    private Integer intFooBar;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFields.java
index afbec96..8787c0c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/HungarianNotationFields.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.hugariannotation;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-
-/**
- * Created by IntelliJ IDEA.
- * User: Ben
- * Date: 30-Oct-2007
- * Time: 22:11:00
- */
-@Entity
-public class HungarianNotationFields {
-
-    @Id
-    private Long mFooBar7;
-
-    private String mFooBar1;
-
-    private String strFooBar2;
-
-    private Integer intFooBar3;
-
-    private Long lgFooBar4;
-
-    private int m_intFooBar5;
-
-    @ManyToOne(targetEntity = OtherClass.class)
-    private OtherClass m_clzFooBar6;
-
-    @Column(name="M_INTFOOBAR7_CUSTOM_NAME")
-    private int m_intFooBar7;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.hugariannotation;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Ben
+ * Date: 30-Oct-2007
+ * Time: 22:11:00
+ */
+@Entity
+public class HungarianNotationFields {
+
+    @Id
+    private Long mFooBar7;
+
+    private String mFooBar1;
+
+    private String strFooBar2;
+
+    private Integer intFooBar3;
+
+    private Long lgFooBar4;
+
+    private int m_intFooBar5;
+
+    @ManyToOne(targetEntity = OtherClass.class)
+    private OtherClass m_clzFooBar6;
+
+    @Column(name="M_INTFOOBAR7_CUSTOM_NAME")
+    private int m_intFooBar7;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/OtherClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/OtherClass.java
index 73db300..bd90d14 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/OtherClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/OtherClass.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.hugariannotation;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-/**
- * Created by IntelliJ IDEA.
- * User: Ben
- * Date: 31-Oct-2007
- * Time: 21:04:54
- */
-@Entity
-public class OtherClass {
-
-    @Id
-    private Integer m_intBarFoo1;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.hugariannotation;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Ben
+ * Date: 31-Oct-2007
+ * Time: 21:04:54
+ */
+@Entity
+public class OtherClass {
+
+    @Id
+    private Integer m_intBarFoo1;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/TestHungarianNotationRemoval.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/TestHungarianNotationRemoval.java
index c6ede14..c409f6a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/TestHungarianNotationRemoval.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/hugariannotation/TestHungarianNotationRemoval.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.hugariannotation;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Created by IntelliJ IDEA.
- * User: Ben
- * Date: 02-Nov-2007
- * Time: 21:36:36
- */
-public class TestHungarianNotationRemoval extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(HungarianNotationFieldDuplicates.class,
-            HungarianNotationFields.class, OtherClass.class, CLEAR_TABLES,
-            "openjpa.jdbc.MappingDefaults", "removeHungarianNotation=true");
-    }
-
-    public void testSimpleColumnNameTruncation() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper
-            .getMetaData(emf, HungarianNotationFields.class);
-
-        FieldMapping[] fieldMappings = cm.getFieldMappings();
-
-        for (int i = 0; i < fieldMappings.length; i++) {
-            final String name = fieldMappings[i].getColumns()[0].getName();
-
-            // this one doesn't follow the rules
-            if (fieldMappings[i].getName().equals("m_intFooBar7"))
-                continue;
-
-            assertTrue(
-                "Failed to removed Hungarian Notation, resulting column name : "
-                    + name, name.toUpperCase().startsWith("FOOBAR"));
-        }
-    }
-
-    public void testCustomNameNotAltered() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper
-            .getMetaData(emf, HungarianNotationFields.class);
-
-        assertEquals("M_INTFOOBAR7_CUSTOM_NAME",
-            cm.getFieldMapping("m_intFooBar7").getColumns()[0].getName());
-    }
-
-    /*
-        pcl: This test currently fails. To make it work, we would need to
-        change MappingDefaultsImpl.correctName() to take a ValueMapping as
-        an argument, and do a two-pass algorithm to check for other fields
-        that would turn into duplicates. Even doing this will not be
-        foolproof, as a duplicate column might come from a subclass or an
-        embedded class.
-    public void testDuplicateColumnNameTruncation() {
-
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper
-            .getMetaData(emf, HungarianNotationFieldDuplicates.class);
-
-        for (FieldMapping fm : cm.getFieldMappings()) {
-            String name = fm.getColumns()[0].getName();
-            assertTrue(name.toUpperCase().endsWith("FOOBAR"));
-            assertFalse(name.toUpperCase().startsWith("FOOBAR"));
-        }
-    }
-    */
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.hugariannotation;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Ben
+ * Date: 02-Nov-2007
+ * Time: 21:36:36
+ */
+public class TestHungarianNotationRemoval extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(HungarianNotationFieldDuplicates.class,
+            HungarianNotationFields.class, OtherClass.class, CLEAR_TABLES,
+            "openjpa.jdbc.MappingDefaults", "removeHungarianNotation=true");
+    }
+
+    public void testSimpleColumnNameTruncation() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper
+            .getMetaData(emf, HungarianNotationFields.class);
+
+        FieldMapping[] fieldMappings = cm.getFieldMappings();
+
+        for (int i = 0; i < fieldMappings.length; i++) {
+            final String name = fieldMappings[i].getColumns()[0].getName();
+
+            // this one doesn't follow the rules
+            if (fieldMappings[i].getName().equals("m_intFooBar7"))
+                continue;
+
+            assertTrue(
+                "Failed to removed Hungarian Notation, resulting column name : "
+                    + name, name.toUpperCase().startsWith("FOOBAR"));
+        }
+    }
+
+    public void testCustomNameNotAltered() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper
+            .getMetaData(emf, HungarianNotationFields.class);
+
+        assertEquals("M_INTFOOBAR7_CUSTOM_NAME",
+            cm.getFieldMapping("m_intFooBar7").getColumns()[0].getName());
+    }
+
+    /*
+        pcl: This test currently fails. To make it work, we would need to
+        change MappingDefaultsImpl.correctName() to take a ValueMapping as
+        an argument, and do a two-pass algorithm to check for other fields
+        that would turn into duplicates. Even doing this will not be
+        foolproof, as a duplicate column might come from a subclass or an
+        embedded class.
+    public void testDuplicateColumnNameTruncation() {
+
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper
+            .getMetaData(emf, HungarianNotationFieldDuplicates.class);
+
+        for (FieldMapping fm : cm.getFieldMappings()) {
+            String name = fm.getColumns()[0].getName();
+            assertTrue(name.toUpperCase().endsWith("FOOBAR"));
+            assertFalse(name.toUpperCase().startsWith("FOOBAR"));
+        }
+    }
+    */
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/ComplexCompoundIdTestEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/ComplexCompoundIdTestEntity.java
new file mode 100644
index 0000000..e9b8bab
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/ComplexCompoundIdTestEntity.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ * JPA Entity with a compound Id of two fields, one simple and one an Entity.
+ */
+@Entity
+@Table(name = "test_complex")
+@IdClass(ComplexCompoundIdTestEntityId.class)
+public class ComplexCompoundIdTestEntity {
+
+	@Id
+	@Column(nullable = false)
+	private Long id;
+
+    @Id
+    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, 
+            fetch = FetchType.LAZY, optional = true)
+    @JoinColumn(nullable = true, name = "type_id")
+	private TypeEntity type;
+
+	public Long getId() {
+		return id;
+	}
+
+	public TypeEntity getType() {
+		return type;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/ComplexCompoundIdTestEntityId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/ComplexCompoundIdTestEntityId.java
new file mode 100644
index 0000000..2754897
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/ComplexCompoundIdTestEntityId.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+
+/**
+ * JPA Id for ComplexCompoundIdTestEntity.
+ */
+public class ComplexCompoundIdTestEntityId {
+
+	private Long id;
+
+	private Long type;
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ComplexCompoundIdTestEntityId other = (ComplexCompoundIdTestEntityId) obj;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		return true;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigDecimalIdEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigDecimalIdEntity.java
index 50bf3b6..4a58be2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigDecimalIdEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigDecimalIdEntity.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.identity;
-
-import java.math.BigDecimal;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-/**
- * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
- */
-@Entity
-public class SQLBigDecimalIdEntity {
-
-    @Id
-    private BigDecimal id;
-    private int data;
-
-    public BigDecimal getId() {
-        return id;
-    }
-
-    public void setId(BigDecimal id) {
-        this.id = id;
-    }
-
-    public int getData() {
-        return data;
-    }
-
-    public void setData(int data) {
-        this.data = data;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import java.math.BigDecimal;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
+ */
+@Entity
+public class SQLBigDecimalIdEntity {
+
+    @Id
+    private BigDecimal id;
+    private int data;
+
+    public BigDecimal getId() {
+        return id;
+    }
+
+    public void setId(BigDecimal id) {
+        this.id = id;
+    }
+
+    public int getData() {
+        return data;
+    }
+
+    public void setData(int data) {
+        this.data = data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigIntegerIdEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigIntegerIdEntity.java
index 2f107fb..1b56f4e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigIntegerIdEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SQLBigIntegerIdEntity.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.identity;
-
-import java.math.BigInteger;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-/**
- * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
- */
-@Entity
-public class SQLBigIntegerIdEntity {
-
-    @Id
-    private BigInteger id;
-    private int data;
-
-    public BigInteger getId() {
-        return id;
-    }
-
-    public void setId(BigInteger id) {
-        this.id = id;
-    }
-
-    public int getData() {
-        return data;
-    }
-
-    public void setData(int data) {
-        this.data = data;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import java.math.BigInteger;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
+ */
+@Entity
+public class SQLBigIntegerIdEntity {
+
+    @Id
+    private BigInteger id;
+    private int data;
+
+    public BigInteger getId() {
+        return id;
+    }
+
+    public void setId(BigInteger id) {
+        this.id = id;
+    }
+
+    public int getData() {
+        return data;
+    }
+
+    public void setData(int data) {
+        this.data = data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SimpleCompoundIdTestEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SimpleCompoundIdTestEntity.java
new file mode 100644
index 0000000..5bf6b24
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SimpleCompoundIdTestEntity.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+
+/**
+ * JPA Entity with a compound Id of two fields, both simple.
+ */
+@Entity
+@Table(name = "test_simple")
+@IdClass(SimpleCompoundIdTestEntityId.class)
+public class SimpleCompoundIdTestEntity {
+
+	@Id
+	@Column(nullable = false)
+	private Long firstId;
+
+	@Id
+	@Column(nullable = true)
+	private Long secondId;
+
+	// ...
+	
+	public Long getFirstId() {
+		return firstId;
+	}
+
+	public Long getSecondId() {
+		return secondId;
+	}
+	
+	// ...
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SimpleCompoundIdTestEntityId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SimpleCompoundIdTestEntityId.java
new file mode 100644
index 0000000..779b8bc
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/SimpleCompoundIdTestEntityId.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+
+/**
+ * JPA Id for SimpleCompoundIdTestEntity.
+ */
+public class SimpleCompoundIdTestEntityId {
+
+	public Long firstId;
+
+	public Long secondId;
+
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((firstId == null) ? 0 : firstId.hashCode());
+		result = prime * result + ((secondId == null) ? 0 : secondId.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		SimpleCompoundIdTestEntityId other = (SimpleCompoundIdTestEntityId) obj;
+		if (firstId == null) {
+			if (other.firstId != null)
+				return false;
+		} else if (!firstId.equals(other.firstId))
+			return false;
+		if (secondId == null) {
+			if (other.secondId != null)
+				return false;
+		} else if (!secondId.equals(other.secondId))
+			return false;
+		return true;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestCompundIdWithNull.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestCompundIdWithNull.java
new file mode 100644
index 0000000..7dc7861
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestCompundIdWithNull.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import java.sql.Connection;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test that compound identity can consists of null component column value.
+ * 
+ * This test uses pre-defined database tables created by DDL explicitly.
+ * The tables have <em>logical</em> compound primary keys in the sense non-null
+ * constraint is <em>not</em> set on the primary columns. The tables are populated 
+ * with SQL to contain null values in these columns. 
+ * The test verifies that results are returned as par expectation.
+ * For more details, refer
+ * <A href="https://issues.apache.org/jira/browse/OPENJPA-1397">JIRA-1397</A>
+ */
+public class TestCompundIdWithNull extends SingleEMFTestCase {
+    private static boolean tablesCreated = false;
+	public void setUp() throws Exception {
+	    // do not use CLEAR_TABLES or DROP_TABLES
+	    super.setUp(SimpleCompoundIdTestEntity.class, ComplexCompoundIdTestEntity.class, TypeEntity.class);
+	    if (!tablesCreated) {
+	        createTables(emf.createEntityManager());
+	    }
+	    
+	}
+	
+	public void testSimpleCompoundIdTestEntity() throws Exception  {
+			EntityManager em = emf.createEntityManager();
+			String jpql = "SELECT o FROM SimpleCompoundIdTestEntity o ORDER BY o.secondId";
+			List list = em.createQuery(jpql).getResultList();
+			assertEquals(2, list.size());
+			assertEquals(Long.valueOf(123), ((SimpleCompoundIdTestEntity) list.get(0)).getSecondId());
+			
+			SimpleCompoundIdTestEntity secondResult = (SimpleCompoundIdTestEntity) list.get(1);
+			assertNotNull("BUG (JIRA-1397)! Result list contains null in second element", secondResult);
+			assertNull(secondResult.getSecondId());
+			em.close();
+	}
+
+	
+	public void testComplexCompoundIdTestEntity() throws Exception  {
+			EntityManager em = emf.createEntityManager();
+			String jpql = "SELECT o FROM ComplexCompoundIdTestEntity o ORDER BY o.type";
+			List list = em.createQuery(jpql).getResultList();
+			assertEquals(2, list.size());
+			ComplexCompoundIdTestEntity secondResult = (ComplexCompoundIdTestEntity) list.get(1);
+			assertNotNull("Result list contains null in second element", secondResult);
+			assertNull("Result list's second record secondId field was not null", secondResult.getType());
+			em.close();
+	}
+	
+	/**
+	 * Create tables with logical compound keys without non-null constraint.
+	 * Populate them with null values in some of the columns.
+	 */
+    private void createTables(EntityManager em) throws Exception {
+        em.getTransaction().begin();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+
+        Connection conn = (Connection) kem.getConnection();
+        // NOTE that 'logically' test_simple has a ", CONSTRAINT test_simple_pk PRIMARY KEY (firstId, secondId)",
+        // but at least Derby doesn't permit NULL then.. in our real-world underlying schema that leads
+        // to this there are *NO* PRIMARY KEY on any tables, but there is a logical model expressed
+        // elsewhere stating that those two columns uniquely identify a row.
+        try {
+            conn.createStatement().execute("DROP TABLE test_type");
+            conn.createStatement().execute("DROP TABLE test_simple");
+            conn.createStatement().execute("DROP TABLE test_complex");
+        } catch (Exception e) {
+        }
+        
+        conn.createStatement().execute("CREATE TABLE test_simple(firstId NUMERIC, secondId NUMERIC)");
+        conn.createStatement().execute("INSERT INTO test_simple(firstId, secondId) VALUES (1, 123)");
+        conn.createStatement().execute("INSERT INTO test_simple(firstId, secondId) VALUES (1, NULL)");
+
+        conn.createStatement().execute("CREATE TABLE test_type(id NUMERIC CONSTRAINT test_type_pk PRIMARY KEY, " +
+                "code VARCHAR(16))");
+        conn.createStatement().execute("INSERT INTO test_type(id, code) VALUES (987, 'ABC')");
+
+        conn.createStatement().execute("CREATE TABLE test_complex(id NUMERIC, type_id NUMERIC)");
+        conn.createStatement().execute("INSERT INTO test_complex(id, type_id) VALUES (1, 987)");
+        conn.createStatement().execute("INSERT INTO test_complex(id, type_id) VALUES (1, NULL)");
+
+        conn.close();
+        
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+	    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigDecimalId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigDecimalId.java
index ab378a7..22b248f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigDecimalId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigDecimalId.java
@@ -1,61 +1,61 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.identity;
-
-import java.math.BigDecimal;
-import javax.persistence.EntityManager;
-
-import junit.textui.TestRunner;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
- */
-public class TestSQLBigDecimalId
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(SQLBigDecimalIdEntity.class, CLEAR_TABLES);
-    }
-
-    public void testPersist() {
-        long time = ((long) (System.currentTimeMillis() / 1000)) * 1000;
-        BigDecimal decimal = new BigDecimal(time);
-
-        SQLBigDecimalIdEntity e = new SQLBigDecimalIdEntity();
-        e.setId(decimal);
-        e.setData(1);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(e);
-        em.getTransaction().commit();
-        assertEquals(time, e.getId().longValue());
-        em.close();
-
-        em = emf.createEntityManager();
-        e = em.find(SQLBigDecimalIdEntity.class, decimal);
-        assertEquals(1, e.getData());
-        em.close();
-    }
-
-    public static void main(String[] args) {
-        TestRunner.run(SQLBigDecimalIdEntity.class);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import java.math.BigDecimal;
+import javax.persistence.EntityManager;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
+ */
+public class TestSQLBigDecimalId
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(SQLBigDecimalIdEntity.class, CLEAR_TABLES);
+    }
+
+    public void testPersist() {
+        long time = ((long) (System.currentTimeMillis() / 1000)) * 1000;
+        BigDecimal decimal = new BigDecimal(time);
+
+        SQLBigDecimalIdEntity e = new SQLBigDecimalIdEntity();
+        e.setId(decimal);
+        e.setData(1);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(e);
+        em.getTransaction().commit();
+        assertEquals(time, e.getId().longValue());
+        em.close();
+
+        em = emf.createEntityManager();
+        e = em.find(SQLBigDecimalIdEntity.class, decimal);
+        assertEquals(1, e.getData());
+        em.close();
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(SQLBigDecimalIdEntity.class);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigIntegerId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigIntegerId.java
index 5d62bf1..c972c3d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigIntegerId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestSQLBigIntegerId.java
@@ -1,62 +1,62 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.identity;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import javax.persistence.EntityManager;
-
-import junit.textui.TestRunner;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
- */
-public class TestSQLBigIntegerId
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(SQLBigIntegerIdEntity.class, CLEAR_TABLES);
-    }
-
-    public void testPersist() {
-        long time = ((long) (System.currentTimeMillis() / 1000)) * 1000;
-        BigInteger integer = new BigDecimal(time).toBigInteger();
-
-        SQLBigIntegerIdEntity e = new SQLBigIntegerIdEntity();
-        e.setId(integer);
-        e.setData(1);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(e);
-        em.getTransaction().commit();
-        assertEquals(time, e.getId().longValue());
-        em.close();
-
-        em = emf.createEntityManager();
-        e = em.find(SQLBigIntegerIdEntity.class, integer);
-        assertEquals(1, e.getData());
-        em.close();
-    }
-
-    public static void main(String[] args) {
-        TestRunner.run(SQLBigIntegerIdEntity.class);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import javax.persistence.EntityManager;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * @author <a href="mailto:mnachev@gmail.com">Miroslav Nachev</a>
+ */
+public class TestSQLBigIntegerId
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(SQLBigIntegerIdEntity.class, CLEAR_TABLES);
+    }
+
+    public void testPersist() {
+        long time = ((long) (System.currentTimeMillis() / 1000)) * 1000;
+        BigInteger integer = new BigDecimal(time).toBigInteger();
+
+        SQLBigIntegerIdEntity e = new SQLBigIntegerIdEntity();
+        e.setId(integer);
+        e.setData(1);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(e);
+        em.getTransaction().commit();
+        assertEquals(time, e.getId().longValue());
+        em.close();
+
+        em = emf.createEntityManager();
+        e = em.find(SQLBigIntegerIdEntity.class, integer);
+        assertEquals(1, e.getData());
+        em.close();
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(SQLBigIntegerIdEntity.class);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TypeEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TypeEntity.java
new file mode 100644
index 0000000..59a584a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TypeEntity.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * JPA Entity
+ */
+@Entity
+@Table(name = "test_type")
+public class TypeEntity {
+
+	@Id
+	private Long id;
+	
+	private String code;
+	
+	// ...
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/Account.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/Account.java
new file mode 100644
index 0000000..3e879b5
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/Account.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity.entityasidentity;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="EAIAccount")
+@IdClass(AccountId.class)
+public class Account {
+    @Id
+    @Column(name="account_id")
+    private Integer accountId;
+    
+    @Id
+    @Column(name="group_id")
+    private Integer groupId;
+    
+    @Id
+    @ManyToOne(cascade = CascadeType.ALL)
+    @JoinColumn(name="accountHolder_id")
+    private Person accountHolder;
+    
+    private long balanceInDollars;
+    private int  balanceInCents;
+    private boolean accountLocked;
+    
+    public Account() {
+        
+    }
+
+    public Integer getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(Integer accountId) {
+        this.accountId = accountId;
+    }
+
+    public Integer getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(Integer groupId) {
+        this.groupId = groupId;
+    }
+
+    public Person getAccountHolder() {
+        return accountHolder;
+    }
+
+    public void setAccountHolder(Person accountHolder) {
+        this.accountHolder = accountHolder;
+    }
+
+    public long getBalanceInDollars() {
+        return balanceInDollars;
+    }
+
+    public void setBalanceInDollars(long balanceInDollars) {
+        this.balanceInDollars = balanceInDollars;
+    }
+
+    public int getBalanceInCents() {
+        return balanceInCents;
+    }
+
+    public void setBalanceInCents(int balanceInCents) {
+        this.balanceInCents = balanceInCents;
+    }
+
+    public boolean isAccountLocked() {
+        return accountLocked;
+    }
+
+    public void setAccountLocked(boolean accountLocked) {
+        this.accountLocked = accountLocked;
+    }       
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/AccountGroup.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/AccountGroup.java
new file mode 100644
index 0000000..d98a713
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/AccountGroup.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity.entityasidentity;
+
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="EAIAccountGroup")
+public class AccountGroup {
+    @Id
+    private Integer id;
+    
+    @OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
+    private Set<Account> accountSet;
+    
+    public AccountGroup() {
+        accountSet = new java.util.HashSet<Account>();
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Set<Account> getAccountSet() {
+        return accountSet;
+    }
+
+    public void setAccountSet(Set<Account> accountSet) {
+        this.accountSet = accountSet;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/AccountId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/AccountId.java
new file mode 100644
index 0000000..dc55341
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/AccountId.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity.entityasidentity;
+
+public class AccountId implements java.io.Serializable {
+    private static final long serialVersionUID = 4262907482129342511L;
+    
+    private Integer accountId;
+    private Integer groupId;
+    private Integer accountHolder;
+    
+    private Integer hashcode = null;
+    
+    public AccountId() {
+        
+    }
+
+    public Integer getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(Integer accountId) {
+        this.accountId = accountId;
+    }
+    
+
+    public Integer getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(Integer groupId) {
+        this.groupId = groupId;
+    }
+
+    public Integer getAccountHolder() {
+        return accountHolder;
+    }
+
+    public void setAccountHolder(Integer accountHolder) {
+        this.accountHolder = accountHolder;
+    }
+    
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+            
+        if (o instanceof AccountId) {
+            AccountId oId = (AccountId) o;
+            if (    oId.accountId.equals(this.accountId) && 
+                    oId.accountHolder.equals(this.accountHolder) &&
+                    oId.groupId.equals(this.groupId)) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    public int hashCode() {
+        if (hashcode == null) {
+            String hashStr = this.groupId + ":" + this.accountHolder + ":" + this.accountId;
+            hashcode = hashStr.hashCode();
+        }
+        return hashcode.intValue();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/Person.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/Person.java
new file mode 100644
index 0000000..02e45c3
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/Person.java
@@ -0,0 +1,61 @@
+/*
+s * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity.entityasidentity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="EAIPerson")
+public class Person {
+    @Id
+    private Integer id;
+    
+    private String firstName;
+    private String lastName;
+    
+    public Person() {
+        
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/TestEntityAsIdentityFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/TestEntityAsIdentityFields.java
new file mode 100644
index 0000000..7ad6795
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/entityasidentity/TestEntityAsIdentityFields.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.identity.entityasidentity;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestEntityAsIdentityFields extends SingleEMFTestCase {    
+    public void setUp() {
+        setUp(
+                Account.class, AccountGroup.class, Person.class,
+                "openjpa.Compatibility", "reorderMetaDataResolution=true");
+    }
+    
+    /**
+     * Tests for the NullPointerException in MappingInfo.mergeJoinColumn reported in OpenJPA-1141.
+     */
+    public void testEntityAsIdentityField001() {
+        EntityManager em = null;
+        em = emf.createEntityManager();
+        
+        Query query = em.createQuery("SELECT ag from AccountGroup ag");
+        List resultList = query.getResultList();
+        
+        em.close();
+    }
+    
+    /**
+     * Test EntityManager persist() and find() with entities with entity relationships as
+     * part of their identity.  Clears persistence context between entity create and find.
+     */
+    public void testEntityAsIdentityField002A() {
+        EntityManager em = null;
+        
+        try {
+            em = emf.createEntityManager();
+            
+            // Create population
+            createPopulation(em);
+            
+            // Clear persistence context, fetch from database
+            em.clear();
+            AccountId aId = new AccountId();
+            aId.setAccountId(1);
+            aId.setAccountHolder(1);
+            aId.setGroupId(1);
+            Account findAccount = em.find(Account.class, aId);
+            assertTrue(findAccount != null);
+        } finally {
+            // Cleanup
+            if (em != null) {
+                if (em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                em.close();
+            }
+        }
+    }
+    
+    /**
+     * Test EntityManager persist() and find() with entities with entity relationships as
+     * part of their identity.  Does not clear persistence context between entity create and find.
+     */
+    public void testEntityAsIdentityField002B() {
+        EntityManager em = null;
+        
+        try {
+            em = emf.createEntityManager();
+            
+            // Create population
+            createPopulation(em);
+            
+            // Fetch from database
+            AccountId aId = new AccountId();
+            aId.setAccountId(1);
+            aId.setAccountHolder(1);
+            aId.setGroupId(1);
+            Account findAccount = em.find(Account.class, aId);
+            assertTrue(findAccount != null);
+        } finally {
+            // Cleanup
+            if (em != null) {
+                if (em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                em.close();
+            }
+        }
+    }
+    
+    /**
+     * Test EntityManager persist() and find() with entities with entity relationships as
+     * part of their identity.  Uses different EntityManagers for create and find.
+     * 
+     */
+    public void testEntityAsIdentityField002C() {
+        EntityManager em = null;
+        EntityManager emPop = null;
+        
+        try {
+            emPop = emf.createEntityManager();
+            em = emf.createEntityManager();
+            
+            // Create population
+            createPopulation(emPop);
+            
+            // Clear persistence context, fetch from database
+            em.clear();
+            AccountId aId = new AccountId();
+            aId.setAccountId(1);
+            aId.setAccountHolder(1);
+            aId.setGroupId(1);
+            Account findAccount = em.find(Account.class, aId);
+            assertTrue(findAccount != null);
+        } finally {
+            // Cleanup
+            if (em != null) {
+                if (em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                em.close();
+            }
+            if (emPop != null) {
+                if (emPop.getTransaction().isActive()) {
+                    emPop.getTransaction().rollback();
+                }
+                emPop.close();
+            }
+        }
+    }
+    
+    /**
+     * Test a query with a where clause that crosses through the identity relationship.
+     * Clear persistence context before performing the query.
+     */
+    public void testEntityAsIdentityField003A() {
+        EntityManager em = null;
+        
+        try {
+            em = emf.createEntityManager();
+            
+            // Create population
+            createPopulation(em);
+            em.clear();
+            
+            Query query = em.createQuery("SELECT a FROM Account a WHERE a.accountHolder.id > 5");
+            List resultList = query.getResultList();
+            assertEquals(5, resultList.size());
+        } finally {
+            // Cleanup
+            if (em != null) {
+                if (em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                em.close();
+            }
+        }
+    }
+    
+    /**
+     * Test a query with a where clause that crosses through the identity relationship.
+     * Use a separate EntityManager to populate the database, and a separate EntityManager
+     * to perform the query
+     */
+    public void testEntityAsIdentityField004A() {
+        EntityManager em = null;
+        EntityManager emPop = null;
+        
+        try {
+            emPop = emf.createEntityManager();
+            em = emf.createEntityManager();
+            
+            // Create population
+            createPopulation(emPop);
+            em.clear();
+            
+            Query query = em.createQuery("SELECT a FROM Account a WHERE a.accountHolder.id > 5");
+            List resultList = query.getResultList();
+            assertEquals(5, resultList.size());
+        } finally {
+            // Cleanup
+            if (em != null) {
+                if (em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                em.close();
+            }
+            if (emPop != null) {
+                if (emPop.getTransaction().isActive()) {
+                    emPop.getTransaction().rollback();
+                }
+                emPop.close();
+            }
+        }
+    }
+    
+    /**
+     * Database population
+     * 
+     */
+    private void createPopulation(EntityManager em) {
+        em.getTransaction().begin();
+        
+        AccountGroup ag = new AccountGroup();
+        ag.setId(1);
+        Set<Account> agAccountSet = ag.getAccountSet();
+        em.persist(ag);
+        
+        for (int index = 1; index <= 10; index++) {
+            Person peep = new Person();
+            peep.setId(index);
+            peep.setFirstName("John");
+            peep.setLastName("Doe");
+            
+            Account account = new Account();
+            account.setAccountId(index);
+            account.setAccountHolder(peep);
+            account.setGroupId((index / 5) + 1);
+            
+            account.setBalanceInCents(0);
+            account.setBalanceInDollars(index * 1000);
+                       
+            em.persist(peep);
+            em.persist(account);
+            
+            agAccountSet.add(account);
+        }    
+        
+        em.getTransaction().commit();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/NoGenEntityL3Sibling.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/NoGenEntityL3Sibling.java
index 38450be..b442917 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/NoGenEntityL3Sibling.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/NoGenEntityL3Sibling.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.inheritance;
-
-import javax.persistence.Entity;
-
-@Entity 
-public class NoGenEntityL3Sibling 
-    extends NoGenMappedSuperclassL2 {
-
-    private int siblingl3data;
-
-    public int getSiblingL3Data() {
-        return siblingl3data;
-    }
-
-    public void setSiblingL3Data(int data) {
-        siblingl3data = data;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance;
+
+import javax.persistence.Entity;
+
+@Entity 
+public class NoGenEntityL3Sibling 
+    extends NoGenMappedSuperclassL2 {
+
+    private int siblingl3data;
+
+    public int getSiblingL3Data() {
+        return siblingl3data;
+    }
+
+    public void setSiblingL3Data(int data) {
+        siblingl3data = data;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestInheritanceWithMSCID.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestInheritanceWithMSCID.java
new file mode 100644
index 0000000..80029c7
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestInheritanceWithMSCID.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.inheritance.entities.EntityMapping;
+import org.apache.openjpa.persistence.inheritance.entities.EntityMapping.
+    InheritanceEntityMapping;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestInheritanceWithMSCID extends SingleEMFTestCase {
+    @SuppressWarnings("unchecked")
+    public void setUp() {
+        /*
+         * All entities used by this test are defined in the enumeration
+         * EntityMapping.InheritanceEntityMapping.
+         */
+        EntityMapping.InheritanceEntityMapping[] entityClassEnums = 
+            EntityMapping.InheritanceEntityMapping.values();
+        
+        Class[] entityClassTypes = new Class[entityClassEnums.length];
+        int idx = 0;
+        for (EntityMapping.InheritanceEntityMapping eEnum : entityClassEnums) {
+            entityClassTypes[idx] = eEnum.getEntityClass();
+            idx++;
+        }
+        
+        setUp((Object[]) entityClassTypes);
+    }
+
+    private InheritanceEntityMapping[][] allEntityGroups = { 
+            EntityMapping.PIdJTIDMSC, 
+            EntityMapping.PIdJTCDMSC,
+            EntityMapping.PIdJTSDMSC,
+            
+            EntityMapping.PIdSTIDMSC, 
+            EntityMapping.PIdSTCDMSC,
+            EntityMapping.PIdSTSDMSC
+    };
+    
+    /**
+     * Verifies that each entity type in the inheritance structure can be
+     * persisted.  Entities are not cleared out of the persistence context
+     * (the L1 cache) when they are created.
+     */
+    @SuppressWarnings("unchecked")
+    public void testPersistableWithEntitiesInL1Cache() {
+        EntityManager em = emf.createEntityManager();
+        
+        for (InheritanceEntityMapping[] tEntities : allEntityGroups ) {
+            int idx = 0;
+            
+            try {
+                for (InheritanceEntityMapping tEntity : tEntities) {
+                    RootEntity entity = (RootEntity) 
+                        EntityMapping.createEntityObjectInstance(tEntity);
+                    entity.updateId(new Integer(idx++));
+                    entity.setRootEntityData("Root " + (idx - 1));
+                    
+                    em.getTransaction().begin();
+                    em.persist(entity);
+                    em.getTransaction().commit();
+                }
+            } catch (Exception e) {
+                fail("Test failed with Exception\n" + e);
+            }
+            
+            List<RootEntity> resultList = (List<RootEntity>) em.createQuery(
+                    "SELECT e FROM " + tEntities[0].getEntityName() + 
+                    " e ORDER BY e.id").getResultList();
+            assertEquals(tEntities.length, resultList.size());
+      
+            idx = 0;
+            for (Object obj : resultList) {
+                RootEntity entity = (RootEntity) obj;
+                Class<? extends RootEntity> actualType = entity.getClass();
+                Class<? extends RootEntity> expectedType = 
+                    tEntities[idx].getEntityClass();
+                
+                assertEquals(
+                        "Assert Entity " + (idx + 1) + "is entity of type " + 
+                        expectedType, expectedType, actualType);
+                
+                idx++;
+            }
+        }
+        
+        em.close();
+    }
+    
+    /**
+     * Verifies that each entity type in the inheritance structure can be
+     * persisted.  Entities are cleared out of the persistence context
+     * (the L1 cache) after they are created.
+     */
+    @SuppressWarnings("unchecked")
+    public void testPersistableWithEntitiesClearedFromL1Cache() {
+        EntityManager em = emf.createEntityManager();       
+        
+        for (InheritanceEntityMapping[] tEntities : allEntityGroups ) {
+            int idx = 0;
+            
+            try {
+                for (InheritanceEntityMapping tEntity : tEntities) {
+                    RootEntity entity = (RootEntity) 
+                        EntityMapping.createEntityObjectInstance(tEntity);
+                    entity.updateId(new Integer(idx++));
+                    entity.setRootEntityData("Root " + (idx - 1));
+                    
+                    em.getTransaction().begin();
+                    em.persist(entity);
+                    em.getTransaction().commit();
+                    em.clear();
+                }
+            } catch (Exception e) {
+                fail("Test failed with Exception\n" + e);
+            }
+            
+            List<RootEntity>  resultList = (List<RootEntity>) em.createQuery(
+                    "SELECT e FROM " + tEntities[0].getEntityName() + 
+                    " e ORDER BY e.id").getResultList();
+            assertEquals(tEntities.length, resultList.size());
+      
+            idx = 0;
+            for (Object obj : resultList) {
+                RootEntity entity = (RootEntity) obj;
+                Class<? extends RootEntity> actualType = entity.getClass();
+                Class<? extends RootEntity> expectedType = 
+                    tEntities[idx].getEntityClass();
+                
+                assertEquals(
+                        "Assert Entity " + (idx + 1) + "is entity of type " + 
+                        expectedType, expectedType, actualType);
+                
+                idx++;
+            }
+        }
+        
+        em.close();
+    }
+    
+
+    
+    /*
+     * The following tests exercise the following scenario:
+     * 
+     * Verify that all-inclusive SELECT against an entity that is a member
+     * of an inheritance hierarchy will include all of its subclasses within
+     * the query results as well.
+     * 
+     * Variations of this test include clearing the L1 cache after db 
+     * population and between each Query check, and not clearing the L1 
+     * cache.
+     * 
+     */
+    
+    private boolean[][] queryLogic001AcceptenceMapping = new boolean[][] {
+            // RootEntity
+            new boolean[] { true, true, true, true, true, true, true, true,
+                    true },
+            // Leaf A
+            new boolean[] { false, true, false, false, false, false, false,
+                    false, false },
+            // EntityB
+            new boolean[] { false, false, true, true, true, false, false,
+                    false, false },
+            // Leaf B1
+            new boolean[] { false, false, false, true, false, false, false,
+                    false, false },
+            // Leaf B2
+            new boolean[] { false, false, false, false, true, false, false,
+                    false, false },
+            // Leaf C
+            new boolean[] { false, false, false, false, false, true, false,
+                    false, false },
+            // Entity D
+            new boolean[] { false, false, false, false, false, false, true,
+                    true, true },
+            // Leaf D1
+            new boolean[] { false, false, false, false, false, false, false,
+                    true, false },
+            // Leaf D2
+            new boolean[] { false, false, false, false, false, false, false,
+                    false, true } };
+
+    @SuppressWarnings("unchecked")
+    private void query001TestLogic(boolean clearL1Cache) {
+        EntityManager em = emf.createEntityManager();         
+            
+        boolean[][] acceptenceMapping = queryLogic001AcceptenceMapping;
+        
+        for (InheritanceEntityMapping[] tEntities : allEntityGroups ) {
+            // Populate Database
+            int idx = 0;
+            try {
+                for (InheritanceEntityMapping tEntity : tEntities) {
+                    RootEntity entity = (RootEntity) 
+                        EntityMapping.createEntityObjectInstance(tEntity);
+                    entity.updateId(new Integer(idx++));
+                    entity.setRootEntityData("Root " + (idx - 1));
+                    
+                    em.getTransaction().begin();
+                    em.persist(entity);
+                    em.getTransaction().commit();
+                    
+                    if (clearL1Cache)
+                        em.clear();
+                }
+            } catch (Exception e) {
+                fail("Test failed with Exception\n" + e);
+            }
+            
+            // Run through acceptance tests
+            idx = 0;
+            for (boolean[] acceptenceMap : acceptenceMapping) {
+                int expectedQueryResultListSize = 0;
+                for (boolean acceptence : acceptenceMap) {
+                    if (acceptence)
+                        expectedQueryResultListSize++;
+                }
+                String queryStr = "SELECT e FROM " + 
+                    tEntities[idx].getEntityName() + " e";
+                List<RootEntity> resultList = (List<RootEntity>)
+                    em.createQuery(queryStr).getResultList();
+
+                assertEquals(
+                        "Assert the following query creates a result list " +
+                        "with " + expectedQueryResultListSize + " entities: " +
+                        "\"" + queryStr + "\".  ",
+                        expectedQueryResultListSize, 
+                        resultList.size());
+                idx++;
+                
+                if (clearL1Cache)
+                    em.clear();
+            }        
+        }
+
+        em.close();
+    }
+    
+    /**
+     * Verify that all-inclusive SELECT against an entity that is a member of an
+     * inheritance hierarchy will include all of its subclasses within the query
+     * results as well.  Test will not clear the L1 cache after populating DB
+     * and will not clear the L1 cache in between Query executions.
+     */
+    public void testQuery001WithL1() {
+        query001TestLogic(false);
+    }
+    
+    /**
+     * Verify that all-inclusive SELECT against an entity that is a member of an
+     * inheritance hierarchy will include all of its subclasses within the query
+     * results as well.  Test will clear the L1 cache after populating DB
+     * and will  clear the L1 cache in between Query executions.
+     */
+    public void testQuery001NoL1() {
+        query001TestLogic(true);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestMappedSuperclass.java
new file mode 100644
index 0000000..6e5df22
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestMappedSuperclass.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.inheritance.entity.BaseClass;
+import org.apache.openjpa.persistence.inheritance.entity.MappedSuper;
+import org.apache.openjpa.persistence.inheritance.entity.SubclassC;
+import org.apache.openjpa.persistence.inheritance.entity.SubclassD;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * This test verifies basic Mapped Superclass functionality as dictated by
+ * the JPA Specification contract. 
+ * 
+ * OpenJPA JIRA: {@link http://issues.apache.org/jira/browse/OPENJPA-1061}
+ *
+ */
+public class TestMappedSuperclass extends SingleEMFTestCase {
+    public void setUp() {
+        setUp(BaseClass.class, SubclassC.class, MappedSuper.class,
+                SubclassD.class);
+    }
+
+    private Class[] classArray(Class... classes) {
+        return classes;
+    }
+
+    /**
+     * Verify that two entity classes, extending a Mapped Superclass that
+     * defines an ID field, are not members of a common inheritance
+     * hierarchy.  This test variant inserts new entities into the persistence
+     * context by calling EntityManager.persist() on the new entity object.
+     */
+    public void testMappedSuperclassContract001() {
+        EntityManager em = emf.createEntityManager();
+
+        // Create two entities, SubclassC and SubclassD, with the same
+        // primary key value     
+        SubclassC sc = new SubclassC();
+        sc.setId(42);
+        sc.setName("SubclassCMappedSuperName");
+        sc.setClassCName("SubclassCName");
+
+        em.getTransaction().begin();
+        em.persist(sc);
+        em.getTransaction().commit();
+
+        SubclassD sd = new SubclassD();
+        sd.setId(42);
+        sd.setName("SubclassDMappedSuperName");
+        sd.setClassDName("SubclassDName");
+
+        // No EntityExistsException should be thrown by the persist
+        em.getTransaction().begin();
+        em.persist(sd);
+        em.getTransaction().commit();
+    }
+
+    /**
+     * Verify that two entity classes, extending a Mapped Superclass that
+     * defines an ID field, are not members of a common inheritance
+     * hierarchy.  This test variant inserts new entities into the persistence
+     * context by calling EntityManager.merge() on the new entity object.
+     */
+    public void testMappedSuperclassContract002() {
+        EntityManager em = emf.createEntityManager();
+
+        // Create two entities, SubclassC and SubclassD, with the same
+        // primary key value
+
+        SubclassC sc = new SubclassC();
+        sc.setId(43);
+        sc.setName("SubclassCMappedSuperName");
+        sc.setClassCName("SubclassCName");
+
+        em.getTransaction().begin();
+        em.merge(sc);
+        em.getTransaction().commit();
+
+        SubclassD sd = new SubclassD();
+        sd.setId(43);
+        sd.setName("SubclassDMappedSuperName");
+        sd.setClassDName("SubclassDName");
+
+        // No EntityExistsException should be thrown by the merge
+        em.getTransaction().begin();
+        em.merge(sd);
+        em.getTransaction().commit();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestSharedUnqualifiedClassNames.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestSharedUnqualifiedClassNames.java
index 2ae5fc7..b7ad136 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestSharedUnqualifiedClassNames.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/TestSharedUnqualifiedClassNames.java
@@ -1,62 +1,62 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.kernel.AbstractBrokerFactory;
-
-/**
- * Test that entities, mapped superclasses, and embeddables can all share
- * the same short names without any collisions.
- */
-public class TestSharedUnqualifiedClassNames
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(org.apache.openjpa.persistence.inheritance.mappedsuperclass
-                .SharedName1.class,
-            org.apache.openjpa.persistence.inheritance.entity
-                .SharedName1.class,
-            org.apache.openjpa.persistence.inheritance.embeddable
-                .SharedName2.class,
-            org.apache.openjpa.persistence.inheritance.entity
-                .SharedName2.class);
-        emf.createEntityManager().close();
-    }
-
-        public void testMappedSuperclass() {
-        ClassMetaData meta = emf.getConfiguration()
-            .getMetaDataRepositoryInstance()
-            .getMetaData("SharedName1", getClass().getClassLoader(), true);
-        assertEquals(
-            org.apache.openjpa.persistence.inheritance.entity.SharedName1.class,
-            meta.getDescribedType());
-    }
-
-    public void testEmbeddable() {
-        ClassMetaData meta = emf.getConfiguration()
-            .getMetaDataRepositoryInstance()
-            .getMetaData("SharedName2", getClass().getClassLoader(), true);
-        assertEquals(
-            org.apache.openjpa.persistence.inheritance.entity.SharedName2.class,
-            meta.getDescribedType());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
+
+/**
+ * Test that entities, mapped superclasses, and embeddables can all share
+ * the same short names without any collisions.
+ */
+public class TestSharedUnqualifiedClassNames
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(org.apache.openjpa.persistence.inheritance.mappedsuperclass
+                .SharedName1.class,
+            org.apache.openjpa.persistence.inheritance.entity
+                .SharedName1.class,
+            org.apache.openjpa.persistence.inheritance.embeddable
+                .SharedName2.class,
+            org.apache.openjpa.persistence.inheritance.entity
+                .SharedName2.class);
+        emf.createEntityManager().close();
+    }
+
+        public void testMappedSuperclass() {
+        ClassMetaData meta = emf.getConfiguration()
+            .getMetaDataRepositoryInstance()
+            .getMetaData("SharedName1", getClass().getClassLoader(), true);
+        assertEquals(
+            org.apache.openjpa.persistence.inheritance.entity.SharedName1.class,
+            meta.getDescribedType());
+    }
+
+    public void testEmbeddable() {
+        ClassMetaData meta = emf.getConfiguration()
+            .getMetaDataRepositoryInstance()
+            .getMetaData("SharedName2", getClass().getClassLoader(), true);
+        assertEquals(
+            org.apache.openjpa.persistence.inheritance.entity.SharedName2.class,
+            meta.getDescribedType());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/RelationOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/RelationOwner.java
index 948bdb6..81da48f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/RelationOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/RelationOwner.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
-
-import java.util.*;
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
-
-@Entity
-@Table(name="TEST")
-public class RelationOwner {
-	
-	private Integer id;
-	private Collection<Superclass> supers = new ArrayList<Superclass>();
-	
-	@Id
-	@Column(name="ID")
-	public Integer getId() { return id;	}
-	public void setId(Integer id) { this.id = id; }
-	
-	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
-	@ElementJoinColumn(name="TEST", referencedColumnName="ID")
-	public Collection<Superclass> getSupers() {	return supers; }
-	public void setSupers(Collection<Superclass> supers) { this.supers = supers; }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
+
+import java.util.*;
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
+
+@Entity
+@Table(name="TEST")
+public class RelationOwner {
+	
+	private Integer id;
+	private Collection<Superclass> supers = new ArrayList<Superclass>();
+	
+	@Id
+	@Column(name="ID")
+	public Integer getId() { return id;	}
+	public void setId(Integer id) { this.id = id; }
+	
+	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
+	@ElementJoinColumn(name="TEST", referencedColumnName="ID")
+	public Collection<Superclass> getSupers() {	return supers; }
+	public void setSupers(Collection<Superclass> supers) { this.supers = supers; }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SubID.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SubID.java
index 612802b..49a4d2c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SubID.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SubID.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
-
-public class SubID extends SuperID {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
+
+public class SubID extends SuperID {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Subclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Subclass.java
index e1c9b31..29bad78 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Subclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Subclass.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
-
-import javax.persistence.*;
-
-@Entity
-@IdClass(SubID.class)
-@Table(name="SUB")
-public class Subclass extends Superclass {
-	
-	private String attr2;
-	
-	@Column(name="ATTR2")
-	public String getAttr2() { return attr2; }
-	public void setAttr2(String attr2) { this.attr2 = attr2; }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
+
+import javax.persistence.*;
+
+@Entity
+@IdClass(SubID.class)
+@Table(name="SUB")
+public class Subclass extends Superclass {
+	
+	private String attr2;
+	
+	@Column(name="ATTR2")
+	public String getAttr2() { return attr2; }
+	public void setAttr2(String attr2) { this.attr2 = attr2; }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SuperID.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SuperID.java
index a5de491..5acc179 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SuperID.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/SuperID.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
-
-import java.io.Serializable;
-
-public abstract class SuperID implements Serializable {
-	
-	private Integer id;
-
-	public Integer getId() { return id; }
-	public void setId(Integer id) {	this.id = id; }
-	
-	public int hashCode() {
-		return id;
-	}
-	
-	public boolean equals(Object obj) {
-		if (obj == this) return true;
-		if (!(obj instanceof SuperID)) return false;
-		SuperID pk = (SuperID) obj;
-		if ( pk.getId().equals(id)) {
-			return true;
-		} else {
-			return false;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
+
+import java.io.Serializable;
+
+public abstract class SuperID implements Serializable {
+	
+	private Integer id;
+
+	public Integer getId() { return id; }
+	public void setId(Integer id) {	this.id = id; }
+	
+	public int hashCode() {
+		return id;
+	}
+	
+	public boolean equals(Object obj) {
+		if (obj == this) return true;
+		if (!(obj instanceof SuperID)) return false;
+		SuperID pk = (SuperID) obj;
+		if ( pk.getId().equals(id)) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Superclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Superclass.java
index 063806a..bf721a7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Superclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/abstractjoinedappid/Superclass.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
-
-import javax.persistence.*;
-
-@Entity
-@IdClass(SuperID.class)
-@Table(name="SUPER")
-@Inheritance(strategy=InheritanceType.JOINED)
-public abstract class Superclass {
-	
-	private Integer id;
-	private String attr1;
-	
-	@Id
-	@Column(name="ID")
-	public Integer getId() { return id; }
-	public void setId(Integer id) {	this.id = id; }
-	
-	@Column(name="ATTR1")
-	public String getAttr1() { return attr1; }
-	public void setAttr1(String attr1) { this.attr1 = attr1; }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance.abstractjoinedappid;
+
+import javax.persistence.*;
+
+@Entity
+@IdClass(SuperID.class)
+@Table(name="SUPER")
+@Inheritance(strategy=InheritanceType.JOINED)
+public abstract class Superclass {
+	
+	private Integer id;
+	private String attr1;
+	
+	@Id
+	@Column(name="ID")
+	public Integer getId() { return id; }
+	public void setId(Integer id) {	this.id = id; }
+	
+	@Column(name="ATTR1")
+	public String getAttr1() { return attr1; }
+	public void setAttr1(String attr1) { this.attr1 = attr1; }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/embeddable/SharedName2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/embeddable/SharedName2.java
index 4dd8221..886f123 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/embeddable/SharedName2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/embeddable/SharedName2.java
@@ -1,30 +1,30 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.embeddable;
-
-import javax.persistence.Embeddable;
-
-/**
- * This class has the same name as {@link
- * org.apache.openjpa.persistence.inheritance.entity.SharedName2}
- */
-@Embeddable
-public class SharedName2 {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.embeddable;
+
+import javax.persistence.Embeddable;
+
+/**
+ * This class has the same name as {@link
+ * org.apache.openjpa.persistence.inheritance.entity.SharedName2}
+ */
+@Embeddable
+public class SharedName2 {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/EntityMapping.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/EntityMapping.java
new file mode 100644
index 0000000..e964847
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/EntityMapping.java
@@ -0,0 +1,521 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.inheritance.entities;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCEntityB;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCEntityD;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCLeafA;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCLeafB1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCLeafB2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCLeafC;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCLeafD1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCLeafD2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator.PIdJTCDMSCRootEntity;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCEntityB;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCEntityD;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCLeafA;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCLeafB1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCLeafB2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCLeafC;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCLeafD1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCLeafD2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator.PIdJTIDMSCRootEntity;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCEntityB;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCEntityD;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCLeafA;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCLeafB1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCLeafB2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCLeafC;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCLeafD1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCLeafD2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.
+    PIdJTSDMSCMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator.PIdJTSDMSCRootEntity;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCEntityB;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCEntityD;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCLeafA;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCLeafB1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCLeafB2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCLeafC;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCLeafD1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCLeafD2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.
+    PIdSTCDMSCMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator.PIdSTCDMSCRootEntity;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCEntityB;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCEntityD;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCLeafA;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCLeafB1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCLeafB2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCLeafC;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCLeafD1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCLeafD2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.
+    PIdSTIDMSCMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator.PIdSTIDMSCRootEntity;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCEntityB;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCEntityD;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCLeafA;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCLeafB1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCLeafB2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCLeafC;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCLeafD1;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCLeafD2;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.
+    PIdSTSDMSCMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator.PIdSTSDMSCRootEntity;
+
+public class EntityMapping {
+    @SuppressWarnings("unchecked")
+    public static enum InheritanceEntityMapping {
+        /*
+         * Primitive Identity defined on a Mapped Superclass, 
+         * Joined Table Entity Inheritance
+         */
+        
+        // Primitive Identity defined on a Mapped Superclass, 
+        // Joined Table Entity Inheritance, Integer Discriminator
+        PIdJTIDMSCRootEntity {         
+            public Class getEntityClass() {
+                return PIdJTIDMSCRootEntity.class;
+            }
+        },
+        PIdJTIDMSCLeafA {
+            public Class getEntityClass() {
+                return PIdJTIDMSCLeafA.class;
+            }
+        },
+        PIdJTIDMSCEntityB {
+            public Class getEntityClass() {
+                return PIdJTIDMSCEntityB.class;
+            }
+        },
+        PIdJTIDMSCLeafB1 {
+            public Class getEntityClass() {
+                return PIdJTIDMSCLeafB1.class;
+            }
+        },
+        PIdJTIDMSCLeafB2 {
+            public Class getEntityClass() {
+                return PIdJTIDMSCLeafB2.class;
+            }
+        },
+        PIdJTIDMSCLeafC {
+            public Class getEntityClass() {
+                return PIdJTIDMSCLeafC.class;
+            }
+        },
+        PIdJTIDMSCEntityD {
+            public Class getEntityClass() {
+                return PIdJTIDMSCEntityD.class;
+            }
+        },
+        PIdJTIDMSCLeafD1 {
+            public Class getEntityClass() {
+                return PIdJTIDMSCLeafD1.class;
+            }
+        },
+        PIdJTIDMSCLeafD2 {
+            public Class getEntityClass() {
+                return PIdJTIDMSCLeafD2.class;
+            }
+        },
+        
+        // Primitive Identity defined on a Mapped Superclass, 
+        // Joined Table Entity Inheritance, Char Discriminator
+        PIdJTCDMSCRootEntity {
+            public Class getEntityClass() {
+                return PIdJTCDMSCRootEntity.class;
+            }
+        },
+        PIdJTCDMSCLeafA {
+            public Class getEntityClass() {
+                return PIdJTCDMSCLeafA.class;
+            }
+        },
+        PIdJTCDMSCEntityB {
+            public Class getEntityClass() {
+                return PIdJTCDMSCEntityB.class;
+            }
+        },
+        PIdJTCDMSCLeafB1 {
+            public Class getEntityClass() {
+                return PIdJTCDMSCLeafB1.class;
+            }
+        },
+        PIdJTCDMSCLeafB2 {
+            public Class getEntityClass() {
+                return PIdJTCDMSCLeafB2.class;
+            }
+        },
+        PIdJTCDMSCLeafC {
+            public Class getEntityClass() {
+                return PIdJTCDMSCLeafC.class;
+            }
+        },
+        PIdJTCDMSCEntityD {
+            public Class getEntityClass() {
+                return PIdJTCDMSCEntityD.class;
+            }
+        },
+        PIdJTCDMSCLeafD1 {
+            public Class getEntityClass() {
+                return PIdJTCDMSCLeafD1.class;
+            }
+        },
+        PIdJTCDMSCLeafD2 {
+            public Class getEntityClass() {
+                return PIdJTCDMSCLeafD2.class;
+            }
+        },
+        
+        // Primitive Identity defined on a Mapped Superclass, 
+        // Joined Table Entity Inheritance, String Discriminator
+        PIdJTSDMSCRootEntity {
+            public Class getEntityClass() {
+                return PIdJTSDMSCRootEntity.class;
+            }
+        },
+        PIdJTSDMSCLeafA {
+            public Class getEntityClass() {
+                return PIdJTSDMSCLeafA.class;
+            }
+        },
+        PIdJTSDMSCEntityB {
+            public Class getEntityClass() {
+                return PIdJTSDMSCEntityB.class;
+            }
+        },
+        PIdJTSDMSCLeafB1 {
+            public Class getEntityClass() {
+                return PIdJTSDMSCLeafB1.class;
+            }
+        },
+        PIdJTSDMSCLeafB2 {
+            public Class getEntityClass() {
+                return PIdJTSDMSCLeafB2.class;
+            }
+        },
+        PIdJTSDMSCLeafC {
+            public Class getEntityClass() {
+                return PIdJTSDMSCLeafC.class;
+            }
+        },
+        PIdJTSDMSCEntityD {
+            public Class getEntityClass() {
+                return PIdJTSDMSCEntityD.class;
+            }
+        },
+        PIdJTSDMSCLeafD1 {
+            public Class getEntityClass() {
+                return PIdJTSDMSCLeafD1.class;
+            }
+        },
+        PIdJTSDMSCLeafD2 {
+            public Class getEntityClass() {
+                return PIdJTSDMSCLeafD2.class;
+            }
+        },
+        
+        /*
+         * Primitive Identity defined on a Mapped Superclass, 
+         * Single Table Entity Inheritance
+         */
+        
+        // Primitive Identity defined on a Mapped Superclass, 
+        // Single Table Entity Inheritance, Integer Discriminator
+        PIdSTIDMSCRootEntity {
+            public Class getEntityClass() {
+                return PIdSTIDMSCRootEntity.class;
+            }
+        },
+        PIdSTIDMSCLeafA {
+            public Class getEntityClass() {
+                return PIdSTIDMSCLeafA.class;
+            }
+        },
+        PIdSTIDMSCEntityB {
+            public Class getEntityClass() {
+                return PIdSTIDMSCEntityB.class;
+            }
+        },
+        PIdSTIDMSCLeafB1 {
+            public Class getEntityClass() {
+                return PIdSTIDMSCLeafB1.class;
+            }
+        },
+        PIdSTIDMSCLeafB2 {
+            public Class getEntityClass() {
+                return PIdSTIDMSCLeafB2.class;
+            }
+        },
+        PIdSTIDMSCLeafC {
+            public Class getEntityClass() {
+                return PIdSTIDMSCLeafC.class;
+            }
+        },
+        PIdSTIDMSCEntityD {
+            public Class getEntityClass() {
+                return PIdSTIDMSCEntityD.class;
+            }
+        },
+        PIdSTIDMSCLeafD1 {
+            public Class getEntityClass() {
+                return PIdSTIDMSCLeafD1.class;
+            }
+        },
+        PIdSTIDMSCLeafD2 {
+            public Class getEntityClass() {
+                return PIdSTIDMSCLeafD2.class;
+            }
+        },
+        
+        // Primitive Identity defined on a Mapped Superclass, 
+        // Single Table Entity Inheritance, Char Discriminator
+        PIdSTCDMSCRootEntity {
+            public Class getEntityClass() {
+                return PIdSTCDMSCRootEntity.class;
+            }
+        },
+        PIdSTCDMSCLeafA {
+            public Class getEntityClass() {
+                return PIdSTCDMSCLeafA.class;
+            }
+        },
+        PIdSTCDMSCEntityB {
+            public Class getEntityClass() {
+                return PIdSTCDMSCEntityB.class;
+            }
+        },
+        PIdSTCDMSCLeafB1 {
+            public Class getEntityClass() {
+                return PIdSTCDMSCLeafB1.class;
+            }
+        },
+        PIdSTCDMSCLeafB2 {
+            public Class getEntityClass() {
+                return PIdSTCDMSCLeafB2.class;
+            }
+        },
+        PIdSTCDMSCLeafC {
+            public Class getEntityClass() {
+                return PIdSTCDMSCLeafC.class;
+            }
+        },
+        PIdSTCDMSCEntityD {
+            public Class getEntityClass() {
+                return PIdSTCDMSCEntityD.class;
+            }
+        },
+        PIdSTCDMSCLeafD1 {
+            public Class getEntityClass() {
+                return PIdSTCDMSCLeafD1.class;
+            }
+        },
+        PIdSTCDMSCLeafD2 {
+            public Class getEntityClass() {
+                return PIdSTCDMSCLeafD2.class;
+            }
+        },
+        
+        // Primitive Identity defined on a Mapped Superclass, 
+        // Single Table Entity Inheritance, String Discriminator
+        PIdSTSDMSCRootEntity {
+            public Class getEntityClass() {
+                return PIdSTSDMSCRootEntity.class;
+            }
+        },
+        PIdSTSDMSCLeafA {
+            public Class getEntityClass() {
+                return PIdSTSDMSCLeafA.class;
+            }
+        },
+        PIdSTSDMSCEntityB {
+            public Class getEntityClass() {
+                return PIdSTSDMSCEntityB.class;
+            }
+        },
+        PIdSTSDMSCLeafB1 {
+            public Class getEntityClass() {
+                return PIdSTSDMSCLeafB1.class;
+            }
+        },
+        PIdSTSDMSCLeafB2 {
+            public Class getEntityClass() {
+                return PIdSTSDMSCLeafB2.class;
+            }
+        },
+        PIdSTSDMSCLeafC {
+            public Class getEntityClass() {
+                return PIdSTSDMSCLeafC.class;
+            }
+        },
+        PIdSTSDMSCEntityD {
+            public Class getEntityClass() {
+                return PIdSTSDMSCEntityD.class;
+            }
+        },
+        PIdSTSDMSCLeafD1 {
+            public Class getEntityClass() {
+                return PIdSTSDMSCLeafD1.class;
+            }
+        },
+        PIdSTSDMSCLeafD2 {
+            public Class getEntityClass() {
+                return PIdSTSDMSCLeafD2.class;
+            }
+        },
+
+        
+        /*
+         * Non Entity PC-Aware Types
+         */
+        PrimitiveIDMappedSuperclass {
+            public Class getEntityClass() {
+                return PrimitiveIDMappedSuperclass.class;
+            }
+        }, 
+        PIdJTIDMSCMappedSuperclass {
+            public Class getEntityClass() {
+                return PIdJTIDMSCMappedSuperclass.class;
+            }
+        },
+        PIdJTICMSCMappedSuperclass {
+            public Class getEntityClass() {
+                return PIdJTCDMSCMappedSuperclass.class;
+            }
+        },
+        PIdJTISMSCMappedSuperclass {
+            public Class getEntityClass() {
+                return PIdJTSDMSCMappedSuperclass.class;
+            }
+        },
+        PIdSTIDMSCMappedSuperclass {
+            public Class getEntityClass() {
+                return PIdSTIDMSCMappedSuperclass.class;
+            }
+        },
+        PIdSTICMSCMappedSuperclass {
+            public Class getEntityClass() {
+                return PIdSTCDMSCMappedSuperclass.class;
+            }
+        },
+        PIdSTISMSCMappedSuperclass {
+            public Class getEntityClass() {
+                return PIdSTSDMSCMappedSuperclass.class;
+            }
+        }
+        
+        ;
+        
+        public abstract Class getEntityClass();
+        public String getEntityName() {
+            return getEntityClass().getSimpleName();
+        }
+    };
+    
+    public final static InheritanceEntityMapping[] PIdJTIDMSC = {
+        InheritanceEntityMapping.PIdJTIDMSCRootEntity,
+        InheritanceEntityMapping.PIdJTIDMSCLeafA,
+        InheritanceEntityMapping.PIdJTIDMSCEntityB,
+        InheritanceEntityMapping.PIdJTIDMSCLeafB1,
+        InheritanceEntityMapping.PIdJTIDMSCLeafB2,
+        InheritanceEntityMapping.PIdJTIDMSCLeafC,
+        InheritanceEntityMapping.PIdJTIDMSCEntityD,
+        InheritanceEntityMapping.PIdJTIDMSCLeafD1,
+        InheritanceEntityMapping.PIdJTIDMSCLeafD2
+    };
+    
+    public final static InheritanceEntityMapping[] PIdJTCDMSC = {
+        InheritanceEntityMapping.PIdJTCDMSCRootEntity,
+        InheritanceEntityMapping.PIdJTCDMSCLeafA,
+        InheritanceEntityMapping.PIdJTCDMSCEntityB,
+        InheritanceEntityMapping.PIdJTCDMSCLeafB1,
+        InheritanceEntityMapping.PIdJTCDMSCLeafB2,
+        InheritanceEntityMapping.PIdJTCDMSCLeafC,
+        InheritanceEntityMapping.PIdJTCDMSCEntityD,
+        InheritanceEntityMapping.PIdJTCDMSCLeafD1,
+        InheritanceEntityMapping.PIdJTCDMSCLeafD2
+    };
+    
+    public final static InheritanceEntityMapping[] PIdJTSDMSC = {
+        InheritanceEntityMapping.PIdJTSDMSCRootEntity,
+        InheritanceEntityMapping.PIdJTSDMSCLeafA,
+        InheritanceEntityMapping.PIdJTSDMSCEntityB,
+        InheritanceEntityMapping.PIdJTSDMSCLeafB1,
+        InheritanceEntityMapping.PIdJTSDMSCLeafB2,
+        InheritanceEntityMapping.PIdJTSDMSCLeafC,
+        InheritanceEntityMapping.PIdJTSDMSCEntityD,
+        InheritanceEntityMapping.PIdJTSDMSCLeafD1,
+        InheritanceEntityMapping.PIdJTSDMSCLeafD2
+    };
+    
+    public final static InheritanceEntityMapping[] PIdSTIDMSC = {
+        InheritanceEntityMapping.PIdSTIDMSCRootEntity,
+        InheritanceEntityMapping.PIdSTIDMSCLeafA,
+        InheritanceEntityMapping.PIdSTIDMSCEntityB,
+        InheritanceEntityMapping.PIdSTIDMSCLeafB1,
+        InheritanceEntityMapping.PIdSTIDMSCLeafB2,
+        InheritanceEntityMapping.PIdSTIDMSCLeafC,
+        InheritanceEntityMapping.PIdSTIDMSCEntityD,
+        InheritanceEntityMapping.PIdSTIDMSCLeafD1,
+        InheritanceEntityMapping.PIdSTIDMSCLeafD2
+    };
+    
+    public final static InheritanceEntityMapping[] PIdSTCDMSC = {
+        InheritanceEntityMapping.PIdSTCDMSCRootEntity,
+        InheritanceEntityMapping.PIdSTCDMSCLeafA,
+        InheritanceEntityMapping.PIdSTCDMSCEntityB,
+        InheritanceEntityMapping.PIdSTCDMSCLeafB1,
+        InheritanceEntityMapping.PIdSTCDMSCLeafB2,
+        InheritanceEntityMapping.PIdSTCDMSCLeafC,
+        InheritanceEntityMapping.PIdSTCDMSCEntityD,
+        InheritanceEntityMapping.PIdSTCDMSCLeafD1,
+        InheritanceEntityMapping.PIdSTCDMSCLeafD2
+    };
+    
+    public final static InheritanceEntityMapping[] PIdSTSDMSC = {
+        InheritanceEntityMapping.PIdSTSDMSCRootEntity,
+        InheritanceEntityMapping.PIdSTSDMSCLeafA,
+        InheritanceEntityMapping.PIdSTSDMSCEntityB,
+        InheritanceEntityMapping.PIdSTSDMSCLeafB1,
+        InheritanceEntityMapping.PIdSTSDMSCLeafB2,
+        InheritanceEntityMapping.PIdSTSDMSCLeafC,
+        InheritanceEntityMapping.PIdSTSDMSCEntityD,
+        InheritanceEntityMapping.PIdSTSDMSCLeafD1,
+        InheritanceEntityMapping.PIdSTSDMSCLeafD2
+    };
+
+    
+    @SuppressWarnings("unchecked")
+    public static Object createEntityObjectInstance(
+            InheritanceEntityMapping eType) throws Exception {
+        Class eClassType = eType.getEntityClass();
+        
+        Constructor c = eClassType.getConstructor(new Class[] {});
+        Object eObj = c.newInstance(new Object[] {});
+        return eObj;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/PrimitiveIDMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/PrimitiveIDMappedSuperclass.java
new file mode 100644
index 0000000..81f445d
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/PrimitiveIDMappedSuperclass.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc;
+
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Mapped Superclass defining an integer-type primary key field.
+ *
+ */
+@MappedSuperclass
+public abstract class PrimitiveIDMappedSuperclass {
+    @Id
+    private int id;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+    
+    public Object fetchId() {
+        return new Integer(getId());
+    }
+    
+    public void updateId(Object obj) {
+        Integer i = (Integer) obj;
+        setId(i.intValue());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCEntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCEntityB.java
new file mode 100644
index 0000000..1ec5c9d
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCEntityB.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityB;
+
+@Entity
+@DiscriminatorValue("C")
+public class PIdJTCDMSCEntityB 
+extends PIdJTCDMSCRootEntity implements EntityB {
+    private String entityBData;
+    
+    public String getEntityBData() {
+        return entityBData;
+    }
+    public void setEntityBData(String entityBData) {
+        this.entityBData = entityBData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCEntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCEntityD.java
new file mode 100644
index 0000000..6802f7f
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCEntityD.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityD;
+@Entity
+@DiscriminatorValue("G")
+public class PIdJTCDMSCEntityD 
+extends PIdJTCDMSCMappedSuperclass implements EntityD {
+private String entityDData;
+    
+    public String getEntityDData() {
+        return entityDData;
+    }
+    public void setEntityDData(String entityDData) {
+        this.entityDData = entityDData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafA.java
new file mode 100644
index 0000000..934f35d
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafA.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafA;
+
+@Entity
+@DiscriminatorValue("B")
+public class PIdJTCDMSCLeafA 
+extends PIdJTCDMSCRootEntity implements LeafA {
+    private String leafAData;
+    
+    public String getLeafAData() 
+    {
+        return leafAData;
+    }
+    
+    public void setLeafAData(String leafAData) {
+        this.leafAData = leafAData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafB1.java
new file mode 100644
index 0000000..721d572
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafB1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB1;
+
+@Entity
+@DiscriminatorValue("D")
+public class PIdJTCDMSCLeafB1 
+extends PIdJTCDMSCEntityB implements LeafB1 {
+    private String leafB1Data;
+    
+    public String getLeafB1Data() {
+        return leafB1Data;
+    }
+    public void setLeafB1Data(String leafB1Data) {
+        this.leafB1Data = leafB1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafB2.java
new file mode 100644
index 0000000..295c31b
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafB2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB2;
+
+@Entity
+@DiscriminatorValue("E")
+public class PIdJTCDMSCLeafB2
+extends PIdJTCDMSCEntityB implements LeafB2 {
+private String leafB2Data;
+    
+    public String getLeafB2Data() {
+        return leafB2Data;
+    }
+    public void setLeafB2Data(String leafB2Data) {
+        this.leafB2Data = leafB2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafC.java
new file mode 100644
index 0000000..5e58581
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafC;
+
+@Entity
+@DiscriminatorValue("F")
+public class PIdJTCDMSCLeafC 
+extends PIdJTCDMSCMappedSuperclass implements LeafC {
+    private String leafCData;
+    
+    public String getLeafCData() 
+    {
+        return leafCData;
+    }
+    
+    public void setLeafCData(String leafCData) {
+        this.leafCData = leafCData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafD1.java
new file mode 100644
index 0000000..29a82b4
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafD1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD1;
+
+@Entity
+@DiscriminatorValue("H")
+public class PIdJTCDMSCLeafD1 
+extends PIdJTCDMSCEntityD implements LeafD1 {
+    private String leafD1Data;
+    
+    public String getLeafD1Data() {
+        return leafD1Data;
+    }
+    public void setLeafD1Data(String leafD1Data) {
+        this.leafD1Data = leafD1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafD2.java
new file mode 100644
index 0000000..f627048
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCLeafD2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD2;
+
+@Entity
+@DiscriminatorValue("I")
+public class PIdJTCDMSCLeafD2 
+extends PIdJTCDMSCEntityD implements LeafD2 {
+    private String leafD2Data;
+    
+    public String getLeafD2Data() {
+        return leafD2Data;
+    }
+    public void setLeafD2Data(String leafD2Data) {
+        this.leafD2Data = leafD2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCMappedSuperclass.java
new file mode 100644
index 0000000..da360c3
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCMappedSuperclass.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.MSC;
+
+@MappedSuperclass
+public class PIdJTCDMSCMappedSuperclass 
+extends PIdJTCDMSCRootEntity implements MSC {
+    private String mappedSuperclassData;
+    
+    public String getMappedSuperclassData() {
+        return mappedSuperclassData;
+    }
+    
+    public void setMappedSuperclassData(String mappedSuperclassData) {
+        this.mappedSuperclassData = mappedSuperclassData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCRootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCRootEntity.java
new file mode 100644
index 0000000..a1e4683
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/chardiscriminator/PIdJTCDMSCRootEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.chardiscriminator;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+
+@Entity
+@Inheritance(strategy=InheritanceType.JOINED)
+@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.CHAR)
+@DiscriminatorValue("A")
+public class PIdJTCDMSCRootEntity 
+    extends PrimitiveIDMappedSuperclass implements RootEntity {
+    private String rootEntityData;
+    
+    public String getRootEntityData() {
+        return rootEntityData;
+    }
+    public void setRootEntityData(String rootEntityData) {
+        this.rootEntityData = rootEntityData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCEntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCEntityB.java
new file mode 100644
index 0000000..509a625
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCEntityB.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityB;
+
+@Entity
+@DiscriminatorValue("3")
+public class PIdJTIDMSCEntityB 
+extends PIdJTIDMSCRootEntity implements EntityB {
+    private String entityBData;
+    
+    public String getEntityBData() {
+        return entityBData;
+    }
+    public void setEntityBData(String entityBData) {
+        this.entityBData = entityBData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCEntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCEntityD.java
new file mode 100644
index 0000000..4203e4d
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCEntityD.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityD;
+@Entity
+@DiscriminatorValue("7")
+public class PIdJTIDMSCEntityD 
+extends PIdJTIDMSCMappedSuperclass implements EntityD {
+private String entityDData;
+    
+    public String getEntityDData() {
+        return entityDData;
+    }
+    public void setEntityDData(String entityDData) {
+        this.entityDData = entityDData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafA.java
new file mode 100644
index 0000000..765248d
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafA.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafA;
+
+@Entity
+@DiscriminatorValue("2")
+public class PIdJTIDMSCLeafA 
+extends PIdJTIDMSCRootEntity implements LeafA {
+    private String leafAData;
+    
+    public String getLeafAData() 
+    {
+        return leafAData;
+    }
+    
+    public void setLeafAData(String leafAData) {
+        this.leafAData = leafAData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafB1.java
new file mode 100644
index 0000000..5390dee
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafB1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB1;
+
+@Entity
+@DiscriminatorValue("4")
+public class PIdJTIDMSCLeafB1 
+extends PIdJTIDMSCEntityB implements LeafB1 {
+    private String leafB1Data;
+    
+    public String getLeafB1Data() {
+        return leafB1Data;
+    }
+    public void setLeafB1Data(String leafB1Data) {
+        this.leafB1Data = leafB1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafB2.java
new file mode 100644
index 0000000..ef639c2
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafB2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB2;
+
+@Entity
+@DiscriminatorValue("5")
+public class PIdJTIDMSCLeafB2
+extends PIdJTIDMSCEntityB implements LeafB2 {
+private String leafB2Data;
+    
+    public String getLeafB2Data() {
+        return leafB2Data;
+    }
+    public void setLeafB2Data(String leafB2Data) {
+        this.leafB2Data = leafB2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafC.java
new file mode 100644
index 0000000..7855109
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafC;
+
+@Entity
+@DiscriminatorValue("6")
+public class PIdJTIDMSCLeafC 
+extends PIdJTIDMSCMappedSuperclass implements LeafC {
+    private String leafCData;
+    
+    public String getLeafCData() 
+    {
+        return leafCData;
+    }
+    
+    public void setLeafCData(String leafCData) {
+        this.leafCData = leafCData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafD1.java
new file mode 100644
index 0000000..43f35bb
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafD1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD1;
+
+@Entity
+@DiscriminatorValue("8")
+public class PIdJTIDMSCLeafD1 
+extends PIdJTIDMSCEntityD implements LeafD1 {
+    private String leafD1Data;
+    
+    public String getLeafD1Data() {
+        return leafD1Data;
+    }
+    public void setLeafD1Data(String leafD1Data) {
+        this.leafD1Data = leafD1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafD2.java
new file mode 100644
index 0000000..6d59305
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCLeafD2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD2;
+
+@Entity
+@DiscriminatorValue("9")
+public class PIdJTIDMSCLeafD2 
+extends PIdJTIDMSCEntityD implements LeafD2 {
+    private String leafD2Data;
+    
+    public String getLeafD2Data() {
+        return leafD2Data;
+    }
+    public void setLeafD2Data(String leafD2Data) {
+        this.leafD2Data = leafD2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCMappedSuperclass.java
new file mode 100644
index 0000000..1f1de94
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCMappedSuperclass.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.MSC;
+
+@MappedSuperclass
+public class PIdJTIDMSCMappedSuperclass 
+extends PIdJTIDMSCRootEntity implements MSC {
+    private String mappedSuperclassData;
+    
+    public String getMappedSuperclassData() {
+        return mappedSuperclassData;
+    }
+    
+    public void setMappedSuperclassData(String mappedSuperclassData) {
+        this.mappedSuperclassData = mappedSuperclassData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCRootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCRootEntity.java
new file mode 100644
index 0000000..8e23055
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/intdiscriminator/PIdJTIDMSCRootEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.intdiscriminator;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+
+@Entity
+@Inheritance(strategy=InheritanceType.JOINED)
+@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.INTEGER)
+@DiscriminatorValue("1")
+public class PIdJTIDMSCRootEntity 
+    extends PrimitiveIDMappedSuperclass implements RootEntity {
+    private String rootEntityData;
+    
+    public String getRootEntityData() {
+        return rootEntityData;
+    }
+    public void setRootEntityData(String rootEntityData) {
+        this.rootEntityData = rootEntityData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCEntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCEntityB.java
new file mode 100644
index 0000000..490d6f9
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCEntityB.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityB;
+
+@Entity
+@DiscriminatorValue("StrC")
+public class PIdJTSDMSCEntityB 
+extends PIdJTSDMSCRootEntity implements EntityB {
+    private String entityBData;
+    
+    public String getEntityBData() {
+        return entityBData;
+    }
+    public void setEntityBData(String entityBData) {
+        this.entityBData = entityBData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCEntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCEntityD.java
new file mode 100644
index 0000000..2fff6ad
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCEntityD.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityD;
+@Entity
+@DiscriminatorValue("StrG")
+public class PIdJTSDMSCEntityD 
+extends PIdJTSDMSCMappedSuperclass implements EntityD {
+private String entityDData;
+    
+    public String getEntityDData() {
+        return entityDData;
+    }
+    public void setEntityDData(String entityDData) {
+        this.entityDData = entityDData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafA.java
new file mode 100644
index 0000000..6e6569a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafA.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafA;
+
+@Entity
+@DiscriminatorValue("StrB")
+public class PIdJTSDMSCLeafA 
+extends PIdJTSDMSCRootEntity implements LeafA {
+    private String leafAData;
+    
+    public String getLeafAData() 
+    {
+        return leafAData;
+    }
+    
+    public void setLeafAData(String leafAData) {
+        this.leafAData = leafAData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafB1.java
new file mode 100644
index 0000000..7dab5e2
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafB1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB1;
+
+@Entity
+@DiscriminatorValue("StrD")
+public class PIdJTSDMSCLeafB1 
+extends PIdJTSDMSCEntityB implements LeafB1 {
+    private String leafB1Data;
+    
+    public String getLeafB1Data() {
+        return leafB1Data;
+    }
+    public void setLeafB1Data(String leafB1Data) {
+        this.leafB1Data = leafB1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafB2.java
new file mode 100644
index 0000000..0e16123
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafB2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB2;
+
+@Entity
+@DiscriminatorValue("StrE")
+public class PIdJTSDMSCLeafB2
+extends PIdJTSDMSCEntityB implements LeafB2 {
+private String leafB2Data;
+    
+    public String getLeafB2Data() {
+        return leafB2Data;
+    }
+    public void setLeafB2Data(String leafB2Data) {
+        this.leafB2Data = leafB2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafC.java
new file mode 100644
index 0000000..ea50110
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafC;
+
+@Entity
+@DiscriminatorValue("StrF")
+public class PIdJTSDMSCLeafC 
+extends PIdJTSDMSCMappedSuperclass implements LeafC {
+    private String leafCData;
+    
+    public String getLeafCData() 
+    {
+        return leafCData;
+    }
+    
+    public void setLeafCData(String leafCData) {
+        this.leafCData = leafCData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafD1.java
new file mode 100644
index 0000000..3967a50
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafD1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD1;
+
+@Entity
+@DiscriminatorValue("StrH")
+public class PIdJTSDMSCLeafD1 
+extends PIdJTSDMSCEntityD implements LeafD1 {
+    private String leafD1Data;
+    
+    public String getLeafD1Data() {
+        return leafD1Data;
+    }
+    public void setLeafD1Data(String leafD1Data) {
+        this.leafD1Data = leafD1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafD2.java
new file mode 100644
index 0000000..96ea1ad
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCLeafD2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD2;
+
+@Entity
+@DiscriminatorValue("StrI")
+public class PIdJTSDMSCLeafD2 
+extends PIdJTSDMSCEntityD implements LeafD2 {
+    private String leafD2Data;
+    
+    public String getLeafD2Data() {
+        return leafD2Data;
+    }
+    public void setLeafD2Data(String leafD2Data) {
+        this.leafD2Data = leafD2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCMappedSuperclass.java
new file mode 100644
index 0000000..77bd5dc
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCMappedSuperclass.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.MSC;
+
+@MappedSuperclass
+public class PIdJTSDMSCMappedSuperclass 
+extends PIdJTSDMSCRootEntity implements MSC {
+    private String mappedSuperclassData;
+    
+    public String getMappedSuperclassData() {
+        return mappedSuperclassData;
+    }
+    
+    public void setMappedSuperclassData(String mappedSuperclassData) {
+        this.mappedSuperclassData = mappedSuperclassData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCRootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCRootEntity.java
new file mode 100644
index 0000000..9ec792b
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/jointable/stringdiscriminator/PIdJTSDMSCRootEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.jointable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+
+@Entity
+@Inheritance(strategy=InheritanceType.JOINED)
+@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING)
+@DiscriminatorValue("StrA")
+public class PIdJTSDMSCRootEntity 
+    extends PrimitiveIDMappedSuperclass implements RootEntity {
+    private String rootEntityData;
+    
+    public String getRootEntityData() {
+        return rootEntityData;
+    }
+    public void setRootEntityData(String rootEntityData) {
+        this.rootEntityData = rootEntityData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCEntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCEntityB.java
new file mode 100644
index 0000000..93bdad7
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCEntityB.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityB;
+
+@Entity
+@DiscriminatorValue("C")
+public class PIdSTCDMSCEntityB 
+extends PIdSTCDMSCRootEntity implements EntityB {
+    private String entityBData;
+    
+    public String getEntityBData() {
+        return entityBData;
+    }
+    public void setEntityBData(String entityBData) {
+        this.entityBData = entityBData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCEntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCEntityD.java
new file mode 100644
index 0000000..5cf87a6
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCEntityD.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityD;
+@Entity
+@DiscriminatorValue("G")
+public class PIdSTCDMSCEntityD 
+extends PIdSTCDMSCMappedSuperclass implements EntityD {
+private String entityDData;
+    
+    public String getEntityDData() {
+        return entityDData;
+    }
+    public void setEntityDData(String entityDData) {
+        this.entityDData = entityDData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafA.java
new file mode 100644
index 0000000..aad5142
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafA.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafA;
+
+@Entity
+@DiscriminatorValue("B")
+public class PIdSTCDMSCLeafA 
+extends PIdSTCDMSCRootEntity implements LeafA {
+    private String leafAData;
+    
+    public String getLeafAData() 
+    {
+        return leafAData;
+    }
+    
+    public void setLeafAData(String leafAData) {
+        this.leafAData = leafAData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafB1.java
new file mode 100644
index 0000000..10e70d9
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafB1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB1;
+
+@Entity
+@DiscriminatorValue("D")
+public class PIdSTCDMSCLeafB1 
+extends PIdSTCDMSCEntityB implements LeafB1 {
+    private String leafB1Data;
+    
+    public String getLeafB1Data() {
+        return leafB1Data;
+    }
+    public void setLeafB1Data(String leafB1Data) {
+        this.leafB1Data = leafB1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafB2.java
new file mode 100644
index 0000000..6736a8a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafB2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB2;
+
+@Entity
+@DiscriminatorValue("E")
+public class PIdSTCDMSCLeafB2
+extends PIdSTCDMSCEntityB implements LeafB2 {
+private String leafB2Data;
+    
+    public String getLeafB2Data() {
+        return leafB2Data;
+    }
+    public void setLeafB2Data(String leafB2Data) {
+        this.leafB2Data = leafB2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafC.java
new file mode 100644
index 0000000..4f24735
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafC;
+
+@Entity
+@DiscriminatorValue("F")
+public class PIdSTCDMSCLeafC 
+extends PIdSTCDMSCMappedSuperclass implements LeafC {
+    private String leafCData;
+    
+    public String getLeafCData() 
+    {
+        return leafCData;
+    }
+    
+    public void setLeafCData(String leafCData) {
+        this.leafCData = leafCData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafD1.java
new file mode 100644
index 0000000..0b103b1
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafD1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD1;
+
+@Entity
+@DiscriminatorValue("H")
+public class PIdSTCDMSCLeafD1 
+extends PIdSTCDMSCEntityD implements LeafD1 {
+    private String leafD1Data;
+    
+    public String getLeafD1Data() {
+        return leafD1Data;
+    }
+    public void setLeafD1Data(String leafD1Data) {
+        this.leafD1Data = leafD1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafD2.java
new file mode 100644
index 0000000..bce03be
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCLeafD2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD2;
+
+@Entity
+@DiscriminatorValue("I")
+public class PIdSTCDMSCLeafD2 
+extends PIdSTCDMSCEntityD implements LeafD2 {
+    private String leafD2Data;
+    
+    public String getLeafD2Data() {
+        return leafD2Data;
+    }
+    public void setLeafD2Data(String leafD2Data) {
+        this.leafD2Data = leafD2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCMappedSuperclass.java
new file mode 100644
index 0000000..366b208
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCMappedSuperclass.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.MSC;
+
+@MappedSuperclass
+public class PIdSTCDMSCMappedSuperclass 
+extends PIdSTCDMSCRootEntity implements MSC {
+    private String mappedSuperclassData;
+    
+    public String getMappedSuperclassData() {
+        return mappedSuperclassData;
+    }
+    
+    public void setMappedSuperclassData(String mappedSuperclassData) {
+        this.mappedSuperclassData = mappedSuperclassData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCRootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCRootEntity.java
new file mode 100644
index 0000000..1aa152f
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/chardiscriminator/PIdSTCDMSCRootEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.chardiscriminator;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.CHAR)
+@DiscriminatorValue("A")
+public class PIdSTCDMSCRootEntity 
+    extends PrimitiveIDMappedSuperclass implements RootEntity {
+    private String rootEntityData;
+    
+    public String getRootEntityData() {
+        return rootEntityData;
+    }
+    public void setRootEntityData(String rootEntityData) {
+        this.rootEntityData = rootEntityData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCEntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCEntityB.java
new file mode 100644
index 0000000..a52f940
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCEntityB.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityB;
+
+@Entity
+@DiscriminatorValue("3")
+public class PIdSTIDMSCEntityB 
+extends PIdSTIDMSCRootEntity implements EntityB {
+    private String entityBData;
+    
+    public String getEntityBData() {
+        return entityBData;
+    }
+    public void setEntityBData(String entityBData) {
+        this.entityBData = entityBData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCEntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCEntityD.java
new file mode 100644
index 0000000..80d6fef
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCEntityD.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityD;
+@Entity
+@DiscriminatorValue("7")
+public class PIdSTIDMSCEntityD 
+extends PIdSTIDMSCMappedSuperclass implements EntityD {
+private String entityDData;
+    
+    public String getEntityDData() {
+        return entityDData;
+    }
+    public void setEntityDData(String entityDData) {
+        this.entityDData = entityDData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafA.java
new file mode 100644
index 0000000..2a5555c
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafA.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafA;
+
+@Entity
+@DiscriminatorValue("2")
+public class PIdSTIDMSCLeafA 
+extends PIdSTIDMSCRootEntity implements LeafA {
+    private String leafAData;
+    
+    public String getLeafAData() 
+    {
+        return leafAData;
+    }
+    
+    public void setLeafAData(String leafAData) {
+        this.leafAData = leafAData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafB1.java
new file mode 100644
index 0000000..f0621d1
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafB1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB1;
+
+@Entity
+@DiscriminatorValue("4")
+public class PIdSTIDMSCLeafB1 
+extends PIdSTIDMSCEntityB implements LeafB1 {
+    private String leafB1Data;
+    
+    public String getLeafB1Data() {
+        return leafB1Data;
+    }
+    public void setLeafB1Data(String leafB1Data) {
+        this.leafB1Data = leafB1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafB2.java
new file mode 100644
index 0000000..e620f40
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafB2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB2;
+
+@Entity
+@DiscriminatorValue("5")
+public class PIdSTIDMSCLeafB2
+extends PIdSTIDMSCEntityB implements LeafB2 {
+private String leafB2Data;
+    
+    public String getLeafB2Data() {
+        return leafB2Data;
+    }
+    public void setLeafB2Data(String leafB2Data) {
+        this.leafB2Data = leafB2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafC.java
new file mode 100644
index 0000000..18d1e15
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafC;
+
+@Entity
+@DiscriminatorValue("6")
+public class PIdSTIDMSCLeafC 
+extends PIdSTIDMSCMappedSuperclass implements LeafC {
+    private String leafCData;
+    
+    public String getLeafCData() 
+    {
+        return leafCData;
+    }
+    
+    public void setLeafCData(String leafCData) {
+        this.leafCData = leafCData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafD1.java
new file mode 100644
index 0000000..f7e84b4
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafD1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD1;
+
+@Entity
+@DiscriminatorValue("8")
+public class PIdSTIDMSCLeafD1 
+extends PIdSTIDMSCEntityD implements LeafD1 {
+    private String leafD1Data;
+    
+    public String getLeafD1Data() {
+        return leafD1Data;
+    }
+    public void setLeafD1Data(String leafD1Data) {
+        this.leafD1Data = leafD1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafD2.java
new file mode 100644
index 0000000..b3ba753
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCLeafD2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD2;
+
+@Entity
+@DiscriminatorValue("9")
+public class PIdSTIDMSCLeafD2 
+extends PIdSTIDMSCEntityD implements LeafD2 {
+    private String leafD2Data;
+    
+    public String getLeafD2Data() {
+        return leafD2Data;
+    }
+    public void setLeafD2Data(String leafD2Data) {
+        this.leafD2Data = leafD2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCMappedSuperclass.java
new file mode 100644
index 0000000..602bf81
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCMappedSuperclass.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.MSC;
+
+@MappedSuperclass
+public class PIdSTIDMSCMappedSuperclass 
+extends PIdSTIDMSCRootEntity implements MSC {
+    private String mappedSuperclassData;
+    
+    public String getMappedSuperclassData() {
+        return mappedSuperclassData;
+    }
+    
+    public void setMappedSuperclassData(String mappedSuperclassData) {
+        this.mappedSuperclassData = mappedSuperclassData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCRootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCRootEntity.java
new file mode 100644
index 0000000..27782a9
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/intdiscriminator/PIdSTIDMSCRootEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.intdiscriminator;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.INTEGER)
+@DiscriminatorValue("1")
+public class PIdSTIDMSCRootEntity 
+    extends PrimitiveIDMappedSuperclass implements RootEntity {
+    private String rootEntityData;
+    
+    public String getRootEntityData() {
+        return rootEntityData;
+    }
+    public void setRootEntityData(String rootEntityData) {
+        this.rootEntityData = rootEntityData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCEntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCEntityB.java
new file mode 100644
index 0000000..657ec15
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCEntityB.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityB;
+
+@Entity
+@DiscriminatorValue("StrC")
+public class PIdSTSDMSCEntityB 
+extends PIdSTSDMSCRootEntity implements EntityB {
+    private String entityBData;
+    
+    public String getEntityBData() {
+        return entityBData;
+    }
+    public void setEntityBData(String entityBData) {
+        this.entityBData = entityBData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCEntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCEntityD.java
new file mode 100644
index 0000000..1961c91
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCEntityD.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    EntityD;
+@Entity
+@DiscriminatorValue("StrG")
+public class PIdSTSDMSCEntityD 
+extends PIdSTSDMSCMappedSuperclass implements EntityD {
+private String entityDData;
+    
+    public String getEntityDData() {
+        return entityDData;
+    }
+    public void setEntityDData(String entityDData) {
+        this.entityDData = entityDData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafA.java
new file mode 100644
index 0000000..4597c43
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafA.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafA;
+
+@Entity
+@DiscriminatorValue("StrB")
+public class PIdSTSDMSCLeafA 
+extends PIdSTSDMSCRootEntity implements LeafA {
+    private String leafAData;
+    
+    public String getLeafAData() 
+    {
+        return leafAData;
+    }
+    
+    public void setLeafAData(String leafAData) {
+        this.leafAData = leafAData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafB1.java
new file mode 100644
index 0000000..103ac0e
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafB1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB1;
+
+@Entity
+@DiscriminatorValue("StrD")
+public class PIdSTSDMSCLeafB1 
+extends PIdSTSDMSCEntityB implements LeafB1 {
+    private String leafB1Data;
+    
+    public String getLeafB1Data() {
+        return leafB1Data;
+    }
+    public void setLeafB1Data(String leafB1Data) {
+        this.leafB1Data = leafB1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafB2.java
new file mode 100644
index 0000000..e12e77e
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafB2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafB2;
+
+@Entity
+@DiscriminatorValue("StrE")
+public class PIdSTSDMSCLeafB2
+extends PIdSTSDMSCEntityB implements LeafB2 {
+private String leafB2Data;
+    
+    public String getLeafB2Data() {
+        return leafB2Data;
+    }
+    public void setLeafB2Data(String leafB2Data) {
+        this.leafB2Data = leafB2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafC.java
new file mode 100644
index 0000000..9f7e52a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.LeafC;
+
+@Entity
+@DiscriminatorValue("StrF")
+public class PIdSTSDMSCLeafC 
+extends PIdSTSDMSCMappedSuperclass implements LeafC {
+    private String leafCData;
+    
+    public String getLeafCData() 
+    {
+        return leafCData;
+    }
+    
+    public void setLeafCData(String leafCData) {
+        this.leafCData = leafCData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafD1.java
new file mode 100644
index 0000000..5b220e3
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafD1.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD1;
+
+@Entity
+@DiscriminatorValue("StrH")
+public class PIdSTSDMSCLeafD1 
+extends PIdSTSDMSCEntityD implements LeafD1 {
+    private String leafD1Data;
+    
+    public String getLeafD1Data() {
+        return leafD1Data;
+    }
+    public void setLeafD1Data(String leafD1Data) {
+        this.leafD1Data = leafD1Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafD2.java
new file mode 100644
index 0000000..8c8275f
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCLeafD2.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    LeafD2;
+
+@Entity
+@DiscriminatorValue("StrI")
+public class PIdSTSDMSCLeafD2 
+extends PIdSTSDMSCEntityD implements LeafD2 {
+    private String leafD2Data;
+    
+    public String getLeafD2Data() {
+        return leafD2Data;
+    }
+    public void setLeafD2Data(String leafD2Data) {
+        this.leafD2Data = leafD2Data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCMappedSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCMappedSuperclass.java
new file mode 100644
index 0000000..88d3f36
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCMappedSuperclass.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.MappedSuperclass;
+
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.MSC;
+
+@MappedSuperclass
+public class PIdSTSDMSCMappedSuperclass 
+extends PIdSTSDMSCRootEntity implements MSC {
+    private String mappedSuperclassData;
+    
+    public String getMappedSuperclassData() {
+        return mappedSuperclassData;
+    }
+    
+    public void setMappedSuperclassData(String mappedSuperclassData) {
+        this.mappedSuperclassData = mappedSuperclassData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCRootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCRootEntity.java
new file mode 100644
index 0000000..0b766c0
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/idmsc/singletable/stringdiscriminator/PIdSTSDMSCRootEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entities.idmsc.singletable.stringdiscriminator;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.persistence.inheritance.entities.idmsc.
+    PrimitiveIDMappedSuperclass;
+import org.apache.openjpa.persistence.inheritance.entities.testinterfaces.
+    RootEntity;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING)
+@DiscriminatorValue("StrA")
+public class PIdSTSDMSCRootEntity 
+    extends PrimitiveIDMappedSuperclass implements RootEntity {
+    private String rootEntityData;
+    
+    public String getRootEntityData() {
+        return rootEntityData;
+    }
+    public void setRootEntityData(String rootEntityData) {
+        this.rootEntityData = rootEntityData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/EntityB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/EntityB.java
new file mode 100644
index 0000000..5dcb57e
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/EntityB.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface EntityB extends RootEntity {
+    public String getEntityBData();
+    public void setEntityBData(String entityBData);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/EntityD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/EntityD.java
new file mode 100644
index 0000000..f3a5e4e
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/EntityD.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface EntityD {
+    public String getEntityDData();
+    public void setEntityDData(String entityDData);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafA.java
new file mode 100644
index 0000000..4f8e326
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafA.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface LeafA extends RootEntity {
+    public String getLeafAData();
+    public void setLeafAData(String leafAData);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafB1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafB1.java
new file mode 100644
index 0000000..4d41bbe
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafB1.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface LeafB1 extends EntityB {
+    public String getLeafB1Data(); 
+    
+    public void setLeafB1Data(String leafB1Data);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafB2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafB2.java
new file mode 100644
index 0000000..8e16582
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafB2.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface LeafB2 {
+    public String getLeafB2Data(); 
+    
+    public void setLeafB2Data(String leafB2Data);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafC.java
new file mode 100644
index 0000000..8cf6124
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafC.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface LeafC {
+    public String getLeafCData();
+    public void setLeafCData(String leafCData);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafD1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafD1.java
new file mode 100644
index 0000000..8072af4
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafD1.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface LeafD1 {
+    public String getLeafD1Data();
+    public void setLeafD1Data(String leafD1Data);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafD2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafD2.java
new file mode 100644
index 0000000..3218e05
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/LeafD2.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface LeafD2 {
+    public String getLeafD2Data();
+    public void setLeafD2Data(String leafD2Data);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/MSC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/MSC.java
new file mode 100644
index 0000000..a49c07c
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/MSC.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface MSC {
+    public String getMappedSuperclassData();
+    public void setMappedSuperclassData(String mappedSuperclassData);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/RootEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/RootEntity.java
new file mode 100644
index 0000000..22801d7
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entities/testinterfaces/RootEntity.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.inheritance.entities.testinterfaces;
+
+public interface RootEntity {
+    public Object fetchId();    
+    public void updateId(Object obj);
+    
+    public String getRootEntityData();
+    public void setRootEntityData(String rootEntityData);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName1.java
index ddf26e8..ff6857b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName1.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.entity;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-/**
- * This class has the same name as {@link
- * org.apache.openjpa.persistence.inheritance.mappedsuperclass.SharedName1}
- */
-@Entity
-public class SharedName1 {
-
-    @Id
-    private long id;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * This class has the same name as {@link
+ * org.apache.openjpa.persistence.inheritance.mappedsuperclass.SharedName1}
+ */
+@Entity
+public class SharedName1 {
+
+    @Id
+    private long id;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName2.java
index ed9f500..58947ed 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/entity/SharedName2.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.entity;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-/**
- * This class has the same name as {@link
- * org.apache.openjpa.persistence.inheritance.embeddable.SharedName2}
- */
-@Entity
-public class SharedName2 {
-
-    @Id
-    private long id;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * This class has the same name as {@link
+ * org.apache.openjpa.persistence.inheritance.embeddable.SharedName2}
+ */
+@Entity
+public class SharedName2 {
+
+    @Id
+    private long id;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/BaseEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/BaseEntity.java
new file mode 100644
index 0000000..63499c4
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/BaseEntity.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
+
+
+/**
+ * Entity used to test MappedSuperClass which does not have IdClass. 
+ * 
+ * Test case and domain classes were originally part of the reported issue
+ * <A href="https://issues.apache.org/jira/browse/OPENJPA-873">OPENJPA-873</A>
+ *  
+ * @author pioneer_ip@yahoo.com
+ * @author Fay Wang
+ *
+ */
+public class BaseEntity {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/CashBaseEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/CashBaseEntity.java
new file mode 100644
index 0000000..97663e7
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/CashBaseEntity.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
+
+import java.util.Date;
+
+import javax.persistence.*;
+
+/**
+ * Entity used to test MappedSuperClass which does not have IdClass. 
+ * 
+ * Test case and domain classes were originally part of the reported issue
+ * <A href="https://issues.apache.org/jira/browse/OPENJPA-873">OPENJPA-873</A>
+ *  
+ * @author pioneer_ip@yahoo.com
+ * @author Fay Wang
+ *
+ */
+
+@MappedSuperclass
+public abstract class CashBaseEntity extends BaseEntity{
+    @Column(name="TRCCRUI")
+    private String createUser;
+
+    @Column(name="TRCCRTS")
+    private Date createTime;
+
+    @Column(name="TRCLUUID")
+    private String updateUser;
+
+    @Column(name="TRCLUTS")
+    private Date updateTime;
+
+    @Version
+    @Column(name="TRCVER")
+    private int version;
+
+    public String getCreateUser() {
+        return createUser;
+    }
+    
+    public void setCreateUser(String createUser) {
+        this.createUser = createUser;
+    }
+    
+    public Date getCreateTime() {
+        return createTime;
+    }
+    
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+    
+    public String getUpdateUser() {
+        return updateUser;
+    }
+    
+    public void setUpdateUser(String updateUser) {
+        this.updateUser = updateUser;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+    
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+    
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SharedName1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SharedName1.java
index 07a4c09..ae0534c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SharedName1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SharedName1.java
@@ -1,30 +1,30 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
-
-import javax.persistence.MappedSuperclass;
-
-/**
- * This class has the same name as {@link
- * org.apache.openjpa.persistence.inheritance.entity.SharedName1}
- */
-@MappedSuperclass
-public class SharedName1 {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
+
+import javax.persistence.MappedSuperclass;
+
+/**
+ * This class has the same name as {@link
+ * org.apache.openjpa.persistence.inheritance.entity.SharedName1}
+ */
+@MappedSuperclass
+public class SharedName1 {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SituationDA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SituationDA.java
new file mode 100644
index 0000000..2988f9a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/SituationDA.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
+
+import javax.persistence.*;
+
+/**
+ * Entity used to test MappedSuperClass which does not have IdClass. 
+ * 
+ * Test case and domain classes were originally part of the reported issue
+ * <A href="https://issues.apache.org/jira/browse/OPENJPA-873">OPENJPA-873</A>
+ *  
+ * @author pioneer_ip@yahoo.com
+ * @author Fay Wang
+ *
+ */
+
+@Entity
+@Table (name = "cc2SITUATION")
+@IdClass(SituationDA.SituationId.class)
+public class SituationDA extends CashBaseEntity {
+   
+    @Id
+    @Column(name="C2008SRL")
+    private String cashBoxPeriodSerial;
+   
+    @Id
+    @Column(name="C2012TYPE")
+    private short type;
+    
+    public static class SituationId implements java.io.Serializable{
+        private static final long serialVersionUID = 1L;
+        private String cashBoxPeriodSerial;
+        private short type;
+       
+        public SituationId(){}
+        
+        public SituationId(String cashBoxPeriodSerial, short type){
+            this.cashBoxPeriodSerial = cashBoxPeriodSerial;
+            this.type = type;
+        }
+        
+        
+        public boolean equals(Object other){
+            if (other instanceof SituationId) {
+                final SituationId otherId = (SituationId)other;
+                return ( otherId.cashBoxPeriodSerial.equals(
+                    this.cashBoxPeriodSerial) && otherId.type == this.type );
+                }
+                return false;   
+        }
+       
+        public int hashCode() {
+            return super.hashCode();
+        }
+    }
+    
+    public short getType() {
+        return type;
+    }
+    
+    public void setType(short type) {
+        this.type = type;
+    }
+    
+    public String getCashBoxPeriodSerial() {
+        return cashBoxPeriodSerial;
+    }
+    
+    public void setCashBoxPeriodSerial(String cashBoxPeriodSerial) {
+        this.cashBoxPeriodSerial = cashBoxPeriodSerial;
+    }
+    
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/TestMappedSuperClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/TestMappedSuperClass.java
new file mode 100644
index 0000000..c0c2fe9
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/TestMappedSuperClass.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test case and domain classes were originally part of the reported issue
+ * <A href="https://issues.apache.org/jira/browse/OPENJPA-873">OPENJPA-873</A>
+ *  
+ * @author pioneer_ip@yahoo.com
+ * @author Fay Wang
+ *
+ */
+public class TestMappedSuperClass extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(CashBaseEntity.class, 
+              SituationDA.class, ValuableItemDA.class);
+    }
+
+    public void testMappedSuperClass() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        SituationDA s = new SituationDA();
+        s.setCashBoxPeriodSerial("test");
+        s.setType((short)1);
+        em.persist(s);
+        em.getTransaction().commit();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/ValuableItemDA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/ValuableItemDA.java
new file mode 100644
index 0000000..7e0eac1
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/mappedsuperclass/ValuableItemDA.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.mappedsuperclass;
+
+import javax.persistence.*;
+
+/**
+ * Entity used to test MappedSuperClass which does not have IdClass. 
+ * 
+ * Test case and domain classes were originally part of the reported issue
+ * <A href="https://issues.apache.org/jira/browse/OPENJPA-873">OPENJPA-873</A>
+ *  
+ * @author pioneer_ip@yahoo.com
+ * @author Fay Wang
+ *
+ */
+@Entity
+@Table (name = "CF2VLUITEM")
+public class ValuableItemDA extends CashBaseEntity {
+    @Id
+    @Column(name="C2001COD")
+    private short code;
+
+    public void setCode(short code) {
+        this.code = code;
+    }
+    
+    public short getCode() {
+        return code;
+    }
+}
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/BaseEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/BaseEntity.java
index a5f5622..02c4d2f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/BaseEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/BaseEntity.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.Version;
-
-/**
- * An abstract base entity class with auto-generated identty and version field.
- * Used for testing special case of table-per-class inheritance strategy when 
- * the root of persistent inheritance hierarchy is abstract and itself 
- * derives from an abstract MappedSuperClass (i.e. this class).
- * 
- * For a more detailed description of the domain model to which this receiver
- * belongs
- * @see TestTablePerClassInheritanceWithAbstractRoot
- * 
- * @author Pinaki Poddar
- * 
- */
-@MappedSuperclass
-public abstract class BaseEntity {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	@Version
-	private long version;
-
-	public long getId() {
-		return id;
-	}
-
-	public long getVersion() {
-		return version;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Version;
+
+/**
+ * An abstract base entity class with auto-generated identty and version field.
+ * Used for testing special case of table-per-class inheritance strategy when 
+ * the root of persistent inheritance hierarchy is abstract and itself 
+ * derives from an abstract MappedSuperClass (i.e. this class).
+ * 
+ * For a more detailed description of the domain model to which this receiver
+ * belongs
+ * @see TestTablePerClassInheritanceWithAbstractRoot
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+@MappedSuperclass
+public abstract class BaseEntity {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	@Version
+	private long version;
+
+	public long getId() {
+		return id;
+	}
+
+	public long getVersion() {
+		return version;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/EnglishParagraph.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/EnglishParagraph.java
index 1572ffb..3738955 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/EnglishParagraph.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/EnglishParagraph.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import javax.persistence.Entity;
-
-/**
- * A persistent class derived from an abstract persistent class and 
- * using table-per-concrete-class inheritance strategy.
- * 
- * For a more detailed description of the domain model to which this receiver
- * belongs
- * @see TestTablePerClassInheritanceWithAbstractRoot
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class EnglishParagraph extends Translatable {
-	private String content;
-
-	public String getContent() {
-		return content;
-	}
-
-	public void setContent(String content) {
-		this.content = content;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import javax.persistence.Entity;
+
+/**
+ * A persistent class derived from an abstract persistent class and 
+ * using table-per-concrete-class inheritance strategy.
+ * 
+ * For a more detailed description of the domain model to which this receiver
+ * belongs
+ * @see TestTablePerClassInheritanceWithAbstractRoot
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class EnglishParagraph extends Translatable {
+	private String content;
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/FrenchParagraph.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/FrenchParagraph.java
index 16aba3f..5accc7c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/FrenchParagraph.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/FrenchParagraph.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import javax.persistence.Entity;
-
-/**
- * A persistent class derived from an abstract persistent class and 
- * using table-per-concrete-class inheritance strategy.
- * 
- * For a more detailed description of the domain model to which this receiver
- * belongs
- * @see TestTablePerClassInheritanceWithAbstractRoot
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class FrenchParagraph extends Translatable {
-	private String content;
-
-	public String getContent() {
-		return content;
-	}
-
-	public void setContent(String content) {
-		this.content = content;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import javax.persistence.Entity;
+
+/**
+ * A persistent class derived from an abstract persistent class and 
+ * using table-per-concrete-class inheritance strategy.
+ * 
+ * For a more detailed description of the domain model to which this receiver
+ * belongs
+ * @see TestTablePerClassInheritanceWithAbstractRoot
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class FrenchParagraph extends Translatable {
+	private String content;
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/GermanParagraph.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/GermanParagraph.java
index 8852f56..afb7072 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/GermanParagraph.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/GermanParagraph.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import javax.persistence.Entity;
-
-/**
- * A persistent class derived from an abstract persistent class and 
- * using table-per-concrete-class inheritance strategy.
- * 
- * For a more detailed description of the domain model to which this receiver
- * belongs
- * @see TestTablePerClassInheritanceWithAbstractRoot
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class GermanParagraph extends Translatable {
-	private String content;
-
-	public String getContent() {
-		return content;
-	}
-
-	public void setContent(String content) {
-		this.content = content;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import javax.persistence.Entity;
+
+/**
+ * A persistent class derived from an abstract persistent class and 
+ * using table-per-concrete-class inheritance strategy.
+ * 
+ * For a more detailed description of the domain model to which this receiver
+ * belongs
+ * @see TestTablePerClassInheritanceWithAbstractRoot
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class GermanParagraph extends Translatable {
+	private String content;
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/TestTablePerClassInheritanceWithAbstractRoot.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/TestTablePerClassInheritanceWithAbstractRoot.java
index f9e25c4..fb27b03 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/TestTablePerClassInheritanceWithAbstractRoot.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/TestTablePerClassInheritanceWithAbstractRoot.java
@@ -1,155 +1,155 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import java.util.List;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests a domain model with following characteristics:
- * a) A typical bidirectional ManyToOne/OneToMany relation 
- *    EntityA references a single instance of EntityB
- *    EntityB references a collection of EntityA
- * b) EntityB itself is abstract 
- * c) Many concrete subclasses of EntityB exist
- * d) EntityB uses TABLE_PER_CLASS inheritance strategy, hence no mapping table 
- *    exists for EntityB itself.
- * e) Relation field in EntityA is declared as abstract type EntityB (for which
- * f) all the domain classes i.e. EntityA, EntityB and all its subclasses is
- *    derived from an abstract MappedSuperClass which holds primary key and
- *    version fields.
- *    
- *  The test addresses a reported error [1] in mapping the above domain model.
- *  The test verifies basic persist, query and delete operations on the domain
- *  model.
- *  
- *  [1] <A HREF="https://issues.apache.org/jira/browse/OPENJPA-602"> OPENJPA-602</A>}
- *        
- * @author Pinaki Poddar
- *
- */
-public class TestTablePerClassInheritanceWithAbstractRoot extends
-		SingleEMFTestCase {
-	Class[] UNJOINED_SUBCLASSES = {
-			EnglishParagraph.class, 
-			FrenchParagraph.class, 
-			GermanParagraph.class};
-	
-    public void setUp() {
-        setUp(CLEAR_TABLES, 
-        		"openjpa.Log", "SQL=TRACE", 
-        		Translation.class, BaseEntity.class,
-        		EnglishParagraph.class, FrenchParagraph.class, 
-        		GermanParagraph.class, Translatable.class);
-    }
-    
-	public void testConsistency() {
-		OpenJPAEntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		/**
-		 * Aggregate query operations can not be performed on unjoined 
-		 * subclasses. Hence all concrete subclasses of abstract base
-		 * class is counted separately to count all Translatable instances.
-		 */
-		int nTranslatableBefore = count(UNJOINED_SUBCLASSES);
-		int nTranslationBefore = count(Translation.class);
-		
-		EnglishParagraph english = new EnglishParagraph();
-		FrenchParagraph french   = new FrenchParagraph();
-		GermanParagraph german   = new GermanParagraph();
-		
-		Translation translation1 = new Translation(); 
-		Translation translation2 = new Translation(); 
-		Translation translation3 = new Translation(); 
-		Translation translation4 = new Translation(); 
-		
-		english.setContent("Hello");
-		french.setContent("Bon jour");
-		german.setContent("Guten Tag");
-
-		
-		translation1.setTranslatable(english);
-		translation2.setTranslatable(english);
-		translation3.setTranslatable(french);
-		translation4.setTranslatable(german);
-		
-		english.addTranslation(translation1);
-		english.addTranslation(translation2);
-		french.addTranslation(translation3);
-		german.addTranslation(translation4);
-		
-		em.persist(translation1);
-		em.persist(translation2);
-		em.persist(translation3);
-		em.persist(translation4);
-		em.getTransaction().commit();
-		
-		em.clear();
-
-		int nTranslatableAfter = count(UNJOINED_SUBCLASSES);
-		int nTranslationAfter  = count(Translation.class);
-		
-		assertEquals(nTranslatableBefore+3, nTranslatableAfter);
-		assertEquals(nTranslationBefore+4, nTranslationAfter);
-		
-		/**
-		 * Verify that if A refers to B then A must be a member of the set 
-		 * referred by B
-		 */
-		em.getTransaction().begin();
-		List<Translation> result = em.createQuery("SELECT p FROM Translation p")
-			.getResultList();
-		assertTrue(!result.isEmpty());
-		for (Translation translation : result) {
-			assertTrue(translation.getTranslatable()
-					.getTranslations().contains(translation));
-		}
-		em.getTransaction().rollback();
-	}
-	
-	
-	void linkConsistently(Translation translation, Translatable translatable) {
-		translatable.addTranslation(translation);
-		translation.setTranslatable(translatable);
-	}
-	
-	/**
-	 * Count the number of instances in the given class by aggregate JPQL query.
-	 */
-	public int count(Class c) {
-		OpenJPAEntityManager em = emf.createEntityManager();
-		return ((Number) em.createQuery("SELECT COUNT(p) FROM " + 
-				c.getSimpleName() + " p").getSingleResult()).intValue();
-	}
-	
-	/**
-	 * Count total number of instances of all the given classes by separate JPQL
-	 * aggregate query. Useful when a base class has unjoined subclasses.
-	 */
-	public int count(Class... classes) {
-		int total = 0;
-		for (Class c:classes) {
-			total += count(c);
-		}
-		return total;
-	}
-	
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import java.util.List;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests a domain model with following characteristics:
+ * a) A typical bidirectional ManyToOne/OneToMany relation 
+ *    EntityA references a single instance of EntityB
+ *    EntityB references a collection of EntityA
+ * b) EntityB itself is abstract 
+ * c) Many concrete subclasses of EntityB exist
+ * d) EntityB uses TABLE_PER_CLASS inheritance strategy, hence no mapping table 
+ *    exists for EntityB itself.
+ * e) Relation field in EntityA is declared as abstract type EntityB (for which
+ * f) all the domain classes i.e. EntityA, EntityB and all its subclasses is
+ *    derived from an abstract MappedSuperClass which holds primary key and
+ *    version fields.
+ *    
+ *  The test addresses a reported error [1] in mapping the above domain model.
+ *  The test verifies basic persist, query and delete operations on the domain
+ *  model.
+ *  
+ *  [1] <A HREF="https://issues.apache.org/jira/browse/OPENJPA-602"> OPENJPA-602</A>}
+ *        
+ * @author Pinaki Poddar
+ *
+ */
+public class TestTablePerClassInheritanceWithAbstractRoot extends
+		SingleEMFTestCase {
+	Class[] UNJOINED_SUBCLASSES = {
+			EnglishParagraph.class, 
+			FrenchParagraph.class, 
+			GermanParagraph.class};
+	
+    public void setUp() {
+        setUp(CLEAR_TABLES, 
+        		"openjpa.Log", "SQL=TRACE", 
+        		Translation.class, BaseEntity.class,
+        		EnglishParagraph.class, FrenchParagraph.class, 
+        		GermanParagraph.class, Translatable.class);
+    }
+    
+	public void testConsistency() {
+		OpenJPAEntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		/**
+		 * Aggregate query operations can not be performed on unjoined 
+		 * subclasses. Hence all concrete subclasses of abstract base
+		 * class is counted separately to count all Translatable instances.
+		 */
+		int nTranslatableBefore = count(UNJOINED_SUBCLASSES);
+		int nTranslationBefore = count(Translation.class);
+		
+		EnglishParagraph english = new EnglishParagraph();
+		FrenchParagraph french   = new FrenchParagraph();
+		GermanParagraph german   = new GermanParagraph();
+		
+		Translation translation1 = new Translation(); 
+		Translation translation2 = new Translation(); 
+		Translation translation3 = new Translation(); 
+		Translation translation4 = new Translation(); 
+		
+		english.setContent("Hello");
+		french.setContent("Bon jour");
+		german.setContent("Guten Tag");
+
+		
+		translation1.setTranslatable(english);
+		translation2.setTranslatable(english);
+		translation3.setTranslatable(french);
+		translation4.setTranslatable(german);
+		
+		english.addTranslation(translation1);
+		english.addTranslation(translation2);
+		french.addTranslation(translation3);
+		german.addTranslation(translation4);
+		
+		em.persist(translation1);
+		em.persist(translation2);
+		em.persist(translation3);
+		em.persist(translation4);
+		em.getTransaction().commit();
+		
+		em.clear();
+
+		int nTranslatableAfter = count(UNJOINED_SUBCLASSES);
+		int nTranslationAfter  = count(Translation.class);
+		
+		assertEquals(nTranslatableBefore+3, nTranslatableAfter);
+		assertEquals(nTranslationBefore+4, nTranslationAfter);
+		
+		/**
+		 * Verify that if A refers to B then A must be a member of the set 
+		 * referred by B
+		 */
+		em.getTransaction().begin();
+		List<Translation> result = em.createQuery("SELECT p FROM Translation p")
+			.getResultList();
+		assertTrue(!result.isEmpty());
+		for (Translation translation : result) {
+			assertTrue(translation.getTranslatable()
+					.getTranslations().contains(translation));
+		}
+		em.getTransaction().rollback();
+	}
+	
+	
+	void linkConsistently(Translation translation, Translatable translatable) {
+		translatable.addTranslation(translation);
+		translation.setTranslatable(translatable);
+	}
+	
+	/**
+	 * Count the number of instances in the given class by aggregate JPQL query.
+	 */
+	public int count(Class c) {
+		OpenJPAEntityManager em = emf.createEntityManager();
+		return ((Number) em.createQuery("SELECT COUNT(p) FROM " + 
+				c.getSimpleName() + " p").getSingleResult()).intValue();
+	}
+	
+	/**
+	 * Count total number of instances of all the given classes by separate JPQL
+	 * aggregate query. Useful when a base class has unjoined subclasses.
+	 */
+	public int count(Class... classes) {
+		int total = 0;
+		for (Class c:classes) {
+			total += count(c);
+		}
+		return total;
+	}
+	
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translatable.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translatable.java
index f995bfa..95fe843 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translatable.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translatable.java
@@ -1,57 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToMany;
-
-/**
- * An abstract persistent class used as root of inheritance hierarchy and 
- * using table-per-concrete-class inheritance strategy.
- * 
- * For a more detailed description of the domain model to which this receiver
- * belongs
- * @see TestTablePerClassInheritanceWithAbstractRoot
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
-public abstract class Translatable extends BaseEntity {
-	@OneToMany(mappedBy="translatable", cascade=CascadeType.PERSIST)
-	private Set<Translation> translations;
-	
-	public void addTranslation(Translation t) {
-		if (translations == null)
-			translations = new HashSet<Translation>();
-		translations.add(t);
-	}
-	
-	public Set<Translation> getTranslations() {
-		return Collections.unmodifiableSet(translations);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+
+/**
+ * An abstract persistent class used as root of inheritance hierarchy and 
+ * using table-per-concrete-class inheritance strategy.
+ * 
+ * For a more detailed description of the domain model to which this receiver
+ * belongs
+ * @see TestTablePerClassInheritanceWithAbstractRoot
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
+public abstract class Translatable extends BaseEntity {
+	@OneToMany(mappedBy="translatable", cascade=CascadeType.PERSIST)
+	private Set<Translation> translations;
+	
+	public void addTranslation(Translation t) {
+		if (translations == null)
+			translations = new HashSet<Translation>();
+		translations.add(t);
+	}
+	
+	public Set<Translation> getTranslations() {
+		return Collections.unmodifiableSet(translations);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translation.java
index 1b93a03..4ba8cac 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/polymorphic/Translation.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.inheritance.polymorphic;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name="TRANSLATIONS")
-/**
- * An persistent class that refers to a polymorphic uni-cardinality relation. 
- * The polymorphic relation itself derives from an abstract class that uses
- * table-per-class inheritance strategy.
- *   
- * For a more detailed description of the domain model to which this receiver
- * belongs
- * @see TestTablePerClassInheritanceWithAbstractRoot
- * 
- * @author Pinaki Poddar
- *
- */
-public class Translation extends BaseEntity {
-	@ManyToOne(cascade=CascadeType.PERSIST)
-	private Translatable translatable;
-
-	public Translatable getTranslatable() {
-		return translatable;
-	}
-
-	public void setTranslatable(Translatable translatable) {
-		this.translatable = translatable;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.inheritance.polymorphic;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="TRANSLATIONS")
+/**
+ * An persistent class that refers to a polymorphic uni-cardinality relation. 
+ * The polymorphic relation itself derives from an abstract class that uses
+ * table-per-class inheritance strategy.
+ *   
+ * For a more detailed description of the domain model to which this receiver
+ * belongs
+ * @see TestTablePerClassInheritanceWithAbstractRoot
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class Translation extends BaseEntity {
+	@ManyToOne(cascade=CascadeType.PERSIST)
+	private Translatable translatable;
+
+	public Translatable getTranslatable() {
+		return translatable;
+	}
+
+	public void setTranslatable(Translatable translatable) {
+		this.translatable = translatable;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/serializable/Person.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/serializable/Person.java
index 72143db..ad53841 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/serializable/Person.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/serializable/Person.java
@@ -23,6 +23,7 @@
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
+import javax.persistence.Version;
 
 @Entity
 public class Person implements Serializable {
@@ -35,6 +36,8 @@
     
     private String lastName;
 
+    private int version;
+    
     @Id
     @GeneratedValue
     public int getId() {
@@ -60,6 +63,14 @@
     public void setLastName(String lastName) {
         this.lastName = lastName;
     }
+    
+    @Version
+    public int getVersion(){
+        return version;
+    }
+    public void setVersion(int v){
+        version = v;
+    }
 
     @Override
     public int hashCode() {
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/SQLSniffer.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/SQLSniffer.java
index b9aba60..1869a0e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/SQLSniffer.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/SQLSniffer.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.regexp.RE;
-
-/**
- * Utility class to verify whether a set of fragments appear in a list of
- * possible SQL statement.
- * 
- * @author Pinaki Poddar
- *
- */
-public class SQLSniffer {
-	
-	private static Map<String, RE> cache = new HashMap<String, RE>();
-	/**
-	 * Checks that the given set of regular expressions occur in at least one of
-	 * the given input SQL.
-	 */
-	public static boolean matches(List<String> SQLs, String...regexes) {
-		if (SQLs == null || regexes == null)
-			return false;
-		for (String sql : SQLs) {
-			boolean matched = true;
-			for (String key : regexes) {
-				RE regex = getRegularExpression(key);
-				if (!regex.match(sql)) {
-					matched = false;
-					break;
-				}
-			}
-			if (matched)
-				return true;
-		}
-		return false;
-	}
-	
-	private static RE getRegularExpression(String regex) {
-		if (cache.containsKey(regex)) 
-			return cache.get(regex);
-		RE re = new RE(regex);
-		cache.put(regex, re);
-		return re;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.regexp.RE;
+
+/**
+ * Utility class to verify whether a set of fragments appear in a list of
+ * possible SQL statement.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class SQLSniffer {
+	
+	private static Map<String, RE> cache = new HashMap<String, RE>();
+	/**
+	 * Checks that the given set of regular expressions occur in at least one of
+	 * the given input SQL.
+	 */
+	public static boolean matches(List<String> SQLs, String...regexes) {
+		if (SQLs == null || regexes == null)
+			return false;
+		for (String sql : SQLs) {
+			boolean matched = true;
+			for (String key : regexes) {
+				RE regex = getRegularExpression(key);
+				if (!regex.match(sql)) {
+					matched = false;
+					break;
+				}
+			}
+			if (matched)
+				return true;
+		}
+		return false;
+	}
+	
+	private static RE getRegularExpression(String regex) {
+		if (cache.containsKey(regex)) 
+			return cache.get(regex);
+		RE re = new RE(regex);
+		cache.put(regex, re);
+		return re;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestJDBCEnumToKernelConstantMappings.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestJDBCEnumToKernelConstantMappings.java
index 988c791..34b3f97 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestJDBCEnumToKernelConstantMappings.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestJDBCEnumToKernelConstantMappings.java
@@ -1,166 +1,166 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import java.sql.ResultSet;
-
-import junit.framework.TestCase;
-import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
-import org.apache.openjpa.jdbc.kernel.LRSSizes;
-import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
-
-public class TestJDBCEnumToKernelConstantMappings
-    extends TestCase {
-
-    public void testEagerFetchModes() {
-        assertEquals(EagerFetchModes.EAGER_NONE,
-            FetchMode.NONE.toKernelConstant());
-        assertEquals(FetchMode.NONE,
-            FetchMode.fromKernelConstant(
-                EagerFetchModes.EAGER_NONE));
-        assertEquals(FetchMode.NONE.toKernelConstant(),
-            FetchMode.NONE.ordinal());
-
-        assertEquals(EagerFetchModes.EAGER_JOIN,
-            FetchMode.JOIN.toKernelConstant());
-        assertEquals(FetchMode.JOIN,
-            FetchMode.fromKernelConstant(
-                EagerFetchModes.EAGER_JOIN));
-        assertEquals(FetchMode.JOIN.toKernelConstant(),
-            FetchMode.JOIN.ordinal());
-
-        assertEquals(EagerFetchModes.EAGER_PARALLEL,
-            FetchMode.PARALLEL.toKernelConstant());
-        assertEquals(FetchMode.PARALLEL,
-            FetchMode.fromKernelConstant(
-                EagerFetchModes.EAGER_PARALLEL));
-        assertEquals(FetchMode.PARALLEL.toKernelConstant(),
-            FetchMode.PARALLEL.ordinal());
-
-        assertEquals(getConstantCount(EagerFetchModes.class),
-            FetchMode.values().length);
-    }
-
-    public void testLRSSizeType() {
-        assertEquals(LRSSizes.SIZE_UNKNOWN,
-            LRSSizeAlgorithm.UNKNOWN.toKernelConstant());
-        assertEquals(LRSSizeAlgorithm.UNKNOWN,
-            LRSSizeAlgorithm.fromKernelConstant(
-                LRSSizes.SIZE_UNKNOWN));
-        assertEquals(LRSSizeAlgorithm.UNKNOWN.toKernelConstant(),
-            LRSSizeAlgorithm.UNKNOWN.ordinal());
-
-        assertEquals(LRSSizes.SIZE_LAST,
-            LRSSizeAlgorithm.LAST.toKernelConstant());
-        assertEquals(LRSSizeAlgorithm.LAST,
-            LRSSizeAlgorithm.fromKernelConstant(
-                LRSSizes.SIZE_LAST));
-        assertEquals(LRSSizeAlgorithm.LAST.toKernelConstant(),
-            LRSSizeAlgorithm.LAST.ordinal());
-
-        assertEquals(LRSSizes.SIZE_QUERY,
-            LRSSizeAlgorithm.QUERY.toKernelConstant());
-        assertEquals(LRSSizeAlgorithm.QUERY,
-            LRSSizeAlgorithm.fromKernelConstant(
-                LRSSizes.SIZE_QUERY));
-        assertEquals(LRSSizeAlgorithm.QUERY.toKernelConstant(),
-            LRSSizeAlgorithm.QUERY.ordinal());
-
-        assertEquals(getConstantCount(LRSSizes.class),
-            LRSSizeAlgorithm.values().length);
-    }
-
-    public void testJoinSyntaxType() {
-        assertEquals(JoinSyntaxes.SYNTAX_SQL92,
-            JoinSyntax.SQL92.toKernelConstant());
-        assertEquals(JoinSyntax.SQL92,
-            JoinSyntax.fromKernelConstant(
-                JoinSyntaxes.SYNTAX_SQL92));
-        assertEquals(JoinSyntax.SQL92.toKernelConstant(),
-            JoinSyntax.SQL92.ordinal());
-
-        assertEquals(JoinSyntaxes.SYNTAX_TRADITIONAL,
-            JoinSyntax.TRADITIONAL.toKernelConstant());
-        assertEquals(JoinSyntax.TRADITIONAL,
-            JoinSyntax.fromKernelConstant(
-                JoinSyntaxes.SYNTAX_TRADITIONAL));
-        assertEquals(JoinSyntax.TRADITIONAL.toKernelConstant(),
-            JoinSyntax.TRADITIONAL.ordinal());
-
-        assertEquals(JoinSyntaxes.SYNTAX_DATABASE,
-            JoinSyntax.DATABASE.toKernelConstant());
-        assertEquals(JoinSyntax.DATABASE,
-            JoinSyntax.fromKernelConstant(
-                JoinSyntaxes.SYNTAX_DATABASE));
-        assertEquals(JoinSyntax.DATABASE.toKernelConstant(),
-            JoinSyntax.DATABASE.ordinal());
-
-        assertEquals(getConstantCount(JoinSyntaxes.class),
-            JoinSyntax.values().length);
-    }
-
-    public void testResultSetType() {
-        assertEquals(ResultSet.TYPE_FORWARD_ONLY,
-            ResultSetType.FORWARD_ONLY.toKernelConstant());
-        assertEquals(ResultSetType.FORWARD_ONLY,
-            ResultSetType.fromKernelConstant(
-                ResultSet.TYPE_FORWARD_ONLY));
-
-        assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE,
-            ResultSetType.SCROLL_INSENSITIVE.toKernelConstant());
-        assertEquals(ResultSetType.SCROLL_INSENSITIVE,
-            ResultSetType.fromKernelConstant(
-                ResultSet.TYPE_SCROLL_INSENSITIVE));
-
-        assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE,
-            ResultSetType.SCROLL_SENSITIVE.toKernelConstant());
-        assertEquals(ResultSetType.SCROLL_SENSITIVE,
-            ResultSetType.fromKernelConstant(
-                ResultSet.TYPE_SCROLL_SENSITIVE));
-
-        assertEquals(3, ResultSetType.values().length);
-    }
-
-    public void testFetchDirection() {
-        assertEquals(ResultSet.FETCH_FORWARD,
-            FetchDirection.FORWARD.toKernelConstant());
-        assertEquals(FetchDirection.FORWARD,
-            FetchDirection.fromKernelConstant(
-                ResultSet.FETCH_FORWARD));
-
-        assertEquals(ResultSet.FETCH_REVERSE,
-            FetchDirection.REVERSE.toKernelConstant());
-        assertEquals(FetchDirection.REVERSE,
-            FetchDirection.fromKernelConstant(
-                ResultSet.FETCH_REVERSE));
-
-        assertEquals(ResultSet.FETCH_UNKNOWN,
-            FetchDirection.UNKNOWN.toKernelConstant());
-        assertEquals(FetchDirection.UNKNOWN,
-            FetchDirection.fromKernelConstant(
-                ResultSet.FETCH_UNKNOWN));
-
-        assertEquals(3, FetchDirection.values().length);
-    }
-
-
-    private int getConstantCount(Class cls) {
-        return cls.getDeclaredFields().length;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import java.sql.ResultSet;
+
+import junit.framework.TestCase;
+import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
+import org.apache.openjpa.jdbc.kernel.LRSSizes;
+import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
+
+public class TestJDBCEnumToKernelConstantMappings
+    extends TestCase {
+
+    public void testEagerFetchModes() {
+        assertEquals(EagerFetchModes.EAGER_NONE,
+            FetchMode.NONE.toKernelConstant());
+        assertEquals(FetchMode.NONE,
+            FetchMode.fromKernelConstant(
+                EagerFetchModes.EAGER_NONE));
+        assertEquals(FetchMode.NONE.toKernelConstant(),
+            FetchMode.NONE.ordinal());
+
+        assertEquals(EagerFetchModes.EAGER_JOIN,
+            FetchMode.JOIN.toKernelConstant());
+        assertEquals(FetchMode.JOIN,
+            FetchMode.fromKernelConstant(
+                EagerFetchModes.EAGER_JOIN));
+        assertEquals(FetchMode.JOIN.toKernelConstant(),
+            FetchMode.JOIN.ordinal());
+
+        assertEquals(EagerFetchModes.EAGER_PARALLEL,
+            FetchMode.PARALLEL.toKernelConstant());
+        assertEquals(FetchMode.PARALLEL,
+            FetchMode.fromKernelConstant(
+                EagerFetchModes.EAGER_PARALLEL));
+        assertEquals(FetchMode.PARALLEL.toKernelConstant(),
+            FetchMode.PARALLEL.ordinal());
+
+        assertEquals(getConstantCount(EagerFetchModes.class),
+            FetchMode.values().length);
+    }
+
+    public void testLRSSizeType() {
+        assertEquals(LRSSizes.SIZE_UNKNOWN,
+            LRSSizeAlgorithm.UNKNOWN.toKernelConstant());
+        assertEquals(LRSSizeAlgorithm.UNKNOWN,
+            LRSSizeAlgorithm.fromKernelConstant(
+                LRSSizes.SIZE_UNKNOWN));
+        assertEquals(LRSSizeAlgorithm.UNKNOWN.toKernelConstant(),
+            LRSSizeAlgorithm.UNKNOWN.ordinal());
+
+        assertEquals(LRSSizes.SIZE_LAST,
+            LRSSizeAlgorithm.LAST.toKernelConstant());
+        assertEquals(LRSSizeAlgorithm.LAST,
+            LRSSizeAlgorithm.fromKernelConstant(
+                LRSSizes.SIZE_LAST));
+        assertEquals(LRSSizeAlgorithm.LAST.toKernelConstant(),
+            LRSSizeAlgorithm.LAST.ordinal());
+
+        assertEquals(LRSSizes.SIZE_QUERY,
+            LRSSizeAlgorithm.QUERY.toKernelConstant());
+        assertEquals(LRSSizeAlgorithm.QUERY,
+            LRSSizeAlgorithm.fromKernelConstant(
+                LRSSizes.SIZE_QUERY));
+        assertEquals(LRSSizeAlgorithm.QUERY.toKernelConstant(),
+            LRSSizeAlgorithm.QUERY.ordinal());
+
+        assertEquals(getConstantCount(LRSSizes.class),
+            LRSSizeAlgorithm.values().length);
+    }
+
+    public void testJoinSyntaxType() {
+        assertEquals(JoinSyntaxes.SYNTAX_SQL92,
+            JoinSyntax.SQL92.toKernelConstant());
+        assertEquals(JoinSyntax.SQL92,
+            JoinSyntax.fromKernelConstant(
+                JoinSyntaxes.SYNTAX_SQL92));
+        assertEquals(JoinSyntax.SQL92.toKernelConstant(),
+            JoinSyntax.SQL92.ordinal());
+
+        assertEquals(JoinSyntaxes.SYNTAX_TRADITIONAL,
+            JoinSyntax.TRADITIONAL.toKernelConstant());
+        assertEquals(JoinSyntax.TRADITIONAL,
+            JoinSyntax.fromKernelConstant(
+                JoinSyntaxes.SYNTAX_TRADITIONAL));
+        assertEquals(JoinSyntax.TRADITIONAL.toKernelConstant(),
+            JoinSyntax.TRADITIONAL.ordinal());
+
+        assertEquals(JoinSyntaxes.SYNTAX_DATABASE,
+            JoinSyntax.DATABASE.toKernelConstant());
+        assertEquals(JoinSyntax.DATABASE,
+            JoinSyntax.fromKernelConstant(
+                JoinSyntaxes.SYNTAX_DATABASE));
+        assertEquals(JoinSyntax.DATABASE.toKernelConstant(),
+            JoinSyntax.DATABASE.ordinal());
+
+        assertEquals(getConstantCount(JoinSyntaxes.class),
+            JoinSyntax.values().length);
+    }
+
+    public void testResultSetType() {
+        assertEquals(ResultSet.TYPE_FORWARD_ONLY,
+            ResultSetType.FORWARD_ONLY.toKernelConstant());
+        assertEquals(ResultSetType.FORWARD_ONLY,
+            ResultSetType.fromKernelConstant(
+                ResultSet.TYPE_FORWARD_ONLY));
+
+        assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSetType.SCROLL_INSENSITIVE.toKernelConstant());
+        assertEquals(ResultSetType.SCROLL_INSENSITIVE,
+            ResultSetType.fromKernelConstant(
+                ResultSet.TYPE_SCROLL_INSENSITIVE));
+
+        assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE,
+            ResultSetType.SCROLL_SENSITIVE.toKernelConstant());
+        assertEquals(ResultSetType.SCROLL_SENSITIVE,
+            ResultSetType.fromKernelConstant(
+                ResultSet.TYPE_SCROLL_SENSITIVE));
+
+        assertEquals(3, ResultSetType.values().length);
+    }
+
+    public void testFetchDirection() {
+        assertEquals(ResultSet.FETCH_FORWARD,
+            FetchDirection.FORWARD.toKernelConstant());
+        assertEquals(FetchDirection.FORWARD,
+            FetchDirection.fromKernelConstant(
+                ResultSet.FETCH_FORWARD));
+
+        assertEquals(ResultSet.FETCH_REVERSE,
+            FetchDirection.REVERSE.toKernelConstant());
+        assertEquals(FetchDirection.REVERSE,
+            FetchDirection.fromKernelConstant(
+                ResultSet.FETCH_REVERSE));
+
+        assertEquals(ResultSet.FETCH_UNKNOWN,
+            FetchDirection.UNKNOWN.toKernelConstant());
+        assertEquals(FetchDirection.UNKNOWN,
+            FetchDirection.fromKernelConstant(
+                ResultSet.FETCH_UNKNOWN));
+
+        assertEquals(3, FetchDirection.values().length);
+    }
+
+
+    private int getConstantCount(Class cls) {
+        return cls.getDeclaredFields().length;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestOptimizeForClause.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestOptimizeForClause.java
index c8ba923..50cb00d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestOptimizeForClause.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/TestOptimizeForClause.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc;
-
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.InvalidStateException;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.jdbc.sql.DB2Dictionary;
-import org.apache.openjpa.jdbc.sql.HSQLDictionary;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-
-public class TestOptimizeForClause
-    extends SQLListenerTestCase {
-
-    public void setUp() {
-        setUp(AllFieldTypes.class);
-    }
-
-    public void testOptimizeForClauseViaHint() {
-        testOptimizeForClause(true,false,false);
-    }
-
-    public void testOptimizeForClauseViaFind() {
-        testOptimizeForClause(false,true,false);
-    }
-    public void testOptimizeForClauseViaQueryHint() {
-        testOptimizeForClause(false,true,true);
-    }
-    public void testOptimizeForClause(boolean hint,
-        boolean find, boolean queryHint) {
-        OpenJPAEntityManagerSPI em = emf.createEntityManager();
-        DBDictionary dict = ((JDBCConfiguration) em.getConfiguration())
-            .getDBDictionaryInstance();
-
-        // hsql doesn't support optimizing; circumvent the test
-        if (dict instanceof HSQLDictionary)
-            return;
-
-        sql.clear();
-        try {
-            em.getTransaction().begin();
-            if (hint || queryHint) {
-                if (hint) {
-                    Query q = em.createQuery(
-                    "select o from AllFieldTypes o where o.intField = :p");
-                    q.setParameter("p", 0);
-                    q.setHint("openjpa.hint.OptimizeResultCount"
-                         ,new Integer(8));
-                    q.getResultList();
-                }    
-                else {
-                    OpenJPAQuery q =  OpenJPAPersistence.cast (em.createQuery 
-                        ("select o from AllFieldTypes o where o.intField " +
-                         "= :p"));
-                    q.setParameter("p", 0);
-                    q.setHint(q.HINT_RESULT_COUNT, new Integer(8)); 
-                    q.getResultList();
-               }     
-               if (dict instanceof DB2Dictionary) {
-                   assertEquals(1, sql.size());
-                   assertContainsSQL(" optimize for 8 row");
-               }
-            }
-            else {
-                 em.find(AllFieldTypes.class, 0);
-                 if (dict instanceof DB2Dictionary ) {
-                    assertEquals(1, sql.size());
-                    assertContainsSQL(" optimize for 1 row");
-                }
-                   
-            }
-        } catch (InvalidStateException pe) {
-            // if we're not using DB2, we expect an InvalidStateException.
-            if (dict instanceof DB2Dictionary)
-                throw pe;
-        } finally {
-            em.getTransaction().rollback();
-            em.close();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.InvalidStateException;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.DB2Dictionary;
+import org.apache.openjpa.jdbc.sql.HSQLDictionary;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+
+public class TestOptimizeForClause
+    extends SQLListenerTestCase {
+
+    public void setUp() {
+        setUp(AllFieldTypes.class);
+    }
+
+    public void testOptimizeForClauseViaHint() {
+        testOptimizeForClause(true,false,false);
+    }
+
+    public void testOptimizeForClauseViaFind() {
+        testOptimizeForClause(false,true,false);
+    }
+    public void testOptimizeForClauseViaQueryHint() {
+        testOptimizeForClause(false,true,true);
+    }
+    public void testOptimizeForClause(boolean hint,
+        boolean find, boolean queryHint) {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        DBDictionary dict = ((JDBCConfiguration) em.getConfiguration())
+            .getDBDictionaryInstance();
+
+        // hsql doesn't support optimizing; circumvent the test
+        if (dict instanceof HSQLDictionary)
+            return;
+
+        sql.clear();
+        try {
+            em.getTransaction().begin();
+            if (hint || queryHint) {
+                if (hint) {
+                    Query q = em.createQuery(
+                    "select o from AllFieldTypes o where o.intField = :p");
+                    q.setParameter("p", 0);
+                    q.setHint("openjpa.hint.OptimizeResultCount"
+                         ,new Integer(8));
+                    q.getResultList();
+                }    
+                else {
+                    OpenJPAQuery q =  OpenJPAPersistence.cast (em.createQuery 
+                        ("select o from AllFieldTypes o where o.intField " +
+                         "= :p"));
+                    q.setParameter("p", 0);
+                    q.setHint(q.HINT_RESULT_COUNT, new Integer(8)); 
+                    q.getResultList();
+               }     
+               if (dict instanceof DB2Dictionary) {
+                   assertEquals(1, sql.size());
+                   assertContainsSQL(" optimize for 8 row");
+               }
+            }
+            else {
+                 em.find(AllFieldTypes.class, 0);
+                 if (dict instanceof DB2Dictionary ) {
+                    assertEquals(1, sql.size());
+                    assertContainsSQL(" optimize for 1 row");
+                }
+                   
+            }
+        } catch (InvalidStateException pe) {
+            // if we're not using DB2, we expect an InvalidStateException.
+            if (dict instanceof DB2Dictionary)
+                throw pe;
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest1.java
index e4400fb..5d2d940 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest1.java
@@ -1,312 +1,312 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.jdbc.*;
-
-@Entity
-@Table(name = "ANNOTEST1")
-@Inheritance(strategy = InheritanceType.JOINED)
-@DiscriminatorColumn(name = "ANNOCLS")
-@DiscriminatorValue("ANNO1")
-@SecondaryTables({ @SecondaryTable(name = "OTHER_ANNOTEST1",
-    pkJoinColumns = @PrimaryKeyJoinColumn(name = "OTHER_PK",
-        referencedColumnName = "PK")) })
-public class AnnoTest1 {
-
-    @Id
-    @Column(name = "PK")
-    protected Long pk;
-
-    @Version
-    @Column(name = "ANNOVER")
-    protected int version;
-
-    @Basic
-    protected int basic;
-
-    @Transient
-    protected int trans;
-
-    @Basic
-    @Column(name = "OTHERVALUE", table = "OTHER_ANNOTEST1")
-    protected int otherTableBasic;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "SELFONEONE_PK", referencedColumnName = "PK")
-    protected AnnoTest1 selfOneOne;
-
-    @OneToOne
-    @PrimaryKeyJoinColumn
-    protected AnnoTest1 pkJoinSelfOneOne;
-
-    @OneToOne
-    @JoinColumns({
-    @JoinColumn(name = "ONEONE_PK1", referencedColumnName = "PK1"),
-    @JoinColumn(name = "ONEONE_PK2", referencedColumnName = "PK2") })
-    protected AnnoTest2 oneOne;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @JoinColumns({
-    @JoinColumn(name = "OTHERONE_PK1", referencedColumnName = "PK1",
-        table = "OTHER_ANNOTEST1"),
-    @JoinColumn(name = "OTHERONE_PK2", referencedColumnName = "PK2",
-        table = "OTHER_ANNOTEST1") })
-    protected AnnoTest2 otherTableOneOne;
-
-    @OneToOne(mappedBy = "inverseOneOne", fetch = FetchType.LAZY)
-    protected AnnoTest2 inverseOwnerOneOne;
-
-    @Lob
-    @Column(name = "BLOBVAL")
-    protected byte[] blob;
-
-    @Basic
-    @Lob
-    @Column(name = "SERVAL")
-    protected Object serial;
-
-    @Column(name = "CLOBVAL")
-    @Lob
-    protected String clob;
-
-    // un-annotated enum should be persisted by default
-    @Column(name = "ENUMVAL")
-    protected InheritanceType enumeration;
-
-    @Enumerated
-    @Column(name = "ORD_ENUMVAL")
-    protected InheritanceType ordinalEnumeration;
-
-    @Enumerated(EnumType.STRING)
-    @Column(name = "STR_ENUMVAL")
-    protected InheritanceType stringEnumeration;
-
-    @OneToMany
-    @ElementJoinColumn(name = "ONEMANY_PK", referencedColumnName = "PK")
-    protected Set<AnnoTest2> oneMany = new HashSet();
-
-    @OneToMany(mappedBy = "oneManyOwner")
-    protected Set<AnnoTest2> inverseOwnerOneMany = new HashSet();
-
-    @ManyToMany
-    @JoinTable(name = "ANNOTEST1_MANYMANY",
-        joinColumns = @JoinColumn(name = "MANY_PK"),
-        inverseJoinColumns = {
-        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
-        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") })
-    protected Set<AnnoTest2> manyMany = new HashSet();
-
-    @ManyToMany(mappedBy = "manyMany")
-    protected Set<AnnoTest2> inverseOwnerManyMany = new HashSet();
-
-    @MapKey
-    @OneToMany
-    protected Map<Integer, Flat1> defaultMapKey = new HashMap();
-
-    @MapKey(name = "basic")
-    @OneToMany
-    protected Map<Integer, Flat1> namedMapKey = new HashMap();
-
-    @MapKey(name = "basic")
-    @OneToMany(mappedBy = "oneManyOwner")
-    protected Map<String, AnnoTest2> inverseOwnerMapKey = new HashMap();
-
-    public AnnoTest1() {
-    }
-
-    public AnnoTest1(long pk) {
-        this(new Long(pk));
-    }
-
-    public AnnoTest1(Long pk) {
-        this.pk = pk;
-    }
-
-    public void setPk(Long val) {
-        pk = val;
-    }
-
-    public Long getPk() {
-        return pk;
-    }
-
-    public int getVersion() {
-        return version;
-    }
-
-    public void setBasic(int i) {
-        basic = i;
-    }
-
-    public int getBasic() {
-        return basic;
-    }
-
-    public void setTransient(int i) {
-        trans = i;
-    }
-
-    public int getTransient() {
-        return trans;
-    }
-
-    public void setOtherTableBasic(int i) {
-        otherTableBasic = i;
-    }
-
-    public int getOtherTableBasic() {
-        return otherTableBasic;
-    }
-
-    public void setSelfOneOne(AnnoTest1 other) {
-        selfOneOne = other;
-    }
-
-    public AnnoTest1 getSelfOneOne() {
-        return selfOneOne;
-    }
-
-    public void setPKJoinSelfOneOne(AnnoTest1 other) {
-        pkJoinSelfOneOne = other;
-    }
-
-    public AnnoTest1 getPKJoinSelfOneOne() {
-        return pkJoinSelfOneOne;
-    }
-
-    public void setOneOne(AnnoTest2 other) {
-        oneOne = other;
-    }
-
-    public AnnoTest2 getOneOne() {
-        return oneOne;
-    }
-
-    public void setOtherTableOneOne(AnnoTest2 other) {
-        otherTableOneOne = other;
-    }
-
-    public AnnoTest2 getOtherTableOneOne() {
-        return otherTableOneOne;
-    }
-
-    public void setInverseOwnerOneOne(AnnoTest2 other) {
-        inverseOwnerOneOne = other;
-    }
-
-    public AnnoTest2 getInverseOwnerOneOne() {
-        return inverseOwnerOneOne;
-    }
-
-    public void setBlob(byte[] bytes) {
-        blob = bytes;
-    }
-
-    public byte[] getBlob() {
-        return blob;
-    }
-
-    public void setSerialized(Object o) {
-        serial = o;
-    }
-
-    public Object getSerialized() {
-        return serial;
-    }
-
-    public void setClob(String s) {
-        clob = s;
-    }
-
-    public String getClob() {
-        return clob;
-    }
-
-    public InheritanceType getEnumeration() {
-        return enumeration;
-    }
-
-    public void setEnumeration(InheritanceType val) {
-        enumeration = val;
-    }
-
-    public InheritanceType getOrdinalEnumeration() {
-        return ordinalEnumeration;
-    }
-
-    public void setOrdinalEnumeration(InheritanceType val) {
-        ordinalEnumeration = val;
-    }
-
-    public InheritanceType getStringEnumeration() {
-        return stringEnumeration;
-    }
-
-    public void setStringEnumeration(InheritanceType val) {
-        stringEnumeration = val;
-    }
-
-    public Set<AnnoTest2> getOneMany() {
-        return oneMany;
-    }
-
-    public Set<AnnoTest2> getInverseOwnerOneMany() {
-        return inverseOwnerOneMany;
-    }
-
-    public Set<AnnoTest2> getManyMany() {
-        return manyMany;
-    }
-
-    public Set<AnnoTest2> getInverseOwnerManyMany() {
-        return inverseOwnerManyMany;
-    }
-
-    public Map<Integer, Flat1> getDefaultMapKey() {
-        return this.defaultMapKey;
-    }
-
-    public void setDefaultMapKey(Map<Integer, Flat1> defaultMapKey) {
-        this.defaultMapKey = defaultMapKey;
-    }
-
-    public Map<Integer, Flat1> getNamedMapKey() {
-        return this.namedMapKey;
-    }
-
-    public void setNamedMapKey(Map<Integer, Flat1> namedMapKey) {
-        this.namedMapKey = namedMapKey;
-    }
-
-    public Map<String, AnnoTest2> getInverseOwnerMapKey() {
-        return this.inverseOwnerMapKey;
-    }
-
-    public void setInverseOwnerMapKey(
-        Map<String, AnnoTest2> inverseOwnerMapKey) {
-        this.inverseOwnerMapKey = inverseOwnerMapKey;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.jdbc.*;
+
+@Entity
+@Table(name = "ANNOTEST1")
+@Inheritance(strategy = InheritanceType.JOINED)
+@DiscriminatorColumn(name = "ANNOCLS")
+@DiscriminatorValue("ANNO1")
+@SecondaryTables({ @SecondaryTable(name = "OTHER_ANNOTEST1",
+    pkJoinColumns = @PrimaryKeyJoinColumn(name = "OTHER_PK",
+        referencedColumnName = "PK")) })
+public class AnnoTest1 {
+
+    @Id
+    @Column(name = "PK")
+    protected Long pk;
+
+    @Version
+    @Column(name = "ANNOVER")
+    protected int version;
+
+    @Basic
+    protected int basic;
+
+    @Transient
+    protected int trans;
+
+    @Basic
+    @Column(name = "OTHERVALUE", table = "OTHER_ANNOTEST1")
+    protected int otherTableBasic;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "SELFONEONE_PK", referencedColumnName = "PK")
+    protected AnnoTest1 selfOneOne;
+
+    @OneToOne
+    @PrimaryKeyJoinColumn
+    protected AnnoTest1 pkJoinSelfOneOne;
+
+    @OneToOne
+    @JoinColumns({
+    @JoinColumn(name = "ONEONE_PK1", referencedColumnName = "PK1"),
+    @JoinColumn(name = "ONEONE_PK2", referencedColumnName = "PK2") })
+    protected AnnoTest2 oneOne;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @JoinColumns({
+    @JoinColumn(name = "OTHERONE_PK1", referencedColumnName = "PK1",
+        table = "OTHER_ANNOTEST1"),
+    @JoinColumn(name = "OTHERONE_PK2", referencedColumnName = "PK2",
+        table = "OTHER_ANNOTEST1") })
+    protected AnnoTest2 otherTableOneOne;
+
+    @OneToOne(mappedBy = "inverseOneOne", fetch = FetchType.LAZY)
+    protected AnnoTest2 inverseOwnerOneOne;
+
+    @Lob
+    @Column(name = "BLOBVAL")
+    protected byte[] blob;
+
+    @Basic
+    @Lob
+    @Column(name = "SERVAL")
+    protected Object serial;
+
+    @Column(name = "CLOBVAL")
+    @Lob
+    protected String clob;
+
+    // un-annotated enum should be persisted by default
+    @Column(name = "ENUMVAL")
+    protected InheritanceType enumeration;
+
+    @Enumerated
+    @Column(name = "ORD_ENUMVAL")
+    protected InheritanceType ordinalEnumeration;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "STR_ENUMVAL")
+    protected InheritanceType stringEnumeration;
+
+    @OneToMany
+    @ElementJoinColumn(name = "ONEMANY_PK", referencedColumnName = "PK")
+    protected Set<AnnoTest2> oneMany = new HashSet();
+
+    @OneToMany(mappedBy = "oneManyOwner")
+    protected Set<AnnoTest2> inverseOwnerOneMany = new HashSet();
+
+    @ManyToMany
+    @JoinTable(name = "ANNOTEST1_MANYMANY",
+        joinColumns = @JoinColumn(name = "MANY_PK"),
+        inverseJoinColumns = {
+        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
+        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") })
+    protected Set<AnnoTest2> manyMany = new HashSet();
+
+    @ManyToMany(mappedBy = "manyMany")
+    protected Set<AnnoTest2> inverseOwnerManyMany = new HashSet();
+
+    @MapKey
+    @OneToMany
+    protected Map<Integer, Flat1> defaultMapKey = new HashMap();
+
+    @MapKey(name = "basic")
+    @OneToMany
+    protected Map<Integer, Flat1> namedMapKey = new HashMap();
+
+    @MapKey(name = "basic")
+    @OneToMany(mappedBy = "oneManyOwner")
+    protected Map<String, AnnoTest2> inverseOwnerMapKey = new HashMap();
+
+    public AnnoTest1() {
+    }
+
+    public AnnoTest1(long pk) {
+        this(new Long(pk));
+    }
+
+    public AnnoTest1(Long pk) {
+        this.pk = pk;
+    }
+
+    public void setPk(Long val) {
+        pk = val;
+    }
+
+    public Long getPk() {
+        return pk;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setBasic(int i) {
+        basic = i;
+    }
+
+    public int getBasic() {
+        return basic;
+    }
+
+    public void setTransient(int i) {
+        trans = i;
+    }
+
+    public int getTransient() {
+        return trans;
+    }
+
+    public void setOtherTableBasic(int i) {
+        otherTableBasic = i;
+    }
+
+    public int getOtherTableBasic() {
+        return otherTableBasic;
+    }
+
+    public void setSelfOneOne(AnnoTest1 other) {
+        selfOneOne = other;
+    }
+
+    public AnnoTest1 getSelfOneOne() {
+        return selfOneOne;
+    }
+
+    public void setPKJoinSelfOneOne(AnnoTest1 other) {
+        pkJoinSelfOneOne = other;
+    }
+
+    public AnnoTest1 getPKJoinSelfOneOne() {
+        return pkJoinSelfOneOne;
+    }
+
+    public void setOneOne(AnnoTest2 other) {
+        oneOne = other;
+    }
+
+    public AnnoTest2 getOneOne() {
+        return oneOne;
+    }
+
+    public void setOtherTableOneOne(AnnoTest2 other) {
+        otherTableOneOne = other;
+    }
+
+    public AnnoTest2 getOtherTableOneOne() {
+        return otherTableOneOne;
+    }
+
+    public void setInverseOwnerOneOne(AnnoTest2 other) {
+        inverseOwnerOneOne = other;
+    }
+
+    public AnnoTest2 getInverseOwnerOneOne() {
+        return inverseOwnerOneOne;
+    }
+
+    public void setBlob(byte[] bytes) {
+        blob = bytes;
+    }
+
+    public byte[] getBlob() {
+        return blob;
+    }
+
+    public void setSerialized(Object o) {
+        serial = o;
+    }
+
+    public Object getSerialized() {
+        return serial;
+    }
+
+    public void setClob(String s) {
+        clob = s;
+    }
+
+    public String getClob() {
+        return clob;
+    }
+
+    public InheritanceType getEnumeration() {
+        return enumeration;
+    }
+
+    public void setEnumeration(InheritanceType val) {
+        enumeration = val;
+    }
+
+    public InheritanceType getOrdinalEnumeration() {
+        return ordinalEnumeration;
+    }
+
+    public void setOrdinalEnumeration(InheritanceType val) {
+        ordinalEnumeration = val;
+    }
+
+    public InheritanceType getStringEnumeration() {
+        return stringEnumeration;
+    }
+
+    public void setStringEnumeration(InheritanceType val) {
+        stringEnumeration = val;
+    }
+
+    public Set<AnnoTest2> getOneMany() {
+        return oneMany;
+    }
+
+    public Set<AnnoTest2> getInverseOwnerOneMany() {
+        return inverseOwnerOneMany;
+    }
+
+    public Set<AnnoTest2> getManyMany() {
+        return manyMany;
+    }
+
+    public Set<AnnoTest2> getInverseOwnerManyMany() {
+        return inverseOwnerManyMany;
+    }
+
+    public Map<Integer, Flat1> getDefaultMapKey() {
+        return this.defaultMapKey;
+    }
+
+    public void setDefaultMapKey(Map<Integer, Flat1> defaultMapKey) {
+        this.defaultMapKey = defaultMapKey;
+    }
+
+    public Map<Integer, Flat1> getNamedMapKey() {
+        return this.namedMapKey;
+    }
+
+    public void setNamedMapKey(Map<Integer, Flat1> namedMapKey) {
+        this.namedMapKey = namedMapKey;
+    }
+
+    public Map<String, AnnoTest2> getInverseOwnerMapKey() {
+        return this.inverseOwnerMapKey;
+    }
+
+    public void setInverseOwnerMapKey(
+        Map<String, AnnoTest2> inverseOwnerMapKey) {
+        this.inverseOwnerMapKey = inverseOwnerMapKey;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest2.java
index d2321d6..843d15d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest2.java
@@ -1,166 +1,166 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name = "ANNOTEST2")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "ANNOCLS")
-@DiscriminatorValue("ANNO2")
-@IdClass(AnnoTest2.Oid.class)
-public class AnnoTest2 {
-
-    @Id
-    @Column(name = "PK1")
-    protected long pk1;
-
-    @Id
-    @Column(name = "PK2")
-    protected String pk2;
-
-    @Version
-    @Column(name = "ANNOVER")
-    protected Date version;
-
-    @Basic
-    protected String basic;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "INVERSEONEONE_PK", referencedColumnName = "PK")
-    protected AnnoTest1 inverseOneOne;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "MANYONEONE_PK", referencedColumnName = "PK")
-    protected AnnoTest1 oneManyOwner;
-
-    @ManyToMany
-    @JoinTable(name = "ANNOTEST2_MANYMANY",
-        joinColumns = {
-        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
-        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") },
-        inverseJoinColumns =
-        @JoinColumn(name = "MANYE_PK", referencedColumnName = "PK"))
-    protected Set<AnnoTest1> manyMany = new HashSet();
-
-    public AnnoTest2() {
-    }
-
-    public AnnoTest2(long pk1, String pk2) {
-        this.pk1 = pk1;
-        this.pk2 = pk2;
-    }
-
-    public void setPk1(long val) {
-        pk1 = val;
-    }
-
-    public long getPk1() {
-        return pk1;
-    }
-
-    public void setPk2(String str) {
-        pk2 = str;
-    }
-
-    public String getPk2() {
-        return pk2;
-    }
-
-    public Date getVersion() {
-        return version;
-    }
-
-    public void setBasic(String s) {
-        basic = s;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setInverseOneOne(AnnoTest1 other) {
-        inverseOneOne = other;
-    }
-
-    public AnnoTest1 getInverseOneOne() {
-        return inverseOneOne;
-    }
-
-    public void setOneManyOwner(AnnoTest1 other) {
-        oneManyOwner = other;
-    }
-
-    public AnnoTest1 getOneManyOwner() {
-        return oneManyOwner;
-    }
-
-    public Set getManyMany() {
-        return manyMany;
-    }
-
-    public static class Oid {
-
-        public long pk1;
-        public String pk2;
-
-        public Oid() {
-        }
-
-        public Oid(long pk1, String pk2) {
-            this.pk1 = pk1;
-            this.pk2 = pk2;
-        }
-
-        public Oid(String str) {
-            if (str != null) {
-                int index = str.indexOf(",");
-                pk1 = Long.parseLong(str.substring(0, index));
-                pk2 = str.substring(index + 1);
-                if ("null".equals(pk2))
-                    pk2 = null;
-            }
-        }
-
-        public boolean equals(Object o) {
-            if (o == this)
-                return true;
-            if (!(o instanceof Oid))
-                return false;
-            Oid other = (Oid) o;
-            if (pk1 != other.pk1)
-                return false;
-            if (pk2 == null)
-                return other.pk2 == null;
-            return pk2.equals(other.pk2);
-        }
-
-        public int hashCode() {
-            return ((int) pk1) + (pk2 == null ? 0 : pk2.hashCode());
-        }
-
-        public String toString() {
-            return pk1 + "," + (pk2 == null ? "null" : pk2);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "ANNOTEST2")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "ANNOCLS")
+@DiscriminatorValue("ANNO2")
+@IdClass(AnnoTest2.Oid.class)
+public class AnnoTest2 {
+
+    @Id
+    @Column(name = "PK1")
+    protected long pk1;
+
+    @Id
+    @Column(name = "PK2")
+    protected String pk2;
+
+    @Version
+    @Column(name = "ANNOVER")
+    protected Date version;
+
+    @Basic
+    protected String basic;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "INVERSEONEONE_PK", referencedColumnName = "PK")
+    protected AnnoTest1 inverseOneOne;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "MANYONEONE_PK", referencedColumnName = "PK")
+    protected AnnoTest1 oneManyOwner;
+
+    @ManyToMany
+    @JoinTable(name = "ANNOTEST2_MANYMANY",
+        joinColumns = {
+        @JoinColumn(name = "MANY_PK1", referencedColumnName = "PK1"),
+        @JoinColumn(name = "MANY_PK2", referencedColumnName = "PK2") },
+        inverseJoinColumns =
+        @JoinColumn(name = "MANYE_PK", referencedColumnName = "PK"))
+    protected Set<AnnoTest1> manyMany = new HashSet();
+
+    public AnnoTest2() {
+    }
+
+    public AnnoTest2(long pk1, String pk2) {
+        this.pk1 = pk1;
+        this.pk2 = pk2;
+    }
+
+    public void setPk1(long val) {
+        pk1 = val;
+    }
+
+    public long getPk1() {
+        return pk1;
+    }
+
+    public void setPk2(String str) {
+        pk2 = str;
+    }
+
+    public String getPk2() {
+        return pk2;
+    }
+
+    public Date getVersion() {
+        return version;
+    }
+
+    public void setBasic(String s) {
+        basic = s;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setInverseOneOne(AnnoTest1 other) {
+        inverseOneOne = other;
+    }
+
+    public AnnoTest1 getInverseOneOne() {
+        return inverseOneOne;
+    }
+
+    public void setOneManyOwner(AnnoTest1 other) {
+        oneManyOwner = other;
+    }
+
+    public AnnoTest1 getOneManyOwner() {
+        return oneManyOwner;
+    }
+
+    public Set getManyMany() {
+        return manyMany;
+    }
+
+    public static class Oid {
+
+        public long pk1;
+        public String pk2;
+
+        public Oid() {
+        }
+
+        public Oid(long pk1, String pk2) {
+            this.pk1 = pk1;
+            this.pk2 = pk2;
+        }
+
+        public Oid(String str) {
+            if (str != null) {
+                int index = str.indexOf(",");
+                pk1 = Long.parseLong(str.substring(0, index));
+                pk2 = str.substring(index + 1);
+                if ("null".equals(pk2))
+                    pk2 = null;
+            }
+        }
+
+        public boolean equals(Object o) {
+            if (o == this)
+                return true;
+            if (!(o instanceof Oid))
+                return false;
+            Oid other = (Oid) o;
+            if (pk1 != other.pk1)
+                return false;
+            if (pk2 == null)
+                return other.pk2 == null;
+            return pk2.equals(other.pk2);
+        }
+
+        public int hashCode() {
+            return ((int) pk1) + (pk2 == null ? 0 : pk2.hashCode());
+        }
+
+        public String toString() {
+            return pk1 + "," + (pk2 == null ? "null" : pk2);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest3.java
index f989ea9..3cd7171 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/AnnoTest3.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity
-@DiscriminatorValue("ANNO3")
-@Table(name = "ANNOTEST3")
-@PrimaryKeyJoinColumns(@PrimaryKeyJoinColumn(name = "SUB_PK",
-    referencedColumnName = "PK"))
-public class AnnoTest3 extends AnnoTest1 {
-
-    @Basic
-    @Column(name = "SUBBASIC")
-    protected int basic2;
-
-    @OneToOne(fetch = FetchType.LAZY)
-    protected AnnoTest2 subOneOne;
-
-    public AnnoTest3() {
-    }
-
-    public AnnoTest3(long pk) {
-        super(pk);
-    }
-
-    public AnnoTest3(Long pk) {
-        super(pk);
-    }
-
-    public void setBasic2(int i) {
-        basic2 = i;
-    }
-
-    public int getBasic2() {
-        return basic2;
-    }
-
-    public AnnoTest2 getSubOneOne() {
-        return subOneOne;
-    }
-
-    public void setSubOneOne(AnnoTest2 anno2) {
-        subOneOne = anno2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorValue("ANNO3")
+@Table(name = "ANNOTEST3")
+@PrimaryKeyJoinColumns(@PrimaryKeyJoinColumn(name = "SUB_PK",
+    referencedColumnName = "PK"))
+public class AnnoTest3 extends AnnoTest1 {
+
+    @Basic
+    @Column(name = "SUBBASIC")
+    protected int basic2;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    protected AnnoTest2 subOneOne;
+
+    public AnnoTest3() {
+    }
+
+    public AnnoTest3(long pk) {
+        super(pk);
+    }
+
+    public AnnoTest3(Long pk) {
+        super(pk);
+    }
+
+    public void setBasic2(int i) {
+        basic2 = i;
+    }
+
+    public int getBasic2() {
+        return basic2;
+    }
+
+    public AnnoTest2 getSubOneOne() {
+        return subOneOne;
+    }
+
+    public void setSubOneOne(AnnoTest2 anno2) {
+        subOneOne = anno2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java
index a66ba8e..fff0ee5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedOwner.java
@@ -1,68 +1,68 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity
-@SqlResultSetMapping(name = "EmbedMapping", entities = {
-@EntityResult(entityClass = EmbedOwner.class, fields = {
-@FieldResult(name = "pk", column = "OWNER_PK"),
-@FieldResult(name = "basic", column = "OWNER_BASIC"),
-@FieldResult(name = "embed.basic", column = "EMBED_BASIC"),
-@FieldResult(name = "embed.clob", column = "EMBED_CLOB")
-    })
-    })
-public class EmbedOwner {
-
-    @Embedded
-    @AttributeOverride(name = "basic", column = @Column(name = "OVER_BASIC"))
-    @AssociationOverride(name = "owner",
-        joinColumns = @JoinColumn(name = "OVER_OWNER"))
-    protected EmbedValue embed;
-
-    @Basic
-    @Column(name = "OWN_BASIC")
-    protected String basic;
-
-    @Id
-    @GeneratedValue
-    protected int pk;
-
-    public int getPk() {
-        return pk;
-    }
-
-    public void setBasic(String basic) {
-        this.basic = basic;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setEmbed(EmbedValue embed) {
-        this.embed = embed;
-    }
-
-    public EmbedValue getEmbed() {
-        return embed;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity
+@SqlResultSetMapping(name = "EmbedMapping", entities = {
+@EntityResult(entityClass = EmbedOwner.class, fields = {
+@FieldResult(name = "pk", column = "OWNER_PK"),
+@FieldResult(name = "basic", column = "OWNER_BASIC"),
+@FieldResult(name = "embed.basic", column = "EMBED_BASIC"),
+@FieldResult(name = "embed.clob", column = "EMBED_CLOB")
+    })
+    })
+public class EmbedOwner {
+
+    @Embedded
+    @AttributeOverride(name = "basic", column = @Column(name = "OVER_BASIC"))
+    @AssociationOverride(name = "owner",
+        joinColumns = @JoinColumn(name = "OVER_OWNER"))
+    protected EmbedValue embed;
+
+    @Basic
+    @Column(name = "OWN_BASIC")
+    protected String basic;
+
+    @Id
+    @GeneratedValue
+    protected int pk;
+
+    public int getPk() {
+        return pk;
+    }
+
+    public void setBasic(String basic) {
+        this.basic = basic;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setEmbed(EmbedValue embed) {
+        this.embed = embed;
+    }
+
+    public EmbedValue getEmbed() {
+        return embed;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue.java
index d95680c..ee9cf4a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue.java
@@ -1,77 +1,77 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Embeddable
-public class EmbedValue {
-
-    @Basic
-    @Column(name = "EMB_BASIC")
-    protected String basic;
-
-    @Lob
-    @Column(name = "EMB_CLOB")
-    protected String clob;
-
-    @Lob
-    @Column(name = "EMB_BLOB")
-    protected byte[] blob;
-
-    @ManyToOne
-    @JoinColumn(name = "EMB_REL")
-    protected EmbedOwner owner;
-
-    @Transient
-    private int transientField;
-
-    public void setBasic(String basic) {
-        this.basic = basic;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setClob(String clob) {
-        this.clob = clob;
-    }
-
-    public String getClob() {
-        return clob;
-    }
-
-    public void setBlob(byte[] blob) {
-        this.blob = blob;
-    }
-
-    public byte[] getBlob() {
-        return blob;
-    }
-
-    public void setOwner(EmbedOwner owner) {
-        this.owner = owner;
-    }
-
-    public EmbedOwner getOwner() {
-        return owner;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Embeddable
+public class EmbedValue {
+
+    @Basic
+    @Column(name = "EMB_BASIC")
+    protected String basic;
+
+    @Lob
+    @Column(name = "EMB_CLOB")
+    protected String clob;
+
+    @Lob
+    @Column(name = "EMB_BLOB")
+    protected byte[] blob;
+
+    @ManyToOne
+    @JoinColumn(name = "EMB_REL")
+    protected EmbedOwner owner;
+
+    @Transient
+    private int transientField;
+
+    public void setBasic(String basic) {
+        this.basic = basic;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setClob(String clob) {
+        this.clob = clob;
+    }
+
+    public String getClob() {
+        return clob;
+    }
+
+    public void setBlob(byte[] blob) {
+        this.blob = blob;
+    }
+
+    public byte[] getBlob() {
+        return blob;
+    }
+
+    public void setOwner(EmbedOwner owner) {
+        this.owner = owner;
+    }
+
+    public EmbedOwner getOwner() {
+        return owner;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue2.java
index 081e794..34b756c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbedValue2.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-/**
- * Same as EmbedValue but no blobs for suitable use as key/value/element
- * in oracle.
- */
-@Embeddable
-public class EmbedValue2 {
-
-    @Basic
-    @Column(name = "EMB_BASIC")
-    protected String basic;
-
-    @Basic
-    @Column(name = "EMB_INTBASIC")
-    protected int intBasic;
-
-    public void setBasic(String basic) {
-        this.basic = basic;
-    }
-
-    public String getBasic() {
-        return basic;
-    }
-
-    public void setIntBasic(int intBasic) {
-        this.intBasic = intBasic;
-    }
-
-    public int getIntBasic() {
-        return intBasic;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+/**
+ * Same as EmbedValue but no blobs for suitable use as key/value/element
+ * in oracle.
+ */
+@Embeddable
+public class EmbedValue2 {
+
+    @Basic
+    @Column(name = "EMB_BASIC")
+    protected String basic;
+
+    @Basic
+    @Column(name = "EMB_INTBASIC")
+    protected int intBasic;
+
+    public void setBasic(String basic) {
+        this.basic = basic;
+    }
+
+    public String getBasic() {
+        return basic;
+    }
+
+    public void setIntBasic(int intBasic) {
+        this.intBasic = intBasic;
+    }
+
+    public int getIntBasic() {
+        return intBasic;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuper.java
index 15dcf2f..d9ae687 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuper.java
@@ -1,77 +1,77 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@MappedSuperclass
-public class EmbeddableSuper {
-
-    @Id
-    @GeneratedValue
-    @Column(name = "ID")
-    private long pk;
-
-    @Version
-    @Column(name = "SUPVERS")
-    private int version;
-
-    @Transient
-    private int trans;
-
-    @Lob
-    @Column(name = "CLOBVAL")
-    protected String clob;
-
-    public EmbeddableSuper() {
-    }
-
-    public long getPK() {
-        return this.pk;
-    }
-
-    public void setPK(long pk) {
-        this.pk = pk;
-    }
-
-    public int getTrans() {
-        return this.trans;
-    }
-
-    public void setTrans(int trans) {
-        this.trans = trans;
-    }
-
-    public String getClob() {
-        return this.clob;
-    }
-
-    public void setClob(String clob) {
-        this.clob = clob;
-    }
-
-    public int getVersion() {
-        return this.version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@MappedSuperclass
+public class EmbeddableSuper {
+
+    @Id
+    @GeneratedValue
+    @Column(name = "ID")
+    private long pk;
+
+    @Version
+    @Column(name = "SUPVERS")
+    private int version;
+
+    @Transient
+    private int trans;
+
+    @Lob
+    @Column(name = "CLOBVAL")
+    protected String clob;
+
+    public EmbeddableSuper() {
+    }
+
+    public long getPK() {
+        return this.pk;
+    }
+
+    public void setPK(long pk) {
+        this.pk = pk;
+    }
+
+    public int getTrans() {
+        return this.trans;
+    }
+
+    public void setTrans(int trans) {
+        this.trans = trans;
+    }
+
+    public String getClob() {
+        return this.clob;
+    }
+
+    public void setClob(String clob) {
+        this.clob = clob;
+    }
+
+    public int getVersion() {
+        return this.version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuperSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuperSub.java
index c476ad9..13b768b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuperSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddableSuperSub.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity
-@DiscriminatorColumn(name = "DISC")
-@AttributeOverrides({
-    @AttributeOverride(name = "clob", column = @Column(name = "CC")),
-    @AttributeOverride(name = "version", column = @Column(name = "VERSVAL"))
-})
-public class EmbeddableSuperSub
-    extends EmbeddableSuper {
-
-    @ManyToOne
-    private EmbeddableSuperSub sub;
-
-    @ManyToOne
-    // #####
-    private EmbeddableSuper sup;
-
-    public EmbeddableSuperSub() {
-    }
-
-    public EmbeddableSuperSub getSub() {
-        return this.sub;
-    }
-
-    public void setSub(EmbeddableSuperSub sub) {
-        this.sub = sub;
-    }
-
-    public EmbeddableSuper getSup() {
-        return this.sup;
-    }
-
-    public void setSup(EmbeddableSuper sup) {
-        this.sup = sup;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorColumn(name = "DISC")
+@AttributeOverrides({
+    @AttributeOverride(name = "clob", column = @Column(name = "CC")),
+    @AttributeOverride(name = "version", column = @Column(name = "VERSVAL"))
+})
+public class EmbeddableSuperSub
+    extends EmbeddableSuper {
+
+    @ManyToOne
+    private EmbeddableSuperSub sub;
+
+    @ManyToOne
+    // #####
+    private EmbeddableSuper sup;
+
+    public EmbeddableSuperSub() {
+    }
+
+    public EmbeddableSuperSub getSub() {
+        return this.sub;
+    }
+
+    public void setSub(EmbeddableSuperSub sub) {
+        this.sub = sub;
+    }
+
+    public EmbeddableSuper getSup() {
+        return this.sup;
+    }
+
+    public void setSup(EmbeddableSuper sup) {
+        this.sup = sup;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdClass.java
index 5c0f1f5..b20bbab 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdClass.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Embeddable
-public class EmbeddedIdClass {
-
-    @Column(name = "EPK1")
-    private long pk1;
-
-    @Column(name = "EPK2")
-    private long pk2;
-
-    @Column(name = "EPK3")
-    @GeneratedValue
-    private long pk3;
-
-    public long getPk1() {
-        return pk1;
-    }
-
-    public void setPk1(long pk1) {
-        this.pk1 = pk1;
-    }
-
-    public long getPk2() {
-        return pk2;
-    }
-
-    public void setPk2(long pk2) {
-        this.pk2 = pk2;
-    }
-
-    public long getPk3() {
-        return pk3;
-    }
-
-    public void setPk3(long pk3) {
-        this.pk3 = pk3;
-    }
-
-    public String toString() {
-        return pk1 + ":" + pk2 + ":" + pk3;
-    }
-
-    public int hashCode() {
-        return (int) ((pk1 ^ pk2 ^ pk3) % Integer.MAX_VALUE);
-    }
-
-    public boolean equals(Object other) {
-        if (other == this)
-            return true;
-        if (!(other instanceof EmbeddedIdClass))
-            return false;
-
-        EmbeddedIdClass id = (EmbeddedIdClass) other;
-        return id.pk1 == pk1
-            && id.pk2 == pk2
-            && id.pk3 == pk3;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Embeddable
+public class EmbeddedIdClass {
+
+    @Column(name = "EPK1")
+    private long pk1;
+
+    @Column(name = "EPK2")
+    private long pk2;
+
+    @Column(name = "EPK3")
+    @GeneratedValue
+    private long pk3;
+
+    public long getPk1() {
+        return pk1;
+    }
+
+    public void setPk1(long pk1) {
+        this.pk1 = pk1;
+    }
+
+    public long getPk2() {
+        return pk2;
+    }
+
+    public void setPk2(long pk2) {
+        this.pk2 = pk2;
+    }
+
+    public long getPk3() {
+        return pk3;
+    }
+
+    public void setPk3(long pk3) {
+        this.pk3 = pk3;
+    }
+
+    public String toString() {
+        return pk1 + ":" + pk2 + ":" + pk3;
+    }
+
+    public int hashCode() {
+        return (int) ((pk1 ^ pk2 ^ pk3) % Integer.MAX_VALUE);
+    }
+
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (!(other instanceof EmbeddedIdClass))
+            return false;
+
+        EmbeddedIdClass id = (EmbeddedIdClass) other;
+        return id.pk1 == pk1
+            && id.pk2 == pk2
+            && id.pk3 == pk3;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdEntity.java
index ddc1b55..dbefaa3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EmbeddedIdEntity.java
@@ -1,88 +1,88 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity
-@Table(name = "EMIDENTITY")
-@SqlResultSetMapping(name = "EmbeddedIdMapping", entities = {
-@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
-@FieldResult(name = "id.pk1", column = "OWNER_PK1"),
-@FieldResult(name = "id.pk2", column = "OWNER_PK2"),
-@FieldResult(name = "id.pk3", column = "OWNER_PK3"),
-@FieldResult(name = "value", column = "OWNER_VAL"),
-@FieldResult(name = "relation.id.pk1", column = "REL_PK1"),
-@FieldResult(name = "relation.id.pk2", column = "REL_PK2"),
-@FieldResult(name = "relation.id.pk3", column = "REL_PK3")
-    }),
-@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
-@FieldResult(name = "id.pk1", column = "REL_PK1"),
-@FieldResult(name = "id.pk2", column = "REL_PK2"),
-@FieldResult(name = "id.pk3", column = "REL_PK3"),
-@FieldResult(name = "value", column = "REL_VAL")
-    })
-    })
-public class EmbeddedIdEntity {
-
-    @EmbeddedId
-    private EmbeddedIdClass id;
-
-    @Column(name = "VAL")
-    private String value;
-
-    @ManyToOne
-    private EmbeddedIdEntity relation;
-
-    @ManyToOne
-    @JoinColumns({
-    @JoinColumn(name = "MREL_PK1", referencedColumnName = "EPK1"),
-    @JoinColumn(name = "MREL_PK2", referencedColumnName = "EPK2")
-        })
-    private EmbeddedIdEntity mapOverrideRelation;
-
-    public EmbeddedIdClass getId() {
-        return id;
-    }
-
-    public void setId(EmbeddedIdClass id) {
-        this.id = id;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    public EmbeddedIdEntity getRelation() {
-        return relation;
-    }
-
-    public void setRelation(EmbeddedIdEntity relation) {
-        this.relation = relation;
-    }
-
-    public EmbeddedIdEntity getMappingOverrideRelation() {
-        return mapOverrideRelation;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "EMIDENTITY")
+@SqlResultSetMapping(name = "EmbeddedIdMapping", entities = {
+@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
+@FieldResult(name = "id.pk1", column = "OWNER_PK1"),
+@FieldResult(name = "id.pk2", column = "OWNER_PK2"),
+@FieldResult(name = "id.pk3", column = "OWNER_PK3"),
+@FieldResult(name = "value", column = "OWNER_VAL"),
+@FieldResult(name = "relation.id.pk1", column = "REL_PK1"),
+@FieldResult(name = "relation.id.pk2", column = "REL_PK2"),
+@FieldResult(name = "relation.id.pk3", column = "REL_PK3")
+    }),
+@EntityResult(entityClass = EmbeddedIdEntity.class, fields = {
+@FieldResult(name = "id.pk1", column = "REL_PK1"),
+@FieldResult(name = "id.pk2", column = "REL_PK2"),
+@FieldResult(name = "id.pk3", column = "REL_PK3"),
+@FieldResult(name = "value", column = "REL_VAL")
+    })
+    })
+public class EmbeddedIdEntity {
+
+    @EmbeddedId
+    private EmbeddedIdClass id;
+
+    @Column(name = "VAL")
+    private String value;
+
+    @ManyToOne
+    private EmbeddedIdEntity relation;
+
+    @ManyToOne
+    @JoinColumns({
+    @JoinColumn(name = "MREL_PK1", referencedColumnName = "EPK1"),
+    @JoinColumn(name = "MREL_PK2", referencedColumnName = "EPK2")
+        })
+    private EmbeddedIdEntity mapOverrideRelation;
+
+    public EmbeddedIdClass getId() {
+        return id;
+    }
+
+    public void setId(EmbeddedIdClass id) {
+        this.id = id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public EmbeddedIdEntity getRelation() {
+        return relation;
+    }
+
+    public void setRelation(EmbeddedIdEntity relation) {
+        this.relation = relation;
+    }
+
+    public EmbeddedIdEntity getMappingOverrideRelation() {
+        return mapOverrideRelation;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/ExtensionsEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/ExtensionsEntity.java
index d640e15..48a8505 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/ExtensionsEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/ExtensionsEntity.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.jdbc.meta.strats.*;
-import org.apache.openjpa.persistence.*;
-import org.apache.openjpa.persistence.jdbc.*;
-
-
-@Entity
-@DataStoreId(strategy = GenerationType.SEQUENCE, generator = "system")
-@DataCache(enabled = false)
-@FetchGroup(name = "detail", attributes = {
-    @FetchAttribute(name = "rel", recursionDepth = -1),
-    @FetchAttribute(name = "seq")
-})
-@VersionStrategy(StateComparisonVersionStrategy.ALIAS)
-public class ExtensionsEntity {
-
-    @GeneratedValue(generator = "uuid-hex")
-    @Column(name = "UUID_HEX")
-    private String uuid;
-    
-    @GeneratedValue(generator = "uuid-string")
-    @Column(name = "UUID_STRING")
-    private String uuidString;
-
-    @GeneratedValue(generator = "uuid-type4-hex")
-    @Column(name = "UUIDT4_HEX")
-    private String uuidT4Hex;
-
-    @GeneratedValue(generator = "uuid-type4-string")
-    @Column(name = "UUIDT4_STRING")
-    private String uuidT4String;
-
-    @Basic(fetch = FetchType.LAZY)
-    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "system")
-    @ReadOnly
-    private int seq;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "REL_ID", referencedColumnName = "ID")
-    @Dependent
-    @InverseLogical("owner")
-    private ExtensionsEntity rel;
-
-    @ManyToOne
-    @JoinColumn(name = "OWNER_ID", referencedColumnName = "ID")
-    private ExtensionsEntity owner;
-
-    @ManyToMany
-    @LRS
-    private Collection<ExtensionsEntity> lrs;
-
-    @ManyToMany
-    @EagerFetchMode(FetchMode.JOIN)
-    @ElementClassCriteria
-    @ElementDependent
-    private Collection<ExtensionsEntity> eager;
-
-    @ExternalValues({ "M=1", "F=2" })
-    @Type(int.class)
-    private char externalValues;
-
-    @Persistent
-    @Externalizer("getName")
-    @Factory("Class.forName")
-    private Class externalizer;
-
-    public char getExternalValues() {
-        return this.externalValues;
-    }
-
-    public void setExternalValues(char externalValues) {
-        this.externalValues = externalValues;
-    }
-
-    public Class getExternalizer() {
-        return this.externalizer;
-    }
-
-    public void setExternalizer(Class externalizer) {
-        this.externalizer = externalizer;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+
+@Entity
+@DataStoreId(strategy = GenerationType.SEQUENCE, generator = "system")
+@DataCache(enabled = false)
+@FetchGroup(name = "detail", attributes = {
+    @FetchAttribute(name = "rel", recursionDepth = -1),
+    @FetchAttribute(name = "seq")
+})
+@VersionStrategy(StateComparisonVersionStrategy.ALIAS)
+public class ExtensionsEntity {
+
+    @GeneratedValue(generator = "uuid-hex")
+    @Column(name = "UUID_HEX")
+    private String uuid;
+    
+    @GeneratedValue(generator = "uuid-string")
+    @Column(name = "UUID_STRING")
+    private String uuidString;
+
+    @GeneratedValue(generator = "uuid-type4-hex")
+    @Column(name = "UUIDT4_HEX")
+    private String uuidT4Hex;
+
+    @GeneratedValue(generator = "uuid-type4-string")
+    @Column(name = "UUIDT4_STRING")
+    private String uuidT4String;
+
+    @Basic(fetch = FetchType.LAZY)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "system")
+    @ReadOnly
+    private int seq;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "REL_ID", referencedColumnName = "ID")
+    @Dependent
+    @InverseLogical("owner")
+    private ExtensionsEntity rel;
+
+    @ManyToOne
+    @JoinColumn(name = "OWNER_ID", referencedColumnName = "ID")
+    private ExtensionsEntity owner;
+
+    @ManyToMany
+    @LRS
+    private Collection<ExtensionsEntity> lrs;
+
+    @ManyToMany
+    @EagerFetchMode(FetchMode.JOIN)
+    @ElementClassCriteria
+    @ElementDependent
+    private Collection<ExtensionsEntity> eager;
+
+    @ExternalValues({ "M=1", "F=2" })
+    @Type(int.class)
+    private char externalValues;
+
+    @Persistent
+    @Externalizer("getName")
+    @Factory("Class.forName")
+    private Class externalizer;
+
+    public char getExternalValues() {
+        return this.externalValues;
+    }
+
+    public void setExternalValues(char externalValues) {
+        this.externalValues = externalValues;
+    }
+
+    public Class getExternalizer() {
+        return this.externalizer;
+    }
+
+    public void setExternalizer(Class externalizer) {
+        this.externalizer = externalizer;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat1.java
index c500a8f..df2b5cf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat1.java
@@ -1,68 +1,68 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity(name="Flat1")
-@Table(name="Flat1")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "EJB_CLS", length=100)
-public class Flat1 {
-
-    @Id
-    @Column(name = "PK")
-    protected int pk;
-
-    @Version
-    @Column(name = "EJB_VER")
-    protected int version;
-
-    @Basic
-    protected int basic;
-
-    public Flat1() {
-    }
-
-    public Flat1(int pk) {
-        this.pk = pk;
-    }
-
-    public void setPk(int val) {
-        pk = val;
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public int getVersion() {
-        return version;
-    }
-
-    public void setBasic(int i) {
-        basic = i;
-    }
-
-    public int getBasic() {
-        return basic;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity(name="Flat1")
+@Table(name="Flat1")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "EJB_CLS", length=100)
+public class Flat1 {
+
+    @Id
+    @Column(name = "PK")
+    protected int pk;
+
+    @Version
+    @Column(name = "EJB_VER")
+    protected int version;
+
+    @Basic
+    protected int basic;
+
+    public Flat1() {
+    }
+
+    public Flat1(int pk) {
+        this.pk = pk;
+    }
+
+    public void setPk(int val) {
+        pk = val;
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setBasic(int i) {
+        basic = i;
+    }
+
+    public int getBasic() {
+        return basic;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat2.java
index 16d74a0..e295af9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Flat2.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity(name="Flat2")
-public class Flat2
-    extends Flat1 {
-
-    @Basic
-    protected String basic2;
-
-    public Flat2() {
-    }
-
-    public Flat2(int pk) {
-        super(pk);
-    }
-
-    public void setBasic2(String s) {
-        basic2 = s;
-    }
-
-    public String getBasic2() {
-        return basic2;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity(name="Flat2")
+public class Flat2
+    extends Flat1 {
+
+    @Basic
+    protected String basic2;
+
+    public Flat2() {
+    }
+
+    public Flat2(int pk) {
+        super(pk);
+    }
+
+    public void setBasic2(String s) {
+        basic2 = s;
+    }
+
+    public String getBasic2() {
+        return basic2;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Generator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Generator.java
index 9ea4ed9..b0ab6d0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Generator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/Generator.java
@@ -1,110 +1,110 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-@Entity
-// non-psql/ora dbs cause issues with SequenceGenerator in auto-mapping
-//@SequenceGenerator(name="seq", sequenceName="ejb_sequence")
-@TableGenerator(name = "tab")
-@IdClass(Generator.Oid.class)
-public class Generator {
-
-    @Id
-    protected int pk;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab")
-    protected Integer pk2;
-
-    @Id
-    @GeneratedValue
-    protected long pk3;
-
-    @Basic
-    protected String stringField;
-
-    // for non-seq
-    public void setPk(int pk) {
-        this.pk = pk;
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public Integer getPk2() {
-        return pk2;
-    }
-
-    public long getPk3() {
-        return pk3;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public static class Oid {
-
-        public int pk;
-        public Integer pk2;
-        public long pk3;
-
-        public Oid() {
-        }
-
-        public Oid(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ",");
-            pk = Integer.parseInt(tok.nextToken());
-            pk2 = Integer.valueOf(tok.nextToken());
-            pk3 = Long.valueOf(tok.nextToken());
-        }
-
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof Oid))
-                return false;
-            Oid other = (Oid) o;
-            if (pk != other.pk)
-                return false;
-            if (pk3 != other.pk3)
-                return false;
-            if (pk2 == null)
-                return other.pk2 == null;
-            return pk2.equals(other.pk2);
-        }
-
-        public int hashCode() {
-            return pk + (pk2 == null ? 0 : pk2.hashCode())
-                + (int) (pk3 % Integer.MAX_VALUE);
-        }
-
-        public String toString() {
-            return pk + "," + pk2 + "," + pk3;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+@Entity
+// non-psql/ora dbs cause issues with SequenceGenerator in auto-mapping
+//@SequenceGenerator(name="seq", sequenceName="ejb_sequence")
+@TableGenerator(name = "tab")
+@IdClass(Generator.Oid.class)
+public class Generator {
+
+    @Id
+    protected int pk;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab")
+    protected Integer pk2;
+
+    @Id
+    @GeneratedValue
+    protected long pk3;
+
+    @Basic
+    protected String stringField;
+
+    // for non-seq
+    public void setPk(int pk) {
+        this.pk = pk;
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public Integer getPk2() {
+        return pk2;
+    }
+
+    public long getPk3() {
+        return pk3;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public static class Oid {
+
+        public int pk;
+        public Integer pk2;
+        public long pk3;
+
+        public Oid() {
+        }
+
+        public Oid(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ",");
+            pk = Integer.parseInt(tok.nextToken());
+            pk2 = Integer.valueOf(tok.nextToken());
+            pk3 = Long.valueOf(tok.nextToken());
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof Oid))
+                return false;
+            Oid other = (Oid) o;
+            if (pk != other.pk)
+                return false;
+            if (pk3 != other.pk3)
+                return false;
+            if (pk2 == null)
+                return other.pk2 == null;
+            return pk2.equals(other.pk2);
+        }
+
+        public int hashCode() {
+            return pk + (pk2 == null ? 0 : pk2.hashCode())
+                + (int) (pk3 % Integer.MAX_VALUE);
+        }
+
+        public String toString() {
+            return pk + "," + pk2 + "," + pk3;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java
index 33a3188..aa24357 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java
@@ -1,148 +1,148 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.jdbc.meta.strats.*;
-import org.apache.openjpa.persistence.*;
-import org.apache.openjpa.persistence.jdbc.*;
-
-
-@Entity
-@Table(name = "NONSTD_ENTITY")
-@DataStoreIdColumn(name = "OID")
-@DiscriminatorStrategy(ClassNameDiscriminatorStrategy.ALIAS)
-@DiscriminatorColumn(name = "DISCRIM", length = 128)
-@XMappingOverride(name = "superCollection",
-    containerTable = @ContainerTable(name = "SUP_COLL",
-        joinColumns = @XJoinColumn(name = "OWNER")),
-    elementColumns = @ElementColumn(name = "SUP_ELEM"))
-public class NonstandardMappingEntity
-    extends NonstandardMappingMappedSuper {
-
-    @Persistent(fetch = FetchType.LAZY)
-    @Strategy("org.apache.openjpa.persistence.jdbc.annotations.PointHandler")
-    @Columns({
-    @Column(name = "X_COL"),
-    @Column(name = "Y_COL")
-        })
-    @Index(name = "PNT_IDX")
-    private Point custom;
-
-    @PersistentCollection(elementType = String.class)
-    @ContainerTable(name = "STRINGS_COLL",
-        joinColumns = @XJoinColumn(name = "OWNER"),
-        joinIndex = @Index(enabled = false))
-    @ElementColumn(name = "STR_ELEM", length = 127)
-    @OrderColumn(name = "ORDER_COL")
-    @ElementIndex
-    private List stringCollection = new ArrayList();
-
-    @PersistentCollection
-    @ContainerTable(name = "JOIN_COLL",
-        joinColumns = @XJoinColumn(name = "OWNER"),
-        joinForeignKey = @ForeignKey)
-    @ElementJoinColumn(name = "JOIN_ELEM")
-    @ElementForeignKey
-    @ElementNonpolymorphic(NonpolymorphicType.JOINABLE)
-    private List<NonstandardMappingEntity> joinCollection =
-        new ArrayList<NonstandardMappingEntity>();
-
-    @PersistentMap(keyType = String.class, elementType = String.class)
-    @ContainerTable(name = "STRINGS_MAP",
-        joinColumns = @XJoinColumn(name = "OWNER"),
-        joinIndex = @Index(enabled = false))
-    @KeyColumn(name = "STR_KEY", length = 127)
-    @ElementColumn(name = "STR_VAL", length = 127)
-    @KeyIndex
-    @ElementIndex
-    private Map stringMap = new HashMap();
-
-    @PersistentMap
-    @ContainerTable(name = "JOIN_MAP",
-        joinColumns = @XJoinColumn(name = "OWNER"),
-        joinForeignKey = @ForeignKey)
-    @KeyJoinColumn(name = "JOIN_KEY")
-    @KeyForeignKey
-    @KeyNonpolymorphic
-    @ElementJoinColumn(name = "JOIN_VAL")
-    @ElementForeignKey
-    @ElementNonpolymorphic
-    private Map<NonstandardMappingEntity, NonstandardMappingEntity> joinMap =
-        new HashMap<NonstandardMappingEntity, NonstandardMappingEntity>();
-
-    @Embedded
-    @EmbeddedMapping(nullIndicatorAttributeName = "uuid", overrides = {
-    @MappingOverride(name = "rel",
-        joinColumns = @XJoinColumn(name = "EM_REL_ID")),
-    @MappingOverride(name = "eager",
-        containerTable = @ContainerTable(name = "EM_EAGER"),
-        elementJoinColumns = @ElementJoinColumn(name = "ELEM_EAGER_ID"))
-        })
-    private ExtensionsEntity embed;
-
-    @PersistentCollection(elementEmbedded = true)
-    @ContainerTable(name = "EMBED_COLL")
-    @ElementEmbeddedMapping(overrides = {
-    @XMappingOverride(name = "basic", columns = @Column(name = "EM_BASIC"))
-        })
-    private List<EmbedValue2> embedCollection = new ArrayList<EmbedValue2>();
-
-    public Point getCustom() {
-        return this.custom;
-    }
-
-    public void setCustom(Point custom) {
-        this.custom = custom;
-    }
-
-    public List getStringCollection() {
-        return this.stringCollection;
-    }
-
-    public List<NonstandardMappingEntity> getJoinCollection() {
-        return this.joinCollection;
-    }
-
-    public Map getStringMap() {
-        return this.stringMap;
-    }
-
-    public Map<NonstandardMappingEntity,NonstandardMappingEntity> getJoinMap() {
-        return this.joinMap;
-    }
-
-    public ExtensionsEntity getEmbed() {
-        return this.embed;
-    }
-
-    public void setEmbed(ExtensionsEntity embed) {
-        this.embed = embed;
-    }
-
-    public List<EmbedValue2> getEmbedCollection() {
-        return this.embedCollection;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+
+@Entity
+@Table(name = "NONSTD_ENTITY")
+@DataStoreIdColumn(name = "OID")
+@DiscriminatorStrategy(ClassNameDiscriminatorStrategy.ALIAS)
+@DiscriminatorColumn(name = "DISCRIM", length = 128)
+@XMappingOverride(name = "superCollection",
+    containerTable = @ContainerTable(name = "SUP_COLL",
+        joinColumns = @XJoinColumn(name = "OWNER")),
+    elementColumns = @ElementColumn(name = "SUP_ELEM"))
+public class NonstandardMappingEntity
+    extends NonstandardMappingMappedSuper {
+
+    @Persistent(fetch = FetchType.LAZY)
+    @Strategy("org.apache.openjpa.persistence.jdbc.annotations.PointHandler")
+    @Columns({
+    @Column(name = "X_COL"),
+    @Column(name = "Y_COL")
+        })
+    @Index(name = "PNT_IDX")
+    private Point custom;
+
+    @PersistentCollection(elementType = String.class)
+    @ContainerTable(name = "STRINGS_COLL",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinIndex = @Index(enabled = false))
+    @ElementColumn(name = "STR_ELEM", length = 127)
+    @OrderColumn(name = "ORDER_COL")
+    @ElementIndex
+    private List stringCollection = new ArrayList();
+
+    @PersistentCollection
+    @ContainerTable(name = "JOIN_COLL",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinForeignKey = @ForeignKey)
+    @ElementJoinColumn(name = "JOIN_ELEM")
+    @ElementForeignKey
+    @ElementNonpolymorphic(NonpolymorphicType.JOINABLE)
+    private List<NonstandardMappingEntity> joinCollection =
+        new ArrayList<NonstandardMappingEntity>();
+
+    @PersistentMap(keyType = String.class, elementType = String.class)
+    @ContainerTable(name = "STRINGS_MAP",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinIndex = @Index(enabled = false))
+    @KeyColumn(name = "STR_KEY", length = 127)
+    @ElementColumn(name = "STR_VAL", length = 127)
+    @KeyIndex
+    @ElementIndex
+    private Map stringMap = new HashMap();
+
+    @PersistentMap
+    @ContainerTable(name = "JOIN_MAP",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinForeignKey = @ForeignKey)
+    @KeyJoinColumn(name = "JOIN_KEY")
+    @KeyForeignKey
+    @KeyNonpolymorphic
+    @ElementJoinColumn(name = "JOIN_VAL")
+    @ElementForeignKey
+    @ElementNonpolymorphic
+    private Map<NonstandardMappingEntity, NonstandardMappingEntity> joinMap =
+        new HashMap<NonstandardMappingEntity, NonstandardMappingEntity>();
+
+    @Embedded
+    @EmbeddedMapping(nullIndicatorAttributeName = "uuid", overrides = {
+    @MappingOverride(name = "rel",
+        joinColumns = @XJoinColumn(name = "EM_REL_ID")),
+    @MappingOverride(name = "eager",
+        containerTable = @ContainerTable(name = "EM_EAGER"),
+        elementJoinColumns = @ElementJoinColumn(name = "ELEM_EAGER_ID"))
+        })
+    private ExtensionsEntity embed;
+
+    @PersistentCollection(elementEmbedded = true)
+    @ContainerTable(name = "EMBED_COLL")
+    @ElementEmbeddedMapping(overrides = {
+    @XMappingOverride(name = "basic", columns = @Column(name = "EM_BASIC"))
+        })
+    private List<EmbedValue2> embedCollection = new ArrayList<EmbedValue2>();
+
+    public Point getCustom() {
+        return this.custom;
+    }
+
+    public void setCustom(Point custom) {
+        this.custom = custom;
+    }
+
+    public List getStringCollection() {
+        return this.stringCollection;
+    }
+
+    public List<NonstandardMappingEntity> getJoinCollection() {
+        return this.joinCollection;
+    }
+
+    public Map getStringMap() {
+        return this.stringMap;
+    }
+
+    public Map<NonstandardMappingEntity,NonstandardMappingEntity> getJoinMap() {
+        return this.joinMap;
+    }
+
+    public ExtensionsEntity getEmbed() {
+        return this.embed;
+    }
+
+    public void setEmbed(ExtensionsEntity embed) {
+        this.embed = embed;
+    }
+
+    public List<EmbedValue2> getEmbedCollection() {
+        return this.embedCollection;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java
index 8cb3508..27a59b0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.*;
-import org.apache.openjpa.persistence.jdbc.*;
-
-@MappedSuperclass
-public class NonstandardMappingMappedSuper {
-
-    @PersistentCollection
-    private List<String> superCollection = new ArrayList<String>();
-
-    @ManyToOne
-    @Nonpolymorphic
-    NonstandardMappingEntity superRel;
-
-    public List<String> getSuperCollection() {
-        return this.superCollection;
-    }
-
-    public NonstandardMappingEntity getSuperRel() {
-        return this.superRel;
-    }
-
-    public void setSuperRel(NonstandardMappingEntity superRel) {
-        this.superRel = superRel;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+@MappedSuperclass
+public class NonstandardMappingMappedSuper {
+
+    @PersistentCollection
+    private List<String> superCollection = new ArrayList<String>();
+
+    @ManyToOne
+    @Nonpolymorphic
+    NonstandardMappingEntity superRel;
+
+    public List<String> getSuperCollection() {
+        return this.superCollection;
+    }
+
+    public NonstandardMappingEntity getSuperRel() {
+        return this.superRel;
+    }
+
+    public void setSuperRel(NonstandardMappingEntity superRel) {
+        this.superRel = superRel;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java
index ea7e2e3..bc2ace9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java
@@ -1,89 +1,89 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.awt.*;
-
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.meta.ValueMapping;
-import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.ColumnIO;
-import org.apache.openjpa.meta.JavaTypes;
-import serp.util.Numbers;
-
-/**
- * Handler for {@link Point}. This is a sample of how to create custom
- * handlers, and is in this package for unit testing purposes.
- */
-public class PointHandler extends AbstractValueHandler {
-
-    /**
-     * Create columns with default names and java type values.  Kodo will
-     * fill in the rest of the information and merge in any information given
-     * in the user's mapping data.  If the user does not give column names,
-     * Kodo will alter your default names as necessary to avoid conflicts and
-     * meet the database's name limitations.
-     *
-     * @param    name    default base name for columns
-     */
-    public Column[] map(ValueMapping vm, String name, ColumnIO io,
-        boolean adapt) {
-        Column xcol = new Column();
-        xcol.setName("X" + name);
-        xcol.setJavaType(JavaTypes.INT);
-        Column ycol = new Column();
-        ycol.setName("Y" + name);
-        ycol.setJavaType(JavaTypes.INT);
-        return new Column[]{ xcol, ycol };
-    }
-
-    /**
-     * Return whether the column value is an exact value that can be used
-     * in state-comparison versioning.
-     */
-    public boolean isVersionable() {
-        return true;
-    }
-
-    /**
-     * Convert the object value to its datastore equivalent.
-     */
-    public Object toDataStoreValue(ValueMapping vm, Object val,
-        JDBCStore store) {
-        if (val == null)
-            return null;
-
-        Point p = (Point) val;
-        return new Object[]{ Numbers.valueOf(p.x), Numbers.valueOf(p.y) };
-    }
-
-    /**
-     *  Convert the datastore value to its object equivalent.
-     */
-    public Object toObjectValue(ValueMapping vm, Object val) {
-        Object[] vals = (Object[]) val;
-        if (vals[0] == null || vals[1] == null)
-            return null;
-
-        int x = ((Number) vals[0]).intValue();
-        int y = ((Number) vals[1]).intValue();
-        return new Point(x, y);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.awt.*;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.meta.JavaTypes;
+import serp.util.Numbers;
+
+/**
+ * Handler for {@link Point}. This is a sample of how to create custom
+ * handlers, and is in this package for unit testing purposes.
+ */
+public class PointHandler extends AbstractValueHandler {
+
+    /**
+     * Create columns with default names and java type values.  Kodo will
+     * fill in the rest of the information and merge in any information given
+     * in the user's mapping data.  If the user does not give column names,
+     * Kodo will alter your default names as necessary to avoid conflicts and
+     * meet the database's name limitations.
+     *
+     * @param    name    default base name for columns
+     */
+    public Column[] map(ValueMapping vm, String name, ColumnIO io,
+        boolean adapt) {
+        Column xcol = new Column();
+        xcol.setName("X" + name);
+        xcol.setJavaType(JavaTypes.INT);
+        Column ycol = new Column();
+        ycol.setName("Y" + name);
+        ycol.setJavaType(JavaTypes.INT);
+        return new Column[]{ xcol, ycol };
+    }
+
+    /**
+     * Return whether the column value is an exact value that can be used
+     * in state-comparison versioning.
+     */
+    public boolean isVersionable() {
+        return true;
+    }
+
+    /**
+     * Convert the object value to its datastore equivalent.
+     */
+    public Object toDataStoreValue(ValueMapping vm, Object val,
+        JDBCStore store) {
+        if (val == null)
+            return null;
+
+        Point p = (Point) val;
+        return new Object[]{ Numbers.valueOf(p.x), Numbers.valueOf(p.y) };
+    }
+
+    /**
+     *  Convert the datastore value to its object equivalent.
+     */
+    public Object toObjectValue(ValueMapping vm, Object val) {
+        Object[] vals = (Object[]) val;
+        if (vals[0] == null || vals[1] == null)
+            return null;
+
+        int x = ((Number) vals[0]).intValue();
+        int y = ((Number) vals[1]).intValue();
+        return new Point(x, y);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PropertyAccess1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PropertyAccess1.java
index 9dbf366..83b79c6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PropertyAccess1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PropertyAccess1.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-/**
- * Entity test object that uses property access mode.
- */
-@Entity
-public class PropertyAccess1 {
-
-    private int id;
-    private String name;
-    private int intVal; // this intentionally does not match the getter name
-
-    protected PropertyAccess1() {
-    }
-
-    public PropertyAccess1(int id) {
-        this.id = id;
-    }
-
-    @Id
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String n) {
-        this.name = n;
-    }
-
-    public int getIntValue() {
-        return intVal;
-    }
-
-    public void setIntValue(int intVal) {
-        this.intVal = intVal;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+/**
+ * Entity test object that uses property access mode.
+ */
+@Entity
+public class PropertyAccess1 {
+
+    private int id;
+    private String name;
+    private int intVal; // this intentionally does not match the getter name
+
+    protected PropertyAccess1() {
+    }
+
+    public PropertyAccess1(int id) {
+        this.id = id;
+    }
+
+    @Id
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String n) {
+        this.name = n;
+    }
+
+    public int getIntValue() {
+        return intVal;
+    }
+
+    public void setIntValue(int intVal) {
+        this.intVal = intVal;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass1.java
index d93ce3a..d85eb3d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass1.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity
-@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
-public class TablePerClass1 {
-
-    @Id
-    @GeneratedValue
-    protected int pk;
-
-    @Column(name = "TPC_BASIC")
-    protected int basic;
-
-    @Embedded
-    @AttributeOverrides({
-    @AttributeOverride(name = "basic",
-        column = @Column(name = "TPC_EMB_BASIC")),
-    @AttributeOverride(name = "clob", column = @Column(name = "TPC_EMB_CLOB")),
-    @AttributeOverride(name = "blob", column = @Column(name = "TPC_EMB_BLOB"))
-        })
-    protected EmbedValue embed;
-
-    public int getPk() {
-        return pk;
-    }
-
-    public void setBasic(int i) {
-        basic = i;
-    }
-
-    public int getBasic() {
-        return basic;
-    }
-
-    public EmbedValue getEmbed() {
-        return embed;
-    }
-
-    public void setEmbed(EmbedValue ev) {
-        embed = ev;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class TablePerClass1 {
+
+    @Id
+    @GeneratedValue
+    protected int pk;
+
+    @Column(name = "TPC_BASIC")
+    protected int basic;
+
+    @Embedded
+    @AttributeOverrides({
+    @AttributeOverride(name = "basic",
+        column = @Column(name = "TPC_EMB_BASIC")),
+    @AttributeOverride(name = "clob", column = @Column(name = "TPC_EMB_CLOB")),
+    @AttributeOverride(name = "blob", column = @Column(name = "TPC_EMB_BLOB"))
+        })
+    protected EmbedValue embed;
+
+    public int getPk() {
+        return pk;
+    }
+
+    public void setBasic(int i) {
+        basic = i;
+    }
+
+    public int getBasic() {
+        return basic;
+    }
+
+    public EmbedValue getEmbed() {
+        return embed;
+    }
+
+    public void setEmbed(EmbedValue ev) {
+        embed = ev;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass2.java
index cca9d7d7..96e259d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TablePerClass2.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-
-import javax.persistence.*;
-
-@Entity
-public class TablePerClass2
-    extends TablePerClass1 {
-
-    @Basic
-    protected String basic2;
-
-    public void setBasic2(String s) {
-        basic2 = s;
-    }
-
-    public String getBasic2() {
-        return basic2;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+
+import javax.persistence.*;
+
+@Entity
+public class TablePerClass2
+    extends TablePerClass1 {
+
+    @Basic
+    protected String basic2;
+
+    public void setBasic2(String s) {
+        basic2 = s;
+    }
+
+    public String getBasic2() {
+        return basic2;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java
index 72dafb2..5986408 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java
@@ -1,82 +1,82 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
-import org.apache.openjpa.jdbc.meta.strats.SubclassJoinDiscriminatorStrategy;
-import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
-import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test discriminator mappings.</p>
- *
- * @author Abe White
- */
-public class TestDiscriminator
-    extends SingleEMFTestCase {
-
-    public void setUp() throws Exception {
-        super.setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class,
-            CLEAR_TABLES);
-        // Commented out since OpenJPA does not have Entity1 and Entity2.
-        // These tests should be ported to use classes that are available
-        // in OpenJPA.
-//        setUp(Entity1.class, Entity2.class, AnnoTest1.class, CLEAR_TABLES);
-    }
-
-//    public void testNoDefaultJoinedDiscriminatorWithoutColumn() {
-//        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-//        ClassMapping cls = conf.getMappingRepositoryInstance().
-//            getMapping(Entity1.class, null, true);
-//        if (conf.getDBDictionaryInstance().joinSyntax
-//            != JoinSyntaxes.SYNTAX_TRADITIONAL) {
-//            assertTrue(cls.getDiscriminator().getStrategy()
-//                instanceof SubclassJoinDiscriminatorStrategy);
-//        } else {
-//            assertEquals(NoneDiscriminatorStrategy.getInstance(),
-//                cls.getDiscriminator().getStrategy());
-//        }
-//        assertEquals(0, cls.getDiscriminator().getColumns().length);
-//    }
-
-    public void testJoinedDiscriminatorWithColumn() {
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        MappingRepository repo = conf.getMappingRepositoryInstance();
-        ClassMapping cls = repo.getMapping(AnnoTest1.class, 
-            null, true);
-        assertTrue(cls.getDiscriminator().getStrategy()
-            instanceof ValueMapDiscriminatorStrategy);
-        assertEquals(1, cls.getDiscriminator().getColumns().length);
-        assertEquals("ANNOCLS", cls.getDiscriminator().getColumns()[0].
-            getName());
-    }
-
-//    public void testDefaultFlatDiscriminator() {
-//        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
-//            getMappingRepositoryInstance().getMapping(Entity2.class,
-//            null, true);
-//        assertTrue(cls.getDiscriminator().getStrategy()
-//            instanceof ValueMapDiscriminatorStrategy);
-//        assertEquals(1, cls.getDiscriminator().getColumns().length);
-//    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.MappingRepository;
+import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.meta.strats.SubclassJoinDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test discriminator mappings.</p>
+ *
+ * @author Abe White
+ */
+public class TestDiscriminator
+    extends SingleEMFTestCase {
+
+    public void setUp() throws Exception {
+        super.setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class,
+            CLEAR_TABLES);
+        // Commented out since OpenJPA does not have Entity1 and Entity2.
+        // These tests should be ported to use classes that are available
+        // in OpenJPA.
+//        setUp(Entity1.class, Entity2.class, AnnoTest1.class, CLEAR_TABLES);
+    }
+
+//    public void testNoDefaultJoinedDiscriminatorWithoutColumn() {
+//        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+//        ClassMapping cls = conf.getMappingRepositoryInstance().
+//            getMapping(Entity1.class, null, true);
+//        if (conf.getDBDictionaryInstance().joinSyntax
+//            != JoinSyntaxes.SYNTAX_TRADITIONAL) {
+//            assertTrue(cls.getDiscriminator().getStrategy()
+//                instanceof SubclassJoinDiscriminatorStrategy);
+//        } else {
+//            assertEquals(NoneDiscriminatorStrategy.getInstance(),
+//                cls.getDiscriminator().getStrategy());
+//        }
+//        assertEquals(0, cls.getDiscriminator().getColumns().length);
+//    }
+
+    public void testJoinedDiscriminatorWithColumn() {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        MappingRepository repo = conf.getMappingRepositoryInstance();
+        ClassMapping cls = repo.getMapping(AnnoTest1.class, 
+            null, true);
+        assertTrue(cls.getDiscriminator().getStrategy()
+            instanceof ValueMapDiscriminatorStrategy);
+        assertEquals(1, cls.getDiscriminator().getColumns().length);
+        assertEquals("ANNOCLS", cls.getDiscriminator().getColumns()[0].
+            getName());
+    }
+
+//    public void testDefaultFlatDiscriminator() {
+//        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
+//            getMappingRepositoryInstance().getMapping(Entity2.class,
+//            null, true);
+//        assertTrue(cls.getDiscriminator().getStrategy()
+//            instanceof ValueMapDiscriminatorStrategy);
+//        assertEquals(1, cls.getDiscriminator().getColumns().length);
+//    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java
index 8e66402..9288fd9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEJBEmbedded.java
@@ -1,139 +1,139 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.sql.Types;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
-import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
-import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-
-/**
- * Test for embedded
- *
- * @author Steve Kim
- */
-public class TestEJBEmbedded extends SingleEMFTestCase {
-
-    private static final String CLOB;
-
-    static {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < 1000; i++)
-            buf.append('a');
-        CLOB = buf.toString();
-    }
-
-    public void setUp() {
-        setUp(EmbedOwner.class, EmbedValue.class, CLEAR_TABLES);
-    }
-
-    public void testEmbedded() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        EmbedOwner owner = new EmbedOwner();
-        owner.setBasic("foo");
-        EmbedValue embed = new EmbedValue();
-        embed.setClob(CLOB);
-        embed.setBasic("bar");
-        embed.setBlob("foobar".getBytes());
-        embed.setOwner(owner);
-        owner.setEmbed(embed);
-        em.persist(owner);
-        int pk = owner.getPk();
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        owner = em.find(EmbedOwner.class, pk);
-        assertEquals("foo", owner.getBasic());
-        embed = owner.getEmbed();
-        assertNotNull(embed);
-        assertEquals(CLOB, embed.getClob());
-        assertEquals("bar", embed.getBasic());
-        assertEquals("foobar", new String(embed.getBlob()));
-        assertEquals(owner, embed.getOwner());
-        em.close();
-    }
-
-    public void testEmbeddedMetaData() {
-        ClassMetaData ownerMeta =
-            JPAFacadeHelper.getMetaData(emf, EmbedOwner.class);
-        FieldMetaData fmd = ownerMeta.getField("embed");
-        ClassMetaData embeddedMeta = fmd.getDefiningMetaData();
-        assertNotNull(embeddedMeta);
-        assertNull(embeddedMeta.getField("transientField"));
-    }
-
-    public void testNull() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        EmbedOwner owner = new EmbedOwner();
-        owner.setBasic("foo");
-        em.persist(owner);
-        int pk = owner.getPk();
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        owner = em.find(EmbedOwner.class, pk);
-        assertEquals("foo", owner.getBasic());
-        EmbedValue embed = owner.getEmbed();
-        assertNotNull(embed);
-        assertNull(embed.getClob());
-        assertNull(embed.getBasic());
-        assertNull(embed.getBlob());
-        em.close();
-    }
-
-    public void testMappingTransferAndOverride() {
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().getMapping
-            (EmbedOwner.class, null, true);
-        assertEquals("OWN_BASIC", cls.getFieldMapping("basic").
-            getColumns()[0].getName());
-        ClassMapping embed = cls.getFieldMapping("embed").getEmbeddedMapping();
-        assertEquals("EMB_BLOB", embed.getFieldMapping("blob").
-            getColumns()[0].getName());
-        assertEquals("OVER_BASIC", embed.getFieldMapping("basic").
-            getColumns()[0].getName());
-        assertEquals("OVER_OWNER", embed.getFieldMapping("owner").
-            getColumns()[0].getName());
-
-        FieldMapping fm = embed.getFieldMapping("clob");
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
-            if (dict.maxEmbeddedClobSize > 0)
-                assertTrue(fm.getStrategy() instanceof
-                    MaxEmbeddedClobFieldStrategy);
-            else
-                assertTrue(fm.getHandler() instanceof ClobValueHandler);
-        } else
-            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.sql.Types;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
+import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
+import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+
+/**
+ * Test for embedded
+ *
+ * @author Steve Kim
+ */
+public class TestEJBEmbedded extends SingleEMFTestCase {
+
+    private static final String CLOB;
+
+    static {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < 1000; i++)
+            buf.append('a');
+        CLOB = buf.toString();
+    }
+
+    public void setUp() {
+        setUp(EmbedOwner.class, EmbedValue.class, CLEAR_TABLES);
+    }
+
+    public void testEmbedded() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        EmbedOwner owner = new EmbedOwner();
+        owner.setBasic("foo");
+        EmbedValue embed = new EmbedValue();
+        embed.setClob(CLOB);
+        embed.setBasic("bar");
+        embed.setBlob("foobar".getBytes());
+        embed.setOwner(owner);
+        owner.setEmbed(embed);
+        em.persist(owner);
+        int pk = owner.getPk();
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        owner = em.find(EmbedOwner.class, pk);
+        assertEquals("foo", owner.getBasic());
+        embed = owner.getEmbed();
+        assertNotNull(embed);
+        assertEquals(CLOB, embed.getClob());
+        assertEquals("bar", embed.getBasic());
+        assertEquals("foobar", new String(embed.getBlob()));
+        assertEquals(owner, embed.getOwner());
+        em.close();
+    }
+
+    public void testEmbeddedMetaData() {
+        ClassMetaData ownerMeta =
+            JPAFacadeHelper.getMetaData(emf, EmbedOwner.class);
+        FieldMetaData fmd = ownerMeta.getField("embed");
+        ClassMetaData embeddedMeta = fmd.getDefiningMetaData();
+        assertNotNull(embeddedMeta);
+        assertNull(embeddedMeta.getField("transientField"));
+    }
+
+    public void testNull() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        EmbedOwner owner = new EmbedOwner();
+        owner.setBasic("foo");
+        em.persist(owner);
+        int pk = owner.getPk();
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        owner = em.find(EmbedOwner.class, pk);
+        assertEquals("foo", owner.getBasic());
+        EmbedValue embed = owner.getEmbed();
+        assertNotNull(embed);
+        assertNull(embed.getClob());
+        assertNull(embed.getBasic());
+        assertNull(embed.getBlob());
+        em.close();
+    }
+
+    public void testMappingTransferAndOverride() {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().getMapping
+            (EmbedOwner.class, null, true);
+        assertEquals("OWN_BASIC", cls.getFieldMapping("basic").
+            getColumns()[0].getName());
+        ClassMapping embed = cls.getFieldMapping("embed").getEmbeddedMapping();
+        assertEquals("EMB_BLOB", embed.getFieldMapping("blob").
+            getColumns()[0].getName());
+        assertEquals("OVER_BASIC", embed.getFieldMapping("basic").
+            getColumns()[0].getName());
+        assertEquals("OVER_OWNER", embed.getFieldMapping("owner").
+            getColumns()[0].getName());
+
+        FieldMapping fm = embed.getFieldMapping("clob");
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
+            if (dict.maxEmbeddedClobSize > 0)
+                assertTrue(fm.getStrategy() instanceof
+                    MaxEmbeddedClobFieldStrategy);
+            else
+                assertTrue(fm.getHandler() instanceof ClobValueHandler);
+        } else
+            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddableSuperclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddableSuperclass.java
index 1f3adc1..3c31767 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddableSuperclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddableSuperclass.java
@@ -1,136 +1,136 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.sql.Types;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
-import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
-import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
-import org.apache.openjpa.jdbc.meta.strats.NoneClassStrategy;
-import org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy;
-import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.meta.ValueStrategies;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test embeddable superclasses.</p>
- *
- * @author Abe White
- */
-public class TestEmbeddableSuperclass
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(EmbeddableSuper.class, EmbeddableSuperSub.class, CLEAR_TABLES);
-    }
-
-    public void testSuperclassEmbeddedOnly() {
-        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
-            getMappingRepositoryInstance().getMapping(EmbeddableSuper.class, 
-            null, true);
-        assertTrue(cls.isEmbeddedOnly());
-        assertEquals(NoneClassStrategy.getInstance(), cls.getStrategy());
-    }
-
-    public void testSubclassMappingDefaultsAndOverrides() {
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        assertTrue(!cls.isEmbeddedOnly());
-        assertTrue(cls.getStrategy() instanceof FullClassStrategy);
-        assertEquals(ClassMapping.ID_APPLICATION, cls.getIdentityType());
-        assertTrue(cls.isOpenJPAIdentity());
-
-        FieldMapping fm = cls.getFieldMapping("pk");
-        assertTrue(fm.isPrimaryKey());
-        assertEquals(ValueStrategies.SEQUENCE, fm.getValueStrategy());
-        assertEquals("ID", fm.getColumns()[0].getName());
-
-        assertNull(cls.getField("trans"));
-
-        fm = cls.getFieldMapping("clob");
-        assertEquals("CC", fm.getColumns()[0].getName());
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
-            if (dict.maxEmbeddedClobSize > 0)
-                assertTrue(fm.getStrategy() instanceof
-                    MaxEmbeddedClobFieldStrategy);
-            else
-                assertTrue(fm.getHandler() instanceof ClobValueHandler);
-        } else
-            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
-    }
-
-    public void testSubclassDiscriminatorMapping() {
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        assertEquals("DISC", cls.getDiscriminator().getColumns()[0].
-            getName());
-    }
-
-    public void testVersionOverrideMapping() {
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        assertEquals("VERSVAL", cls.getVersion().getColumns()[0].getName());
-    }
-
-    public void testRelationMappings() {
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        ClassMapping cls = conf.getMappingRepositoryInstance().
-            getMapping(EmbeddableSuperSub.class, null, true);
-        FieldMapping fm = cls.getFieldMapping("sub");
-        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
-
-        fm = cls.getFieldMapping("sup");
-        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
-    }
-
-    public void testPersistAndFind() {
-        EmbeddableSuperSub parent = new EmbeddableSuperSub();
-        parent.setClob("parent");
-        EmbeddableSuperSub sub = new EmbeddableSuperSub();
-        sub.setClob("sub");
-        EmbeddableSuperSub sup = new EmbeddableSuperSub();
-        sup.setClob("sup");
-        parent.setSub(sub);
-        parent.setSup(sup);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persistAll(parent, sub, sup);
-        em.getTransaction().commit();
-        long pk = parent.getPK();
-        em.close();
-
-        em = emf.createEntityManager();
-        parent = em.find(EmbeddableSuperSub.class, pk);
-        assertEquals("parent", parent.getClob());
-        assertEquals("sub", parent.getSub().getClob());
-        assertEquals("sup", parent.getSup().getClob());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.sql.Types;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
+import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
+import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
+import org.apache.openjpa.jdbc.meta.strats.NoneClassStrategy;
+import org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy;
+import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test embeddable superclasses.</p>
+ *
+ * @author Abe White
+ */
+public class TestEmbeddableSuperclass
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(EmbeddableSuper.class, EmbeddableSuperSub.class, CLEAR_TABLES);
+    }
+
+    public void testSuperclassEmbeddedOnly() {
+        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
+            getMappingRepositoryInstance().getMapping(EmbeddableSuper.class, 
+            null, true);
+        assertTrue(cls.isEmbeddedOnly());
+        assertEquals(NoneClassStrategy.getInstance(), cls.getStrategy());
+    }
+
+    public void testSubclassMappingDefaultsAndOverrides() {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        assertTrue(!cls.isEmbeddedOnly());
+        assertTrue(cls.getStrategy() instanceof FullClassStrategy);
+        assertEquals(ClassMapping.ID_APPLICATION, cls.getIdentityType());
+        assertTrue(cls.isOpenJPAIdentity());
+
+        FieldMapping fm = cls.getFieldMapping("pk");
+        assertTrue(fm.isPrimaryKey());
+        assertEquals(ValueStrategies.SEQUENCE, fm.getValueStrategy());
+        assertEquals("ID", fm.getColumns()[0].getName());
+
+        assertNull(cls.getField("trans"));
+
+        fm = cls.getFieldMapping("clob");
+        assertEquals("CC", fm.getColumns()[0].getName());
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        if (dict.getPreferredType(Types.CLOB) == Types.CLOB) {
+            if (dict.maxEmbeddedClobSize > 0)
+                assertTrue(fm.getStrategy() instanceof
+                    MaxEmbeddedClobFieldStrategy);
+            else
+                assertTrue(fm.getHandler() instanceof ClobValueHandler);
+        } else
+            assertTrue(fm.getStrategy() instanceof StringFieldStrategy);
+    }
+
+    public void testSubclassDiscriminatorMapping() {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        assertEquals("DISC", cls.getDiscriminator().getColumns()[0].
+            getName());
+    }
+
+    public void testVersionOverrideMapping() {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        assertEquals("VERSVAL", cls.getVersion().getColumns()[0].getName());
+    }
+
+    public void testRelationMappings() {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        ClassMapping cls = conf.getMappingRepositoryInstance().
+            getMapping(EmbeddableSuperSub.class, null, true);
+        FieldMapping fm = cls.getFieldMapping("sub");
+        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
+
+        fm = cls.getFieldMapping("sup");
+        assertTrue(fm.getStrategy() instanceof RelationFieldStrategy);
+    }
+
+    public void testPersistAndFind() {
+        EmbeddableSuperSub parent = new EmbeddableSuperSub();
+        parent.setClob("parent");
+        EmbeddableSuperSub sub = new EmbeddableSuperSub();
+        sub.setClob("sub");
+        EmbeddableSuperSub sup = new EmbeddableSuperSub();
+        sup.setClob("sup");
+        parent.setSub(sub);
+        parent.setSup(sup);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persistAll(parent, sub, sup);
+        em.getTransaction().commit();
+        long pk = parent.getPK();
+        em.close();
+
+        em = emf.createEntityManager();
+        parent = em.find(EmbeddableSuperSub.class, pk);
+        assertEquals("parent", parent.getClob());
+        assertEquals("sub", parent.getSub().getClob());
+        assertEquals("sup", parent.getSup().getClob());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddedId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddedId.java
index 333b835..6eb8fc6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddedId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEmbeddedId.java
@@ -1,244 +1,244 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.Query;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test embedded id classes.</p>
- *
- * @author Abe White
- */
-public class TestEmbeddedId
-    extends SingleEMFTestCase {
-
-    EmbeddedIdClass _oid;
-    EmbeddedIdClass _roid;
-
-    public void setUp() {
-        setUp(EmbeddedIdEntity.class, EmbeddedIdClass.class, CLEAR_TABLES);
-
-        _oid = new EmbeddedIdClass();
-        _oid.setPk1(1);
-        _oid.setPk2(2);
-
-        EmbeddedIdEntity e = new EmbeddedIdEntity();
-        e.setId(_oid);
-        e.setValue("e");
-
-        _roid = new EmbeddedIdClass();
-        _roid.setPk1(2);
-        _roid.setPk2(3);
-
-        EmbeddedIdEntity rel = new EmbeddedIdEntity();
-        rel.setId(_roid);
-        rel.setValue("r");
-        e.setRelation(rel);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persistAll(e, rel);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testGetObjectId() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
-        assertNotNull(e);
-        assertEquals("e", e.getValue());
-        assertNull(e.getMappingOverrideRelation());
-        assertNotNull(e.getRelation());
-        assertEquals("r", e.getRelation().getValue());
-
-        assertEquals(_oid, em.getObjectId(e));
-        assertEquals(_roid, em.getObjectId(e.getRelation()));
-        assertEquals(_oid, e.getId());
-        assertEquals(_roid, e.getRelation().getId());
-        assertNull(((PersistenceCapable) e.getId()).pcGetGenericContext());
-        em.close();
-    }
-
-    public void testMutateEmbeddedIdFieldValueOfNew() {
-        EmbeddedIdEntity e1 = new EmbeddedIdEntity();
-        e1.setValue("e1");
-        EmbeddedIdEntity e2 = new EmbeddedIdEntity();
-        e2.setValue("e2");
-        EmbeddedIdClass id = new EmbeddedIdClass();
-        e2.setId(id);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persistAll(e1, e2);
-
-        EmbeddedIdClass oid = new EmbeddedIdClass();
-        oid.setPk1(4);
-        oid.setPk2(5);
-        e1.setId(oid);
-        e2.getId().setPk1(6);
-        e2.getId().setPk2(7);
-        em.getTransaction().commit();
-
-        EmbeddedIdClass oid1 = e1.getId();
-        assertEquals(oid1, em.getObjectId(e1));
-        assertEquals(4, oid1.getPk1());
-        assertEquals(5, oid1.getPk2());
-
-        EmbeddedIdClass oid2 = e2.getId();
-        // pcl: 30 October 2007: this fails currently; commenting out.
-        // See OPENJPA-425
-        //assertEquals(oid2, em.getObjectId(e2));
-        assertEquals(6, oid2.getPk1());
-        assertEquals(7, oid2.getPk2());
-        em.close();
-
-        em = emf.createEntityManager();
-        e1 = em.find(EmbeddedIdEntity.class, oid1);
-        e2 = em.find(EmbeddedIdEntity.class, oid2);
-        assertEquals(oid1, em.getObjectId(e1));
-        assertEquals(oid2, em.getObjectId(e2));
-        assertEquals(oid1, e1.getId());
-        assertEquals(oid2, e2.getId());
-        em.close();
-    }
-
-    public void testMutateEmbeddedIdFieldValueOfExisting() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
-        e.setValue("changed");
-        try {
-            e.getId().setPk1(9);
-            em.getTransaction().commit();
-            fail("Committed with changed oid field.");
-        } catch (RuntimeException re) {
-            if (em.getTransaction().isActive())
-                em.getTransaction().rollback();
-        }
-        em.close();
-    }
-
-    public void testDetachAttach() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
-        e.getRelation();
-        em.close();
-
-        e.setValue("echanged");
-        e.getRelation().setValue("rchanged");
-
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        EmbeddedIdEntity me = (EmbeddedIdEntity) em.mergeAll(e,
-            e.getRelation())[0];
-        assertTrue(me != e);
-        assertNotNull(me.getRelation());
-        assertTrue(me.getRelation() != e.getRelation());
-        assertEquals("echanged", me.getValue());
-        assertEquals("rchanged", me.getRelation().getValue());
-        assertEquals(_oid, me.getId());
-        assertEquals(_oid, em.getObjectId(me));
-        assertEquals(_roid, me.getRelation().getId());
-        assertEquals(_roid, em.getObjectId(me.getRelation()));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testQuery() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        Query q = em.createQuery("select e from EmbeddedIdEntity e "
-            + "where e.id.pk1 = 1");
-        EmbeddedIdEntity e = (EmbeddedIdEntity) q.getSingleResult();
-        assertEquals(_oid, e.getId());
-        assertEquals("e", e.getValue());
-
-        q = em.createQuery("select e.id.pk2 from EmbeddedIdEntity e "
-            + "where e.id.pk1 = 1");
-        assertEquals(new Long(_oid.getPk2()), q.getSingleResult());
-
-        q = em.createQuery("select e.id from EmbeddedIdEntity e "
-            + "where e.id.pk1 = 1");
-        assertEquals(_oid, q.getSingleResult());
-        em.close();
-    }
-
-    public void testAutoAssigned() {
-        // begin with null id object
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        EmbeddedIdEntity e = new EmbeddedIdEntity();
-        em.persist(e);
-        EmbeddedIdClass oid = e.getId();
-        assertNotNull(oid);
-        assertTrue(oid.getPk3() != 0);
-        assertEquals(oid, em.getObjectId(e));
-        em.getTransaction().commit();
-        assertEquals(oid, em.getObjectId(e));
-        em.close();
-
-        em = emf.createEntityManager();
-        e = em.find(EmbeddedIdEntity.class, oid);
-        assertEquals(oid, em.getObjectId(e));
-        em.close();
-
-        // begin with non-null id object
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        e = new EmbeddedIdEntity();
-        oid = new EmbeddedIdClass();
-        oid.setPk1(4);
-        oid.setPk2(5);
-        e.setId(oid);
-        em.persist(e);
-        oid = e.getId();
-        assertEquals(4, oid.getPk1());
-        assertEquals(5, oid.getPk2());
-        assertTrue(oid.getPk3() != 0);
-        assertEquals(oid, em.getObjectId(e));
-        em.getTransaction().commit();
-        assertEquals(oid, em.getObjectId(e));
-        em.close();
-
-        em = emf.createEntityManager();
-        e = em.find(EmbeddedIdEntity.class, oid);
-        assertEquals(oid, em.getObjectId(e));
-        em.close();
-
-        // flush before accessing id field
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        e = new EmbeddedIdEntity();
-        em.persist(e);
-        em.getTransaction().commit();
-        oid = e.getId();
-        assertTrue(oid.getPk3() != 0);
-        assertEquals(oid, em.getObjectId(e));
-        em.close();
-
-        em = emf.createEntityManager();
-        e = em.find(EmbeddedIdEntity.class, oid);
-        assertEquals(oid, em.getObjectId(e));
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test embedded id classes.</p>
+ *
+ * @author Abe White
+ */
+public class TestEmbeddedId
+    extends SingleEMFTestCase {
+
+    EmbeddedIdClass _oid;
+    EmbeddedIdClass _roid;
+
+    public void setUp() {
+        setUp(EmbeddedIdEntity.class, EmbeddedIdClass.class, CLEAR_TABLES);
+
+        _oid = new EmbeddedIdClass();
+        _oid.setPk1(1);
+        _oid.setPk2(2);
+
+        EmbeddedIdEntity e = new EmbeddedIdEntity();
+        e.setId(_oid);
+        e.setValue("e");
+
+        _roid = new EmbeddedIdClass();
+        _roid.setPk1(2);
+        _roid.setPk2(3);
+
+        EmbeddedIdEntity rel = new EmbeddedIdEntity();
+        rel.setId(_roid);
+        rel.setValue("r");
+        e.setRelation(rel);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persistAll(e, rel);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testGetObjectId() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
+        assertNotNull(e);
+        assertEquals("e", e.getValue());
+        assertNull(e.getMappingOverrideRelation());
+        assertNotNull(e.getRelation());
+        assertEquals("r", e.getRelation().getValue());
+
+        assertEquals(_oid, em.getObjectId(e));
+        assertEquals(_roid, em.getObjectId(e.getRelation()));
+        assertEquals(_oid, e.getId());
+        assertEquals(_roid, e.getRelation().getId());
+        assertNull(((PersistenceCapable) e.getId()).pcGetGenericContext());
+        em.close();
+    }
+
+    public void testMutateEmbeddedIdFieldValueOfNew() {
+        EmbeddedIdEntity e1 = new EmbeddedIdEntity();
+        e1.setValue("e1");
+        EmbeddedIdEntity e2 = new EmbeddedIdEntity();
+        e2.setValue("e2");
+        EmbeddedIdClass id = new EmbeddedIdClass();
+        e2.setId(id);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persistAll(e1, e2);
+
+        EmbeddedIdClass oid = new EmbeddedIdClass();
+        oid.setPk1(4);
+        oid.setPk2(5);
+        e1.setId(oid);
+        e2.getId().setPk1(6);
+        e2.getId().setPk2(7);
+        em.getTransaction().commit();
+
+        EmbeddedIdClass oid1 = e1.getId();
+        assertEquals(oid1, em.getObjectId(e1));
+        assertEquals(4, oid1.getPk1());
+        assertEquals(5, oid1.getPk2());
+
+        EmbeddedIdClass oid2 = e2.getId();
+        // pcl: 30 October 2007: this fails currently; commenting out.
+        // See OPENJPA-425
+        //assertEquals(oid2, em.getObjectId(e2));
+        assertEquals(6, oid2.getPk1());
+        assertEquals(7, oid2.getPk2());
+        em.close();
+
+        em = emf.createEntityManager();
+        e1 = em.find(EmbeddedIdEntity.class, oid1);
+        e2 = em.find(EmbeddedIdEntity.class, oid2);
+        assertEquals(oid1, em.getObjectId(e1));
+        assertEquals(oid2, em.getObjectId(e2));
+        assertEquals(oid1, e1.getId());
+        assertEquals(oid2, e2.getId());
+        em.close();
+    }
+
+    public void testMutateEmbeddedIdFieldValueOfExisting() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
+        e.setValue("changed");
+        try {
+            e.getId().setPk1(9);
+            em.getTransaction().commit();
+            fail("Committed with changed oid field.");
+        } catch (RuntimeException re) {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+        }
+        em.close();
+    }
+
+    public void testDetachAttach() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        EmbeddedIdEntity e = em.find(EmbeddedIdEntity.class, _oid);
+        e.getRelation();
+        em.close();
+
+        e.setValue("echanged");
+        e.getRelation().setValue("rchanged");
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        EmbeddedIdEntity me = (EmbeddedIdEntity) em.mergeAll(e,
+            e.getRelation())[0];
+        assertTrue(me != e);
+        assertNotNull(me.getRelation());
+        assertTrue(me.getRelation() != e.getRelation());
+        assertEquals("echanged", me.getValue());
+        assertEquals("rchanged", me.getRelation().getValue());
+        assertEquals(_oid, me.getId());
+        assertEquals(_oid, em.getObjectId(me));
+        assertEquals(_roid, me.getRelation().getId());
+        assertEquals(_roid, em.getObjectId(me.getRelation()));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testQuery() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        Query q = em.createQuery("select e from EmbeddedIdEntity e "
+            + "where e.id.pk1 = 1");
+        EmbeddedIdEntity e = (EmbeddedIdEntity) q.getSingleResult();
+        assertEquals(_oid, e.getId());
+        assertEquals("e", e.getValue());
+
+        q = em.createQuery("select e.id.pk2 from EmbeddedIdEntity e "
+            + "where e.id.pk1 = 1");
+        assertEquals(new Long(_oid.getPk2()), q.getSingleResult());
+
+        q = em.createQuery("select e.id from EmbeddedIdEntity e "
+            + "where e.id.pk1 = 1");
+        assertEquals(_oid, q.getSingleResult());
+        em.close();
+    }
+
+    public void testAutoAssigned() {
+        // begin with null id object
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        EmbeddedIdEntity e = new EmbeddedIdEntity();
+        em.persist(e);
+        EmbeddedIdClass oid = e.getId();
+        assertNotNull(oid);
+        assertTrue(oid.getPk3() != 0);
+        assertEquals(oid, em.getObjectId(e));
+        em.getTransaction().commit();
+        assertEquals(oid, em.getObjectId(e));
+        em.close();
+
+        em = emf.createEntityManager();
+        e = em.find(EmbeddedIdEntity.class, oid);
+        assertEquals(oid, em.getObjectId(e));
+        em.close();
+
+        // begin with non-null id object
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        e = new EmbeddedIdEntity();
+        oid = new EmbeddedIdClass();
+        oid.setPk1(4);
+        oid.setPk2(5);
+        e.setId(oid);
+        em.persist(e);
+        oid = e.getId();
+        assertEquals(4, oid.getPk1());
+        assertEquals(5, oid.getPk2());
+        assertTrue(oid.getPk3() != 0);
+        assertEquals(oid, em.getObjectId(e));
+        em.getTransaction().commit();
+        assertEquals(oid, em.getObjectId(e));
+        em.close();
+
+        em = emf.createEntityManager();
+        e = em.find(EmbeddedIdEntity.class, oid);
+        assertEquals(oid, em.getObjectId(e));
+        em.close();
+
+        // flush before accessing id field
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        e = new EmbeddedIdEntity();
+        em.persist(e);
+        em.getTransaction().commit();
+        oid = e.getId();
+        assertTrue(oid.getPk3() != 0);
+        assertEquals(oid, em.getObjectId(e));
+        em.close();
+
+        em = emf.createEntityManager();
+        e = em.find(EmbeddedIdEntity.class, oid);
+        assertEquals(oid, em.getObjectId(e));
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEnumerated.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEnumerated.java
index ca0050f..5e33781 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEnumerated.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestEnumerated.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.InheritanceType;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test enums and the @Enumerated annotation.
- *
- * @author Abe White
- */
-public class TestEnumerated
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
-    }
-
-    public void testMapping() {
-        ClassMapping cls = (ClassMapping) emf.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(AnnoTest1.class, 
-            null, true);
-        FieldMapping fm = cls.getDeclaredFieldMapping("enumeration");
-        assertNotNull(fm);
-        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
-        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
-        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
-
-        fm = cls.getDeclaredFieldMapping("ordinalEnumeration");
-        assertNotNull(fm);
-        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
-        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
-        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
-
-        fm = cls.getDeclaredFieldMapping("stringEnumeration");
-        assertNotNull(fm);
-        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
-        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
-        assertEquals(JavaTypes.STRING, fm.getColumns()[0].getJavaType());
-    }
-
-    public void testBehavior() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(1);
-        pc.setEnumeration(InheritanceType.TABLE_PER_CLASS);
-        pc.setOrdinalEnumeration(InheritanceType.TABLE_PER_CLASS);
-        pc.setStringEnumeration(InheritanceType.JOINED);
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(1));
-        assertEquals(InheritanceType.TABLE_PER_CLASS, pc.getEnumeration());
-        assertEquals(InheritanceType.TABLE_PER_CLASS,
-            pc.getOrdinalEnumeration());
-        assertEquals(InheritanceType.JOINED,
-            pc.getStringEnumeration());
-        em.getTransaction().begin();
-        pc.setEnumeration(InheritanceType.JOINED);
-        pc.setOrdinalEnumeration(InheritanceType.JOINED);
-        pc.setStringEnumeration(InheritanceType.TABLE_PER_CLASS);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(1));
-        assertEquals(InheritanceType.JOINED, pc.getEnumeration());
-        assertEquals(InheritanceType.JOINED, pc.getOrdinalEnumeration());
-        assertEquals(InheritanceType.TABLE_PER_CLASS,
-            pc.getStringEnumeration());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.InheritanceType;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test enums and the @Enumerated annotation.
+ *
+ * @author Abe White
+ */
+public class TestEnumerated
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
+    }
+
+    public void testMapping() {
+        ClassMapping cls = (ClassMapping) emf.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(AnnoTest1.class, 
+            null, true);
+        FieldMapping fm = cls.getDeclaredFieldMapping("enumeration");
+        assertNotNull(fm);
+        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
+        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
+        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
+
+        fm = cls.getDeclaredFieldMapping("ordinalEnumeration");
+        assertNotNull(fm);
+        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
+        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
+        assertEquals(JavaTypes.SHORT, fm.getColumns()[0].getJavaType());
+
+        fm = cls.getDeclaredFieldMapping("stringEnumeration");
+        assertNotNull(fm);
+        assertEquals(FieldMapping.MANAGE_PERSISTENT, fm.getManagement());
+        assertEquals(JavaTypes.OBJECT, fm.getTypeCode());
+        assertEquals(JavaTypes.STRING, fm.getColumns()[0].getJavaType());
+    }
+
+    public void testBehavior() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(1);
+        pc.setEnumeration(InheritanceType.TABLE_PER_CLASS);
+        pc.setOrdinalEnumeration(InheritanceType.TABLE_PER_CLASS);
+        pc.setStringEnumeration(InheritanceType.JOINED);
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(1));
+        assertEquals(InheritanceType.TABLE_PER_CLASS, pc.getEnumeration());
+        assertEquals(InheritanceType.TABLE_PER_CLASS,
+            pc.getOrdinalEnumeration());
+        assertEquals(InheritanceType.JOINED,
+            pc.getStringEnumeration());
+        em.getTransaction().begin();
+        pc.setEnumeration(InheritanceType.JOINED);
+        pc.setOrdinalEnumeration(InheritanceType.JOINED);
+        pc.setStringEnumeration(InheritanceType.TABLE_PER_CLASS);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(1));
+        assertEquals(InheritanceType.JOINED, pc.getEnumeration());
+        assertEquals(InheritanceType.JOINED, pc.getOrdinalEnumeration());
+        assertEquals(InheritanceType.TABLE_PER_CLASS,
+            pc.getStringEnumeration());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestExtensionAnnotations.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestExtensionAnnotations.java
index e65be4f..bbd9f59 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestExtensionAnnotations.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestExtensionAnnotations.java
@@ -1,138 +1,138 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.meta.FetchGroup;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.UpdateStrategies;
-import org.apache.openjpa.meta.ValueMetaData;
-import org.apache.openjpa.meta.ValueStrategies;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test the parsing of Kodo metadata extension annotations.</p>
- *
- * @author Abe White
- */
-public class TestExtensionAnnotations
-    extends SingleEMFTestCase {
-
-    private ClassMapping _mapping;
-
-    public void setUp() {
-        setUp(ExtensionsEntity.class);
-        _mapping = ((JDBCConfiguration) emf.getConfiguration()).
-            getMappingRepositoryInstance().getMapping(ExtensionsEntity.class,
-            null, true);
-    }
-
-    public void testDataStoreId() {
-        assertEquals(ClassMapping.ID_DATASTORE, _mapping.getIdentityType());
-        assertEquals(ValueStrategies.SEQUENCE, _mapping.getIdentityStrategy());
-        assertEquals("system", _mapping.getIdentitySequenceName());
-    }
-
-    public void testDataCache() {
-        assertNull(_mapping.getDataCacheName());
-    }
-
-    public void testFetchGroups() {
-        FetchGroup fg = _mapping.getFetchGroup("detail");
-        assertNotNull(fg);
-        assertFalse(fg.isPostLoad());
-        FieldMapping fm = _mapping.getFieldMapping("rel");
-        assertEquals(1, fm.getCustomFetchGroups().length);
-        assertEquals("detail", fm.getCustomFetchGroups()[0]);
-        assertEquals(-1, fg.getRecursionDepth(fm));
-        fm = _mapping.getFieldMapping("seq");
-        assertEquals(1, fm.getCustomFetchGroups().length);
-        assertEquals("detail", fm.getCustomFetchGroups()[0]);
-        assertEquals(1, fg.getRecursionDepth(fm));
-    }
-
-    public void testValueStrategy() {
-        assertEquals(ValueStrategies.UUID_HEX,
-            _mapping.getField("uuid").getValueStrategy());
-        assertEquals(ValueStrategies.UUID_STRING,
-            _mapping.getField("uuidString").getValueStrategy());
-        assertEquals(ValueStrategies.UUID_TYPE4_HEX,
-            _mapping.getField("uuidT4Hex").getValueStrategy());
-        assertEquals(ValueStrategies.UUID_TYPE4_STRING,
-            _mapping.getField("uuidT4String").getValueStrategy());
-        FieldMapping seq = _mapping.getFieldMapping("seq");
-        assertEquals(ValueStrategies.SEQUENCE, seq.getValueStrategy());
-        assertEquals("system", seq.getValueSequenceName());
-    }
-
-    public void testReadOnly() {
-        assertEquals(UpdateStrategies.RESTRICT,
-            _mapping.getField("seq").getUpdateStrategy());
-    }
-
-    public void testInverseLogical() {
-        assertEquals("owner", _mapping.getField("rel").getInverse());
-        assertNull(_mapping.getField("owner").getInverse());
-    }
-
-    public void testDependent() {
-        assertEquals(ValueMetaData.CASCADE_AUTO,
-            _mapping.getField("rel").getCascadeDelete());
-        assertEquals(ValueMetaData.CASCADE_NONE,
-            _mapping.getField("eager").getCascadeDelete());
-        assertEquals(ValueMetaData.CASCADE_AUTO,
-            _mapping.getField("eager").getElement().getCascadeDelete());
-    }
-
-    public void testLRS() {
-        assertTrue(_mapping.getField("lrs").isLRS());
-        assertFalse(_mapping.getField("eager").isLRS());
-    }
-
-    public void testClassCriteria() {
-        assertTrue(_mapping.getFieldMapping("eager").getElementMapping().
-            getUseClassCriteria());
-        assertFalse(_mapping.getFieldMapping("eager").getUseClassCriteria());
-        assertFalse(_mapping.getFieldMapping("lrs").getElementMapping().
-            getUseClassCriteria());
-    }
-
-    public void testExternalValues() {
-        FieldMapping externalValues = _mapping.getFieldMapping
-            ("externalValues");
-        assertEquals(JavaTypes.CHAR, externalValues.getDeclaredTypeCode());
-        assertEquals(JavaTypes.INT, externalValues.getTypeCode());
-        assertEquals(new Integer(1), externalValues.getExternalValueMap().
-            get(new Character('M')));
-        assertEquals(new Integer(2), externalValues.getExternalValueMap().
-            get(new Character('F')));
-    }
-
-    public void testExternalizer() {
-        FieldMapping externalizer = _mapping.getFieldMapping("externalizer");
-        assertEquals(JavaTypes.OBJECT, externalizer.getDeclaredTypeCode());
-        assertEquals(JavaTypes.STRING, externalizer.getTypeCode());
-        assertEquals("java.lang.String", externalizer.getExternalValue
-            (String.class, null));
-        assertEquals(String.class, externalizer.getFieldValue
-            (String.class.getName(), null));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.meta.FetchGroup;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.UpdateStrategies;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test the parsing of Kodo metadata extension annotations.</p>
+ *
+ * @author Abe White
+ */
+public class TestExtensionAnnotations
+    extends SingleEMFTestCase {
+
+    private ClassMapping _mapping;
+
+    public void setUp() {
+        setUp(ExtensionsEntity.class);
+        _mapping = ((JDBCConfiguration) emf.getConfiguration()).
+            getMappingRepositoryInstance().getMapping(ExtensionsEntity.class,
+            null, true);
+    }
+
+    public void testDataStoreId() {
+        assertEquals(ClassMapping.ID_DATASTORE, _mapping.getIdentityType());
+        assertEquals(ValueStrategies.SEQUENCE, _mapping.getIdentityStrategy());
+        assertEquals("system", _mapping.getIdentitySequenceName());
+    }
+
+    public void testDataCache() {
+        assertNull(_mapping.getDataCacheName());
+    }
+
+    public void testFetchGroups() {
+        FetchGroup fg = _mapping.getFetchGroup("detail");
+        assertNotNull(fg);
+        assertFalse(fg.isPostLoad());
+        FieldMapping fm = _mapping.getFieldMapping("rel");
+        assertEquals(1, fm.getCustomFetchGroups().length);
+        assertEquals("detail", fm.getCustomFetchGroups()[0]);
+        assertEquals(-1, fg.getRecursionDepth(fm));
+        fm = _mapping.getFieldMapping("seq");
+        assertEquals(1, fm.getCustomFetchGroups().length);
+        assertEquals("detail", fm.getCustomFetchGroups()[0]);
+        assertEquals(1, fg.getRecursionDepth(fm));
+    }
+
+    public void testValueStrategy() {
+        assertEquals(ValueStrategies.UUID_HEX,
+            _mapping.getField("uuid").getValueStrategy());
+        assertEquals(ValueStrategies.UUID_STRING,
+            _mapping.getField("uuidString").getValueStrategy());
+        assertEquals(ValueStrategies.UUID_TYPE4_HEX,
+            _mapping.getField("uuidT4Hex").getValueStrategy());
+        assertEquals(ValueStrategies.UUID_TYPE4_STRING,
+            _mapping.getField("uuidT4String").getValueStrategy());
+        FieldMapping seq = _mapping.getFieldMapping("seq");
+        assertEquals(ValueStrategies.SEQUENCE, seq.getValueStrategy());
+        assertEquals("system", seq.getValueSequenceName());
+    }
+
+    public void testReadOnly() {
+        assertEquals(UpdateStrategies.RESTRICT,
+            _mapping.getField("seq").getUpdateStrategy());
+    }
+
+    public void testInverseLogical() {
+        assertEquals("owner", _mapping.getField("rel").getInverse());
+        assertNull(_mapping.getField("owner").getInverse());
+    }
+
+    public void testDependent() {
+        assertEquals(ValueMetaData.CASCADE_AUTO,
+            _mapping.getField("rel").getCascadeDelete());
+        assertEquals(ValueMetaData.CASCADE_NONE,
+            _mapping.getField("eager").getCascadeDelete());
+        assertEquals(ValueMetaData.CASCADE_AUTO,
+            _mapping.getField("eager").getElement().getCascadeDelete());
+    }
+
+    public void testLRS() {
+        assertTrue(_mapping.getField("lrs").isLRS());
+        assertFalse(_mapping.getField("eager").isLRS());
+    }
+
+    public void testClassCriteria() {
+        assertTrue(_mapping.getFieldMapping("eager").getElementMapping().
+            getUseClassCriteria());
+        assertFalse(_mapping.getFieldMapping("eager").getUseClassCriteria());
+        assertFalse(_mapping.getFieldMapping("lrs").getElementMapping().
+            getUseClassCriteria());
+    }
+
+    public void testExternalValues() {
+        FieldMapping externalValues = _mapping.getFieldMapping
+            ("externalValues");
+        assertEquals(JavaTypes.CHAR, externalValues.getDeclaredTypeCode());
+        assertEquals(JavaTypes.INT, externalValues.getTypeCode());
+        assertEquals(new Integer(1), externalValues.getExternalValueMap().
+            get(new Character('M')));
+        assertEquals(new Integer(2), externalValues.getExternalValueMap().
+            get(new Character('F')));
+    }
+
+    public void testExternalizer() {
+        FieldMapping externalizer = _mapping.getFieldMapping("externalizer");
+        assertEquals(JavaTypes.OBJECT, externalizer.getDeclaredTypeCode());
+        assertEquals(JavaTypes.STRING, externalizer.getTypeCode());
+        assertEquals("java.lang.String", externalizer.getExternalValue
+            (String.class, null));
+        assertEquals(String.class, externalizer.getFieldValue
+            (String.class.getName(), null));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestFlatInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestFlatInheritance.java
index 7f00de5..db63744 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestFlatInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestFlatInheritance.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for InheritanceType.SINGLE_TABLE
- *
- * @author Steve Kim
- */
-public class TestFlatInheritance extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(Flat1.class, Flat2.class, CLEAR_TABLES);
-    }
-
-    public void testInheritance() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Flat1 pc = new Flat1(1);
-        Flat2 pc2 = new Flat2(2);
-        pc.setBasic(10);
-        pc2.setBasic(20);
-        pc2.setBasic2("DOG");
-        em.persist(pc);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(Flat1.class, 1);
-        assertEquals(10, pc.getBasic());
-        pc = em.find(Flat1.class, 2);
-        assertEquals(Flat2.class, pc.getClass());
-        assertEquals(20, pc.getBasic());
-        assertEquals("DOG", ((Flat2) pc).getBasic2());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for InheritanceType.SINGLE_TABLE
+ *
+ * @author Steve Kim
+ */
+public class TestFlatInheritance extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Flat1.class, Flat2.class, CLEAR_TABLES);
+    }
+
+    public void testInheritance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Flat1 pc = new Flat1(1);
+        Flat2 pc2 = new Flat2(2);
+        pc.setBasic(10);
+        pc2.setBasic(20);
+        pc2.setBasic2("DOG");
+        em.persist(pc);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(Flat1.class, 1);
+        assertEquals(10, pc.getBasic());
+        pc = em.find(Flat1.class, 2);
+        assertEquals(Flat2.class, pc.getClass());
+        assertEquals(20, pc.getBasic());
+        assertEquals("DOG", ((Flat2) pc).getBasic2());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestGenerators.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestGenerators.java
index 12533a5..c957301 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestGenerators.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestGenerators.java
@@ -1,96 +1,96 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.enhance.ClassRedefiner;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for generators
- *
- * @author Steve Kim
- */
-public class TestGenerators extends SingleEMFTestCase {
-
-    public void setUp()
-        throws Exception {
-        setUp(Generator.class, CLEAR_TABLES);
-    }
-
-    public void testGet() {
-        if (!PersistenceCapable.class.isAssignableFrom(Generator.class)
-            && !ClassRedefiner.canRedefineClasses())
-            fail("This test requires a higher level of enhancement than"
-                + " is available in the current environment.");
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Generator g = new Generator();
-        g.setPk(5);
-        em.persist(g);
-        assertPks(g);
-        em.getTransaction().commit();
-        em.close();
-        assertNew();
-    }
-
-    public void testFlush() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Generator g = new Generator();
-        g.setPk(5);
-        em.persist(g);
-        em.flush();
-        assertPks(g);
-        em.getTransaction().commit();
-        em.close();
-        assertNew();
-    }
-
-    public void testCommit() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Generator g = new Generator();
-        g.setPk(5);
-        em.persist(g);
-        em.getTransaction().commit();
-        em.close();
-        assertNew();
-    }
-
-    private void assertNew() {
-        EntityManager em = emf.createEntityManager();
-        Query q = em.createQuery("select g from Generator g where "
-            + "g.stringField = 'foo'");
-        for (Object o : q.getResultList())
-            assertPks((Generator) o);
-        em.close();
-    }
-
-    private void assertPks(Generator g) {
-        assertNotEquals(0, g.getPk());
-        assertNotNull(g.getPk2());
-        assertNotEquals(new Integer(0), g);
-        assertNotEquals(0, g.getPk3());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.enhance.ClassRedefiner;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for generators
+ *
+ * @author Steve Kim
+ */
+public class TestGenerators extends SingleEMFTestCase {
+
+    public void setUp()
+        throws Exception {
+        setUp(Generator.class, CLEAR_TABLES);
+    }
+
+    public void testGet() {
+        if (!PersistenceCapable.class.isAssignableFrom(Generator.class)
+            && !ClassRedefiner.canRedefineClasses())
+            fail("This test requires a higher level of enhancement than"
+                + " is available in the current environment.");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Generator g = new Generator();
+        g.setPk(5);
+        em.persist(g);
+        assertPks(g);
+        em.getTransaction().commit();
+        em.close();
+        assertNew();
+    }
+
+    public void testFlush() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Generator g = new Generator();
+        g.setPk(5);
+        em.persist(g);
+        em.flush();
+        assertPks(g);
+        em.getTransaction().commit();
+        em.close();
+        assertNew();
+    }
+
+    public void testCommit() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Generator g = new Generator();
+        g.setPk(5);
+        em.persist(g);
+        em.getTransaction().commit();
+        em.close();
+        assertNew();
+    }
+
+    private void assertNew() {
+        EntityManager em = emf.createEntityManager();
+        Query q = em.createQuery("select g from Generator g where "
+            + "g.stringField = 'foo'");
+        for (Object o : q.getResultList())
+            assertPks((Generator) o);
+        em.close();
+    }
+
+    private void assertPks(Generator g) {
+        assertNotEquals(0, g.getPk());
+        assertNotNull(g.getPk2());
+        assertNotEquals(new Integer(0), g);
+        assertNotEquals(0, g.getPk3());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestJoinedInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestJoinedInheritance.java
index b5e4b50..6e82a3e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestJoinedInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestJoinedInheritance.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for InheritanceType.JOINED
- *
- * @author Steve Kim
- */
-public class TestJoinedInheritance extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, AnnoTest3.class, Flat1.class,
-            CLEAR_TABLES);
-    }
-
-    public void testInheritance() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest3 pc = new AnnoTest3();
-        pc.setPk(new Long(1));
-        pc.setBasic(10);
-        pc.setBasic2(20);
-        em.persist(pc);
-
-        AnnoTest2 pc2 = new AnnoTest2();
-        pc2.setPk1(2);
-        pc2.setPk2("bar");
-        pc2.setInverseOneOne(pc);
-        pc.setSubOneOne(pc2);
-        em.persist(pc2);
-
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc2 = em.find(AnnoTest2.class, new AnnoTest2.Oid(2, "bar"));
-        pc = (AnnoTest3) pc2.getInverseOneOne();
-        assertEquals(pc.getInverseOwnerOneOne(), pc2);
-        assertEquals(10, pc.getBasic());
-        assertEquals(20, pc.getBasic2());
-        assertEquals(pc2, pc.getSubOneOne());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for InheritanceType.JOINED
+ *
+ * @author Steve Kim
+ */
+public class TestJoinedInheritance extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, AnnoTest3.class, Flat1.class,
+            CLEAR_TABLES);
+    }
+
+    public void testInheritance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest3 pc = new AnnoTest3();
+        pc.setPk(new Long(1));
+        pc.setBasic(10);
+        pc.setBasic2(20);
+        em.persist(pc);
+
+        AnnoTest2 pc2 = new AnnoTest2();
+        pc2.setPk1(2);
+        pc2.setPk2("bar");
+        pc2.setInverseOneOne(pc);
+        pc.setSubOneOne(pc2);
+        em.persist(pc2);
+
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc2 = em.find(AnnoTest2.class, new AnnoTest2.Oid(2, "bar"));
+        pc = (AnnoTest3) pc2.getInverseOneOne();
+        assertEquals(pc.getInverseOwnerOneOne(), pc2);
+        assertEquals(10, pc.getBasic());
+        assertEquals(20, pc.getBasic2());
+        assertEquals(pc2, pc.getSubOneOne());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestManyToMany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestManyToMany.java
index 334de0e..1c803ae 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestManyToMany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestManyToMany.java
@@ -1,110 +1,110 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.util.Set;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for m-m
- *
- * @author Steve Kim
- */
-public class TestManyToMany
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
-    }
-
-    public void testManyToMany() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(4);
-        em.persist(pc);
-        AnnoTest2 pc2;
-        for (int i = 0; i < 3; i++) {
-            pc2 = new AnnoTest2(5 + i, "foo" + i);
-            pc.getManyMany().add(pc2);
-            em.persist(pc2);
-        }
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(4));
-        Set<AnnoTest2> many = pc.getManyMany();
-        assertEquals(3, many.size());
-        for (AnnoTest2 manyPc2 : many) {
-            switch ((int) manyPc2.getPk1()) {
-                case 5:
-                    assertEquals("foo0", manyPc2.getPk2());
-                    break;
-                case 6:
-                    assertEquals("foo1", manyPc2.getPk2());
-                    break;
-                case 7:
-                    assertEquals("foo2", manyPc2.getPk2());
-                    break;
-                default:
-                    fail("bad pk:" + manyPc2.getPk1());
-            }
-        }
-        em.close();
-    }
-
-    public void testInverseOwnerManyToMany() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(4);
-        em.persist(pc);
-        AnnoTest2 pc2;
-        for (int i = 0; i < 3; i++) {
-            pc2 = new AnnoTest2(5 + i, "foo" + i);
-            pc2.getManyMany().add(pc);
-            em.persist(pc2);
-        }
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(4));
-        Set<AnnoTest2> many = pc.getInverseOwnerManyMany();
-        assertEquals(3, many.size());
-        for (AnnoTest2 manyPc2 : many) {
-            assertTrue(manyPc2.getManyMany().contains(pc));
-            switch ((int) manyPc2.getPk1()) {
-                case 5:
-                    assertEquals("foo0", manyPc2.getPk2());
-                    break;
-                case 6:
-                    assertEquals("foo1", manyPc2.getPk2());
-                    break;
-                case 7:
-                    assertEquals("foo2", manyPc2.getPk2());
-                    break;
-                default:
-                    fail("bad pk:" + manyPc2.getPk1());
-            }
-        }
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.util.Set;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for m-m
+ *
+ * @author Steve Kim
+ */
+public class TestManyToMany
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
+    }
+
+    public void testManyToMany() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(4);
+        em.persist(pc);
+        AnnoTest2 pc2;
+        for (int i = 0; i < 3; i++) {
+            pc2 = new AnnoTest2(5 + i, "foo" + i);
+            pc.getManyMany().add(pc2);
+            em.persist(pc2);
+        }
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(4));
+        Set<AnnoTest2> many = pc.getManyMany();
+        assertEquals(3, many.size());
+        for (AnnoTest2 manyPc2 : many) {
+            switch ((int) manyPc2.getPk1()) {
+                case 5:
+                    assertEquals("foo0", manyPc2.getPk2());
+                    break;
+                case 6:
+                    assertEquals("foo1", manyPc2.getPk2());
+                    break;
+                case 7:
+                    assertEquals("foo2", manyPc2.getPk2());
+                    break;
+                default:
+                    fail("bad pk:" + manyPc2.getPk1());
+            }
+        }
+        em.close();
+    }
+
+    public void testInverseOwnerManyToMany() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(4);
+        em.persist(pc);
+        AnnoTest2 pc2;
+        for (int i = 0; i < 3; i++) {
+            pc2 = new AnnoTest2(5 + i, "foo" + i);
+            pc2.getManyMany().add(pc);
+            em.persist(pc2);
+        }
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(4));
+        Set<AnnoTest2> many = pc.getInverseOwnerManyMany();
+        assertEquals(3, many.size());
+        for (AnnoTest2 manyPc2 : many) {
+            assertTrue(manyPc2.getManyMany().contains(pc));
+            switch ((int) manyPc2.getPk1()) {
+                case 5:
+                    assertEquals("foo0", manyPc2.getPk2());
+                    break;
+                case 6:
+                    assertEquals("foo1", manyPc2.getPk2());
+                    break;
+                case 7:
+                    assertEquals("foo2", manyPc2.getPk2());
+                    break;
+                default:
+                    fail("bad pk:" + manyPc2.getPk1());
+            }
+        }
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMapKey.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMapKey.java
index 190129d..530824a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMapKey.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMapKey.java
@@ -1,123 +1,123 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-import javax.persistence.MapKey;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.RelationMapInverseKeyFieldStrategy;
-import org.apache.openjpa.jdbc.meta.strats.RelationMapTableFieldStrategy;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test the use of the {@link MapKey} annotation.  Note that we have
- * more thorough Kodo core tests for the mappings themselves.  See
- * {@link kodo.jdbc.meta.TestMappedByKeyMaps}.
- *
- * @author Abe White
- */
-public class TestMapKey
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(Flat1.class, AnnoTest1.class, AnnoTest2.class, CLEAR_TABLES);
-
-    }
-
-    public void testDefaultMapKeyMapping() {
-        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration())
-            .getMappingRepositoryInstance().getMapping(AnnoTest1.class,
-                null, true);
-        FieldMapping fm = mapping.getFieldMapping("defaultMapKey");
-        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
-        assertEquals("pk", fm.getKey().getValueMappedBy());
-        assertEquals(mapping.getRepository().getMetaData(Flat1.class, null,
-            true).getField("pk"), fm.getKey().getValueMappedByMetaData());
-    }
-
-    public void testNamedMapKeyMapping() {
-        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration())
-            .getMappingRepositoryInstance().getMapping(AnnoTest1.class,
-                null, true);
-        FieldMapping fm = mapping.getFieldMapping("namedMapKey");
-        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
-        assertEquals("basic", fm.getKey().getValueMappedBy());
-        assertEquals(mapping.getRepository().getMetaData(Flat1.class, null,
-            true).getField("basic"), fm.getKey().getValueMappedByMetaData());
-    }
-
-    public void testInverseOwnerMapKeyMapping() {
-        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration())
-            .getMappingRepositoryInstance().getMapping(AnnoTest1.class,
-                null, true);
-        FieldMapping fm = mapping.getFieldMapping("inverseOwnerMapKey");
-        assertTrue(fm.getStrategy() instanceof
-            RelationMapInverseKeyFieldStrategy);
-        assertEquals("basic", fm.getKey().getValueMappedBy());
-        assertEquals(mapping.getRepository().getMetaData(AnnoTest2.class,
-            null, true).getField("basic"), fm.getKey().
-            getValueMappedByMetaData());
-    }
-
-    public void testInsertAndRetrieve() {
-        Flat1 f1 = new Flat1(1);
-        f1.setBasic(100);
-        Flat1 f2 = new Flat1(2);
-        f2.setBasic(200);
-        AnnoTest2 a1 = new AnnoTest2(1L, "1");
-        a1.setBasic("100");
-        AnnoTest2 a2 = new AnnoTest2(2L, "2");
-        a2.setBasic("200");
-
-        AnnoTest1 pc = new AnnoTest1(1L);
-        pc.getDefaultMapKey().put(f1.getPk(), f1);
-        pc.getDefaultMapKey().put(f2.getPk(), f2);
-        pc.getNamedMapKey().put(f1.getBasic(), f1);
-        pc.getNamedMapKey().put(f2.getBasic(), f2);
-        pc.getInverseOwnerMapKey().put(a1.getBasic(), a1);
-        pc.getInverseOwnerMapKey().put(a2.getBasic(), a2);
-        a1.setOneManyOwner(pc);
-        a2.setOneManyOwner(pc);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persistAll(new Object[]{ pc, f1, f2, a1, a2 });
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(1));
-        assertEquals(2, pc.getDefaultMapKey().size());
-        assertEquals(1, pc.getDefaultMapKey().get(1).getPk());
-        assertEquals(2, pc.getDefaultMapKey().get(2).getPk());
-        assertEquals(2, pc.getNamedMapKey().size());
-        assertEquals(100, pc.getNamedMapKey().get(100).getBasic());
-        assertEquals(200, pc.getNamedMapKey().get(200).getBasic());
-        assertEquals(2, pc.getInverseOwnerMapKey().size());
-        assertEquals("100", pc.getInverseOwnerMapKey().get("100").
-            getBasic());
-        assertEquals("200", pc.getInverseOwnerMapKey().get("200").
-            getBasic());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+import javax.persistence.MapKey;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.RelationMapInverseKeyFieldStrategy;
+import org.apache.openjpa.jdbc.meta.strats.RelationMapTableFieldStrategy;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test the use of the {@link MapKey} annotation.  Note that we have
+ * more thorough Kodo core tests for the mappings themselves.  See
+ * {@link kodo.jdbc.meta.TestMappedByKeyMaps}.
+ *
+ * @author Abe White
+ */
+public class TestMapKey
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Flat1.class, AnnoTest1.class, AnnoTest2.class, CLEAR_TABLES);
+
+    }
+
+    public void testDefaultMapKeyMapping() {
+        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration())
+            .getMappingRepositoryInstance().getMapping(AnnoTest1.class,
+                null, true);
+        FieldMapping fm = mapping.getFieldMapping("defaultMapKey");
+        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
+        assertEquals("pk", fm.getKey().getValueMappedBy());
+        assertEquals(mapping.getRepository().getMetaData(Flat1.class, null,
+            true).getField("pk"), fm.getKey().getValueMappedByMetaData());
+    }
+
+    public void testNamedMapKeyMapping() {
+        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration())
+            .getMappingRepositoryInstance().getMapping(AnnoTest1.class,
+                null, true);
+        FieldMapping fm = mapping.getFieldMapping("namedMapKey");
+        assertTrue(fm.getStrategy() instanceof RelationMapTableFieldStrategy);
+        assertEquals("basic", fm.getKey().getValueMappedBy());
+        assertEquals(mapping.getRepository().getMetaData(Flat1.class, null,
+            true).getField("basic"), fm.getKey().getValueMappedByMetaData());
+    }
+
+    public void testInverseOwnerMapKeyMapping() {
+        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration())
+            .getMappingRepositoryInstance().getMapping(AnnoTest1.class,
+                null, true);
+        FieldMapping fm = mapping.getFieldMapping("inverseOwnerMapKey");
+        assertTrue(fm.getStrategy() instanceof
+            RelationMapInverseKeyFieldStrategy);
+        assertEquals("basic", fm.getKey().getValueMappedBy());
+        assertEquals(mapping.getRepository().getMetaData(AnnoTest2.class,
+            null, true).getField("basic"), fm.getKey().
+            getValueMappedByMetaData());
+    }
+
+    public void testInsertAndRetrieve() {
+        Flat1 f1 = new Flat1(1);
+        f1.setBasic(100);
+        Flat1 f2 = new Flat1(2);
+        f2.setBasic(200);
+        AnnoTest2 a1 = new AnnoTest2(1L, "1");
+        a1.setBasic("100");
+        AnnoTest2 a2 = new AnnoTest2(2L, "2");
+        a2.setBasic("200");
+
+        AnnoTest1 pc = new AnnoTest1(1L);
+        pc.getDefaultMapKey().put(f1.getPk(), f1);
+        pc.getDefaultMapKey().put(f2.getPk(), f2);
+        pc.getNamedMapKey().put(f1.getBasic(), f1);
+        pc.getNamedMapKey().put(f2.getBasic(), f2);
+        pc.getInverseOwnerMapKey().put(a1.getBasic(), a1);
+        pc.getInverseOwnerMapKey().put(a2.getBasic(), a2);
+        a1.setOneManyOwner(pc);
+        a2.setOneManyOwner(pc);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persistAll(new Object[]{ pc, f1, f2, a1, a2 });
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(1));
+        assertEquals(2, pc.getDefaultMapKey().size());
+        assertEquals(1, pc.getDefaultMapKey().get(1).getPk());
+        assertEquals(2, pc.getDefaultMapKey().get(2).getPk());
+        assertEquals(2, pc.getNamedMapKey().size());
+        assertEquals(100, pc.getNamedMapKey().get(100).getBasic());
+        assertEquals(200, pc.getNamedMapKey().get(200).getBasic());
+        assertEquals(2, pc.getInverseOwnerMapKey().size());
+        assertEquals("100", pc.getInverseOwnerMapKey().get("100").
+            getBasic());
+        assertEquals("200", pc.getInverseOwnerMapKey().get("200").
+            getBasic());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMixedAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMixedAccess.java
index af8cf48..bf1c272 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMixedAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestMixedAccess.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.PersistenceException;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-
-public class TestMixedAccess extends PersistenceTestCase {
-
-    public void testMixedAccessEntityError() {
-        try {
-            EntityManagerFactory emf = createEMF(UnenhancedMixedAccess.class);
-            emf.createEntityManager().close();
-        } catch (RuntimeException e) {
-            String msg = e.getMessage();
-            if (!(msg.contains("UnenhancedMixedAccess.id") &&
-                msg.contains("UnenhancedMixedAccess.getStringField")))
-                throw e;
-        }
-    }
-
-    public void testInappropriateTransientError() {
-        try {
-            EntityManagerFactory emf = createEMF(
-                UnenhancedInappropriateTransient.class);
-            emf.createEntityManager().close();
-         } catch (RuntimeException e) {
-            String msg = e.getMessage();
-            if (!(msg.contains("UnenhancedInappropriateTransient.id") &&
-                msg.contains("UnenhancedInappropriateTransient.prePersist")))
-                throw e;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.PersistenceException;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+
+public class TestMixedAccess extends PersistenceTestCase {
+
+    public void testMixedAccessEntityError() {
+        try {
+            EntityManagerFactory emf = createEMF(UnenhancedMixedAccess.class);
+            emf.createEntityManager().close();
+        } catch (RuntimeException e) {
+            String msg = e.getMessage();
+            if (!(msg.contains("UnenhancedMixedAccess.id") &&
+                msg.contains("UnenhancedMixedAccess.getStringField")))
+                throw e;
+        }
+    }
+
+    public void testInappropriateTransientError() {
+        try {
+            EntityManagerFactory emf = createEMF(
+                UnenhancedInappropriateTransient.class);
+            emf.createEntityManager().close();
+         } catch (RuntimeException e) {
+            String msg = e.getMessage();
+            if (!(msg.contains("UnenhancedInappropriateTransient.id") &&
+                msg.contains("UnenhancedInappropriateTransient.prePersist")))
+                throw e;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java
index 34f7d76..dc5d262 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java
@@ -1,280 +1,280 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.awt.*;
-import java.util.Map;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.Discriminator;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.ValueMapping;
-import org.apache.openjpa.jdbc.meta.strats.ClassNameDiscriminatorStrategy;
-import org.apache.openjpa.jdbc.schema.ForeignKey;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test the parsing of non-standard mapping annotations.</p>
- *
- * @author Abe White
- */
-public class TestNonstandardMappingAnnotations
-    extends SingleEMFTestCase {
-
-    private ClassMapping _mapping;
-    private DBDictionary _dict;
-
-    public void setUp() {
-        setUp(NonstandardMappingEntity.class, ExtensionsEntity.class,
-            NonstandardMappingMappedSuper.class, EmbedValue2.class,
-            EmbedValue.class,
-            CLEAR_TABLES);
-
-        // trigger complete resolution of metadata etc.
-        emf.createEntityManager().close();
-
-        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
-        _dict = conf.getDBDictionaryInstance();
-        _mapping = (ClassMapping) JPAFacadeHelper.getMetaData(emf,
-            NonstandardMappingEntity.class);
-    }
-
-    public void testNonpolymorphic() {
-        FieldMapping fm = _mapping.getFieldMapping("superRel");
-        assertEquals(ValueMapping.POLY_FALSE, fm.getPolymorphic());
-
-        ValueMapping vm = _mapping.getFieldMapping("joinCollection").
-            getElementMapping();
-        assertEquals(ValueMapping.POLY_JOINABLE, vm.getPolymorphic());
-
-        vm = _mapping.getFieldMapping("joinMap").getKeyMapping();
-        assertEquals(ValueMapping.POLY_FALSE, vm.getPolymorphic());
-        vm = _mapping.getFieldMapping("joinMap").getElementMapping();
-        assertEquals(ValueMapping.POLY_FALSE, vm.getPolymorphic());
-    }
-
-    public void testDataStoreIdColumn() {
-        assertEquals("NONSTD_ENTITY", _mapping.getTable().getName());
-        assertEquals(ClassMapping.ID_DATASTORE, _mapping.getIdentityType());
-        assertEquals(1, _mapping.getPrimaryKeyColumns().length);
-        assertEquals("OID", _mapping.getPrimaryKeyColumns()[0].getName());
-    }
-
-    public void testDiscriminator() {
-        Discriminator disc = _mapping.getDiscriminator();
-        assertTrue(disc.getStrategy() instanceof
-            ClassNameDiscriminatorStrategy);
-        assertEquals(1, disc.getColumns().length);
-        assertEquals("DISCRIM", disc.getColumns()[0].getName());
-    }
-
-    public void testSuperclassOverride() {
-        FieldMapping fm = _mapping.getFieldMapping("superCollection");
-        assertEquals("SUP_COLL", fm.getTable().getName());
-        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
-        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
-            getName());
-        assertEquals(1, fm.getElementMapping().getColumns().length);
-        assertEquals("SUP_ELEM", fm.getElementMapping().getColumns()[0].
-            getName());
-        assertNull(fm.getElementMapping().getValueIndex());
-        assertNotNull(fm.getJoinIndex());
-    }
-
-    public void testCustomField() {
-        FieldMapping fm = _mapping.getFieldMapping("custom");
-        assertTrue(fm.getHandler() instanceof PointHandler);
-        assertEquals(2, fm.getColumns().length);
-        assertEquals("X_COL", fm.getColumns()[0].getName());
-        assertEquals("Y_COL", fm.getColumns()[1].getName());
-        assertNotNull(fm.getValueIndex());
-    }
-
-    public void testValueCollection() {
-        FieldMapping fm = _mapping.getFieldMapping("stringCollection");
-        assertEquals("STRINGS_COLL", fm.getTable().getName());
-        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
-        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
-            getName());
-        assertEquals(1, fm.getElementMapping().getColumns().length);
-        assertEquals("STR_ELEM", fm.getElementMapping().getColumns()[0].
-            getName());
-        assertEquals(127, fm.getElementMapping().getColumns()[0].getSize());
-        assertNotNull(fm.getElementMapping().getValueIndex());
-        assertNull(fm.getJoinIndex());
-    }
-
-    public void testJoinCollection() {
-        FieldMapping fm = _mapping.getFieldMapping("joinCollection");
-        assertEquals("JOIN_COLL", fm.getTable().getName());
-        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
-        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
-            getName());
-        assertEquals(1, fm.getElementMapping().getColumns().length);
-        assertEquals("JOIN_ELEM", fm.getElementMapping().getColumns()[0].
-            getName());
-        assertForeignKey(fm.getJoinForeignKey());
-        assertForeignKey(fm.getElementMapping().getForeignKey());
-    }
-
-    private void assertForeignKey(ForeignKey fk) {
-        if (_dict.supportsForeignKeys)
-            assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
-    }
-
-    public void testValueMap() {
-        FieldMapping fm = _mapping.getFieldMapping("stringMap");
-        assertEquals("STRINGS_MAP", fm.getTable().getName());
-        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
-        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
-            getName());
-        assertEquals(1, fm.getKeyMapping().getColumns().length);
-        assertEquals("STR_KEY", fm.getKeyMapping().getColumns()[0].
-            getName());
-        assertEquals(127, fm.getKeyMapping().getColumns()[0].getSize());
-        assertEquals(1, fm.getElementMapping().getColumns().length);
-        assertEquals("STR_VAL", fm.getElementMapping().getColumns()[0].
-            getName());
-        assertEquals(127, fm.getElementMapping().getColumns()[0].getSize());
-        assertNull(fm.getJoinIndex());
-        assertNotNull(fm.getKeyMapping().getValueIndex());
-        assertNotNull(fm.getElementMapping().getValueIndex());
-    }
-
-    public void testJoinMap() {
-        FieldMapping fm = _mapping.getFieldMapping("joinMap");
-        assertEquals("JOIN_MAP", fm.getTable().getName());
-        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
-        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
-            getName());
-        assertEquals(1, fm.getKeyMapping().getColumns().length);
-        assertEquals("JOIN_KEY", fm.getKeyMapping().getColumns()[0].
-            getName());
-        assertEquals(1, fm.getElementMapping().getColumns().length);
-        assertEquals("JOIN_VAL", fm.getElementMapping().getColumns()[0].
-            getName());
-        assertForeignKey(fm.getJoinForeignKey());
-        assertForeignKey(fm.getKeyMapping().getForeignKey());
-        assertForeignKey(fm.getElementMapping().getForeignKey());
-    }
-
-    public void testEmbeddedOverride() {
-        FieldMapping fm = _mapping.getFieldMapping("embed");
-        assertTrue(fm.isEmbedded());
-        assertEquals(1, fm.getColumns().length);
-        assertTrue("UUID_HEX".equalsIgnoreCase(fm.getColumns()[0].
-            getName()));
-
-        ClassMapping embed = fm.getEmbeddedMapping();
-        fm = embed.getFieldMapping("rel");
-        assertEquals(1, fm.getColumns().length);
-        assertEquals("EM_REL_ID", fm.getColumns()[0].getName());
-        fm = embed.getFieldMapping("eager");
-        assertEquals("EM_EAGER", fm.getTable().getName());
-        assertEquals(1, fm.getElementMapping().getColumns().length);
-        assertEquals("ELEM_EAGER_ID", fm.getElementMapping().getColumns()[0].
-            getName());
-    }
-
-    public void testEmbeddedElementOverride() {
-        FieldMapping fm = _mapping.getFieldMapping("embedCollection");
-        assertTrue(fm.getElement().isEmbedded());
-        assertEquals("EMBED_COLL", fm.getTable().getName());
-        assertEquals(0, fm.getElementMapping().getColumns().length);
-
-        ClassMapping embed = fm.getElementMapping().getEmbeddedMapping();
-        fm = embed.getFieldMapping("basic");
-        assertEquals(1, fm.getColumns().length);
-        assertEquals("EM_BASIC", fm.getColumns()[0].getName());
-    }
-
-    public void testInsertAndRetrieve() {
-        NonstandardMappingEntity pc = new NonstandardMappingEntity();
-        pc.getSuperCollection().add("super");
-        pc.setCustom(new Point(1, 2));
-        pc.getStringCollection().add("string");
-        NonstandardMappingEntity pc2 = new NonstandardMappingEntity();
-        pc.getJoinCollection().add(pc2);
-        pc.getStringMap().put("stringKey", "stringValue");
-        NonstandardMappingEntity pc3 = new NonstandardMappingEntity();
-        pc.getJoinMap().put(pc2, pc3);
-        ExtensionsEntity embed = new ExtensionsEntity();
-        embed.setExternalValues('M');
-        embed.setExternalizer(String.class);
-        pc.setEmbed(embed);
-        EmbedValue2 embed2 = new EmbedValue2();
-        embed2.setBasic("basic");
-        pc.getEmbedCollection().add(embed2);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persistAll(new Object[]{ pc, pc2, pc3 });
-        em.getTransaction().commit();
-        Object pcId = em.getObjectId(pc);
-        Object pc2Id = em.getObjectId(pc2);
-        Object pc3Id = em.getObjectId(pc3);
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(NonstandardMappingEntity.class, pcId);
-        assertEquals(1, pc.getSuperCollection().size());
-        assertEquals("super", pc.getSuperCollection().get(0));
-        assertEquals(1, pc.getCustom().x);
-        assertEquals(2, pc.getCustom().y);
-        assertEquals(1, pc.getStringCollection().size());
-        assertEquals("string", pc.getStringCollection().get(0));
-        assertEquals(1, pc.getJoinCollection().size());
-        assertEquals(pc2Id, em.getObjectId(pc.getJoinCollection().get(0)));
-        assertEquals(1, pc.getStringMap().size());
-        assertEquals("stringValue", pc.getStringMap().get("stringKey"));
-        assertEquals(1, pc.getJoinMap().size());
-        Map.Entry entry = pc.getJoinMap().entrySet().iterator().next();
-        assertEquals(pc2Id, em.getObjectId(entry.getKey()));
-        assertEquals(pc3Id, em.getObjectId(entry.getValue()));
-        assertEquals('M', pc.getEmbed().getExternalValues());
-        assertEquals(String.class, pc.getEmbed().getExternalizer());
-        assertEquals(1, pc.getEmbedCollection().size());
-        assertEquals("basic", pc.getEmbedCollection().get(0).getBasic());
-        em.close();
-    }
-
-    public void testInsertAndRetrieveEmbeddedCollection() {
-        NonstandardMappingEntity pc = new NonstandardMappingEntity();
-        EmbedValue2 embed2 = new EmbedValue2();
-        embed2.setBasic("basic");
-        pc.getEmbedCollection().add(embed2);
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(pc);
-        em.getTransaction().commit();
-        Object pcId = em.getObjectId(pc);
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(NonstandardMappingEntity.class, pcId);
-        assertEquals(1, pc.getEmbedCollection().size());
-        assertEquals("basic", pc.getEmbedCollection().get(0).getBasic());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.awt.*;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.meta.strats.ClassNameDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test the parsing of non-standard mapping annotations.</p>
+ *
+ * @author Abe White
+ */
+public class TestNonstandardMappingAnnotations
+    extends SingleEMFTestCase {
+
+    private ClassMapping _mapping;
+    private DBDictionary _dict;
+
+    public void setUp() {
+        setUp(NonstandardMappingEntity.class, ExtensionsEntity.class,
+            NonstandardMappingMappedSuper.class, EmbedValue2.class,
+            EmbedValue.class,
+            CLEAR_TABLES);
+
+        // trigger complete resolution of metadata etc.
+        emf.createEntityManager().close();
+
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        _dict = conf.getDBDictionaryInstance();
+        _mapping = (ClassMapping) JPAFacadeHelper.getMetaData(emf,
+            NonstandardMappingEntity.class);
+    }
+
+    public void testNonpolymorphic() {
+        FieldMapping fm = _mapping.getFieldMapping("superRel");
+        assertEquals(ValueMapping.POLY_FALSE, fm.getPolymorphic());
+
+        ValueMapping vm = _mapping.getFieldMapping("joinCollection").
+            getElementMapping();
+        assertEquals(ValueMapping.POLY_JOINABLE, vm.getPolymorphic());
+
+        vm = _mapping.getFieldMapping("joinMap").getKeyMapping();
+        assertEquals(ValueMapping.POLY_FALSE, vm.getPolymorphic());
+        vm = _mapping.getFieldMapping("joinMap").getElementMapping();
+        assertEquals(ValueMapping.POLY_FALSE, vm.getPolymorphic());
+    }
+
+    public void testDataStoreIdColumn() {
+        assertEquals("NONSTD_ENTITY", _mapping.getTable().getName());
+        assertEquals(ClassMapping.ID_DATASTORE, _mapping.getIdentityType());
+        assertEquals(1, _mapping.getPrimaryKeyColumns().length);
+        assertEquals("OID", _mapping.getPrimaryKeyColumns()[0].getName());
+    }
+
+    public void testDiscriminator() {
+        Discriminator disc = _mapping.getDiscriminator();
+        assertTrue(disc.getStrategy() instanceof
+            ClassNameDiscriminatorStrategy);
+        assertEquals(1, disc.getColumns().length);
+        assertEquals("DISCRIM", disc.getColumns()[0].getName());
+    }
+
+    public void testSuperclassOverride() {
+        FieldMapping fm = _mapping.getFieldMapping("superCollection");
+        assertEquals("SUP_COLL", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("SUP_ELEM", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertNull(fm.getElementMapping().getValueIndex());
+        assertNotNull(fm.getJoinIndex());
+    }
+
+    public void testCustomField() {
+        FieldMapping fm = _mapping.getFieldMapping("custom");
+        assertTrue(fm.getHandler() instanceof PointHandler);
+        assertEquals(2, fm.getColumns().length);
+        assertEquals("X_COL", fm.getColumns()[0].getName());
+        assertEquals("Y_COL", fm.getColumns()[1].getName());
+        assertNotNull(fm.getValueIndex());
+    }
+
+    public void testValueCollection() {
+        FieldMapping fm = _mapping.getFieldMapping("stringCollection");
+        assertEquals("STRINGS_COLL", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("STR_ELEM", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertEquals(127, fm.getElementMapping().getColumns()[0].getSize());
+        assertNotNull(fm.getElementMapping().getValueIndex());
+        assertNull(fm.getJoinIndex());
+    }
+
+    public void testJoinCollection() {
+        FieldMapping fm = _mapping.getFieldMapping("joinCollection");
+        assertEquals("JOIN_COLL", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("JOIN_ELEM", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertForeignKey(fm.getJoinForeignKey());
+        assertForeignKey(fm.getElementMapping().getForeignKey());
+    }
+
+    private void assertForeignKey(ForeignKey fk) {
+        if (_dict.supportsForeignKeys)
+            assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
+    }
+
+    public void testValueMap() {
+        FieldMapping fm = _mapping.getFieldMapping("stringMap");
+        assertEquals("STRINGS_MAP", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getKeyMapping().getColumns().length);
+        assertEquals("STR_KEY", fm.getKeyMapping().getColumns()[0].
+            getName());
+        assertEquals(127, fm.getKeyMapping().getColumns()[0].getSize());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("STR_VAL", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertEquals(127, fm.getElementMapping().getColumns()[0].getSize());
+        assertNull(fm.getJoinIndex());
+        assertNotNull(fm.getKeyMapping().getValueIndex());
+        assertNotNull(fm.getElementMapping().getValueIndex());
+    }
+
+    public void testJoinMap() {
+        FieldMapping fm = _mapping.getFieldMapping("joinMap");
+        assertEquals("JOIN_MAP", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getKeyMapping().getColumns().length);
+        assertEquals("JOIN_KEY", fm.getKeyMapping().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("JOIN_VAL", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertForeignKey(fm.getJoinForeignKey());
+        assertForeignKey(fm.getKeyMapping().getForeignKey());
+        assertForeignKey(fm.getElementMapping().getForeignKey());
+    }
+
+    public void testEmbeddedOverride() {
+        FieldMapping fm = _mapping.getFieldMapping("embed");
+        assertTrue(fm.isEmbedded());
+        assertEquals(1, fm.getColumns().length);
+        assertTrue("UUID_HEX".equalsIgnoreCase(fm.getColumns()[0].
+            getName()));
+
+        ClassMapping embed = fm.getEmbeddedMapping();
+        fm = embed.getFieldMapping("rel");
+        assertEquals(1, fm.getColumns().length);
+        assertEquals("EM_REL_ID", fm.getColumns()[0].getName());
+        fm = embed.getFieldMapping("eager");
+        assertEquals("EM_EAGER", fm.getTable().getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("ELEM_EAGER_ID", fm.getElementMapping().getColumns()[0].
+            getName());
+    }
+
+    public void testEmbeddedElementOverride() {
+        FieldMapping fm = _mapping.getFieldMapping("embedCollection");
+        assertTrue(fm.getElement().isEmbedded());
+        assertEquals("EMBED_COLL", fm.getTable().getName());
+        assertEquals(0, fm.getElementMapping().getColumns().length);
+
+        ClassMapping embed = fm.getElementMapping().getEmbeddedMapping();
+        fm = embed.getFieldMapping("basic");
+        assertEquals(1, fm.getColumns().length);
+        assertEquals("EM_BASIC", fm.getColumns()[0].getName());
+    }
+
+    public void testInsertAndRetrieve() {
+        NonstandardMappingEntity pc = new NonstandardMappingEntity();
+        pc.getSuperCollection().add("super");
+        pc.setCustom(new Point(1, 2));
+        pc.getStringCollection().add("string");
+        NonstandardMappingEntity pc2 = new NonstandardMappingEntity();
+        pc.getJoinCollection().add(pc2);
+        pc.getStringMap().put("stringKey", "stringValue");
+        NonstandardMappingEntity pc3 = new NonstandardMappingEntity();
+        pc.getJoinMap().put(pc2, pc3);
+        ExtensionsEntity embed = new ExtensionsEntity();
+        embed.setExternalValues('M');
+        embed.setExternalizer(String.class);
+        pc.setEmbed(embed);
+        EmbedValue2 embed2 = new EmbedValue2();
+        embed2.setBasic("basic");
+        pc.getEmbedCollection().add(embed2);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persistAll(new Object[]{ pc, pc2, pc3 });
+        em.getTransaction().commit();
+        Object pcId = em.getObjectId(pc);
+        Object pc2Id = em.getObjectId(pc2);
+        Object pc3Id = em.getObjectId(pc3);
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(NonstandardMappingEntity.class, pcId);
+        assertEquals(1, pc.getSuperCollection().size());
+        assertEquals("super", pc.getSuperCollection().get(0));
+        assertEquals(1, pc.getCustom().x);
+        assertEquals(2, pc.getCustom().y);
+        assertEquals(1, pc.getStringCollection().size());
+        assertEquals("string", pc.getStringCollection().get(0));
+        assertEquals(1, pc.getJoinCollection().size());
+        assertEquals(pc2Id, em.getObjectId(pc.getJoinCollection().get(0)));
+        assertEquals(1, pc.getStringMap().size());
+        assertEquals("stringValue", pc.getStringMap().get("stringKey"));
+        assertEquals(1, pc.getJoinMap().size());
+        Map.Entry entry = pc.getJoinMap().entrySet().iterator().next();
+        assertEquals(pc2Id, em.getObjectId(entry.getKey()));
+        assertEquals(pc3Id, em.getObjectId(entry.getValue()));
+        assertEquals('M', pc.getEmbed().getExternalValues());
+        assertEquals(String.class, pc.getEmbed().getExternalizer());
+        assertEquals(1, pc.getEmbedCollection().size());
+        assertEquals("basic", pc.getEmbedCollection().get(0).getBasic());
+        em.close();
+    }
+
+    public void testInsertAndRetrieveEmbeddedCollection() {
+        NonstandardMappingEntity pc = new NonstandardMappingEntity();
+        EmbedValue2 embed2 = new EmbedValue2();
+        embed2.setBasic("basic");
+        pc.getEmbedCollection().add(embed2);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(pc);
+        em.getTransaction().commit();
+        Object pcId = em.getObjectId(pc);
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(NonstandardMappingEntity.class, pcId);
+        assertEquals(1, pc.getEmbedCollection().size());
+        assertEquals("basic", pc.getEmbedCollection().get(0).getBasic());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToMany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToMany.java
index de8bbe9..c2e4dad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToMany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToMany.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.util.Collection;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for 1-m
- *
- * @author Steve Kim
- */
-public class TestOneToMany
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
-    }
-
-    public void testOneToMany() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        pc.getOneMany().add(new AnnoTest2(15, "foo"));
-        pc.getOneMany().add(new AnnoTest2(20, "foobar"));
-        em.persist(pc);
-        em.persistAll(pc.getOneMany());
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        Collection<AnnoTest2> many = pc.getOneMany();
-        assertEquals(2, many.size());
-        for (AnnoTest2 pc2 : many) {
-            switch ((int) pc2.getPk1()) {
-                case 15:
-                    assertEquals("foo", pc2.getPk2());
-                    break;
-                case 20:
-                    assertEquals("foobar", pc2.getPk2());
-                    break;
-                default:
-                    fail("unknown element:" + pc2.getPk1());
-            }
-        }
-        em.close();
-    }
-
-    public void testInverseOwnerOneToMany() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc.getInverseOwnerOneMany().add(pc2);
-        pc2.setOneManyOwner(pc);
-        pc2 = new AnnoTest2(20, "foobar");
-        pc.getInverseOwnerOneMany().add(pc2);
-        pc2.setOneManyOwner(pc);
-        em.persist(pc);
-        em.persistAll(pc.getInverseOwnerOneMany());
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        Collection<AnnoTest2> many = pc.getInverseOwnerOneMany();
-        assertEquals(2, many.size());
-        for (AnnoTest2 pc3 : many) {
-            assertEquals(pc, pc3.getOneManyOwner());
-            switch ((int) pc3.getPk1()) {
-                case 15:
-                    assertEquals("foo", pc3.getPk2());
-                    break;
-                case 20:
-                    assertEquals("foobar", pc3.getPk2());
-                    break;
-                default:
-                    fail("unknown element:" + pc3.getPk1());
-            }
-        }
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.util.Collection;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for 1-m
+ *
+ * @author Steve Kim
+ */
+public class TestOneToMany
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
+    }
+
+    public void testOneToMany() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        pc.getOneMany().add(new AnnoTest2(15, "foo"));
+        pc.getOneMany().add(new AnnoTest2(20, "foobar"));
+        em.persist(pc);
+        em.persistAll(pc.getOneMany());
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        Collection<AnnoTest2> many = pc.getOneMany();
+        assertEquals(2, many.size());
+        for (AnnoTest2 pc2 : many) {
+            switch ((int) pc2.getPk1()) {
+                case 15:
+                    assertEquals("foo", pc2.getPk2());
+                    break;
+                case 20:
+                    assertEquals("foobar", pc2.getPk2());
+                    break;
+                default:
+                    fail("unknown element:" + pc2.getPk1());
+            }
+        }
+        em.close();
+    }
+
+    public void testInverseOwnerOneToMany() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc.getInverseOwnerOneMany().add(pc2);
+        pc2.setOneManyOwner(pc);
+        pc2 = new AnnoTest2(20, "foobar");
+        pc.getInverseOwnerOneMany().add(pc2);
+        pc2.setOneManyOwner(pc);
+        em.persist(pc);
+        em.persistAll(pc.getInverseOwnerOneMany());
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        Collection<AnnoTest2> many = pc.getInverseOwnerOneMany();
+        assertEquals(2, many.size());
+        for (AnnoTest2 pc3 : many) {
+            assertEquals(pc, pc3.getOneManyOwner());
+            switch ((int) pc3.getPk1()) {
+                case 15:
+                    assertEquals("foo", pc3.getPk2());
+                    break;
+                case 20:
+                    assertEquals("foobar", pc3.getPk2());
+                    break;
+                default:
+                    fail("unknown element:" + pc3.getPk1());
+            }
+        }
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToOne.java
index efddefd..89321aa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestOneToOne.java
@@ -1,135 +1,135 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for 1-1
- *
- * @author Steve Kim
- */
-public class TestOneToOne
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
-    }
-
-    public void testOneToOne() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc.setOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        pc2 = pc.getOneOne();
-        assertNotNull(pc2);
-        assertEquals(15, pc2.getPk1());
-        assertEquals("foo", pc2.getPk2());
-        em.close();
-    }
-
-    public void testSelfOneToOne() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest1 pc2 = new AnnoTest1(15);
-        pc.setSelfOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        pc2 = pc.getSelfOneOne();
-        assertNotNull(pc2);
-        assertEquals(new Long(15), pc2.getPk());
-        em.close();
-    }
-
-    public void testPKJoinSelfOneToOne() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest1 pc2 = new AnnoTest1(15);
-        pc.setSelfOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        pc2 = pc.getSelfOneOne();
-        assertNotNull(pc2);
-        assertEquals(new Long(15), pc2.getPk());
-        em.close();
-    }
-
-    public void testOtherTableOneToOne() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc.setOtherTableOneOne(pc2);
-        em.persist(pc);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        pc2 = pc.getOtherTableOneOne();
-        assertNotNull(pc2);
-        assertEquals(15, pc2.getPk1());
-        assertEquals("foo", pc2.getPk2());
-        em.close();
-    }
-
-    public void testInverseOneToOne() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc = new AnnoTest1(5);
-        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
-        pc2.setInverseOneOne(pc);
-        em.persist(pc);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        pc2 = pc.getInverseOwnerOneOne();
-        assertNotNull(pc2);
-        assertEquals(15, pc2.getPk1());
-        assertEquals("foo", pc2.getPk2());
-        assertEquals(pc, pc2.getInverseOneOne());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for 1-1
+ *
+ * @author Steve Kim
+ */
+public class TestOneToOne
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
+    }
+
+    public void testOneToOne() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc.setOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        pc2 = pc.getOneOne();
+        assertNotNull(pc2);
+        assertEquals(15, pc2.getPk1());
+        assertEquals("foo", pc2.getPk2());
+        em.close();
+    }
+
+    public void testSelfOneToOne() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest1 pc2 = new AnnoTest1(15);
+        pc.setSelfOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        pc2 = pc.getSelfOneOne();
+        assertNotNull(pc2);
+        assertEquals(new Long(15), pc2.getPk());
+        em.close();
+    }
+
+    public void testPKJoinSelfOneToOne() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest1 pc2 = new AnnoTest1(15);
+        pc.setSelfOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        pc2 = pc.getSelfOneOne();
+        assertNotNull(pc2);
+        assertEquals(new Long(15), pc2.getPk());
+        em.close();
+    }
+
+    public void testOtherTableOneToOne() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc.setOtherTableOneOne(pc2);
+        em.persist(pc);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        pc2 = pc.getOtherTableOneOne();
+        assertNotNull(pc2);
+        assertEquals(15, pc2.getPk1());
+        assertEquals("foo", pc2.getPk2());
+        em.close();
+    }
+
+    public void testInverseOneToOne() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc = new AnnoTest1(5);
+        AnnoTest2 pc2 = new AnnoTest2(15, "foo");
+        pc2.setInverseOneOne(pc);
+        em.persist(pc);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        pc2 = pc.getInverseOwnerOneOne();
+        assertNotNull(pc2);
+        assertEquals(15, pc2.getPk1());
+        assertEquals("foo", pc2.getPk2());
+        assertEquals(pc, pc2.getInverseOneOne());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestPropertyAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestPropertyAccess.java
index fe8a325..44b9c6c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestPropertyAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestPropertyAccess.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestPropertyAccess
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(PropertyAccess1.class, CLEAR_TABLES);
-    }
-
-    public void testPropertyAccessBasicCreation() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
-        pa1_1.setName("foo");
-        em.persist(pa1_1);
-        em.getTransaction().commit();
-
-        // getting a new EM should not be necessary once the extended PC stuff
-        // is complete.
-        em = emf.createEntityManager();
-
-        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
-        assertNotSame(pa1_1, pa1_2);
-        assertNotNull(pa1_2);
-        assertEquals(10, pa1_2.getId());
-        assertEquals("foo", pa1_2.getName());
-    }
-
-    public void testPropertyAccessBasicMutation() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
-        pa1_1.setName("foo");
-        em.persist(pa1_1);
-        em.getTransaction().commit();
-
-        // getting a new EM should not be necessary once the extended PC stuff
-        // is complete.
-        em = emf.createEntityManager();
-
-        em.getTransaction().begin();
-        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
-        pa1_2.setName(pa1_2.getName() + "bar");
-        em.getTransaction().commit();
-
-        em = emf.createEntityManager();
-        PropertyAccess1 pa1_3 = em.find(PropertyAccess1.class, 10);
-        assertNotSame(pa1_2, pa1_3);
-        assertEquals("foobar", pa1_3.getName());
-    }
-
-    public void testJPQL() {
-        EntityManager em = emf.createEntityManager();
-        em.createQuery("select o from PropertyAccess1 o where " +
-            "o.name = 'foo'").getResultList();
-        em.createQuery("select o from PropertyAccess1 o order by " +
-            "o.name asc").getResultList();
-        em.close();
-    }
-
-    public void testJPQLWithFieldNameMismatch() {
-        EntityManager em = emf.createEntityManager();
-        em.createQuery("select o from PropertyAccess1 o where " +
-            "o.intValue = 0").getResultList();
-        em.createQuery("select o from PropertyAccess1 o order by " +
-            "o.intValue asc").getResultList();
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestPropertyAccess
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(PropertyAccess1.class, CLEAR_TABLES);
+    }
+
+    public void testPropertyAccessBasicCreation() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
+        pa1_1.setName("foo");
+        em.persist(pa1_1);
+        em.getTransaction().commit();
+
+        // getting a new EM should not be necessary once the extended PC stuff
+        // is complete.
+        em = emf.createEntityManager();
+
+        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
+        assertNotSame(pa1_1, pa1_2);
+        assertNotNull(pa1_2);
+        assertEquals(10, pa1_2.getId());
+        assertEquals("foo", pa1_2.getName());
+    }
+
+    public void testPropertyAccessBasicMutation() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        PropertyAccess1 pa1_1 = new PropertyAccess1(10);
+        pa1_1.setName("foo");
+        em.persist(pa1_1);
+        em.getTransaction().commit();
+
+        // getting a new EM should not be necessary once the extended PC stuff
+        // is complete.
+        em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        PropertyAccess1 pa1_2 = em.find(PropertyAccess1.class, 10);
+        pa1_2.setName(pa1_2.getName() + "bar");
+        em.getTransaction().commit();
+
+        em = emf.createEntityManager();
+        PropertyAccess1 pa1_3 = em.find(PropertyAccess1.class, 10);
+        assertNotSame(pa1_2, pa1_3);
+        assertEquals("foobar", pa1_3.getName());
+    }
+
+    public void testJPQL() {
+        EntityManager em = emf.createEntityManager();
+        em.createQuery("select o from PropertyAccess1 o where " +
+            "o.name = 'foo'").getResultList();
+        em.createQuery("select o from PropertyAccess1 o order by " +
+            "o.name asc").getResultList();
+        em.close();
+    }
+
+    public void testJPQLWithFieldNameMismatch() {
+        EntityManager em = emf.createEntityManager();
+        em.createQuery("select o from PropertyAccess1 o where " +
+            "o.intValue = 0").getResultList();
+        em.createQuery("select o from PropertyAccess1 o order by " +
+            "o.intValue asc").getResultList();
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestSerializedLobs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestSerializedLobs.java
index 059ece1..b515d3d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestSerializedLobs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestSerializedLobs.java
@@ -1,137 +1,137 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import java.sql.Blob;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Date;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for serialized, clob, and lob types.
- *
- * @author Steve Kim
- */
-public class TestSerializedLobs extends SingleEMFTestCase {
-
-    private static final Date DATE = new Date();
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
-    }
-
-    // Serialized fields not being read properly
-    public void testSerialized() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 pc1 = new AnnoTest1(1);
-        AnnoTest1 pc2 = new AnnoTest1(2);
-        pc1.setSerialized("ASDASD");
-        pc2.setSerialized(DATE);
-        em.persist(pc1);
-        em.persist(pc2);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc1 = em.find(AnnoTest1.class, new Long(1));
-        pc2 = em.find(AnnoTest1.class, new Long(2));
-        assertEquals("ASDASD", pc1.getSerialized());
-        assertEquals(DATE, pc2.getSerialized());
-        em.close();
-    }
-
-    public void testBlob()
-        throws Exception {
-        OpenJPAEntityManagerSPI em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        AnnoTest1 pc = new AnnoTest1(1);
-        pc.setBlob("Not Null".getBytes());
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(1));
-        assertEquals("Not Null", new String(pc.getBlob()));
-        Connection conn = (Connection) em.getConnection();
-        Statement stmnt = conn.createStatement();
-        ResultSet rs = stmnt.executeQuery("SELECT BLOBVAL FROM ANNOTEST1 "
-            + "WHERE PK = 1");
-        assertTrue(rs.next());
-
-        JDBCConfiguration conf = (JDBCConfiguration) em.getConfiguration();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        if (dict.useGetBytesForBlobs)
-            rs.getBytes(1);
-        else if (dict.useGetObjectForBlobs)
-            rs.getObject(1);
-        else {
-            Blob blob = rs.getBlob(1);
-            blob.getBytes(1L, (int) blob.length());
-        }
-        assertEquals("Not Null", new String(pc.getBlob()));
-
-        try {
-            rs.close();
-        } catch (SQLException e) {
-        }
-        try {
-            stmnt.close();
-        } catch (SQLException e) {
-        }
-        try {
-            conn.close();
-        } catch (SQLException e) {
-        }
-        em.close();
-    }
-
-    public void testClob()
-        throws Exception {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        AnnoTest1 pc = new AnnoTest1(1);
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < 1000; i++)
-            buf.append((char) ('a' + (i % 24)));
-        pc.setClob(buf.toString());
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(1));
-        String str = pc.getClob();
-        assertEquals(1000, str.length());
-        for (int i = 0; i < str.length(); i++)
-            assertEquals('a' + (i % 24), str.charAt(i));
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Date;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for serialized, clob, and lob types.
+ *
+ * @author Steve Kim
+ */
+public class TestSerializedLobs extends SingleEMFTestCase {
+
+    private static final Date DATE = new Date();
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class, CLEAR_TABLES);
+    }
+
+    // Serialized fields not being read properly
+    public void testSerialized() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 pc1 = new AnnoTest1(1);
+        AnnoTest1 pc2 = new AnnoTest1(2);
+        pc1.setSerialized("ASDASD");
+        pc2.setSerialized(DATE);
+        em.persist(pc1);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc1 = em.find(AnnoTest1.class, new Long(1));
+        pc2 = em.find(AnnoTest1.class, new Long(2));
+        assertEquals("ASDASD", pc1.getSerialized());
+        assertEquals(DATE, pc2.getSerialized());
+        em.close();
+    }
+
+    public void testBlob()
+        throws Exception {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        AnnoTest1 pc = new AnnoTest1(1);
+        pc.setBlob("Not Null".getBytes());
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(1));
+        assertEquals("Not Null", new String(pc.getBlob()));
+        Connection conn = (Connection) em.getConnection();
+        Statement stmnt = conn.createStatement();
+        ResultSet rs = stmnt.executeQuery("SELECT BLOBVAL FROM ANNOTEST1 "
+            + "WHERE PK = 1");
+        assertTrue(rs.next());
+
+        JDBCConfiguration conf = (JDBCConfiguration) em.getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        if (dict.useGetBytesForBlobs)
+            rs.getBytes(1);
+        else if (dict.useGetObjectForBlobs)
+            rs.getObject(1);
+        else {
+            Blob blob = rs.getBlob(1);
+            blob.getBytes(1L, (int) blob.length());
+        }
+        assertEquals("Not Null", new String(pc.getBlob()));
+
+        try {
+            rs.close();
+        } catch (SQLException e) {
+        }
+        try {
+            stmnt.close();
+        } catch (SQLException e) {
+        }
+        try {
+            conn.close();
+        } catch (SQLException e) {
+        }
+        em.close();
+    }
+
+    public void testClob()
+        throws Exception {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        AnnoTest1 pc = new AnnoTest1(1);
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < 1000; i++)
+            buf.append((char) ('a' + (i % 24)));
+        pc.setClob(buf.toString());
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(1));
+        String str = pc.getClob();
+        assertEquals(1000, str.length());
+        for (int i = 0; i < str.length(); i++)
+            assertEquals('a' + (i % 24), str.charAt(i));
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestTablePerClassInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestTablePerClassInheritance.java
index 2525241..d2bf954 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestTablePerClassInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestTablePerClassInheritance.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
-import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * <p>Test that InheritanceType.TABLE_PER_CLASS JPA mapping is translated
- * correctly.  See the <code>kodo.jdbc.meta.tableperclass</code> test package
- * for more detailed tests of functionality.</p>
- *
- * @author Abe White
- */
-public class TestTablePerClassInheritance
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(TablePerClass1.class, TablePerClass2.class, EmbedOwner.class,
-            EmbedValue.class, CLEAR_TABLES);
-    }
-
-    public void testMapping() {
-        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration()).
-            getMappingRepositoryInstance().getMapping(TablePerClass2.class,
-            null, true);
-        assertTrue(mapping.getStrategy() instanceof FullClassStrategy);
-        assertTrue(mapping.getDiscriminator().getStrategy()
-            instanceof NoneDiscriminatorStrategy);
-        assertNull(mapping.getJoinForeignKey());
-        assertNull(mapping.getJoinablePCSuperclassMapping());
-        assertEquals("TPC_BASIC", mapping.getFieldMapping("basic").
-            getColumns()[0].getName());
-        ClassMapping embed = mapping.getFieldMapping("embed").
-            getEmbeddedMapping();
-        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
-            getColumns()[0].getName());
-
-        ClassMapping sup = mapping.getPCSuperclassMapping();
-        assertEquals(TablePerClass1.class, sup.getDescribedType());
-        assertTrue(sup.getStrategy() instanceof FullClassStrategy);
-        assertTrue(sup.getDiscriminator().getStrategy()
-            instanceof NoneDiscriminatorStrategy);
-        assertEquals("TPC_BASIC", sup.getFieldMapping("basic").
-            getColumns()[0].getName());
-        embed = sup.getFieldMapping("embed").getEmbeddedMapping();
-        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
-            getColumns()[0].getName());
-    }
-
-    public void testInsertAndRetrieve() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        TablePerClass1 tpc1 = new TablePerClass1();
-        tpc1.setBasic(1);
-        EmbedValue ev = new EmbedValue();
-        ev.setBasic("11");
-        tpc1.setEmbed(ev);
-        TablePerClass2 tpc2 = new TablePerClass2();
-        tpc2.setBasic(2);
-        tpc2.setBasic2("2");
-        ev = new EmbedValue();
-        ev.setBasic("22");
-        tpc2.setEmbed(ev);
-        em.persistAll(tpc1, tpc2);
-        em.getTransaction().commit();
-        int id1 = tpc1.getPk();
-        int id2 = tpc2.getPk();
-        em.close();
-
-        em = emf.createEntityManager();
-        tpc1 = em.find(TablePerClass1.class, id1);
-        assertEquals(1, tpc1.getBasic());
-        assertEquals("11", tpc1.getEmbed().getBasic());
-        tpc2 = (TablePerClass2) em.find(TablePerClass1.class, id2);
-        assertEquals(2, tpc2.getBasic());
-        assertEquals("2", tpc2.getBasic2());
-        assertEquals("22", tpc2.getEmbed().getBasic());
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
+import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test that InheritanceType.TABLE_PER_CLASS JPA mapping is translated
+ * correctly.  See the <code>kodo.jdbc.meta.tableperclass</code> test package
+ * for more detailed tests of functionality.</p>
+ *
+ * @author Abe White
+ */
+public class TestTablePerClassInheritance
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(TablePerClass1.class, TablePerClass2.class, EmbedOwner.class,
+            EmbedValue.class, CLEAR_TABLES);
+    }
+
+    public void testMapping() {
+        ClassMapping mapping = ((JDBCConfiguration) emf.getConfiguration()).
+            getMappingRepositoryInstance().getMapping(TablePerClass2.class,
+            null, true);
+        assertTrue(mapping.getStrategy() instanceof FullClassStrategy);
+        assertTrue(mapping.getDiscriminator().getStrategy()
+            instanceof NoneDiscriminatorStrategy);
+        assertNull(mapping.getJoinForeignKey());
+        assertNull(mapping.getJoinablePCSuperclassMapping());
+        assertEquals("TPC_BASIC", mapping.getFieldMapping("basic").
+            getColumns()[0].getName());
+        ClassMapping embed = mapping.getFieldMapping("embed").
+            getEmbeddedMapping();
+        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
+            getColumns()[0].getName());
+
+        ClassMapping sup = mapping.getPCSuperclassMapping();
+        assertEquals(TablePerClass1.class, sup.getDescribedType());
+        assertTrue(sup.getStrategy() instanceof FullClassStrategy);
+        assertTrue(sup.getDiscriminator().getStrategy()
+            instanceof NoneDiscriminatorStrategy);
+        assertEquals("TPC_BASIC", sup.getFieldMapping("basic").
+            getColumns()[0].getName());
+        embed = sup.getFieldMapping("embed").getEmbeddedMapping();
+        assertEquals("TPC_EMB_BASIC", embed.getFieldMapping("basic").
+            getColumns()[0].getName());
+    }
+
+    public void testInsertAndRetrieve() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        TablePerClass1 tpc1 = new TablePerClass1();
+        tpc1.setBasic(1);
+        EmbedValue ev = new EmbedValue();
+        ev.setBasic("11");
+        tpc1.setEmbed(ev);
+        TablePerClass2 tpc2 = new TablePerClass2();
+        tpc2.setBasic(2);
+        tpc2.setBasic2("2");
+        ev = new EmbedValue();
+        ev.setBasic("22");
+        tpc2.setEmbed(ev);
+        em.persistAll(tpc1, tpc2);
+        em.getTransaction().commit();
+        int id1 = tpc1.getPk();
+        int id2 = tpc2.getPk();
+        em.close();
+
+        em = emf.createEntityManager();
+        tpc1 = em.find(TablePerClass1.class, id1);
+        assertEquals(1, tpc1.getBasic());
+        assertEquals("11", tpc1.getEmbed().getBasic());
+        tpc2 = (TablePerClass2) em.find(TablePerClass1.class, id2);
+        assertEquals(2, tpc2.getBasic());
+        assertEquals("2", tpc2.getBasic2());
+        assertEquals("22", tpc2.getEmbed().getBasic());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestVersion.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestVersion.java
index 589ee3a..3106e02 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestVersion.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestVersion.java
@@ -1,195 +1,195 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.NoneVersionStrategy;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Test for opt-lock
- *
- * @author Steve Kim
- */
-public class TestVersion extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AnnoTest1.class, AnnoTest2.class, AnnoTest3.class, Flat1.class,
-            EmbedOwner.class, EmbedValue.class, CLEAR_TABLES);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AnnoTest1 test1 = new AnnoTest1();
-        test1.setPk(new Long(5));
-        test1.setBasic(50);
-        test1.setTransient(500);
-        em.persist(test1);
-
-        AnnoTest2 test2 = new AnnoTest2();
-        test2.setPk1(5);
-        test2.setPk2("bar");
-        test2.setBasic("50");
-        em.persist(test2);
-
-        AnnoTest3 test3 = new AnnoTest3();
-        test3.setPk(new Long(3));
-        test3.setBasic2(50);
-        em.persist(test3);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testVersionNumeric() {
-        EntityManager em1 = emf.createEntityManager();
-        em1.getTransaction().begin();
-        EntityManager em2 = emf.createEntityManager();
-        em2.getTransaction().begin();
-
-        AnnoTest1 pc1 = em1.find(AnnoTest1.class, new Long(5));
-        AnnoTest1 pc2 = em2.find(AnnoTest1.class, new Long(5));
-        assertEquals(1, pc1.getVersion());
-        assertEquals(1, pc2.getVersion());
-        assertEquals(0, pc1.getTransient());
-        pc1.setBasic(75);
-        pc2.setBasic(75);
-        em1.getTransaction().commit();
-        em1.close();
-
-        em1 = emf.createEntityManager();
-        pc1 = em1.find(AnnoTest1.class, new Long(5));
-        assertEquals(2, pc1.getVersion());
-        em1.close();
-        try {
-            em2.getTransaction().commit();
-            fail("Optimistic fail");
-        } catch (Exception e) {
-        } finally {
-            em2.close();
-        }
-    }
-
-    public void testVersionTimestamp() {
-        // ensure that some time has passed
-        // since the records were created
-        try {
-            Thread.sleep(50);
-        }
-        catch (InterruptedException e) {
-            // do nothing
-        }
-        
-        EntityManager em1 = emf.createEntityManager();
-        em1.getTransaction().begin();
-        EntityManager em2 = emf.createEntityManager();
-        em2.getTransaction().begin();
-
-        AnnoTest2 pc1 = em1.find(AnnoTest2.class,
-            new AnnoTest2.Oid(5, "bar"));
-        AnnoTest2 pc2 = em2.find(AnnoTest2.class,
-            new AnnoTest2.Oid(5, "bar"));
-        assertNotNull(pc1.getVersion());
-        assertEquals(pc1.getVersion(), pc2.getVersion());
-        pc1.setBasic("75");
-        pc2.setBasic("75");
-        em1.getTransaction().commit();
-        em1.close();
-
-        em1 = emf.createEntityManager();
-        pc1 = em1.find(AnnoTest2.class,
-            new AnnoTest2.Oid(5, "bar"));
-        java.util.Date pc1Version = pc1.getVersion();
-        java.util.Date pc2Version = pc2.getVersion();
-        assertTrue(pc1Version.compareTo(pc2Version) > 0);
-        em1.close();
-        try {
-            em2.getTransaction().commit();
-            fail("Optimistic fail");
-        } catch (Exception e) {
-        } finally {
-            em2.close();
-        }
-    }
-
-    public void testVersionSubclass() {
-        EntityManager em1 = emf.createEntityManager();
-        em1.getTransaction().begin();
-        EntityManager em2 = emf.createEntityManager();
-        em2.getTransaction().begin();
-
-        AnnoTest3 pc1 = em1.find(AnnoTest3.class, new Long(3));
-        AnnoTest3 pc2 = em2.find(AnnoTest3.class, new Long(3));
-        assertEquals(1, pc1.getVersion());
-        assertEquals(1, pc2.getVersion());
-        pc1.setBasic2(75);
-        pc2.setBasic2(75);
-        em1.getTransaction().commit();
-        em1.close();
-
-        em1 = emf.createEntityManager();
-        pc1 = em1.find(AnnoTest3.class, new Long(3));
-        assertEquals(2, pc1.getVersion());
-        em1.close();
-        try {
-            em2.getTransaction().commit();
-            fail("Optimistic fail");
-        } catch (Exception e) {
-        } finally {
-            em2.close();
-        }
-    }
-
-    public void testVersionNoChange() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        AnnoTest1 pc = em.find(AnnoTest1.class, new Long(5));
-        assertEquals(1, pc.getVersion());
-        assertEquals(0, pc.getTransient());
-        pc.setTransient(750);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(AnnoTest1.class, new Long(5));
-        assertEquals(1, pc.getVersion());
-        assertEquals(0, pc.getTransient());
-        em.close();
-    }
-
-    public void testNoDefaultVersionWithoutFieldOrColumn() {
-        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
-            getMappingRepositoryInstance().getMapping(EmbedOwner.class, 
-            null, true);
-        assertEquals(NoneVersionStrategy.getInstance(),
-            cls.getVersion().getStrategy());
-        assertEquals(0, cls.getVersion().getColumns().length);
-    }
-
-    public void testVersionWithField() {
-        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
-            getMappingRepositoryInstance().getMapping(AnnoTest1.class, 
-            null, true);
-        assertTrue(NoneVersionStrategy.getInstance() !=
-            cls.getVersion().getStrategy());
-        assertEquals(1, cls.getVersion().getColumns().length);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.NoneVersionStrategy;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test for opt-lock
+ *
+ * @author Steve Kim
+ */
+public class TestVersion extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AnnoTest1.class, AnnoTest2.class, AnnoTest3.class, Flat1.class,
+            EmbedOwner.class, EmbedValue.class, CLEAR_TABLES);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AnnoTest1 test1 = new AnnoTest1();
+        test1.setPk(new Long(5));
+        test1.setBasic(50);
+        test1.setTransient(500);
+        em.persist(test1);
+
+        AnnoTest2 test2 = new AnnoTest2();
+        test2.setPk1(5);
+        test2.setPk2("bar");
+        test2.setBasic("50");
+        em.persist(test2);
+
+        AnnoTest3 test3 = new AnnoTest3();
+        test3.setPk(new Long(3));
+        test3.setBasic2(50);
+        em.persist(test3);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testVersionNumeric() {
+        EntityManager em1 = emf.createEntityManager();
+        em1.getTransaction().begin();
+        EntityManager em2 = emf.createEntityManager();
+        em2.getTransaction().begin();
+
+        AnnoTest1 pc1 = em1.find(AnnoTest1.class, new Long(5));
+        AnnoTest1 pc2 = em2.find(AnnoTest1.class, new Long(5));
+        assertEquals(1, pc1.getVersion());
+        assertEquals(1, pc2.getVersion());
+        assertEquals(0, pc1.getTransient());
+        pc1.setBasic(75);
+        pc2.setBasic(75);
+        em1.getTransaction().commit();
+        em1.close();
+
+        em1 = emf.createEntityManager();
+        pc1 = em1.find(AnnoTest1.class, new Long(5));
+        assertEquals(2, pc1.getVersion());
+        em1.close();
+        try {
+            em2.getTransaction().commit();
+            fail("Optimistic fail");
+        } catch (Exception e) {
+        } finally {
+            em2.close();
+        }
+    }
+
+    public void testVersionTimestamp() {
+        // ensure that some time has passed
+        // since the records were created
+        try {
+            Thread.sleep(50);
+        }
+        catch (InterruptedException e) {
+            // do nothing
+        }
+        
+        EntityManager em1 = emf.createEntityManager();
+        em1.getTransaction().begin();
+        EntityManager em2 = emf.createEntityManager();
+        em2.getTransaction().begin();
+
+        AnnoTest2 pc1 = em1.find(AnnoTest2.class,
+            new AnnoTest2.Oid(5, "bar"));
+        AnnoTest2 pc2 = em2.find(AnnoTest2.class,
+            new AnnoTest2.Oid(5, "bar"));
+        assertNotNull(pc1.getVersion());
+        assertEquals(pc1.getVersion(), pc2.getVersion());
+        pc1.setBasic("75");
+        pc2.setBasic("75");
+        em1.getTransaction().commit();
+        em1.close();
+
+        em1 = emf.createEntityManager();
+        pc1 = em1.find(AnnoTest2.class,
+            new AnnoTest2.Oid(5, "bar"));
+        java.util.Date pc1Version = pc1.getVersion();
+        java.util.Date pc2Version = pc2.getVersion();
+        assertTrue(pc1Version.compareTo(pc2Version) > 0);
+        em1.close();
+        try {
+            em2.getTransaction().commit();
+            fail("Optimistic fail");
+        } catch (Exception e) {
+        } finally {
+            em2.close();
+        }
+    }
+
+    public void testVersionSubclass() {
+        EntityManager em1 = emf.createEntityManager();
+        em1.getTransaction().begin();
+        EntityManager em2 = emf.createEntityManager();
+        em2.getTransaction().begin();
+
+        AnnoTest3 pc1 = em1.find(AnnoTest3.class, new Long(3));
+        AnnoTest3 pc2 = em2.find(AnnoTest3.class, new Long(3));
+        assertEquals(1, pc1.getVersion());
+        assertEquals(1, pc2.getVersion());
+        pc1.setBasic2(75);
+        pc2.setBasic2(75);
+        em1.getTransaction().commit();
+        em1.close();
+
+        em1 = emf.createEntityManager();
+        pc1 = em1.find(AnnoTest3.class, new Long(3));
+        assertEquals(2, pc1.getVersion());
+        em1.close();
+        try {
+            em2.getTransaction().commit();
+            fail("Optimistic fail");
+        } catch (Exception e) {
+        } finally {
+            em2.close();
+        }
+    }
+
+    public void testVersionNoChange() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        AnnoTest1 pc = em.find(AnnoTest1.class, new Long(5));
+        assertEquals(1, pc.getVersion());
+        assertEquals(0, pc.getTransient());
+        pc.setTransient(750);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(AnnoTest1.class, new Long(5));
+        assertEquals(1, pc.getVersion());
+        assertEquals(0, pc.getTransient());
+        em.close();
+    }
+
+    public void testNoDefaultVersionWithoutFieldOrColumn() {
+        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
+            getMappingRepositoryInstance().getMapping(EmbedOwner.class, 
+            null, true);
+        assertEquals(NoneVersionStrategy.getInstance(),
+            cls.getVersion().getStrategy());
+        assertEquals(0, cls.getVersion().getColumns().length);
+    }
+
+    public void testVersionWithField() {
+        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
+            getMappingRepositoryInstance().getMapping(AnnoTest1.class, 
+            null, true);
+        assertTrue(NoneVersionStrategy.getInstance() !=
+            cls.getVersion().getStrategy());
+        assertEquals(1, cls.getVersion().getColumns().length);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedInappropriateTransient.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedInappropriateTransient.java
index 14c34ef..35bb289 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedInappropriateTransient.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedInappropriateTransient.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Transient;
-import javax.persistence.PrePersist;
-
-@Entity
-public class UnenhancedInappropriateTransient {
-
-    @Id private int id;
-
-    @Transient @PrePersist public void prePersist() {
-        throw new UnsupportedOperationException();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+import javax.persistence.PrePersist;
+
+@Entity
+public class UnenhancedInappropriateTransient {
+
+    @Id private int id;
+
+    @Transient @PrePersist public void prePersist() {
+        throw new UnsupportedOperationException();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedMixedAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedMixedAccess.java
index b1a9752..b0b71c1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedMixedAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/UnenhancedMixedAccess.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.annotations;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Transient;
-
-@Entity
-public class UnenhancedMixedAccess {
-
-    @Id private int id;
-
-    @Transient public String getStringField() {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setStringField(String str) {
-        throw new UnsupportedOperationException();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.annotations;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+@Entity
+public class UnenhancedMixedAccess {
+
+    @Id private int id;
+
+    @Transient public String getStringField() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setStringField(String str) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java
index 166e0ac..22f627d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java
@@ -1,118 +1,118 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import java.util.*;
-import java.io.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-@Entity
-
-
-public class AttachA
-    implements Serializable, PreDetachCallback,
-    PostDetachCallback, PreAttachCallback, PostAttachCallback {
-
-    // transient method for testing callbacks
-    public transient Object detachSource = null;
-    public transient Object attachSource = null;
-    public transient int preAttachCalls = 0;
-    public transient int postAttachCalls = 0;
-    public transient int preDetachCalls = 0;
-    public transient int postDetachCalls = 0;
-
-    private String astr;
-    private int aint;
-    private double adbl;
-    private String [] stringArray = new String [0];
-    private AttachE [] attachEArray = new AttachE [0];
-
-    public void jdoPreDetach() {
-        preDetachCalls++;
-    }
-
-    public void jdoPostDetach(Object orig) {
-        postDetachCalls++;
-        detachSource = orig;
-    }
-
-    public void jdoPreAttach() {
-        preAttachCalls++;
-    }
-
-    public void jdoPostAttach(Object orig) {
-        postAttachCalls++;
-        attachSource = orig;
-    }
-
-    public void setAstr(String astr) {
-        this.astr = astr;
-    }
-
-    public String getAstr() {
-        return this.astr;
-    }
-
-    public void setAint(int aint) {
-        this.aint = aint;
-    }
-
-    public int getAint() {
-        return this.aint;
-    }
-
-    public void setAdbl(double adbl) {
-        this.adbl = adbl;
-    }
-
-    public double getAdbl() {
-        return this.adbl;
-    }
-
-    public void setStringArray(String [] stringArray) {
-        this.stringArray = stringArray;
-    }
-
-    public String [] getStringArray() {
-        return this.stringArray;
-    }
-
-    public void setAttachEArray(AttachE [] attachEArray) {
-        this.attachEArray = attachEArray;
-    }
-
-    public AttachE [] getAttachEArray() {
-        return this.attachEArray;
-    }
-
-    private void writeObject(ObjectOutputStream out)
-        throws IOException {
-        out.defaultWriteObject();
-    }
-
-    private void readObject(ObjectInputStream in)
-        throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+import java.io.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+
+
+public class AttachA
+    implements Serializable, PreDetachCallback,
+    PostDetachCallback, PreAttachCallback, PostAttachCallback {
+
+    // transient method for testing callbacks
+    public transient Object detachSource = null;
+    public transient Object attachSource = null;
+    public transient int preAttachCalls = 0;
+    public transient int postAttachCalls = 0;
+    public transient int preDetachCalls = 0;
+    public transient int postDetachCalls = 0;
+
+    private String astr;
+    private int aint;
+    private double adbl;
+    private String [] stringArray = new String [0];
+    private AttachE [] attachEArray = new AttachE [0];
+
+    public void jdoPreDetach() {
+        preDetachCalls++;
+    }
+
+    public void jdoPostDetach(Object orig) {
+        postDetachCalls++;
+        detachSource = orig;
+    }
+
+    public void jdoPreAttach() {
+        preAttachCalls++;
+    }
+
+    public void jdoPostAttach(Object orig) {
+        postAttachCalls++;
+        attachSource = orig;
+    }
+
+    public void setAstr(String astr) {
+        this.astr = astr;
+    }
+
+    public String getAstr() {
+        return this.astr;
+    }
+
+    public void setAint(int aint) {
+        this.aint = aint;
+    }
+
+    public int getAint() {
+        return this.aint;
+    }
+
+    public void setAdbl(double adbl) {
+        this.adbl = adbl;
+    }
+
+    public double getAdbl() {
+        return this.adbl;
+    }
+
+    public void setStringArray(String [] stringArray) {
+        this.stringArray = stringArray;
+    }
+
+    public String [] getStringArray() {
+        return this.stringArray;
+    }
+
+    public void setAttachEArray(AttachE [] attachEArray) {
+        this.attachEArray = attachEArray;
+    }
+
+    public AttachE [] getAttachEArray() {
+        return this.attachEArray;
+    }
+
+    private void writeObject(ObjectOutputStream out)
+        throws IOException {
+        out.defaultWriteObject();
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java
index c34d0a1..8ef39b6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import java.io.*;
-import java.util.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-@Entity
-public class AttachB
-    extends AttachA {
-
-    private String bstr;
-    private int bint;
-    private double bdbl;
-    private Set ds = new HashSet();
-    private Map stringIntMap = new TreeMap();
-
-    public void setBstr(String bstr) {
-        this.bstr = bstr;
-    }
-
-    public String getBstr() {
-        return this.bstr;
-    }
-
-    public void setBint(int bint) {
-        this.bint = bint;
-    }
-
-    public int getBint() {
-        return this.bint;
-    }
-
-    public void setBdbl(double bdbl) {
-        this.bdbl = bdbl;
-    }
-
-    public double getBdbl() {
-        return this.bdbl;
-    }
-
-    public void setDs(Set ds) {
-        this.ds = ds;
-    }
-
-    public Set getDs() {
-        return this.ds;
-    }
-
-    public void setStringIntMap(Map stringIntMap) {
-        this.stringIntMap = stringIntMap;
-    }
-
-    public Map getStringIntMap() {
-        return this.stringIntMap;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.io.*;
+import java.util.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+public class AttachB
+    extends AttachA {
+
+    private String bstr;
+    private int bint;
+    private double bdbl;
+    private Set ds = new HashSet();
+    private Map stringIntMap = new TreeMap();
+
+    public void setBstr(String bstr) {
+        this.bstr = bstr;
+    }
+
+    public String getBstr() {
+        return this.bstr;
+    }
+
+    public void setBint(int bint) {
+        this.bint = bint;
+    }
+
+    public int getBint() {
+        return this.bint;
+    }
+
+    public void setBdbl(double bdbl) {
+        this.bdbl = bdbl;
+    }
+
+    public double getBdbl() {
+        return this.bdbl;
+    }
+
+    public void setDs(Set ds) {
+        this.ds = ds;
+    }
+
+    public Set getDs() {
+        return this.ds;
+    }
+
+    public void setStringIntMap(Map stringIntMap) {
+        this.stringIntMap = stringIntMap;
+    }
+
+    public Map getStringIntMap() {
+        return this.stringIntMap;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachC.java
index 4b87751..b0f0ad9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachC.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import java.util.*;
-import java.io.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-@Entity
-public class AttachC
-    extends AttachB {
-
-    private String cstr;
-    private int cint;
-    private double cdbl;
-    private List es = new LinkedList(); // non-DFG
-
-    public void setCstr(String cstr) {
-        this.cstr = cstr;
-    }
-
-    public String getCstr() {
-        return this.cstr;
-    }
-
-    public void setCint(int cint) {
-        this.cint = cint;
-    }
-
-    public int getCint() {
-        return this.cint;
-    }
-
-    public void setCdbl(double cdbl) {
-        this.cdbl = cdbl;
-    }
-
-    public double getCdbl() {
-        return this.cdbl;
-    }
-
-    public void setEs(List es) {
-        this.es = es;
-    }
-
-    public List getEs() {
-        return this.es;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+import java.io.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+public class AttachC
+    extends AttachB {
+
+    private String cstr;
+    private int cint;
+    private double cdbl;
+    private List es = new LinkedList(); // non-DFG
+
+    public void setCstr(String cstr) {
+        this.cstr = cstr;
+    }
+
+    public String getCstr() {
+        return this.cstr;
+    }
+
+    public void setCint(int cint) {
+        this.cint = cint;
+    }
+
+    public int getCint() {
+        return this.cint;
+    }
+
+    public void setCdbl(double cdbl) {
+        this.cdbl = cdbl;
+    }
+
+    public double getCdbl() {
+        return this.cdbl;
+    }
+
+    public void setEs(List es) {
+        this.es = es;
+    }
+
+    public List getEs() {
+        return this.es;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachD.java
index 728c63a..2488521 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachD.java
@@ -1,122 +1,122 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import java.util.*;
-import java.io.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-@Entity
-public class AttachD
-    implements Serializable {
-
-    private Object version;
-
-    private String dstr;
-    private int dint;
-    private double ddbl;
-    private AttachA a;
-    private Set bs = new HashSet(); // DFG
-    private Map pcStringMap = new HashMap();
-    private TreeMap bigIntegerPCMap = new TreeMap();
-
-    private AttachE embeddedE;
-    private AttachA embeddedA;
-
-    public void setDstr(String dstr) {
-        this.dstr = dstr;
-    }
-
-    public String getDstr() {
-        return this.dstr;
-    }
-
-    public void setDint(int dint) {
-        this.dint = dint;
-    }
-
-    public int getDint() {
-        return this.dint;
-    }
-
-    public void setDdbl(double ddbl) {
-        this.ddbl = ddbl;
-    }
-
-    public double getDdbl() {
-        return this.ddbl;
-    }
-
-    public AttachA getA() {
-        return a;
-    }
-
-    public void setA(AttachA a) {
-        this.a = a;
-    }
-
-    public void setBs(Set bs) {
-        this.bs = bs;
-    }
-
-    public Set getBs() {
-        return this.bs;
-    }
-
-    public void setPcStringMap(Map pcStringMap) {
-        this.pcStringMap = pcStringMap;
-    }
-
-    public Map getPcStringMap() {
-        return this.pcStringMap;
-    }
-
-    public void setBigIntegerPCMap(TreeMap bigIntegerPCMap) {
-        this.bigIntegerPCMap = bigIntegerPCMap;
-    }
-
-    public TreeMap getBigIntegerPCMap() {
-        return this.bigIntegerPCMap;
-    }
-
-    public void setEmbeddedE(AttachE embeddedE) {
-        this.embeddedE = embeddedE;
-    }
-
-    public AttachE getEmbeddedE() {
-        return this.embeddedE;
-    }
-
-    public void setEmbeddedA(AttachA embeddedA) {
-        this.embeddedA = embeddedA;
-    }
-
-    public AttachA getEmbeddedA() {
-        return this.embeddedA;
-    }
-
-    public Object getVersion() {
-        return this.version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+import java.io.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+public class AttachD
+    implements Serializable {
+
+    private Object version;
+
+    private String dstr;
+    private int dint;
+    private double ddbl;
+    private AttachA a;
+    private Set bs = new HashSet(); // DFG
+    private Map pcStringMap = new HashMap();
+    private TreeMap bigIntegerPCMap = new TreeMap();
+
+    private AttachE embeddedE;
+    private AttachA embeddedA;
+
+    public void setDstr(String dstr) {
+        this.dstr = dstr;
+    }
+
+    public String getDstr() {
+        return this.dstr;
+    }
+
+    public void setDint(int dint) {
+        this.dint = dint;
+    }
+
+    public int getDint() {
+        return this.dint;
+    }
+
+    public void setDdbl(double ddbl) {
+        this.ddbl = ddbl;
+    }
+
+    public double getDdbl() {
+        return this.ddbl;
+    }
+
+    public AttachA getA() {
+        return a;
+    }
+
+    public void setA(AttachA a) {
+        this.a = a;
+    }
+
+    public void setBs(Set bs) {
+        this.bs = bs;
+    }
+
+    public Set getBs() {
+        return this.bs;
+    }
+
+    public void setPcStringMap(Map pcStringMap) {
+        this.pcStringMap = pcStringMap;
+    }
+
+    public Map getPcStringMap() {
+        return this.pcStringMap;
+    }
+
+    public void setBigIntegerPCMap(TreeMap bigIntegerPCMap) {
+        this.bigIntegerPCMap = bigIntegerPCMap;
+    }
+
+    public TreeMap getBigIntegerPCMap() {
+        return this.bigIntegerPCMap;
+    }
+
+    public void setEmbeddedE(AttachE embeddedE) {
+        this.embeddedE = embeddedE;
+    }
+
+    public AttachE getEmbeddedE() {
+        return this.embeddedE;
+    }
+
+    public void setEmbeddedA(AttachA embeddedA) {
+        this.embeddedA = embeddedA;
+    }
+
+    public AttachA getEmbeddedA() {
+        return this.embeddedA;
+    }
+
+    public Object getVersion() {
+        return this.version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachE.java
index e521532..0263a59 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachE.java
@@ -1,90 +1,90 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import java.util.*;
-import java.io.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-@Entity
-public class AttachE
-    implements Serializable {
-
-    private Object version;
-
-    private String estr;
-    private int eint;
-    private double edbl;
-    private AttachB b;
-    private AttachF f;
-    private Date date;
-
-    public void setEstr(String estr) {
-        this.estr = estr;
-    }
-
-    public String getEstr() {
-        return this.estr;
-    }
-
-    public void setEint(int eint) {
-        this.eint = eint;
-    }
-
-    public int getEint() {
-        return this.eint;
-    }
-
-    public void setEdbl(double edbl) {
-        this.edbl = edbl;
-    }
-
-    public double getEdbl() {
-        return this.edbl;
-    }
-
-    public void setB(AttachB b) {
-        this.b = b;
-    }
-
-    public AttachB getB() {
-        return this.b;
-    }
-
-    public void setF(AttachF f) {
-        this.f = f;
-    }
-
-    public AttachF getF() {
-        return this.f;
-    }
-
-    public void setDate(Date date) {
-        this.date = date;
-    }
-
-    public Date getDate() {
-        return this.date;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+import java.io.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+public class AttachE
+    implements Serializable {
+
+    private Object version;
+
+    private String estr;
+    private int eint;
+    private double edbl;
+    private AttachB b;
+    private AttachF f;
+    private Date date;
+
+    public void setEstr(String estr) {
+        this.estr = estr;
+    }
+
+    public String getEstr() {
+        return this.estr;
+    }
+
+    public void setEint(int eint) {
+        this.eint = eint;
+    }
+
+    public int getEint() {
+        return this.eint;
+    }
+
+    public void setEdbl(double edbl) {
+        this.edbl = edbl;
+    }
+
+    public double getEdbl() {
+        return this.edbl;
+    }
+
+    public void setB(AttachB b) {
+        this.b = b;
+    }
+
+    public AttachB getB() {
+        return this.b;
+    }
+
+    public void setF(AttachF f) {
+        this.f = f;
+    }
+
+    public AttachF getF() {
+        return this.f;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public Date getDate() {
+        return this.date;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachF.java
index bb02a7f..b17d31b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachF.java
@@ -1,139 +1,139 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-import java.util.*;
-import java.io.*;
-
-
-@Entity
-public class AttachF
-    implements Serializable {
-
-    private int id1;
-    private String id2;
-
-    private String fstr;
-    private int fint;
-    private double fdbl;
-    private AttachE e;
-    private List strings = new ArrayList();
-
-    private AttachC embeddedC;
-
-    public void setFstr(String fstr) {
-        this.fstr = fstr;
-    }
-
-    public String getFstr() {
-        return this.fstr;
-    }
-
-    public void setFint(int fint) {
-        this.fint = fint;
-    }
-
-    public int getFint() {
-        return this.fint;
-    }
-
-    public void setFdbl(double fdbl) {
-        this.fdbl = fdbl;
-    }
-
-    public double getFdbl() {
-        return this.fdbl;
-    }
-
-    public void setE(AttachE e) {
-        this.e = e;
-    }
-
-    public AttachE getE() {
-        return this.e;
-    }
-
-    public void setStrings(List strings) {
-        this.strings = strings;
-    }
-
-    public List getStrings() {
-        return this.strings;
-    }
-
-    public static class ID {
-
-        public int id1;
-        public String id2;
-
-        public ID() {
-        }
-
-        public ID(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ":");
-            id1 = Integer.parseInt(tok.nextToken());
-            id2 = tok.nextToken();
-        }
-
-        public int hashCode() {
-            return id1 + (id2 == null ? 0 : id2.hashCode());
-        }
-
-        public String toString() {
-            return id1 + ":" + id2;
-        }
-
-        public boolean equals(Object other) {
-            return other instanceof ID
-                && ((ID) other).id1 == id1
-                && (id2 == null ? ((ID) other).id2 == null
-                : id2.equals(((ID) other).id2));
-        }
-    }
-
-    public void setId1(int id1) {
-        this.id1 = id1;
-    }
-
-    public int getId1() {
-        return this.id1;
-    }
-
-    public void setId2(String id2) {
-        this.id2 = id2;
-    }
-
-    public String getId2() {
-        return this.id2;
-    }
-
-    public void setEmbeddedC(AttachC embeddedC) {
-        this.embeddedC = embeddedC;
-    }
-
-    public AttachC getEmbeddedC() {
-        return this.embeddedC;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+import java.util.*;
+import java.io.*;
+
+
+@Entity
+public class AttachF
+    implements Serializable {
+
+    private int id1;
+    private String id2;
+
+    private String fstr;
+    private int fint;
+    private double fdbl;
+    private AttachE e;
+    private List strings = new ArrayList();
+
+    private AttachC embeddedC;
+
+    public void setFstr(String fstr) {
+        this.fstr = fstr;
+    }
+
+    public String getFstr() {
+        return this.fstr;
+    }
+
+    public void setFint(int fint) {
+        this.fint = fint;
+    }
+
+    public int getFint() {
+        return this.fint;
+    }
+
+    public void setFdbl(double fdbl) {
+        this.fdbl = fdbl;
+    }
+
+    public double getFdbl() {
+        return this.fdbl;
+    }
+
+    public void setE(AttachE e) {
+        this.e = e;
+    }
+
+    public AttachE getE() {
+        return this.e;
+    }
+
+    public void setStrings(List strings) {
+        this.strings = strings;
+    }
+
+    public List getStrings() {
+        return this.strings;
+    }
+
+    public static class ID {
+
+        public int id1;
+        public String id2;
+
+        public ID() {
+        }
+
+        public ID(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ":");
+            id1 = Integer.parseInt(tok.nextToken());
+            id2 = tok.nextToken();
+        }
+
+        public int hashCode() {
+            return id1 + (id2 == null ? 0 : id2.hashCode());
+        }
+
+        public String toString() {
+            return id1 + ":" + id2;
+        }
+
+        public boolean equals(Object other) {
+            return other instanceof ID
+                && ((ID) other).id1 == id1
+                && (id2 == null ? ((ID) other).id2 == null
+                : id2.equals(((ID) other).id2));
+        }
+    }
+
+    public void setId1(int id1) {
+        this.id1 = id1;
+    }
+
+    public int getId1() {
+        return this.id1;
+    }
+
+    public void setId2(String id2) {
+        this.id2 = id2;
+    }
+
+    public String getId2() {
+        return this.id2;
+    }
+
+    public void setEmbeddedC(AttachC embeddedC) {
+        this.embeddedC = embeddedC;
+    }
+
+    public AttachC getEmbeddedC() {
+        return this.embeddedC;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPC.java
index 277b022..cdd9f38 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPC.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-import java.util.*;
-
-
-@Entity
-public class AutoIncrementOpOrderPC {
-
-	@Id
-    private long id;
-    private AutoIncrementOpOrderPC rel;
-    private AutoIncrementOpOrderPC owner;
-    private String secondary;
-    private List relList = new ArrayList();
-    private List mappedRelList = new ArrayList();
-    private List inverseKeyRelList = new ArrayList();
-
-    public long getId() {
-        return id;
-    }
-
-    public OpOrder getRel() {
-        return (OpOrder) rel;
-    }
-
-    public void setRel(AutoIncrementOpOrderPC rel) {
-        this.rel = rel;
-    }
-
-    public OpOrder getOwner() {
-        return (OpOrder) owner;
-    }
-
-    public void setOwner(AutoIncrementOpOrderPC owner) {
-        this.owner = owner;
-    }
-
-    public String getSecondary() {
-        return secondary;
-    }
-
-    public void setSecondary(String secondary) {
-        this.secondary = secondary;
-    }
-
-    public List getRelList() {
-        return relList;
-    }
-
-    public List getMappedRelList() {
-        return mappedRelList;
-    }
-
-    public List getInverseKeyRelList() {
-        return inverseKeyRelList;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+import java.util.*;
+
+
+@Entity
+public class AutoIncrementOpOrderPC {
+
+	@Id
+    private long id;
+    private AutoIncrementOpOrderPC rel;
+    private AutoIncrementOpOrderPC owner;
+    private String secondary;
+    private List relList = new ArrayList();
+    private List mappedRelList = new ArrayList();
+    private List inverseKeyRelList = new ArrayList();
+
+    public long getId() {
+        return id;
+    }
+
+    public OpOrder getRel() {
+        return (OpOrder) rel;
+    }
+
+    public void setRel(AutoIncrementOpOrderPC rel) {
+        this.rel = rel;
+    }
+
+    public OpOrder getOwner() {
+        return (OpOrder) owner;
+    }
+
+    public void setOwner(AutoIncrementOpOrderPC owner) {
+        this.owner = owner;
+    }
+
+    public String getSecondary() {
+        return secondary;
+    }
+
+    public void setSecondary(String secondary) {
+        this.secondary = secondary;
+    }
+
+    public List getRelList() {
+        return relList;
+    }
+
+    public List getMappedRelList() {
+        return mappedRelList;
+    }
+
+    public List getInverseKeyRelList() {
+        return inverseKeyRelList;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPCSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPCSub.java
index 6e72588..d4ebd4d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPCSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementOpOrderPCSub.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-import java.util.*;
-
-
-@Entity
-public class AutoIncrementOpOrderPCSub
-    extends AutoIncrementOpOrderPC
-    implements OpOrder {
-
-	@Id
-    private String sub;
-
-    public String getSub() {
-        return sub;
-    }
-
-    public void setSub(String sub) {
-        this.sub = sub;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+import java.util.*;
+
+
+@Entity
+public class AutoIncrementOpOrderPCSub
+    extends AutoIncrementOpOrderPC
+    implements OpOrder {
+
+	@Id
+    private String sub;
+
+    public String getSub() {
+        return sub;
+    }
+
+    public void setSub(String sub) {
+        this.sub = sub;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC1.java
index 0a0bde8..125a35f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC1.java
@@ -1,98 +1,98 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.util.*;
-import javax.persistence.*;
-
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@Table(name="autoincpc1")
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class AutoIncrementPC1
-{
-
-	private Set 				setField 	= new HashSet ();
-
-	@Id
-	private int id;
-
-	@Column(name="strngfld", length=50)
-	private String				stringField	= null;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private AutoIncrementPC1	oneOne		= null;
-
-	public AutoIncrementPC1()
-	{
-	}
-
-	public AutoIncrementPC1(int key)
-	{
-		this.id = key;
-	}
-
-	public Set getSetField ()
-	{
-		return this.setField;
-	}
-
-	public void setSetField (Set setField)
-	{
-		this.setField = setField;
-	}
-
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-
-	public AutoIncrementPC1 getOneOne ()
-	{
-		return this.oneOne;
-	}
-
-
-	public void setOneOne (AutoIncrementPC1 oneOne)
-	{
-		this.oneOne = oneOne;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.util.*;
+import javax.persistence.*;
+
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Table(name="autoincpc1")
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class AutoIncrementPC1
+{
+
+	private Set 				setField 	= new HashSet ();
+
+	@Id
+	private int id;
+
+	@Column(name="strngfld", length=50)
+	private String				stringField	= null;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private AutoIncrementPC1	oneOne		= null;
+
+	public AutoIncrementPC1()
+	{
+	}
+
+	public AutoIncrementPC1(int key)
+	{
+		this.id = key;
+	}
+
+	public Set getSetField ()
+	{
+		return this.setField;
+	}
+
+	public void setSetField (Set setField)
+	{
+		this.setField = setField;
+	}
+
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+
+	public AutoIncrementPC1 getOneOne ()
+	{
+		return this.oneOne;
+	}
+
+
+	public void setOneOne (AutoIncrementPC1 oneOne)
+	{
+		this.oneOne = oneOne;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC2.java
index 14691c3..8eb37be 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC2.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@DiscriminatorValue("autoinc2")
-@Entity
-public class AutoIncrementPC2 extends AutoIncrementPC1
-{
-	private int intField = 0;
-
-	public AutoIncrementPC2()
-	{
-	}
-
-	public AutoIncrementPC2(int id)
-	{
-		super(id);
-	}
-
-
-	public int getIntField ()
-	{
-		return this.intField;
-	}
-
-
-	public void setIntField (int intField)
-	{
-		this.intField = intField;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@DiscriminatorValue("autoinc2")
+@Entity
+public class AutoIncrementPC2 extends AutoIncrementPC1
+{
+	private int intField = 0;
+
+	public AutoIncrementPC2()
+	{
+	}
+
+	public AutoIncrementPC2(int id)
+	{
+		super(id);
+	}
+
+
+	public int getIntField ()
+	{
+		return this.intField;
+	}
+
+
+	public void setIntField (int intField)
+	{
+		this.intField = intField;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java
index 628fd3f..0b6aadf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.util.*;
-
-import javax.persistence.*;
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@IdClass(AutoIncrementPC3Id.class)
-@Entity
-@Table(name="autoincpc3")
-public class AutoIncrementPC3
-{
-	@Id
-	private long				id			= 0;
-	private Set 				setField 	= new HashSet ();
-
-	@Column(name="strngfld", length=50)
-	private String				stringField	= null;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private AutoIncrementPC3	oneOne		= null;
-
-	public AutoIncrementPC3()
-	{
-	}
-
-	public AutoIncrementPC3(int id)
-	{
-		this.id = id;
-	}
-
-
-	public long getId ()
-	{
-		return this.id;
-	}
-
-
-	public void setId (long id)
-	{
-		this.id = id;
-	}
-
-
-	public Set getSetField ()
-	{
-		return this.setField;
-	}
-
-
-	public void setSetField (Set setField)
-	{
-		this.setField = setField;
-	}
-
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-
-	public AutoIncrementPC3 getOneOne ()
-	{
-		return this.oneOne;
-	}
-
-
-	public void setOneOne (AutoIncrementPC3 oneOne)
-	{
-		this.oneOne = oneOne;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@IdClass(AutoIncrementPC3Id.class)
+@Entity
+@Table(name="autoincpc3")
+public class AutoIncrementPC3
+{
+	@Id
+	private long				id			= 0;
+	private Set 				setField 	= new HashSet ();
+
+	@Column(name="strngfld", length=50)
+	private String				stringField	= null;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private AutoIncrementPC3	oneOne		= null;
+
+	public AutoIncrementPC3()
+	{
+	}
+
+	public AutoIncrementPC3(int id)
+	{
+		this.id = id;
+	}
+
+
+	public long getId ()
+	{
+		return this.id;
+	}
+
+
+	public void setId (long id)
+	{
+		this.id = id;
+	}
+
+
+	public Set getSetField ()
+	{
+		return this.setField;
+	}
+
+
+	public void setSetField (Set setField)
+	{
+		this.setField = setField;
+	}
+
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+
+	public AutoIncrementPC3 getOneOne ()
+	{
+		return this.oneOne;
+	}
+
+
+	public void setOneOne (AutoIncrementPC3 oneOne)
+	{
+		this.oneOne = oneOne;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3Id.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3Id.java
index 3a5d939..a634cf6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3Id.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3Id.java
@@ -1,74 +1,74 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.io.*;
-
-
-/**
- * Auto-generated by:
- * kodo.enhance.ApplicationIdTool
- */
-@SuppressWarnings("serial")
-public class AutoIncrementPC3Id	implements Serializable
-{
-	static
-	{
-		// register persistent class in JVM
-		Class c = AutoIncrementPC3.class;
-	}
-
-	public long id;
-
-
-	public AutoIncrementPC3Id ()
-	{
-	}
-
-
-	public AutoIncrementPC3Id (String fromString)
-	{
-		id = Long.parseLong (fromString);
-	}
-
-
-	public String toString ()
-	{
-		return String.valueOf (id);
-	}
-
-
-	public int hashCode ()
-	{
-		return (int) (id % Integer.MAX_VALUE);
-	}
-
-
-	public boolean equals (Object obj)
-	{
-		if (this == obj)
-			return true;
-		if (!(obj instanceof AutoIncrementPC3Id))
-			return false;
-
-		AutoIncrementPC3Id other = (AutoIncrementPC3Id) obj;
-		return (id == other.id);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.io.*;
+
+
+/**
+ * Auto-generated by:
+ * kodo.enhance.ApplicationIdTool
+ */
+@SuppressWarnings("serial")
+public class AutoIncrementPC3Id	implements Serializable
+{
+	static
+	{
+		// register persistent class in JVM
+		Class c = AutoIncrementPC3.class;
+	}
+
+	public long id;
+
+
+	public AutoIncrementPC3Id ()
+	{
+	}
+
+
+	public AutoIncrementPC3Id (String fromString)
+	{
+		id = Long.parseLong (fromString);
+	}
+
+
+	public String toString ()
+	{
+		return String.valueOf (id);
+	}
+
+
+	public int hashCode ()
+	{
+		return (int) (id % Integer.MAX_VALUE);
+	}
+
+
+	public boolean equals (Object obj)
+	{
+		if (this == obj)
+			return true;
+		if (!(obj instanceof AutoIncrementPC3Id))
+			return false;
+
+		AutoIncrementPC3Id other = (AutoIncrementPC3Id) obj;
+		return (id == other.id);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Base.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Base.java
index fb38502..e6361f1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Base.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Base.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class Base
-    implements Comparable {
-
-    private int baseField;
-
-    public int getBaseField() {
-        return this.baseField;
-    }
-
-    public void setBaseField(int baseField) {
-        this.baseField = baseField;
-    }
-
-    public int compareTo(Object other) {
-        if (other == this)
-            return 0;
-        if (other == null)
-            return 1;
-        return baseField - ((Base) other).baseField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class Base
+    implements Comparable {
+
+    private int baseField;
+
+    public int getBaseField() {
+        return this.baseField;
+    }
+
+    public void setBaseField(int baseField) {
+        this.baseField = baseField;
+    }
+
+    public int compareTo(Object other) {
+        if (other == this)
+            return 0;
+        if (other == null)
+            return 1;
+        return baseField - ((Base) other).baseField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1.java
index 82ba628..286d610 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class BaseSub1
-    extends Base {
-
-    private int baseSub1Field;
-
-    public int getBaseSub1Field() {
-        return this.baseSub1Field;
-    }
-
-    public void setBaseSub1Field(int baseSub1Field) {
-        this.baseSub1Field = baseSub1Field;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class BaseSub1
+    extends Base {
+
+    private int baseSub1Field;
+
+    public int getBaseSub1Field() {
+        return this.baseSub1Field;
+    }
+
+    public void setBaseSub1Field(int baseSub1Field) {
+        this.baseSub1Field = baseSub1Field;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub1.java
index 3145e6a..53fe24b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub1.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class BaseSub1Sub1
-    extends BaseSub1 {
-
-    private int baseSub1Sub1Field;
-
-    public int getBaseSub1Sub1Field() {
-        return this.baseSub1Sub1Field;
-    }
-
-    public void setBaseSub1Sub1Field(int baseSub1Sub1Field) {
-        this.baseSub1Sub1Field = baseSub1Sub1Field;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class BaseSub1Sub1
+    extends BaseSub1 {
+
+    private int baseSub1Sub1Field;
+
+    public int getBaseSub1Sub1Field() {
+        return this.baseSub1Sub1Field;
+    }
+
+    public void setBaseSub1Sub1Field(int baseSub1Sub1Field) {
+        this.baseSub1Sub1Field = baseSub1Sub1Field;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub2.java
index fb9fe4d..9e89486 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub1Sub2.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class BaseSub1Sub2
-    extends BaseSub1 {
-
-    private int baseSub1Sub2Field;
-
-    public int getBaseSub1Sub2Field() {
-        return this.baseSub1Sub2Field;
-    }
-
-    public void setBaseSub1Sub2Field(int baseSub1Sub2Field) {
-        this.baseSub1Sub2Field = baseSub1Sub2Field;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class BaseSub1Sub2
+    extends BaseSub1 {
+
+    private int baseSub1Sub2Field;
+
+    public int getBaseSub1Sub2Field() {
+        return this.baseSub1Sub2Field;
+    }
+
+    public void setBaseSub1Sub2Field(int baseSub1Sub2Field) {
+        this.baseSub1Sub2Field = baseSub1Sub2Field;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub2.java
index ffb49a0..ac0dec0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BaseSub2.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class BaseSub2
-    extends Base {
-
-    private int baseSub2Field;
-
-    public int getBaseSub2Field() {
-        return this.baseSub2Field;
-    }
-
-    public void setBaseSub2Field(int baseSub2Field) {
-        this.baseSub2Field = baseSub2Field;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class BaseSub2
+    extends Base {
+
+    private int baseSub2Field;
+
+    public int getBaseSub2Field() {
+        return this.baseSub2Field;
+    }
+
+    public void setBaseSub2Field(int baseSub2Field) {
+        this.baseSub2Field = baseSub2Field;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BuildSchemaPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BuildSchemaPC.java
index 0072397..4f3111d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BuildSchemaPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/BuildSchemaPC.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type used in testing the mappingtool's buildSchema action.</p>
- *
- * @author Abe White
- */
-@Entity
-public class BuildSchemaPC {
-
-    private String stringField = null;
-    private int intField = 0;
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type used in testing the mappingtool's buildSchema action.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class BuildSchemaPC {
+
+    private String stringField = null;
+    private int intField = 0;
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC.java
index b3d32c5..986b42b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC.java
@@ -1,77 +1,77 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type using a byte[] for a primary key field.  Used in
- * {@link TestByteArrayAppId}.</p>
- *
- * @author Abe White
- */
-@Entity
-public class ByteArrayPKPC {
-
-    private byte[] pk = null;
-    private String stringField = null;
-    private List rels = new ArrayList();
-    private ByteArrayPKPC parent = null;
-
-    public ByteArrayPKPC() {
-    }
-
-    public ByteArrayPKPC(byte[] pk, String stringField) {
-        this.pk = pk;
-        this.stringField = stringField;
-    }
-
-    public byte[] getPK() {
-        return pk;
-    }
-
-    public void setPK(byte[] pk) {
-        this.pk = pk;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public ByteArrayPKPC getParent() {
-        return parent;
-    }
-
-    public void setParent(ByteArrayPKPC parent) {
-        this.parent = parent;
-    }
-
-    public List getRels() {
-        return this.rels;
-    }
-
-    public void setRels(List rels) {
-        this.rels = rels;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type using a byte[] for a primary key field.  Used in
+ * {@link TestByteArrayAppId}.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class ByteArrayPKPC {
+
+    private byte[] pk = null;
+    private String stringField = null;
+    private List rels = new ArrayList();
+    private ByteArrayPKPC parent = null;
+
+    public ByteArrayPKPC() {
+    }
+
+    public ByteArrayPKPC(byte[] pk, String stringField) {
+        this.pk = pk;
+        this.stringField = stringField;
+    }
+
+    public byte[] getPK() {
+        return pk;
+    }
+
+    public void setPK(byte[] pk) {
+        this.pk = pk;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public ByteArrayPKPC getParent() {
+        return parent;
+    }
+
+    public void setParent(ByteArrayPKPC parent) {
+        this.parent = parent;
+    }
+
+    public List getRels() {
+        return this.rels;
+    }
+
+    public void setRels(List rels) {
+        this.rels = rels;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC2.java
index 7001ea2..10ae14f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPC2.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type using a byte[] for a primary key field.  Used in
- * {@link TestByteArrayAppId}.</p>
- *
- * @author Abe White
- */
-@Entity
-public class ByteArrayPKPC2
-    extends ByteArrayPKPC {
-
-    private String subfield = null;
-
-    public ByteArrayPKPC2() {
-    }
-
-    public ByteArrayPKPC2(byte[] pk, String stringField) {
-        super(pk, stringField);
-    }
-
-    public String getSubfield() {
-        return this.subfield;
-    }
-
-    public void setSubfield(String subfield) {
-        this.subfield = subfield;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type using a byte[] for a primary key field.  Used in
+ * {@link TestByteArrayAppId}.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class ByteArrayPKPC2
+    extends ByteArrayPKPC {
+
+    private String subfield = null;
+
+    public ByteArrayPKPC2() {
+    }
+
+    public ByteArrayPKPC2(byte[] pk, String stringField) {
+        super(pk, stringField);
+    }
+
+    public String getSubfield() {
+        return this.subfield;
+    }
+
+    public void setSubfield(String subfield) {
+        this.subfield = subfield;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPCId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPCId.java
index b799b96..33152db 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPCId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ByteArrayPKPCId.java
@@ -1,120 +1,120 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-
-/**
- * Auto-generated by:
- * org.apache.openjpa.enhance.ApplicationIdTool
- */
-public class ByteArrayPKPCId implements Serializable {
-
-    private static final char[] HEX = new char[]{
-        '0', '1', '2', '3', '4', '5', '6', '7',
-        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-    };
-
-    static {
-        // register persistent class in JVM
-        Class c = ByteArrayPKPC.class;
-    }
-
-    public byte[] pk;
-
-    public ByteArrayPKPCId() {
-    }
-
-    public ByteArrayPKPCId(String fromString) {
-        pk = toBytes(fromString);
-    }
-
-    public String toString() {
-        return toString(pk);
-    }
-
-    public int hashCode() {
-        return hashCode(pk);
-    }
-
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (!(obj instanceof ByteArrayPKPCId))
-            return false;
-
-        ByteArrayPKPCId other = (ByteArrayPKPCId) obj;
-        return (equals(pk, other.pk));
-    }
-
-    private static byte[] toBytes(String s) {
-        if ("null".equals(s))
-            return null;
-
-        int len = s.length();
-        byte[] r = new byte[len / 2];
-        for (int i = 0; i < r.length; i++) {
-            int digit1 = s.charAt(i * 2), digit2 = s.charAt(i * 2 + 1);
-            if (digit1 >= '0' && digit1 <= '9')
-                digit1 -= '0';
-            else if (digit1 >= 'A' && digit1 <= 'F')
-                digit1 -= 'A' - 10;
-            if (digit2 >= '0' && digit2 <= '9')
-                digit2 -= '0';
-            else if (digit2 >= 'A' && digit2 <= 'F')
-                digit2 -= 'A' - 10;
-
-            r[i] = (byte) ((digit1 << 4) + digit2);
-        }
-        return r;
-    }
-
-    private static String toString(byte[] b) {
-        if (b == null)
-            return "null";
-
-        StringBuffer r = new StringBuffer(b.length * 2);
-        for (int i = 0; i < b.length; i++)
-            for (int j = 1; j >= 0; j--)
-                r.append(HEX[(b[i] >> (j * 4)) & 0xF]);
-        return r.toString();
-    }
-
-    private static boolean equals(byte[] b1, byte[] b2) {
-        if (b1 == null && b2 == null)
-            return true;
-        if (b1 == null || b2 == null)
-            return false;
-        if (b1.length != b2.length)
-            return false;
-        for (int i = 0; i < b1.length; i++)
-            if (b1[i] != b2[i])
-                return false;
-        return true;
-    }
-
-    private static int hashCode(byte[] b) {
-        if (b == null)
-            return 0;
-        int sum = 0;
-        for (int i = 0; i < b.length; i++)
-            sum += b[i];
-        return sum;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+
+/**
+ * Auto-generated by:
+ * org.apache.openjpa.enhance.ApplicationIdTool
+ */
+public class ByteArrayPKPCId implements Serializable {
+
+    private static final char[] HEX = new char[]{
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+
+    static {
+        // register persistent class in JVM
+        Class c = ByteArrayPKPC.class;
+    }
+
+    public byte[] pk;
+
+    public ByteArrayPKPCId() {
+    }
+
+    public ByteArrayPKPCId(String fromString) {
+        pk = toBytes(fromString);
+    }
+
+    public String toString() {
+        return toString(pk);
+    }
+
+    public int hashCode() {
+        return hashCode(pk);
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof ByteArrayPKPCId))
+            return false;
+
+        ByteArrayPKPCId other = (ByteArrayPKPCId) obj;
+        return (equals(pk, other.pk));
+    }
+
+    private static byte[] toBytes(String s) {
+        if ("null".equals(s))
+            return null;
+
+        int len = s.length();
+        byte[] r = new byte[len / 2];
+        for (int i = 0; i < r.length; i++) {
+            int digit1 = s.charAt(i * 2), digit2 = s.charAt(i * 2 + 1);
+            if (digit1 >= '0' && digit1 <= '9')
+                digit1 -= '0';
+            else if (digit1 >= 'A' && digit1 <= 'F')
+                digit1 -= 'A' - 10;
+            if (digit2 >= '0' && digit2 <= '9')
+                digit2 -= '0';
+            else if (digit2 >= 'A' && digit2 <= 'F')
+                digit2 -= 'A' - 10;
+
+            r[i] = (byte) ((digit1 << 4) + digit2);
+        }
+        return r;
+    }
+
+    private static String toString(byte[] b) {
+        if (b == null)
+            return "null";
+
+        StringBuffer r = new StringBuffer(b.length * 2);
+        for (int i = 0; i < b.length; i++)
+            for (int j = 1; j >= 0; j--)
+                r.append(HEX[(b[i] >> (j * 4)) & 0xF]);
+        return r.toString();
+    }
+
+    private static boolean equals(byte[] b1, byte[] b2) {
+        if (b1 == null && b2 == null)
+            return true;
+        if (b1 == null || b2 == null)
+            return false;
+        if (b1.length != b2.length)
+            return false;
+        for (int i = 0; i < b1.length; i++)
+            if (b1[i] != b2[i])
+                return false;
+        return true;
+    }
+
+    private static int hashCode(byte[] b) {
+        if (b == null)
+            return 0;
+        int sum = 0;
+        for (int i = 0; i < b.length; i++)
+            sum += b[i];
+        return sum;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC.java
index 58f9ef9..852775a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC.java
@@ -1,57 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- */
-
-@Entity
-public class CircularFKPC {
-	
-    @Id
-    private String stringField;
-    private CircularFKPC2 fkField;
-
-	public CircularFKPC() {
-
-	}
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public CircularFKPC2 getFKField() {
-        return this.fkField;
-    }
-
-    public void setFKField(CircularFKPC2 fkField) {
-        this.fkField = fkField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ */
+
+@Entity
+public class CircularFKPC {
+	
+    @Id
+    private String stringField;
+    private CircularFKPC2 fkField;
+
+	public CircularFKPC() {
+
+	}
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public CircularFKPC2 getFKField() {
+        return this.fkField;
+    }
+
+    public void setFKField(CircularFKPC2 fkField) {
+        this.fkField = fkField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC2.java
index 654bb49..ffecac5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CircularFKPC2.java
@@ -1,57 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- */
-
-@Entity
-public class CircularFKPC2 {
-
-	@Id
-    private String stringField;
-    private CircularFKPC fkField;
-
-	public CircularFKPC2() {
-
-	}
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public CircularFKPC getFKField() {
-        return this.fkField;
-    }
-
-    public void setFKField(CircularFKPC fkField) {
-        this.fkField = fkField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ */
+
+@Entity
+public class CircularFKPC2 {
+
+	@Id
+    private String stringField;
+    private CircularFKPC fkField;
+
+	public CircularFKPC2() {
+
+	}
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public CircularFKPC getFKField() {
+        return this.fkField;
+    }
+
+    public void setFKField(CircularFKPC fkField) {
+        this.fkField = fkField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ComplexEmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ComplexEmbeddedPC.java
index 66886e7..b1acbf9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ComplexEmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ComplexEmbeddedPC.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-
-import java.util.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Embedded type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class ComplexEmbeddedPC
-    extends RecursivelyEmbeddedPC {
-	
-
-    private String stringField;
-    private EmbeddedOwnerPC ownerField;
-    private Set stringSet = new HashSet();
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public EmbeddedOwnerPC getOwnerField() {
-        return this.ownerField;
-    }
-
-    public void setOwnerField(EmbeddedOwnerPC ownerField) {
-        this.ownerField = ownerField;
-    }
-
-    public Set getStringSet() {
-        return this.stringSet;
-    }
-
-    public void setStringSet(Set stringSet) {
-        this.stringSet = stringSet;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Embedded type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class ComplexEmbeddedPC
+    extends RecursivelyEmbeddedPC {
+	
+
+    private String stringField;
+    private EmbeddedOwnerPC ownerField;
+    private Set stringSet = new HashSet();
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public EmbeddedOwnerPC getOwnerField() {
+        return this.ownerField;
+    }
+
+    public void setOwnerField(EmbeddedOwnerPC ownerField) {
+        this.ownerField = ownerField;
+    }
+
+    public Set getStringSet() {
+        return this.stringSet;
+    }
+
+    public void setStringSet(Set stringSet) {
+        this.stringSet = stringSet;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC.java
index 2f06e5e..13896d7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC.java
@@ -1,72 +1,72 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class ConstantJoinPC {
-
-    private int pk1;
-    private int pk2;
-    private NonPKJoinPC nonPK;
-    private NonPKJoinPC nonPK2;
-    private Collection nonPKs = new HashSet();
-
-    public int getPk1() {
-        return this.pk1;
-    }
-
-    public void setPk1(int pk1) {
-        this.pk1 = pk1;
-    }
-
-    public int getPk2() {
-        return this.pk2;
-    }
-
-    public void setPk2(int pk2) {
-        this.pk2 = pk2;
-    }
-
-    public NonPKJoinPC getNonPK() {
-        return this.nonPK;
-    }
-
-    public void setNonPK(NonPKJoinPC nonPK) {
-        this.nonPK = nonPK;
-    }
-
-    public NonPKJoinPC getNonPK2() {
-        return this.nonPK2;
-    }
-
-    public void setNonPK2(NonPKJoinPC nonPK2) {
-        this.nonPK2 = nonPK2;
-    }
-
-    public Collection getNonPKs() {
-        return this.nonPKs;
-    }
-
-    public void setNonPKs(Collection nonPKs) {
-        this.nonPKs = nonPKs;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class ConstantJoinPC {
+
+    private int pk1;
+    private int pk2;
+    private NonPKJoinPC nonPK;
+    private NonPKJoinPC nonPK2;
+    private Collection nonPKs = new HashSet();
+
+    public int getPk1() {
+        return this.pk1;
+    }
+
+    public void setPk1(int pk1) {
+        this.pk1 = pk1;
+    }
+
+    public int getPk2() {
+        return this.pk2;
+    }
+
+    public void setPk2(int pk2) {
+        this.pk2 = pk2;
+    }
+
+    public NonPKJoinPC getNonPK() {
+        return this.nonPK;
+    }
+
+    public void setNonPK(NonPKJoinPC nonPK) {
+        this.nonPK = nonPK;
+    }
+
+    public NonPKJoinPC getNonPK2() {
+        return this.nonPK2;
+    }
+
+    public void setNonPK2(NonPKJoinPC nonPK2) {
+        this.nonPK2 = nonPK2;
+    }
+
+    public Collection getNonPKs() {
+        return this.nonPKs;
+    }
+
+    public void setNonPKs(Collection nonPKs) {
+        this.nonPKs = nonPKs;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC2.java
index 7c1b90e..23e7fad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC2.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ConstantJoinPC2
-    extends ConstantJoinPC {
-
-    private int pc2Field;
-
-    public int getPc2Field() {
-        return this.pc2Field;
-    }
-
-    public void setPc2Field(int pc2Field) {
-        this.pc2Field = pc2Field;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ConstantJoinPC2
+    extends ConstantJoinPC {
+
+    private int pc2Field;
+
+    public int getPc2Field() {
+        return this.pc2Field;
+    }
+
+    public void setPc2Field(int pc2Field) {
+        this.pc2Field = pc2Field;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC3.java
index 2831e01..c291681 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC3.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ConstantJoinPC3
-    extends ConstantJoinPC {
-
-    private int pc3Field;
-
-    public int getPc3Field() {
-        return this.pc3Field;
-    }
-
-    public void setPc3Field(int pc3Field) {
-        this.pc3Field = pc3Field;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ConstantJoinPC3
+    extends ConstantJoinPC {
+
+    private int pc3Field;
+
+    public int getPc3Field() {
+        return this.pc3Field;
+    }
+
+    public void setPc3Field(int pc3Field) {
+        this.pc3Field = pc3Field;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC4.java
index 61b1782..71f79b9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC4.java
@@ -1,90 +1,90 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.util.*;
-import javax.persistence.*;
-
-@Entity
-@Table(name="conjoinpc4")
-public class ConstantJoinPC4
-{
-	@Column(length=50)
-	private String name;
-
-	@Id
-	private int id;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private ConstantJoinPC5 oneToOne1;
-	@ManyToMany
-	private Set manyToMany = new HashSet ();
-
-	public ConstantJoinPC4()
-	{}
-
-	public ConstantJoinPC4 (String name, int id)
-	{
-		this.name = name;
-		this.id = id;
-	}
-
-
-	public String getName ()
-	{
-		return name;
-	}
-
-
-	public void setOneToOne1 (ConstantJoinPC5 val)
-	{
-		oneToOne1 = val;
-	}
-
-
-	public ConstantJoinPC5 getOneToOne1 ()
-	{
-		return oneToOne1;
-	}
-
-
-	public void setManyToMany (Set val)
-	{
-		manyToMany = val;
-	}
-
-
-	public Set getManyToMany ()
-	{
-		return manyToMany;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.util.*;
+import javax.persistence.*;
+
+@Entity
+@Table(name="conjoinpc4")
+public class ConstantJoinPC4
+{
+	@Column(length=50)
+	private String name;
+
+	@Id
+	private int id;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private ConstantJoinPC5 oneToOne1;
+	@ManyToMany
+	private Set manyToMany = new HashSet ();
+
+	public ConstantJoinPC4()
+	{}
+
+	public ConstantJoinPC4 (String name, int id)
+	{
+		this.name = name;
+		this.id = id;
+	}
+
+
+	public String getName ()
+	{
+		return name;
+	}
+
+
+	public void setOneToOne1 (ConstantJoinPC5 val)
+	{
+		oneToOne1 = val;
+	}
+
+
+	public ConstantJoinPC5 getOneToOne1 ()
+	{
+		return oneToOne1;
+	}
+
+
+	public void setManyToMany (Set val)
+	{
+		manyToMany = val;
+	}
+
+
+	public Set getManyToMany ()
+	{
+		return manyToMany;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC5.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC5.java
index 664d327..4c4c072 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC5.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/ConstantJoinPC5.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name="conjoinpc5")
-public class ConstantJoinPC5
-{
-	@Id
-	private int id;
-
-	@Basic
-	private String name;
-
-	public ConstantJoinPC5()
-	{}
-
-	public ConstantJoinPC5(int id)
-	{
-		this.id = id;
-	}
-
-	public ConstantJoinPC5 (String name)
-	{
-		this.name = name;
-	}
-
-
-	public String getName ()
-	{
-		return name;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="conjoinpc5")
+public class ConstantJoinPC5
+{
+	@Id
+	private int id;
+
+	@Basic
+	private String name;
+
+	public ConstantJoinPC5()
+	{}
+
+	public ConstantJoinPC5(int id)
+	{
+		this.id = id;
+	}
+
+	public ConstantJoinPC5 (String name)
+	{
+		this.name = name;
+	}
+
+
+	public String getName ()
+	{
+		return name;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CustomMappingPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CustomMappingPC.java
index 0f0a392..0f74e7d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CustomMappingPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/CustomMappingPC.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.*;
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-
-@Entity
-@Table(name="custmappc")
-public class CustomMappingPC
-{
-
-	private boolean female;
-	@Column(length=50)
-	private String 	name;
-
-	@Id
-	private int id;
-
-	public CustomMappingPC()
-	{
-	}
-
-	public CustomMappingPC(int id)
-	{
-		this.id = id;
-	}
-
-
-	public boolean isFemale ()
-	{
-		return this.female;
-	}
-
-
-	public void setFemale (boolean female)
-	{
-		this.female = female;
-	}
-
-
-	public String getName ()
-	{
-		return this.name;
-	}
-
-
-	public void setName (String name)
-	{
-		this.name = name;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.*;
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+
+@Entity
+@Table(name="custmappc")
+public class CustomMappingPC
+{
+
+	private boolean female;
+	@Column(length=50)
+	private String 	name;
+
+	@Id
+	private int id;
+
+	public CustomMappingPC()
+	{
+	}
+
+	public CustomMappingPC(int id)
+	{
+		this.id = id;
+	}
+
+
+	public boolean isFemale ()
+	{
+		return this.female;
+	}
+
+
+	public void setFemale (boolean female)
+	{
+		this.female = female;
+	}
+
+
+	public String getName ()
+	{
+		return this.name;
+	}
+
+
+	public void setName (String name)
+	{
+		this.name = name;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DFGTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DFGTest.java
index 7f8ccc0..b7f06e2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DFGTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DFGTest.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class DFGTest {
-
-    private int dfgField;
-    private int nonDFGField;
-
-    public int getDFGField() {
-        return this.dfgField;
-    }
-
-    public void setDFGField(int dfgField) {
-        this.dfgField = dfgField;
-    }
-
-    public int getNonDFGField() {
-        return this.nonDFGField;
-    }
-
-    public void setNonDFGField(int nonDFGField) {
-        this.nonDFGField = nonDFGField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class DFGTest {
+
+    private int dfgField;
+    private int nonDFGField;
+
+    public int getDFGField() {
+        return this.dfgField;
+    }
+
+    public void setDFGField(int dfgField) {
+        this.dfgField = dfgField;
+    }
+
+    public int getNonDFGField() {
+        return this.nonDFGField;
+    }
+
+    public void setNonDFGField(int nonDFGField) {
+        this.nonDFGField = nonDFGField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DataStoreTripsPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DataStoreTripsPC.java
index 6407245..deef14b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DataStoreTripsPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/DataStoreTripsPC.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class DataStoreTripsPC {
-
-    private int intField;
-    private String stringField;
-
-    public DataStoreTripsPC() {
-    }
-
-    public DataStoreTripsPC(int i) {
-        this.intField = i;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class DataStoreTripsPC {
+
+    private int intField;
+    private String stringField;
+
+    public DataStoreTripsPC() {
+    }
+
+    public DataStoreTripsPC(int i) {
+        this.intField = i;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC.java
index 8c430ad..81ba47e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-/**
- * <p>Class that uses eager outer joins for its collection fields.</p>
- *
- * @author Abe White
- */
-@Entity
-public class EagerOuterJoinPC {
-
-    private String name = null;
-    private Collection stringCollection = new HashSet();
-    private List stringList = new ArrayList();
-    private Collection oneManyCollection = new HashSet();
-    private Collection manyManyCollection = new HashSet();
-    private List manyManyList = new ArrayList();
-    private HelperPC helper = null;
-
-    public Collection getStringCollection() {
-        return this.stringCollection;
-    }
-
-    public void setStringCollection(Collection stringCollection) {
-        this.stringCollection = stringCollection;
-    }
-
-    public List getStringList() {
-        return this.stringList;
-    }
-
-    public void setStringList(List stringList) {
-        this.stringList = stringList;
-    }
-
-    public Collection getOneManyCollection() {
-        return this.oneManyCollection;
-    }
-
-    public void setOneManyCollection(Collection oneManyCollection) {
-        this.oneManyCollection = oneManyCollection;
-    }
-
-    public Collection getManyManyCollection() {
-        return this.manyManyCollection;
-    }
-
-    public void setManyManyCollection(Collection manyManyCollection) {
-        this.manyManyCollection = manyManyCollection;
-    }
-
-    public List getManyManyList() {
-        return this.manyManyList;
-    }
-
-    public void setManyManyList(List manyManyList) {
-        this.manyManyList = manyManyList;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String toString() {
-        return getClass().getName() + ": " + name;
-    }
-
-    public HelperPC getHelper() {
-        return this.helper;
-    }
-
-    public void setHelper(HelperPC helper) {
-        this.helper = helper;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+/**
+ * <p>Class that uses eager outer joins for its collection fields.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class EagerOuterJoinPC {
+
+    private String name = null;
+    private Collection stringCollection = new HashSet();
+    private List stringList = new ArrayList();
+    private Collection oneManyCollection = new HashSet();
+    private Collection manyManyCollection = new HashSet();
+    private List manyManyList = new ArrayList();
+    private HelperPC helper = null;
+
+    public Collection getStringCollection() {
+        return this.stringCollection;
+    }
+
+    public void setStringCollection(Collection stringCollection) {
+        this.stringCollection = stringCollection;
+    }
+
+    public List getStringList() {
+        return this.stringList;
+    }
+
+    public void setStringList(List stringList) {
+        this.stringList = stringList;
+    }
+
+    public Collection getOneManyCollection() {
+        return this.oneManyCollection;
+    }
+
+    public void setOneManyCollection(Collection oneManyCollection) {
+        this.oneManyCollection = oneManyCollection;
+    }
+
+    public Collection getManyManyCollection() {
+        return this.manyManyCollection;
+    }
+
+    public void setManyManyCollection(Collection manyManyCollection) {
+        this.manyManyCollection = manyManyCollection;
+    }
+
+    public List getManyManyList() {
+        return this.manyManyList;
+    }
+
+    public void setManyManyList(List manyManyList) {
+        this.manyManyList = manyManyList;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return getClass().getName() + ": " + name;
+    }
+
+    public HelperPC getHelper() {
+        return this.helper;
+    }
+
+    public void setHelper(HelperPC helper) {
+        this.helper = helper;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC2.java
index f0a2ad6..eff3d44 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerOuterJoinPC2.java
@@ -1,72 +1,72 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-/**
- * <p>Helper class in eager to-many join testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class EagerOuterJoinPC2 {
-
-    private String name = null;
-    private EagerOuterJoinPC ref = null;
-    private HelperPC helper = null;
-    private Collection stringCollection = new HashSet();
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public EagerOuterJoinPC getRef() {
-        return this.ref;
-    }
-
-    public void setRef(EagerOuterJoinPC ref) {
-        this.ref = ref;
-    }
-
-    public String toString() {
-        return getClass().getName() + ": " + name;
-    }
-
-    public HelperPC getHelper() {
-        return this.helper;
-    }
-
-    public void setHelper(HelperPC helper) {
-        this.helper = helper;
-    }
-
-    public Collection getStringCollection() {
-        return this.stringCollection;
-    }
-
-    public void setStringCollection(Collection stringCollection) {
-        this.stringCollection = stringCollection;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+/**
+ * <p>Helper class in eager to-many join testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class EagerOuterJoinPC2 {
+
+    private String name = null;
+    private EagerOuterJoinPC ref = null;
+    private HelperPC helper = null;
+    private Collection stringCollection = new HashSet();
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public EagerOuterJoinPC getRef() {
+        return this.ref;
+    }
+
+    public void setRef(EagerOuterJoinPC ref) {
+        this.ref = ref;
+    }
+
+    public String toString() {
+        return getClass().getName() + ": " + name;
+    }
+
+    public HelperPC getHelper() {
+        return this.helper;
+    }
+
+    public void setHelper(HelperPC helper) {
+        this.helper = helper;
+    }
+
+    public Collection getStringCollection() {
+        return this.stringCollection;
+    }
+
+    public void setStringCollection(Collection stringCollection) {
+        this.stringCollection = stringCollection;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPC.java
index f4928da..53c10d8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPC.java
@@ -1,161 +1,161 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.*;
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@Inheritance(strategy=InheritanceType.JOINED)
-public class EagerPC
-{
-	@Id
-	private int id;
-
-	@Column(name="strngfld", length=50)
-	private String		stringField;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private HelperPC 	eager;
-	@Column(name="eagsub")
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private HelperPC4	eagerSub;
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private HelperPC2	recurse;
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private HelperPC 	helper;
-	@Transient private List		eagerCollection		= new LinkedList ();
-	@Transient private List		recurseCollection	= new LinkedList ();
-	@Transient private List	 	helperCollection	= new LinkedList ();
-
-	public EagerPC()
-	{}
-
-	public EagerPC(int id)
-	{
-		this.id = id;
-	}
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-
-	public HelperPC getEager ()
-	{
-		return this.eager;
-	}
-
-
-	public void setEager (HelperPC eager)
-	{
-		this.eager = eager;
-	}
-
-
-	public HelperPC2 getRecurse ()
-	{
-		return this.recurse;
-	}
-
-
-	public void setRecurse (HelperPC2 recurse)
-	{
-		this.recurse = recurse;
-	}
-
-
-	public HelperPC getHelper ()
-	{
-		return this.helper;
-	}
-
-
-	public void setHelper (HelperPC helper)
-	{
-		this.helper = helper;
-	}
-
-
-	public List getEagerCollection ()
-	{
-		return this.eagerCollection;
-	}
-
-
-	public void setEagerCollection (List eagerCollection)
-	{
-		this.eagerCollection = eagerCollection;
-	}
-
-
-	public List getRecurseCollection ()
-	{
-		return this.recurseCollection;
-	}
-
-
-	public void setRecurseCollection (List recurseCollection)
-	{
-		this.recurseCollection = recurseCollection;
-	}
-
-
-	public List getHelperCollection ()
-	{
-		return this.helperCollection;
-	}
-
-
-	public void setHelperCollection (List helperCollection)
-	{
-		this.helperCollection = helperCollection;
-	}
-
-
-	public HelperPC4 getEagerSub ()
-	{
-		return this.eagerSub;
-	}
-
-
-	public void setEagerSub (HelperPC4 eagerSub)
-	{
-		this.eagerSub = eagerSub;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.*;
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Inheritance(strategy=InheritanceType.JOINED)
+public class EagerPC
+{
+	@Id
+	private int id;
+
+	@Column(name="strngfld", length=50)
+	private String		stringField;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private HelperPC 	eager;
+	@Column(name="eagsub")
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private HelperPC4	eagerSub;
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private HelperPC2	recurse;
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private HelperPC 	helper;
+	@Transient private List		eagerCollection		= new LinkedList ();
+	@Transient private List		recurseCollection	= new LinkedList ();
+	@Transient private List	 	helperCollection	= new LinkedList ();
+
+	public EagerPC()
+	{}
+
+	public EagerPC(int id)
+	{
+		this.id = id;
+	}
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+
+	public HelperPC getEager ()
+	{
+		return this.eager;
+	}
+
+
+	public void setEager (HelperPC eager)
+	{
+		this.eager = eager;
+	}
+
+
+	public HelperPC2 getRecurse ()
+	{
+		return this.recurse;
+	}
+
+
+	public void setRecurse (HelperPC2 recurse)
+	{
+		this.recurse = recurse;
+	}
+
+
+	public HelperPC getHelper ()
+	{
+		return this.helper;
+	}
+
+
+	public void setHelper (HelperPC helper)
+	{
+		this.helper = helper;
+	}
+
+
+	public List getEagerCollection ()
+	{
+		return this.eagerCollection;
+	}
+
+
+	public void setEagerCollection (List eagerCollection)
+	{
+		this.eagerCollection = eagerCollection;
+	}
+
+
+	public List getRecurseCollection ()
+	{
+		return this.recurseCollection;
+	}
+
+
+	public void setRecurseCollection (List recurseCollection)
+	{
+		this.recurseCollection = recurseCollection;
+	}
+
+
+	public List getHelperCollection ()
+	{
+		return this.helperCollection;
+	}
+
+
+	public void setHelperCollection (List helperCollection)
+	{
+		this.helperCollection = helperCollection;
+	}
+
+
+	public HelperPC4 getEagerSub ()
+	{
+		return this.eagerSub;
+	}
+
+
+	public void setEagerSub (HelperPC4 eagerSub)
+	{
+		this.eagerSub = eagerSub;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPCSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPCSub.java
index c5853fa..0ce52f9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPCSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EagerPCSub.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.*;
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-public class EagerPCSub	extends EagerPC
-{
-	private int 	intField;
-
-	@Column(name="eagercoll2")
-	@OneToMany
-	@Transient private List eagerCollection2 = new LinkedList ();
-
-	public EagerPCSub()
-	{
-	}
-
-	public EagerPCSub(int id)
-	{
-		super(id);
-	}
-
-	public int getIntField ()
-	{
-		return this.intField;
-	}
-
-	public void setIntField (int intField)
-	{
-		this.intField = intField;
-	}
-
-	public List getEagerCollection2 ()
-	{
-		return this.eagerCollection2;
-	}
-
-	public void setEagerCollection2 (List eagerCollection2)
-	{
-		this.eagerCollection2 = eagerCollection2;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.*;
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+public class EagerPCSub	extends EagerPC
+{
+	private int 	intField;
+
+	@Column(name="eagercoll2")
+	@OneToMany
+	@Transient private List eagerCollection2 = new LinkedList ();
+
+	public EagerPCSub()
+	{
+	}
+
+	public EagerPCSub(int id)
+	{
+		super(id);
+	}
+
+	public int getIntField ()
+	{
+		return this.intField;
+	}
+
+	public void setIntField (int intField)
+	{
+		this.intField = intField;
+	}
+
+	public List getEagerCollection2 ()
+	{
+		return this.eagerCollection2;
+	}
+
+	public void setEagerCollection2 (List eagerCollection2)
+	{
+		this.eagerCollection2 = eagerCollection2;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedOwnerPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedOwnerPC.java
index bf4283c..a944a9f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedOwnerPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedOwnerPC.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Persistent type used in testing embedded instances.</p>
- *
- * @author Abe White
- */
-@Entity
-public class EmbeddedOwnerPC {
-
-    private int id1;
-    private int id2;
-    private String stringField;
-    private EmbeddedPC embedded;
-    private ComplexEmbeddedPC complexEmbedded;
-
-    protected EmbeddedOwnerPC() {
-    }
-
-    public EmbeddedOwnerPC(int id1, int id2) {
-        this.id1 = id1;
-        this.id2 = id2;
-    }
-
-    public int getId1() {
-        return id1;
-    }
-
-    public int getId2() {
-        return id2;
-    }
-
-    public EmbeddedPC getEmbedded() {
-        return this.embedded;
-    }
-
-    public void setEmbedded(EmbeddedPC embedded) {
-        this.embedded = embedded;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public ComplexEmbeddedPC getComplexEmbedded() {
-        return this.complexEmbedded;
-    }
-
-    public void setComplexEmbedded(ComplexEmbeddedPC complexEmbedded) {
-        this.complexEmbedded = complexEmbedded;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Persistent type used in testing embedded instances.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class EmbeddedOwnerPC {
+
+    private int id1;
+    private int id2;
+    private String stringField;
+    private EmbeddedPC embedded;
+    private ComplexEmbeddedPC complexEmbedded;
+
+    protected EmbeddedOwnerPC() {
+    }
+
+    public EmbeddedOwnerPC(int id1, int id2) {
+        this.id1 = id1;
+        this.id2 = id2;
+    }
+
+    public int getId1() {
+        return id1;
+    }
+
+    public int getId2() {
+        return id2;
+    }
+
+    public EmbeddedPC getEmbedded() {
+        return this.embedded;
+    }
+
+    public void setEmbedded(EmbeddedPC embedded) {
+        this.embedded = embedded;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public ComplexEmbeddedPC getComplexEmbedded() {
+        return this.complexEmbedded;
+    }
+
+    public void setComplexEmbedded(ComplexEmbeddedPC complexEmbedded) {
+        this.complexEmbedded = complexEmbedded;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedPC.java
index a8a87ea..e4a18fa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/EmbeddedPC.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Embedded type used in testing.</p>
- *
- * @author Abe White
- */
-
-@Entity
-public class EmbeddedPC {
-
-    private int intField;
-    private String stringField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Embedded type used in testing.</p>
+ *
+ * @author Abe White
+ */
+
+@Entity
+public class EmbeddedPC {
+
+    private int intField;
+    private String stringField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC.java
index b96e6d5..a5ba18c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC.java
@@ -1,89 +1,89 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.Serializable;
-
-import javax.persistence.*;
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@SuppressWarnings("serial")
-@Entity
-public class HelperPC implements Serializable
-{
-	@Column(length=50, name="strngfld")
-	private String 		stringField;
-
-	private HelperPC 	helper;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private EagerPC		eager;
-
-	@Id
-	private int id;
-
-	public HelperPC()
-	{}
-
-	public HelperPC(int id)
-	{
-		this.id = id;
-	}
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-	public HelperPC getHelper ()
-	{
-		return this.helper;
-	}
-
-	public void setHelper (HelperPC helper)
-	{
-		this.helper = helper;
-	}
-
-	public EagerPC getEager ()
-	{
-		return this.eager;
-	}
-
-	public void setEager (EagerPC eager)
-	{
-		this.eager = eager;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@SuppressWarnings("serial")
+@Entity
+public class HelperPC implements Serializable
+{
+	@Column(length=50, name="strngfld")
+	private String 		stringField;
+
+	private HelperPC 	helper;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private EagerPC		eager;
+
+	@Id
+	private int id;
+
+	public HelperPC()
+	{}
+
+	public HelperPC(int id)
+	{
+		this.id = id;
+	}
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+	public HelperPC getHelper ()
+	{
+		return this.helper;
+	}
+
+	public void setHelper (HelperPC helper)
+	{
+		this.helper = helper;
+	}
+
+	public EagerPC getEager ()
+	{
+		return this.eager;
+	}
+
+	public void setEager (EagerPC eager)
+	{
+		this.eager = eager;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC2.java
index ea36f4f..f4ddd7e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC2.java
@@ -1,90 +1,90 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-import javax.persistence.*;
-
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-public class HelperPC2
-{
-	@Column(name="strngfld", length=50)
-	private String 		stringField;
-
-	@Id @GeneratedValue
-	private int id;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	private HelperPC3 	helper;
-	@Column(name="helpcoll")
-	private List		helperCollection = new LinkedList ();
-
-	public HelperPC2()
-	{}
-
-	public HelperPC2(int id)
-	{
-		this.id = id;
-	}
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-	public HelperPC3 getHelper ()
-	{
-		return this.helper;
-	}
-
-	public void setHelper (HelperPC3 helper)
-	{
-		this.helper = helper;
-	}
-
-	public List getHelperCollection ()
-	{
-		return this.helperCollection;
-	}
-
-	public void setHelperCollection (List helperCollection)
-	{
-		this.helperCollection = helperCollection;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+import javax.persistence.*;
+
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+public class HelperPC2
+{
+	@Column(name="strngfld", length=50)
+	private String 		stringField;
+
+	@Id @GeneratedValue
+	private int id;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private HelperPC3 	helper;
+	@Column(name="helpcoll")
+	private List		helperCollection = new LinkedList ();
+
+	public HelperPC2()
+	{}
+
+	public HelperPC2(int id)
+	{
+		this.id = id;
+	}
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+	public HelperPC3 getHelper ()
+	{
+		return this.helper;
+	}
+
+	public void setHelper (HelperPC3 helper)
+	{
+		this.helper = helper;
+	}
+
+	public List getHelperCollection ()
+	{
+		return this.helperCollection;
+	}
+
+	public void setHelperCollection (List helperCollection)
+	{
+		this.helperCollection = helperCollection;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC3.java
index 54173ac..5e38856 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC3.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.*;
-
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class HelperPC3
-{
-	@Column(name="strngfld", length=50)
-	private String stringField;
-
-	@Id
-	private int id;
-
-	public HelperPC3()
-	{
-	}
-
-	public HelperPC3(int id)
-	{
-		this.id = id;
-	}
-
-	public String getStringField ()
-	{
-		return this.stringField;
-	}
-
-	public void setStringField (String stringField)
-	{
-		this.stringField = stringField;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.*;
+
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class HelperPC3
+{
+	@Column(name="strngfld", length=50)
+	private String stringField;
+
+	@Id
+	private int id;
+
+	public HelperPC3()
+	{
+	}
+
+	public HelperPC3(int id)
+	{
+		this.id = id;
+	}
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC4.java
index 8f1d157..49c6687 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HelperPC4.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.*;
-
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-@DiscriminatorValue("helppc4")
-public class HelperPC4 extends HelperPC3
-{
-	private int intField;
-
-	public int getIntField ()
-	{
-		return this.intField;
-	}
-
-
-	public void setIntField (int intField)
-	{
-		this.intField = intField;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.*;
+
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@DiscriminatorValue("helppc4")
+public class HelperPC4 extends HelperPC3
+{
+	private int intField;
+
+	public int getIntField ()
+	{
+		return this.intField;
+	}
+
+
+	public void setIntField (int intField)
+	{
+		this.intField = intField;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizA.java
index 18add00..555015c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizA.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import java.io.*;
-import javax.persistence.Entity;
-
-@Entity
-public abstract class HorizA
-    implements Serializable {
-
-    private String stringA;
-    private int intA;
-    private Set relations = new HashSet();
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-
-    public void setRelations(Set relations) {
-        this.relations = relations;
-    }
-
-    public Set getRelations() {
-        return this.relations;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import java.io.*;
+import javax.persistence.Entity;
+
+@Entity
+public abstract class HorizA
+    implements Serializable {
+
+    private String stringA;
+    private int intA;
+    private Set relations = new HashSet();
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+
+    public void setRelations(Set relations) {
+        this.relations = relations;
+    }
+
+    public Set getRelations() {
+        return this.relations;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppA.java
index 0cf5029..ca4b4e3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppA.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-
-import serp.util.*;
-
-public interface HorizAppA {
-
-    public void setPk1(String pk1);
-
-    public String getPk1();
-
-    public void setPk2(int pk2);
-
-    public int getPk2();
-
-    public void setStringA(String stringA);
-
-    public String getStringA();
-
-    public void setIntA(int intA);
-
-    public int getIntA();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+
+import serp.util.*;
+
+public interface HorizAppA {
+
+    public void setPk1(String pk1);
+
+    public String getPk1();
+
+    public void setPk2(int pk2);
+
+    public int getPk2();
+
+    public void setStringA(String stringA);
+
+    public String getStringA();
+
+    public void setIntA(int intA);
+
+    public int getIntA();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppB.java
index 8523a16..6c9145f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppB.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-
-import serp.util.*;
-
-public interface HorizAppB
-    extends HorizAppA {
-
-    public void setStringB(String stringB);
-
-    public String getStringB();
-
-    public void setIntB(int intB);
-
-    public int getIntB();
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+
+import serp.util.*;
+
+public interface HorizAppB
+    extends HorizAppA {
+
+    public void setStringB(String stringB);
+
+    public String getStringB();
+
+    public void setIntB(int intB);
+
+    public int getIntB();
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppC.java
index 1cc4eb3..fc4cf5a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppC.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-
-import serp.util.*;
-
-public interface HorizAppC
-    extends HorizAppA {
-
-    public void setStringC(String stringC);
-
-    public String getStringC();
-
-    public void setIntC(int intC);
-
-    public int getIntC();
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+
+import serp.util.*;
+
+public interface HorizAppC
+    extends HorizAppA {
+
+    public void setStringC(String stringC);
+
+    public String getStringC();
+
+    public void setIntC(int intC);
+
+    public int getIntC();
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppD.java
index 33e1010..c3c7d54 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppD.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-
-import serp.util.*;
-
-public interface HorizAppD
-    extends HorizAppA {
-
-    public void setStringD(String stringD);
-
-    public String getStringD();
-
-    public void setIntD(int intD);
-
-    public int getIntD();
-}
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+
+import serp.util.*;
+
+public interface HorizAppD
+    extends HorizAppA {
+
+    public void setStringD(String stringD);
+
+    public String getStringD();
+
+    public void setIntD(int intD);
+
+    public int getIntD();
+}
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalA.java
index 445f9c1..625c3a9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalA.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizAppInterVerticalA
-    implements HorizInterA {
-
-    private int pk;
-    private String stringA;
-    private int intA;
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-
-    public static class Id implements java.io.Serializable {
-
-        public int pk;
-
-        public Id() {
-        }
-
-        public Id(String str) {
-            pk = Integer.parseInt(str);
-        }
-
-        public String toString() {
-            return pk + "";
-        }
-
-        public int hashCode() {
-            return pk;
-        }
-
-        public boolean equals(Object other) {
-            return other instanceof Id
-                && ((Id) other).pk == pk;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizAppInterVerticalA
+    implements HorizInterA {
+
+    private int pk;
+    private String stringA;
+    private int intA;
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+
+    public static class Id implements java.io.Serializable {
+
+        public int pk;
+
+        public Id() {
+        }
+
+        public Id(String str) {
+            pk = Integer.parseInt(str);
+        }
+
+        public String toString() {
+            return pk + "";
+        }
+
+        public int hashCode() {
+            return pk;
+        }
+
+        public boolean equals(Object other) {
+            return other instanceof Id
+                && ((Id) other).pk == pk;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalB.java
index 36c19c5..8264f72 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalB.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizAppInterVerticalB
-    extends HorizAppInterVerticalA
-    implements HorizInterB {
-
-    private String stringB;
-    private int intB;
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizAppInterVerticalB
+    extends HorizAppInterVerticalA
+    implements HorizInterB {
+
+    private String stringB;
+    private int intB;
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalC.java
index 530fa6c..057805d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalC.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizAppInterVerticalC
-    extends HorizAppInterVerticalB
-    implements HorizInterC {
-
-    private String stringC;
-    private int intC;
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizAppInterVerticalC
+    extends HorizAppInterVerticalB
+    implements HorizInterC {
+
+    private String stringC;
+    private int intC;
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalD.java
index b906cc3..cbbd3fb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppInterVerticalD.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizAppInterVerticalD
-    extends HorizAppInterVerticalB
-    implements HorizInterD {
-
-    private String stringD;
-    private int intD;
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizAppInterVerticalD
+    extends HorizAppInterVerticalB
+    implements HorizInterD {
+
+    private String stringD;
+    private int intD;
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiA.java
index f174043..adbf600 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiA.java
@@ -1,122 +1,122 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-import javax.persistence.Entity;
-
-import serp.util.*;
-
-@Entity
-public class HorizAppMultiA
-    implements HorizAppA {
-
-    // initialize PK values to random values
-	//FIXME 
-	/*
-    private String pk1 = "PK-" + Strings.getClassName(getClass().getName());
-    private int pk2 = com.solarmetric.test.AbstractTestCase.
-        randomInt().intValue();
-    */
-	private String pk1;
-    private int pk2;
-	
-
-    private String stringA;
-    private int intA;
-    private List relations = new ArrayList();
-
-    public void setPk1(String pk1) {
-        this.pk1 = pk1;
-    }
-
-    public String getPk1() {
-        return this.pk1;
-    }
-
-    public void setPk2(int pk2) {
-        this.pk2 = pk2;
-    }
-
-    public int getPk2() {
-        return this.pk2;
-    }
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-
-    public static class ID
-        implements Serializable {
-
-        public String pk1;
-        public int pk2;
-
-        public ID() {
-        }
-
-        public ID(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ":");
-            pk1 = tok.nextToken();
-            pk2 = Integer.parseInt(tok.nextToken());
-        }
-
-        public String toString() {
-            return pk1 + ":" + pk2;
-        }
-
-        public int hashCode() {
-            return (pk2 + (pk1 == null ? 0 : pk1.hashCode()))
-                % Integer.MAX_VALUE;
-        }
-
-        public boolean equals(Object other) {
-            return other instanceof ID
-                && ((ID) other).pk2 == pk2
-                && (((ID) other).pk1 == null
-                ? pk1 == null
-                : ((ID) other).pk1.equals(pk1));
-        }
-    }
-
-    public void setRelations(List relations) {
-        this.relations = relations;
-    }
-
-    public List getRelations() {
-        return this.relations;
-    }
-}
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+import javax.persistence.Entity;
+
+import serp.util.*;
+
+@Entity
+public class HorizAppMultiA
+    implements HorizAppA {
+
+    // initialize PK values to random values
+	//FIXME 
+	/*
+    private String pk1 = "PK-" + Strings.getClassName(getClass().getName());
+    private int pk2 = com.solarmetric.test.AbstractTestCase.
+        randomInt().intValue();
+    */
+	private String pk1;
+    private int pk2;
+	
+
+    private String stringA;
+    private int intA;
+    private List relations = new ArrayList();
+
+    public void setPk1(String pk1) {
+        this.pk1 = pk1;
+    }
+
+    public String getPk1() {
+        return this.pk1;
+    }
+
+    public void setPk2(int pk2) {
+        this.pk2 = pk2;
+    }
+
+    public int getPk2() {
+        return this.pk2;
+    }
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+
+    public static class ID
+        implements Serializable {
+
+        public String pk1;
+        public int pk2;
+
+        public ID() {
+        }
+
+        public ID(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ":");
+            pk1 = tok.nextToken();
+            pk2 = Integer.parseInt(tok.nextToken());
+        }
+
+        public String toString() {
+            return pk1 + ":" + pk2;
+        }
+
+        public int hashCode() {
+            return (pk2 + (pk1 == null ? 0 : pk1.hashCode()))
+                % Integer.MAX_VALUE;
+        }
+
+        public boolean equals(Object other) {
+            return other instanceof ID
+                && ((ID) other).pk2 == pk2
+                && (((ID) other).pk1 == null
+                ? pk1 == null
+                : ((ID) other).pk1.equals(pk1));
+        }
+    }
+
+    public void setRelations(List relations) {
+        this.relations = relations;
+    }
+
+    public List getRelations() {
+        return this.relations;
+    }
+}
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiB.java
index 6106692..a02c7ad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiB.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizAppMultiB
-    extends HorizAppMultiA
-    implements HorizAppB {
-
-    private String stringB;
-    private int intB;
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-
-    public static class ID
-        extends HorizAppMultiA.ID {
-
-        public ID() {
-            super();
-        }
-
-        public ID(String str) {
-            super(str);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizAppMultiB
+    extends HorizAppMultiA
+    implements HorizAppB {
+
+    private String stringB;
+    private int intB;
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+
+    public static class ID
+        extends HorizAppMultiA.ID {
+
+        public ID() {
+            super();
+        }
+
+        public ID(String str) {
+            super(str);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiC.java
index ad9d13f..eb48648 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiC.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizAppMultiC
-    extends HorizAppMultiA
-    implements HorizAppC {
-
-    private String stringC;
-    private int intC;
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-
-    public static class ID
-        extends HorizAppMultiA.ID {
-
-        public ID() {
-            super();
-        }
-
-        public ID(String str) {
-            super(str);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizAppMultiC
+    extends HorizAppMultiA
+    implements HorizAppC {
+
+    private String stringC;
+    private int intC;
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+
+    public static class ID
+        extends HorizAppMultiA.ID {
+
+        public ID() {
+            super();
+        }
+
+        public ID(String str) {
+            super(str);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiD.java
index 0f5f4ce..1906ba2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppMultiD.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizAppMultiD
-    extends HorizAppMultiA
-    implements HorizAppD {
-
-    private String stringD;
-    private int intD;
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-
-    public static class ID
-        extends HorizAppMultiA.ID {
-
-        public ID() {
-            super();
-        }
-
-        public ID(String str) {
-            super(str);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizAppMultiD
+    extends HorizAppMultiA
+    implements HorizAppD {
+
+    private String stringD;
+    private int intD;
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+
+    public static class ID
+        extends HorizAppMultiA.ID {
+
+        public ID() {
+            super();
+        }
+
+        public ID(String str) {
+            super(str);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleA.java
index cd5b298..5178653 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleA.java
@@ -1,121 +1,121 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-import javax.persistence.Entity;
-
-import serp.util.*;
-
-@Entity
-public class HorizAppSingleA
-    implements HorizAppA {
-
-    // initialize PK values to random values
-	//FIXME 
-	/*
-    private String pk1 = "PK-" + Strings.getClassName(getClass().getName());
-    private int pk2 = com.solarmetric.test.AbstractTestCase.
-        randomInt().intValue();
-	*/
-	private String pk1;
-    private int pk2;
-
-    private String stringA;
-    private int intA;
-    private List relations = new ArrayList();
-
-    public void setPk1(String pk1) {
-        this.pk1 = pk1;
-    }
-
-    public String getPk1() {
-        return this.pk1;
-    }
-
-    public void setPk2(int pk2) {
-        this.pk2 = pk2;
-    }
-
-    public int getPk2() {
-        return this.pk2;
-    }
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-
-    public static class ID
-        implements Serializable {
-
-        public String pk1;
-        public int pk2;
-
-        public ID() {
-        }
-
-        public ID(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ":");
-            pk1 = tok.nextToken();
-            pk2 = Integer.parseInt(tok.nextToken());
-        }
-
-        public String toString() {
-            return pk1 + ":" + pk2;
-        }
-
-        public int hashCode() {
-            return (pk2 + (pk1 == null ? 0 : pk1.hashCode()))
-                % Integer.MAX_VALUE;
-        }
-
-        public boolean equals(Object other) {
-            return other instanceof ID
-                && ((ID) other).pk2 == pk2
-                && (((ID) other).pk1 == null
-                ? pk1 == null
-                : ((ID) other).pk1.equals(pk1));
-        }
-    }
-
-    public void setRelations(List relations) {
-        this.relations = relations;
-    }
-
-    public List getRelations() {
-        return this.relations;
-    }
-}
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+import javax.persistence.Entity;
+
+import serp.util.*;
+
+@Entity
+public class HorizAppSingleA
+    implements HorizAppA {
+
+    // initialize PK values to random values
+	//FIXME 
+	/*
+    private String pk1 = "PK-" + Strings.getClassName(getClass().getName());
+    private int pk2 = com.solarmetric.test.AbstractTestCase.
+        randomInt().intValue();
+	*/
+	private String pk1;
+    private int pk2;
+
+    private String stringA;
+    private int intA;
+    private List relations = new ArrayList();
+
+    public void setPk1(String pk1) {
+        this.pk1 = pk1;
+    }
+
+    public String getPk1() {
+        return this.pk1;
+    }
+
+    public void setPk2(int pk2) {
+        this.pk2 = pk2;
+    }
+
+    public int getPk2() {
+        return this.pk2;
+    }
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+
+    public static class ID
+        implements Serializable {
+
+        public String pk1;
+        public int pk2;
+
+        public ID() {
+        }
+
+        public ID(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ":");
+            pk1 = tok.nextToken();
+            pk2 = Integer.parseInt(tok.nextToken());
+        }
+
+        public String toString() {
+            return pk1 + ":" + pk2;
+        }
+
+        public int hashCode() {
+            return (pk2 + (pk1 == null ? 0 : pk1.hashCode()))
+                % Integer.MAX_VALUE;
+        }
+
+        public boolean equals(Object other) {
+            return other instanceof ID
+                && ((ID) other).pk2 == pk2
+                && (((ID) other).pk1 == null
+                ? pk1 == null
+                : ((ID) other).pk1.equals(pk1));
+        }
+    }
+
+    public void setRelations(List relations) {
+        this.relations = relations;
+    }
+
+    public List getRelations() {
+        return this.relations;
+    }
+}
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleB.java
index 4f6a2b0..ac5ea79 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleB.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizAppSingleB
-    extends HorizAppSingleA
-    implements HorizAppB {
-
-    private String stringB;
-    private int intB;
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizAppSingleB
+    extends HorizAppSingleA
+    implements HorizAppB {
+
+    private String stringB;
+    private int intB;
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleC.java
index a276362..abd7634 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleC.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizAppSingleC
-    extends HorizAppSingleA
-    implements HorizAppC {
-
-    private String stringC;
-    private int intC;
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizAppSingleC
+    extends HorizAppSingleA
+    implements HorizAppC {
+
+    private String stringC;
+    private int intC;
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleD.java
index 191bac0..f0f2dc4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizAppSingleD.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizAppSingleD
-    extends HorizAppSingleA
-    implements HorizAppD {
-
-    private String stringD;
-    private int intD;
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizAppSingleD
+    extends HorizAppSingleA
+    implements HorizAppD {
+
+    private String stringD;
+    private int intD;
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizB.java
index b96fee3..fc7db69 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizB.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizB
-    extends HorizA {
-
-    private String stringB;
-    private int intB;
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizB
+    extends HorizA {
+
+    private String stringB;
+    private int intB;
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizC.java
index 05ca347..733bdf6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizC.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public abstract class HorizC
-    extends HorizA {
-
-    private String stringC;
-    private int intC;
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public abstract class HorizC
+    extends HorizA {
+
+    private String stringC;
+    private int intC;
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizD.java
index 125b624..9058c8f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizD.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizD
-    extends HorizC {
-
-    private String stringD;
-    private int intD;
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizD
+    extends HorizC {
+
+    private String stringD;
+    private int intD;
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizE.java
index 0bef9f2..57dd08d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizE.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizE
-    extends HorizC {
-
-    private String stringE;
-    private int intE;
-
-    public void setStringE(String stringE) {
-        this.stringE = stringE;
-    }
-
-    public String getStringE() {
-        return this.stringE;
-    }
-
-    public void setIntE(int intE) {
-        this.intE = intE;
-    }
-
-    public int getIntE() {
-        return this.intE;
-    }
-}
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizE
+    extends HorizC {
+
+    private String stringE;
+    private int intE;
+
+    public void setStringE(String stringE) {
+        this.stringE = stringE;
+    }
+
+    public String getStringE() {
+        return this.stringE;
+    }
+
+    public void setIntE(int intE) {
+        this.intE = intE;
+    }
+
+    public int getIntE() {
+        return this.intE;
+    }
+}
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizF.java
index 2f46d9a..3f22848 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizF.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizF
-    extends HorizE {
-
-    private String stringF;
-    private int intF;
-
-    public void setStringF(String stringF) {
-        this.stringF = stringF;
-    }
-
-    public String getStringF() {
-        return this.stringF;
-    }
-
-    public void setIntF(int intF) {
-        this.intF = intF;
-    }
-
-    public int getIntF() {
-        return this.intF;
-    }
-}
-
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizF
+    extends HorizE {
+
+    private String stringF;
+    private int intF;
+
+    public void setStringF(String stringF) {
+        this.stringF = stringF;
+    }
+
+    public String getStringF() {
+        return this.stringF;
+    }
+
+    public void setIntF(int intF) {
+        this.intF = intF;
+    }
+
+    public int getIntF() {
+        return this.intF;
+    }
+}
+
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizG.java
index 098d09f..ca4f297 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizG.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizG
-    extends HorizE {
-
-    private String stringG;
-    private int intG;
-
-    public void setStringG(String stringG) {
-        this.stringG = stringG;
-    }
-
-    public String getStringG() {
-        return this.stringG;
-    }
-
-    public void setIntG(int intG) {
-        this.intG = intG;
-    }
-
-    public int getIntG() {
-        return this.intG;
-    }
-}
-
-
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizG
+    extends HorizE {
+
+    private String stringG;
+    private int intG;
+
+    public void setStringG(String stringG) {
+        this.stringG = stringG;
+    }
+
+    public String getStringG() {
+        return this.stringG;
+    }
+
+    public void setIntG(int intG) {
+        this.intG = intG;
+    }
+
+    public int getIntG() {
+        return this.intG;
+    }
+}
+
+
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizH.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizH.java
index a84b51d..2385726 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizH.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizH.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizH
-    extends HorizG {
-
-    private String stringH;
-    private int intH;
-
-    public void setStringH(String stringH) {
-        this.stringH = stringH;
-    }
-
-    public String getStringH() {
-        return this.stringH;
-    }
-
-    public void setIntH(int intH) {
-        this.intH = intH;
-    }
-
-    public int getIntH() {
-        return this.intH;
-    }
-}
-
-
-
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizH
+    extends HorizG {
+
+    private String stringH;
+    private int intH;
+
+    public void setStringH(String stringH) {
+        this.stringH = stringH;
+    }
+
+    public String getStringH() {
+        return this.stringH;
+    }
+
+    public void setIntH(int intH) {
+        this.intH = intH;
+    }
+
+    public int getIntH() {
+        return this.intH;
+    }
+}
+
+
+
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizI.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizI.java
index 106a14e..290d10b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizI.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizI.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizI
-    extends HorizG {
-
-    private String stringI;
-    private int intI;
-
-    public void setStringI(String stringI) {
-        this.stringI = stringI;
-    }
-
-    public String getStringI() {
-        return this.stringI;
-    }
-
-    public void setIntI(int intI) {
-        this.intI = intI;
-    }
-
-    public int getIntI() {
-        return this.intI;
-    }
-}
-
-
-
-
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizI
+    extends HorizG {
+
+    private String stringI;
+    private int intI;
+
+    public void setStringI(String stringI) {
+        this.stringI = stringI;
+    }
+
+    public String getStringI() {
+        return this.stringI;
+    }
+
+    public void setIntI(int intI) {
+        this.intI = intI;
+    }
+
+    public int getIntI() {
+        return this.intI;
+    }
+}
+
+
+
+
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterA.java
index 25636ab..09b1d3b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterA.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * Interface for intermediate horizontal mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public interface HorizInterA {
-
-    public void setStringA(String stringA);
-
-    public String getStringA();
-
-    public void setIntA(int intA);
-
-    public int getIntA();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * Interface for intermediate horizontal mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public interface HorizInterA {
+
+    public void setStringA(String stringA);
+
+    public String getStringA();
+
+    public void setIntA(int intA);
+
+    public int getIntA();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterB.java
index 729f0ee..11dc09f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterB.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * Interface for intermediate horizontal mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public interface HorizInterB
-    extends HorizInterA {
-
-    public void setStringB(String stringB);
-
-    public String getStringB();
-
-    public void setIntB(int intB);
-
-    public int getIntB();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * Interface for intermediate horizontal mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public interface HorizInterB
+    extends HorizInterA {
+
+    public void setStringB(String stringB);
+
+    public String getStringB();
+
+    public void setIntB(int intB);
+
+    public int getIntB();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterC.java
index 40dbeb4..05545a8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterC.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * Interface for intermediate horizontal mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public interface HorizInterC
-    extends HorizInterB {
-
-    public void setStringC(String stringC);
-
-    public String getStringC();
-
-    public void setIntC(int intC);
-
-    public int getIntC();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * Interface for intermediate horizontal mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public interface HorizInterC
+    extends HorizInterB {
+
+    public void setStringC(String stringC);
+
+    public String getStringC();
+
+    public void setIntC(int intC);
+
+    public int getIntC();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterD.java
index 84bdc8e..d572b04 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterD.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * Interface for intermediate horizontal mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public interface HorizInterD
-    extends HorizInterB {
-
-    public void setStringD(String stringD);
-
-    public String getStringD();
-
-    public void setIntD(int intD);
-
-    public int getIntD();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * Interface for intermediate horizontal mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public interface HorizInterD
+    extends HorizInterB {
+
+    public void setStringD(String stringD);
+
+    public String getStringD();
+
+    public void setIntD(int intD);
+
+    public int getIntD();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatA.java
index 0dc4049..eaee845 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatA.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterFlatA
-    implements HorizInterA {
-
-    private String stringA;
-    private int intA;
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterFlatA
+    implements HorizInterA {
+
+    private String stringA;
+    private int intA;
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatB.java
index f16ff92..dddd882 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatB.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterFlatB
-    extends HorizInterFlatA
-    implements HorizInterB {
-
-    private String stringB;
-    private int intB;
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterFlatB
+    extends HorizInterFlatA
+    implements HorizInterB {
+
+    private String stringB;
+    private int intB;
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatC.java
index b571277..59dcff3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatC.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterFlatC
-    extends HorizInterFlatB
-    implements HorizInterC {
-
-    private String stringC;
-    private int intC;
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterFlatC
+    extends HorizInterFlatB
+    implements HorizInterC {
+
+    private String stringC;
+    private int intC;
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatD.java
index fa65f0a..10997d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterFlatD.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterFlatD
-    extends HorizInterFlatB
-    implements HorizInterD {
-
-    private String stringD;
-    private int intD;
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterFlatD
+    extends HorizInterFlatB
+    implements HorizInterD {
+
+    private String stringD;
+    private int intD;
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalA.java
index a14ad39..064ae8b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalA.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterVerticalA
-    implements HorizInterA {
-
-    private String stringA;
-    private int intA;
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterVerticalA
+    implements HorizInterA {
+
+    private String stringA;
+    private int intA;
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalB.java
index fc8d5a4..da890e1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalB.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterVerticalB
-    extends HorizInterVerticalA
-    implements HorizInterB {
-
-    private String stringB;
-    private int intB;
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterVerticalB
+    extends HorizInterVerticalA
+    implements HorizInterB {
+
+    private String stringB;
+    private int intB;
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalC.java
index 82db8c9..7fa928b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalC.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterVerticalC
-    extends HorizInterVerticalB
-    implements HorizInterC {
-
-    private String stringC;
-    private int intC;
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterVerticalC
+    extends HorizInterVerticalB
+    implements HorizInterC {
+
+    private String stringC;
+    private int intC;
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalD.java
index cf96d22..758494e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizInterVerticalD.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Interface for intermediate horizontal mappings with flat mappings.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizInterVerticalD
-    extends HorizInterVerticalB
-    implements HorizInterD {
-
-    private String stringD;
-    private int intD;
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Interface for intermediate horizontal mappings with flat mappings.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizInterVerticalD
+    extends HorizInterVerticalB
+    implements HorizInterD {
+
+    private String stringD;
+    private int intD;
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizJ.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizJ.java
index fc66930..f8d1a33 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizJ.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizJ.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizJ
-    extends HorizD {
-
-    private String stringJ;
-    private int intJ;
-
-    public void setStringJ(String stringJ) {
-        this.stringJ = stringJ;
-    }
-
-    public String getStringJ() {
-        return this.stringJ;
-    }
-
-    public void setIntJ(int intJ) {
-        this.intJ = intJ;
-    }
-
-    public int getIntJ() {
-        return this.intJ;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizJ
+    extends HorizD {
+
+    private String stringJ;
+    private int intJ;
+
+    public void setStringJ(String stringJ) {
+        this.stringJ = stringJ;
+    }
+
+    public String getStringJ() {
+        return this.stringJ;
+    }
+
+    public void setIntJ(int intJ) {
+        this.intJ = intJ;
+    }
+
+    public int getIntJ() {
+        return this.intJ;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizK.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizK.java
index a12121c..e02ae02 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizK.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizK.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizK
-    extends HorizJ {
-
-    private String stringK;
-    private int intK;
-
-    public void setStringK(String stringK) {
-        this.stringK = stringK;
-    }
-
-    public String getStringK() {
-        return this.stringK;
-    }
-
-    public void setIntK(int intK) {
-        this.intK = intK;
-    }
-
-    public int getIntK() {
-        return this.intK;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizK
+    extends HorizJ {
+
+    private String stringK;
+    private int intK;
+
+    public void setStringK(String stringK) {
+        this.stringK = stringK;
+    }
+
+    public String getStringK() {
+        return this.stringK;
+    }
+
+    public void setIntK(int intK) {
+        this.intK = intK;
+    }
+
+    public int getIntK() {
+        return this.intK;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizL.java
index 706641a..c16fdf5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizL.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizL
-    extends HorizJ {
-
-    private String stringL;
-    private int intL;
-
-    public void setStringL(String stringL) {
-        this.stringL = stringL;
-    }
-
-    public String getStringL() {
-        return this.stringL;
-    }
-
-    public void setIntL(int intL) {
-        this.intL = intL;
-    }
-
-    public int getIntL() {
-        return this.intL;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizL
+    extends HorizJ {
+
+    private String stringL;
+    private int intL;
+
+    public void setStringL(String stringL) {
+        this.stringL = stringL;
+    }
+
+    public String getStringL() {
+        return this.stringL;
+    }
+
+    public void setIntL(int intL) {
+        this.intL = intL;
+    }
+
+    public int getIntL() {
+        return this.intL;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizM.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizM.java
index a4300cf..6307465 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizM.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizM.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizM
-    extends HorizL {
-
-    private String stringM;
-    private int intM;
-
-    public void setStringM(String stringM) {
-        this.stringM = stringM;
-    }
-
-    public String getStringM() {
-        return this.stringM;
-    }
-
-    public void setIntM(int intM) {
-        this.intM = intM;
-    }
-
-    public int getIntM() {
-        return this.intM;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizM
+    extends HorizL {
+
+    private String stringM;
+    private int intM;
+
+    public void setStringM(String stringM) {
+        this.stringM = stringM;
+    }
+
+    public String getStringM() {
+        return this.stringM;
+    }
+
+    public void setIntM(int intM) {
+        this.intM = intM;
+    }
+
+    public int getIntM() {
+        return this.intM;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizN.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizN.java
index 2652d36..cf15496 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizN.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizN.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizN
-    extends HorizM {
-
-    private String stringN;
-    private int intN;
-
-    public void setStringN(String stringN) {
-        this.stringN = stringN;
-    }
-
-    public String getStringN() {
-        return this.stringN;
-    }
-
-    public void setIntN(int intN) {
-        this.intN = intN;
-    }
-
-    public int getIntN() {
-        return this.intN;
-    }
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizN
+    extends HorizM {
+
+    private String stringN;
+    private int intN;
+
+    public void setStringN(String stringN) {
+        this.stringN = stringN;
+    }
+
+    public String getStringN() {
+        return this.stringN;
+    }
+
+    public void setIntN(int intN) {
+        this.intN = intN;
+    }
+
+    public int getIntN() {
+        return this.intN;
+    }
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizO.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizO.java
index 722cc97..f7b2ac7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizO.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizO.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class HorizO
-    extends HorizN {
-
-    private String stringO;
-    private int intO;
-
-    public void setStringO(String stringO) {
-        this.stringO = stringO;
-    }
-
-    public String getStringO() {
-        return this.stringO;
-    }
-
-    public void setIntO(int intO) {
-        this.intO = intO;
-    }
-
-    public int getIntO() {
-        return this.intO;
-    }
-}
-
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class HorizO
+    extends HorizN {
+
+    private String stringO;
+    private int intO;
+
+    public void setStringO(String stringO) {
+        this.stringO = stringO;
+    }
+
+    public String getStringO() {
+        return this.stringO;
+    }
+
+    public void setIntO(int intO) {
+        this.intO = intO;
+    }
+
+    public int getIntO() {
+        return this.intO;
+    }
+}
+
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizRelation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizRelation.java
index 056a90a..f2c3403 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizRelation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/HorizRelation.java
@@ -1,406 +1,406 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.util.*;
-
-import javax.persistence.Entity;
-
-import org.apache.commons.collections.*;
-
-/**
- * Normal class that has relations to and from various horizontal
- * relations.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class HorizRelation
-    implements Serializable {
-    ///////////////////////
-    // One to one mappings
-    ///////////////////////
-
-    private HorizA obHorizA;
-    private HorizB obHorizB;
-    private HorizC obHorizC;
-    private HorizD obHorizD;
-    private HorizE obHorizE;
-    private HorizF obHorizF;
-    private HorizG obHorizG;
-    private HorizH obHorizH;
-    private HorizI obHorizI;
-    private HorizJ obHorizJ;
-    private HorizK obHorizK;
-    private HorizL obHorizL;
-    private HorizM obHorizM;
-    private HorizN obHorizN;
-    private HorizO obHorizO;
-    private HorizAppSingleA obHorizAppSingleA;
-    private HorizAppSingleB obHorizAppSingleB;
-    private HorizAppSingleC obHorizAppSingleC;
-    private HorizAppSingleD obHorizAppSingleD;
-    private HorizAppMultiA obHorizAppMultiA;
-    private HorizAppMultiB obHorizAppMultiB;
-    private HorizAppMultiC obHorizAppMultiC;
-    private HorizAppMultiD obHorizAppMultiD;
-    private HorizInterFlatA obHorizInterFlatA;
-    private HorizInterFlatB obHorizInterFlatB;
-    private HorizInterFlatC obHorizInterFlatC;
-    private HorizInterFlatD obHorizInterFlatD;
-    private HorizInterVerticalA obHorizInterVerticalA;
-    private HorizInterVerticalB obHorizInterVerticalB;
-    private HorizInterVerticalC obHorizInterVerticalC;
-    private HorizInterVerticalD obHorizInterVerticalD;
-
-    ////////////////////////
-    // One to many mappings
-    ////////////////////////
-
-    private HashSet cHorizA = new HashSet();
-    private LinkedList cHorizB = new LinkedList();
-    private ArrayList cHorizC = new ArrayList();
-    private Vector cHorizD = new Vector();
-    private HashSet cHorizE = new HashSet();
-    private LinkedList cHorizF = new LinkedList();
-    private ArrayList cHorizG = new ArrayList();
-    private Vector cHorizH = new Vector();
-    private HashSet cHorizI = new HashSet();
-    private LinkedList cHorizJ = new LinkedList();
-    private ArrayList cHorizK = new ArrayList();
-    private Vector cHorizL = new Vector();
-    private HashSet cHorizM = new HashSet();
-    private LinkedList cHorizN = new LinkedList();
-    private ArrayList cHorizO = new ArrayList();
-    private Vector cHorizAppSingleA = new Vector();
-    private HashSet cHorizAppSingleB = new HashSet();
-    private LinkedList cHorizAppSingleC = new LinkedList();
-    private ArrayList cHorizAppSingleD = new ArrayList();
-    private Vector cHorizAppMultiA = new Vector();
-    private HashSet cHorizAppMultiB = new HashSet();
-    private LinkedList cHorizAppMultiC = new LinkedList();
-    private ArrayList cHorizAppMultiD = new ArrayList();
-    private Vector cHorizInterFlatA = new Vector();
-    private HashSet cHorizInterFlatB = new HashSet();
-    private LinkedList cHorizInterFlatC = new LinkedList();
-    private ArrayList cHorizInterFlatD = new ArrayList();
-    private Vector cHorizInterVerticalA = new Vector();
-    private HashSet cHorizInterVerticalB = new HashSet();
-    private LinkedList cHorizInterVerticalC = new LinkedList();
-    private ArrayList cHorizInterVerticalD = new ArrayList();
-
-    public Map getCollections() {
-        Map map = new SequencedHashMap();
-        map.put("HorizA", cHorizA);
-        map.put("HorizB", cHorizB);
-        map.put("HorizC", cHorizC);
-        map.put("HorizD", cHorizD);
-        map.put("HorizE", cHorizE);
-        map.put("HorizF", cHorizF);
-        map.put("HorizG", cHorizG);
-        map.put("HorizH", cHorizH);
-        map.put("HorizI", cHorizI);
-        map.put("HorizJ", cHorizJ);
-        map.put("HorizK", cHorizK);
-        map.put("HorizL", cHorizL);
-        map.put("HorizM", cHorizM);
-        map.put("HorizN", cHorizN);
-        map.put("HorizO", cHorizO);
-        map.put("HorizAppSingleA", cHorizAppSingleA);
-        map.put("HorizAppSingleB", cHorizAppSingleB);
-        map.put("HorizAppSingleC", cHorizAppSingleC);
-        map.put("HorizAppSingleD", cHorizAppSingleD);
-        map.put("HorizAppMultiA", cHorizAppMultiA);
-        map.put("HorizAppMultiB", cHorizAppMultiB);
-        map.put("HorizAppMultiC", cHorizAppMultiC);
-        map.put("HorizAppMultiD", cHorizAppMultiD);
-        map.put("HorizInterFlatA", cHorizInterFlatA);
-        map.put("HorizInterFlatB", cHorizInterFlatB);
-        map.put("HorizInterFlatC", cHorizInterFlatC);
-        map.put("HorizInterFlatD", cHorizInterFlatD);
-        map.put("HorizInterVerticalA", cHorizInterVerticalA);
-        map.put("HorizInterVerticalB", cHorizInterVerticalB);
-        map.put("HorizInterVerticalC", cHorizInterVerticalC);
-        map.put("HorizInterVerticalD", cHorizInterVerticalD);
-
-        return map;
-    }
-
-    public void setObHorizA(HorizA obHorizA) {
-        this.obHorizA = obHorizA;
-    }
-
-    public HorizA getObHorizA() {
-        return this.obHorizA;
-    }
-
-    public void setObHorizB(HorizB obHorizB) {
-        this.obHorizB = obHorizB;
-    }
-
-    public HorizB getObHorizB() {
-        return this.obHorizB;
-    }
-
-    public void setObHorizC(HorizC obHorizC) {
-        this.obHorizC = obHorizC;
-    }
-
-    public HorizC getObHorizC() {
-        return this.obHorizC;
-    }
-
-    public void setObHorizD(HorizD obHorizD) {
-        this.obHorizD = obHorizD;
-    }
-
-    public HorizD getObHorizD() {
-        return this.obHorizD;
-    }
-
-    public void setObHorizE(HorizE obHorizE) {
-        this.obHorizE = obHorizE;
-    }
-
-    public HorizE getObHorizE() {
-        return this.obHorizE;
-    }
-
-    public void setObHorizF(HorizF obHorizF) {
-        this.obHorizF = obHorizF;
-    }
-
-    public HorizF getObHorizF() {
-        return this.obHorizF;
-    }
-
-    public void setObHorizG(HorizG obHorizG) {
-        this.obHorizG = obHorizG;
-    }
-
-    public HorizG getObHorizG() {
-        return this.obHorizG;
-    }
-
-    public void setObHorizH(HorizH obHorizH) {
-        this.obHorizH = obHorizH;
-    }
-
-    public HorizH getObHorizH() {
-        return this.obHorizH;
-    }
-
-    public void setObHorizI(HorizI obHorizI) {
-        this.obHorizI = obHorizI;
-    }
-
-    public HorizI getObHorizI() {
-        return this.obHorizI;
-    }
-
-    public void setObHorizJ(HorizJ obHorizJ) {
-        this.obHorizJ = obHorizJ;
-    }
-
-    public HorizJ getObHorizJ() {
-        return this.obHorizJ;
-    }
-
-    public void setObHorizK(HorizK obHorizK) {
-        this.obHorizK = obHorizK;
-    }
-
-    public HorizK getObHorizK() {
-        return this.obHorizK;
-    }
-
-    public void setObHorizL(HorizL obHorizL) {
-        this.obHorizL = obHorizL;
-    }
-
-    public HorizL getObHorizL() {
-        return this.obHorizL;
-    }
-
-    public void setObHorizM(HorizM obHorizM) {
-        this.obHorizM = obHorizM;
-    }
-
-    public HorizM getObHorizM() {
-        return this.obHorizM;
-    }
-
-    public void setObHorizN(HorizN obHorizN) {
-        this.obHorizN = obHorizN;
-    }
-
-    public HorizN getObHorizN() {
-        return this.obHorizN;
-    }
-
-    public void setObHorizO(HorizO obHorizO) {
-        this.obHorizO = obHorizO;
-    }
-
-    public HorizO getObHorizO() {
-        return this.obHorizO;
-    }
-
-    public void setObHorizAppSingleA(HorizAppSingleA obHorizAppSingleA) {
-        this.obHorizAppSingleA = obHorizAppSingleA;
-    }
-
-    public HorizAppSingleA getObHorizAppSingleA() {
-        return this.obHorizAppSingleA;
-    }
-
-    public void setObHorizAppSingleB(HorizAppSingleB obHorizAppSingleB) {
-        this.obHorizAppSingleB = obHorizAppSingleB;
-    }
-
-    public HorizAppSingleB getObHorizAppSingleB() {
-        return this.obHorizAppSingleB;
-    }
-
-    public void setObHorizAppSingleC(HorizAppSingleC obHorizAppSingleC) {
-        this.obHorizAppSingleC = obHorizAppSingleC;
-    }
-
-    public HorizAppSingleC getObHorizAppSingleC() {
-        return this.obHorizAppSingleC;
-    }
-
-    public void setObHorizAppSingleD(HorizAppSingleD obHorizAppSingleD) {
-        this.obHorizAppSingleD = obHorizAppSingleD;
-    }
-
-    public HorizAppSingleD getObHorizAppSingleD() {
-        return this.obHorizAppSingleD;
-    }
-
-    public void setObHorizAppMultiA(HorizAppMultiA obHorizAppMultiA) {
-        this.obHorizAppMultiA = obHorizAppMultiA;
-    }
-
-    public HorizAppMultiA getObHorizAppMultiA() {
-        return this.obHorizAppMultiA;
-    }
-
-    public void setObHorizAppMultiB(HorizAppMultiB obHorizAppMultiB) {
-        this.obHorizAppMultiB = obHorizAppMultiB;
-    }
-
-    public HorizAppMultiB getObHorizAppMultiB() {
-        return this.obHorizAppMultiB;
-    }
-
-    public void setObHorizAppMultiC(HorizAppMultiC obHorizAppMultiC) {
-        this.obHorizAppMultiC = obHorizAppMultiC;
-    }
-
-    public HorizAppMultiC getObHorizAppMultiC() {
-        return this.obHorizAppMultiC;
-    }
-
-    public void setObHorizAppMultiD(HorizAppMultiD obHorizAppMultiD) {
-        this.obHorizAppMultiD = obHorizAppMultiD;
-    }
-
-    public HorizAppMultiD getObHorizAppMultiD() {
-        return this.obHorizAppMultiD;
-    }
-
-    public void setObHorizInterFlatA(HorizInterFlatA obHorizInterFlatA) {
-        this.obHorizInterFlatA = obHorizInterFlatA;
-    }
-
-    public HorizInterFlatA getObHorizInterFlatA() {
-        return this.obHorizInterFlatA;
-    }
-
-    public void setObHorizInterFlatB(HorizInterFlatB obHorizInterFlatB) {
-        this.obHorizInterFlatB = obHorizInterFlatB;
-    }
-
-    public HorizInterFlatB getObHorizInterFlatB() {
-        return this.obHorizInterFlatB;
-    }
-
-    public void setObHorizInterFlatC(HorizInterFlatC obHorizInterFlatC) {
-        this.obHorizInterFlatC = obHorizInterFlatC;
-    }
-
-    public HorizInterFlatC getObHorizInterFlatC() {
-        return this.obHorizInterFlatC;
-    }
-
-    public void setObHorizInterFlatD(HorizInterFlatD obHorizInterFlatD) {
-        this.obHorizInterFlatD = obHorizInterFlatD;
-    }
-
-    public HorizInterFlatD getObHorizInterFlatD() {
-        return this.obHorizInterFlatD;
-    }
-
-    public void setObHorizInterVerticalA
-        (HorizInterVerticalA obHorizInterVerticalA) {
-        this.obHorizInterVerticalA = obHorizInterVerticalA;
-    }
-
-    public HorizInterVerticalA getObHorizInterVerticalA() {
-        return this.obHorizInterVerticalA;
-    }
-
-    public void setObHorizInterVerticalB
-        (HorizInterVerticalB obHorizInterVerticalB) {
-        this.obHorizInterVerticalB = obHorizInterVerticalB;
-    }
-
-    public HorizInterVerticalB getObHorizInterVerticalB() {
-        return this.obHorizInterVerticalB;
-    }
-
-    public void setObHorizInterVerticalC
-        (HorizInterVerticalC obHorizInterVerticalC) {
-        this.obHorizInterVerticalC = obHorizInterVerticalC;
-    }
-
-    public HorizInterVerticalC getObHorizInterVerticalC() {
-        return this.obHorizInterVerticalC;
-    }
-
-    public void setObHorizInterVerticalD
-        (HorizInterVerticalD obHorizInterVerticalD) {
-        this.obHorizInterVerticalD = obHorizInterVerticalD;
-    }
-
-    public HorizInterVerticalD getObHorizInterVerticalD() {
-        return this.obHorizInterVerticalD;
-    }
-
-    public HashSet getCHorizInterVerticalB() {
-        return this.cHorizInterVerticalB;
-    }
-
-    public void setCHorizInterVerticalB(HashSet cHorizInterVerticalB) {
-        this.cHorizInterVerticalB = cHorizInterVerticalB;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.util.*;
+
+import javax.persistence.Entity;
+
+import org.apache.commons.collections.*;
+
+/**
+ * Normal class that has relations to and from various horizontal
+ * relations.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class HorizRelation
+    implements Serializable {
+    ///////////////////////
+    // One to one mappings
+    ///////////////////////
+
+    private HorizA obHorizA;
+    private HorizB obHorizB;
+    private HorizC obHorizC;
+    private HorizD obHorizD;
+    private HorizE obHorizE;
+    private HorizF obHorizF;
+    private HorizG obHorizG;
+    private HorizH obHorizH;
+    private HorizI obHorizI;
+    private HorizJ obHorizJ;
+    private HorizK obHorizK;
+    private HorizL obHorizL;
+    private HorizM obHorizM;
+    private HorizN obHorizN;
+    private HorizO obHorizO;
+    private HorizAppSingleA obHorizAppSingleA;
+    private HorizAppSingleB obHorizAppSingleB;
+    private HorizAppSingleC obHorizAppSingleC;
+    private HorizAppSingleD obHorizAppSingleD;
+    private HorizAppMultiA obHorizAppMultiA;
+    private HorizAppMultiB obHorizAppMultiB;
+    private HorizAppMultiC obHorizAppMultiC;
+    private HorizAppMultiD obHorizAppMultiD;
+    private HorizInterFlatA obHorizInterFlatA;
+    private HorizInterFlatB obHorizInterFlatB;
+    private HorizInterFlatC obHorizInterFlatC;
+    private HorizInterFlatD obHorizInterFlatD;
+    private HorizInterVerticalA obHorizInterVerticalA;
+    private HorizInterVerticalB obHorizInterVerticalB;
+    private HorizInterVerticalC obHorizInterVerticalC;
+    private HorizInterVerticalD obHorizInterVerticalD;
+
+    ////////////////////////
+    // One to many mappings
+    ////////////////////////
+
+    private HashSet cHorizA = new HashSet();
+    private LinkedList cHorizB = new LinkedList();
+    private ArrayList cHorizC = new ArrayList();
+    private Vector cHorizD = new Vector();
+    private HashSet cHorizE = new HashSet();
+    private LinkedList cHorizF = new LinkedList();
+    private ArrayList cHorizG = new ArrayList();
+    private Vector cHorizH = new Vector();
+    private HashSet cHorizI = new HashSet();
+    private LinkedList cHorizJ = new LinkedList();
+    private ArrayList cHorizK = new ArrayList();
+    private Vector cHorizL = new Vector();
+    private HashSet cHorizM = new HashSet();
+    private LinkedList cHorizN = new LinkedList();
+    private ArrayList cHorizO = new ArrayList();
+    private Vector cHorizAppSingleA = new Vector();
+    private HashSet cHorizAppSingleB = new HashSet();
+    private LinkedList cHorizAppSingleC = new LinkedList();
+    private ArrayList cHorizAppSingleD = new ArrayList();
+    private Vector cHorizAppMultiA = new Vector();
+    private HashSet cHorizAppMultiB = new HashSet();
+    private LinkedList cHorizAppMultiC = new LinkedList();
+    private ArrayList cHorizAppMultiD = new ArrayList();
+    private Vector cHorizInterFlatA = new Vector();
+    private HashSet cHorizInterFlatB = new HashSet();
+    private LinkedList cHorizInterFlatC = new LinkedList();
+    private ArrayList cHorizInterFlatD = new ArrayList();
+    private Vector cHorizInterVerticalA = new Vector();
+    private HashSet cHorizInterVerticalB = new HashSet();
+    private LinkedList cHorizInterVerticalC = new LinkedList();
+    private ArrayList cHorizInterVerticalD = new ArrayList();
+
+    public Map getCollections() {
+        Map map = new SequencedHashMap();
+        map.put("HorizA", cHorizA);
+        map.put("HorizB", cHorizB);
+        map.put("HorizC", cHorizC);
+        map.put("HorizD", cHorizD);
+        map.put("HorizE", cHorizE);
+        map.put("HorizF", cHorizF);
+        map.put("HorizG", cHorizG);
+        map.put("HorizH", cHorizH);
+        map.put("HorizI", cHorizI);
+        map.put("HorizJ", cHorizJ);
+        map.put("HorizK", cHorizK);
+        map.put("HorizL", cHorizL);
+        map.put("HorizM", cHorizM);
+        map.put("HorizN", cHorizN);
+        map.put("HorizO", cHorizO);
+        map.put("HorizAppSingleA", cHorizAppSingleA);
+        map.put("HorizAppSingleB", cHorizAppSingleB);
+        map.put("HorizAppSingleC", cHorizAppSingleC);
+        map.put("HorizAppSingleD", cHorizAppSingleD);
+        map.put("HorizAppMultiA", cHorizAppMultiA);
+        map.put("HorizAppMultiB", cHorizAppMultiB);
+        map.put("HorizAppMultiC", cHorizAppMultiC);
+        map.put("HorizAppMultiD", cHorizAppMultiD);
+        map.put("HorizInterFlatA", cHorizInterFlatA);
+        map.put("HorizInterFlatB", cHorizInterFlatB);
+        map.put("HorizInterFlatC", cHorizInterFlatC);
+        map.put("HorizInterFlatD", cHorizInterFlatD);
+        map.put("HorizInterVerticalA", cHorizInterVerticalA);
+        map.put("HorizInterVerticalB", cHorizInterVerticalB);
+        map.put("HorizInterVerticalC", cHorizInterVerticalC);
+        map.put("HorizInterVerticalD", cHorizInterVerticalD);
+
+        return map;
+    }
+
+    public void setObHorizA(HorizA obHorizA) {
+        this.obHorizA = obHorizA;
+    }
+
+    public HorizA getObHorizA() {
+        return this.obHorizA;
+    }
+
+    public void setObHorizB(HorizB obHorizB) {
+        this.obHorizB = obHorizB;
+    }
+
+    public HorizB getObHorizB() {
+        return this.obHorizB;
+    }
+
+    public void setObHorizC(HorizC obHorizC) {
+        this.obHorizC = obHorizC;
+    }
+
+    public HorizC getObHorizC() {
+        return this.obHorizC;
+    }
+
+    public void setObHorizD(HorizD obHorizD) {
+        this.obHorizD = obHorizD;
+    }
+
+    public HorizD getObHorizD() {
+        return this.obHorizD;
+    }
+
+    public void setObHorizE(HorizE obHorizE) {
+        this.obHorizE = obHorizE;
+    }
+
+    public HorizE getObHorizE() {
+        return this.obHorizE;
+    }
+
+    public void setObHorizF(HorizF obHorizF) {
+        this.obHorizF = obHorizF;
+    }
+
+    public HorizF getObHorizF() {
+        return this.obHorizF;
+    }
+
+    public void setObHorizG(HorizG obHorizG) {
+        this.obHorizG = obHorizG;
+    }
+
+    public HorizG getObHorizG() {
+        return this.obHorizG;
+    }
+
+    public void setObHorizH(HorizH obHorizH) {
+        this.obHorizH = obHorizH;
+    }
+
+    public HorizH getObHorizH() {
+        return this.obHorizH;
+    }
+
+    public void setObHorizI(HorizI obHorizI) {
+        this.obHorizI = obHorizI;
+    }
+
+    public HorizI getObHorizI() {
+        return this.obHorizI;
+    }
+
+    public void setObHorizJ(HorizJ obHorizJ) {
+        this.obHorizJ = obHorizJ;
+    }
+
+    public HorizJ getObHorizJ() {
+        return this.obHorizJ;
+    }
+
+    public void setObHorizK(HorizK obHorizK) {
+        this.obHorizK = obHorizK;
+    }
+
+    public HorizK getObHorizK() {
+        return this.obHorizK;
+    }
+
+    public void setObHorizL(HorizL obHorizL) {
+        this.obHorizL = obHorizL;
+    }
+
+    public HorizL getObHorizL() {
+        return this.obHorizL;
+    }
+
+    public void setObHorizM(HorizM obHorizM) {
+        this.obHorizM = obHorizM;
+    }
+
+    public HorizM getObHorizM() {
+        return this.obHorizM;
+    }
+
+    public void setObHorizN(HorizN obHorizN) {
+        this.obHorizN = obHorizN;
+    }
+
+    public HorizN getObHorizN() {
+        return this.obHorizN;
+    }
+
+    public void setObHorizO(HorizO obHorizO) {
+        this.obHorizO = obHorizO;
+    }
+
+    public HorizO getObHorizO() {
+        return this.obHorizO;
+    }
+
+    public void setObHorizAppSingleA(HorizAppSingleA obHorizAppSingleA) {
+        this.obHorizAppSingleA = obHorizAppSingleA;
+    }
+
+    public HorizAppSingleA getObHorizAppSingleA() {
+        return this.obHorizAppSingleA;
+    }
+
+    public void setObHorizAppSingleB(HorizAppSingleB obHorizAppSingleB) {
+        this.obHorizAppSingleB = obHorizAppSingleB;
+    }
+
+    public HorizAppSingleB getObHorizAppSingleB() {
+        return this.obHorizAppSingleB;
+    }
+
+    public void setObHorizAppSingleC(HorizAppSingleC obHorizAppSingleC) {
+        this.obHorizAppSingleC = obHorizAppSingleC;
+    }
+
+    public HorizAppSingleC getObHorizAppSingleC() {
+        return this.obHorizAppSingleC;
+    }
+
+    public void setObHorizAppSingleD(HorizAppSingleD obHorizAppSingleD) {
+        this.obHorizAppSingleD = obHorizAppSingleD;
+    }
+
+    public HorizAppSingleD getObHorizAppSingleD() {
+        return this.obHorizAppSingleD;
+    }
+
+    public void setObHorizAppMultiA(HorizAppMultiA obHorizAppMultiA) {
+        this.obHorizAppMultiA = obHorizAppMultiA;
+    }
+
+    public HorizAppMultiA getObHorizAppMultiA() {
+        return this.obHorizAppMultiA;
+    }
+
+    public void setObHorizAppMultiB(HorizAppMultiB obHorizAppMultiB) {
+        this.obHorizAppMultiB = obHorizAppMultiB;
+    }
+
+    public HorizAppMultiB getObHorizAppMultiB() {
+        return this.obHorizAppMultiB;
+    }
+
+    public void setObHorizAppMultiC(HorizAppMultiC obHorizAppMultiC) {
+        this.obHorizAppMultiC = obHorizAppMultiC;
+    }
+
+    public HorizAppMultiC getObHorizAppMultiC() {
+        return this.obHorizAppMultiC;
+    }
+
+    public void setObHorizAppMultiD(HorizAppMultiD obHorizAppMultiD) {
+        this.obHorizAppMultiD = obHorizAppMultiD;
+    }
+
+    public HorizAppMultiD getObHorizAppMultiD() {
+        return this.obHorizAppMultiD;
+    }
+
+    public void setObHorizInterFlatA(HorizInterFlatA obHorizInterFlatA) {
+        this.obHorizInterFlatA = obHorizInterFlatA;
+    }
+
+    public HorizInterFlatA getObHorizInterFlatA() {
+        return this.obHorizInterFlatA;
+    }
+
+    public void setObHorizInterFlatB(HorizInterFlatB obHorizInterFlatB) {
+        this.obHorizInterFlatB = obHorizInterFlatB;
+    }
+
+    public HorizInterFlatB getObHorizInterFlatB() {
+        return this.obHorizInterFlatB;
+    }
+
+    public void setObHorizInterFlatC(HorizInterFlatC obHorizInterFlatC) {
+        this.obHorizInterFlatC = obHorizInterFlatC;
+    }
+
+    public HorizInterFlatC getObHorizInterFlatC() {
+        return this.obHorizInterFlatC;
+    }
+
+    public void setObHorizInterFlatD(HorizInterFlatD obHorizInterFlatD) {
+        this.obHorizInterFlatD = obHorizInterFlatD;
+    }
+
+    public HorizInterFlatD getObHorizInterFlatD() {
+        return this.obHorizInterFlatD;
+    }
+
+    public void setObHorizInterVerticalA
+        (HorizInterVerticalA obHorizInterVerticalA) {
+        this.obHorizInterVerticalA = obHorizInterVerticalA;
+    }
+
+    public HorizInterVerticalA getObHorizInterVerticalA() {
+        return this.obHorizInterVerticalA;
+    }
+
+    public void setObHorizInterVerticalB
+        (HorizInterVerticalB obHorizInterVerticalB) {
+        this.obHorizInterVerticalB = obHorizInterVerticalB;
+    }
+
+    public HorizInterVerticalB getObHorizInterVerticalB() {
+        return this.obHorizInterVerticalB;
+    }
+
+    public void setObHorizInterVerticalC
+        (HorizInterVerticalC obHorizInterVerticalC) {
+        this.obHorizInterVerticalC = obHorizInterVerticalC;
+    }
+
+    public HorizInterVerticalC getObHorizInterVerticalC() {
+        return this.obHorizInterVerticalC;
+    }
+
+    public void setObHorizInterVerticalD
+        (HorizInterVerticalD obHorizInterVerticalD) {
+        this.obHorizInterVerticalD = obHorizInterVerticalD;
+    }
+
+    public HorizInterVerticalD getObHorizInterVerticalD() {
+        return this.obHorizInterVerticalD;
+    }
+
+    public HashSet getCHorizInterVerticalB() {
+        return this.cHorizInterVerticalB;
+    }
+
+    public void setCHorizInterVerticalB(HashSet cHorizInterVerticalB) {
+        this.cHorizInterVerticalB = cHorizInterVerticalB;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InverseKeyMapPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InverseKeyMapPC.java
index 466bbf7..16caf17 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InverseKeyMapPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InverseKeyMapPC.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class InverseKeyMapPC
-    implements MappedByMapPC {
-
-    private String name;
-    private Map helpers = new HashMap();
-
-    public Map getHelpers() {
-        return this.helpers;
-    }
-
-    public void setHelpers(Map helpers) {
-        this.helpers = helpers;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class InverseKeyMapPC
+    implements MappedByMapPC {
+
+    private String name;
+    private Map helpers = new HashMap();
+
+    public Map getHelpers() {
+        return this.helpers;
+    }
+
+    public void setHelpers(Map helpers) {
+        this.helpers = helpers;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertA.java
index fc5f0ee..02c3c5f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertA.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.io.Serializable;
-import java.util.*;
-import javax.persistence.*;
-
-/**
- *	Used to test invert one-to-ones and stuff
- *
- *	@author		skim
- */
-@SuppressWarnings("serial")
-@Entity
-public class InvertA implements Serializable
-{
-	@Id
-	private int id;
-
-	@Column(length=35)
-	String test;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	InvertB	invertB;
-
-	public InvertA()
-	{
-	}
-
-	public InvertA(int id)
-	{
-		this.id = id;
-	}
-
-	public InvertB getInvertB ()
-	{
-		return invertB;
-	}
-
-	public void setInvertB (InvertB b)
-	{
-		invertB = b;
-	}
-
-	public void setTest (String s)
-	{
-		test = s;
-	}
-
-	public String getTest ()
-	{
-		return test;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.io.Serializable;
+import java.util.*;
+import javax.persistence.*;
+
+/**
+ *	Used to test invert one-to-ones and stuff
+ *
+ *	@author		skim
+ */
+@SuppressWarnings("serial")
+@Entity
+public class InvertA implements Serializable
+{
+	@Id
+	private int id;
+
+	@Column(length=35)
+	String test;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	InvertB	invertB;
+
+	public InvertA()
+	{
+	}
+
+	public InvertA(int id)
+	{
+		this.id = id;
+	}
+
+	public InvertB getInvertB ()
+	{
+		return invertB;
+	}
+
+	public void setInvertB (InvertB b)
+	{
+		invertB = b;
+	}
+
+	public void setTest (String s)
+	{
+		test = s;
+	}
+
+	public String getTest ()
+	{
+		return test;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertB.java
index 77bb629..ffd601f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/InvertB.java
@@ -1,82 +1,82 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.Serializable;
-import java.util.*;
-
-import javax.persistence.*;
-
-
-/**
- *	Used to test invert one to ones and stuff.
- *
- *	@author		skim
- */
-@SuppressWarnings("serial")
-@Entity
-public class InvertB implements Serializable
-{
-
-	@Id
-	private int id;
-
-	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-	public InvertA invertA;
-
-	@Column(length=35)
-	public String test;
-
-	public InvertB()
-	{
-	}
-
-	public InvertB(int id)
-	{
-		this.id = id;
-	}
-
-	public InvertA getInvertA ()
-	{
-		return invertA;
-	}
-
-	public void setInvertA (InvertA a)
-	{
-		invertA = a;
-	}
-
-	public String getTest ()
-	{
-		return test;
-	}
-
-	public void setTest (String s)
-	{
-		test = s;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.Serializable;
+import java.util.*;
+
+import javax.persistence.*;
+
+
+/**
+ *	Used to test invert one to ones and stuff.
+ *
+ *	@author		skim
+ */
+@SuppressWarnings("serial")
+@Entity
+public class InvertB implements Serializable
+{
+
+	@Id
+	private int id;
+
+	@OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	public InvertA invertA;
+
+	@Column(length=35)
+	public String test;
+
+	public InvertB()
+	{
+	}
+
+	public InvertB(int id)
+	{
+		this.id = id;
+	}
+
+	public InvertA getInvertA ()
+	{
+		return invertA;
+	}
+
+	public void setInvertA (InvertA a)
+	{
+		invertA = a;
+	}
+
+	public String getTest ()
+	{
+		return test;
+	}
+
+	public void setTest (String s)
+	{
+		test = s;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBase.java
index 1eb4073..6d7f6c8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBase.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class JoinSubclassBase
-    implements Comparable {
-
-    private int baseField;
-
-    public int getBaseField() {
-        return this.baseField;
-    }
-
-    public void setBaseField(int baseField) {
-        this.baseField = baseField;
-    }
-
-    public int compareTo(Object other) {
-        if (other == this)
-            return 0;
-        if (other == null)
-            return 1;
-        return baseField - ((JoinSubclassBase) other).baseField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class JoinSubclassBase
+    implements Comparable {
+
+    private int baseField;
+
+    public int getBaseField() {
+        return this.baseField;
+    }
+
+    public void setBaseField(int baseField) {
+        this.baseField = baseField;
+    }
+
+    public int compareTo(Object other) {
+        if (other == this)
+            return 0;
+        if (other == null)
+            return 1;
+        return baseField - ((JoinSubclassBase) other).baseField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubFlat.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubFlat.java
index d78aae2..d4a8df6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubFlat.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubFlat.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class JoinSubclassBaseSubFlat
-    extends JoinSubclassBaseSubVert {
-
-    private int baseSubFlatField;
-
-    public int getBaseSubFlatField() {
-        return this.baseSubFlatField;
-    }
-
-    public void setBaseSubFlatField(int baseSubFlatField) {
-        this.baseSubFlatField = baseSubFlatField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class JoinSubclassBaseSubFlat
+    extends JoinSubclassBaseSubVert {
+
+    private int baseSubFlatField;
+
+    public int getBaseSubFlatField() {
+        return this.baseSubFlatField;
+    }
+
+    public void setBaseSubFlatField(int baseSubFlatField) {
+        this.baseSubFlatField = baseSubFlatField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubVert.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubVert.java
index 618a864..84c00cb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubVert.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinSubclassBaseSubVert.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class JoinSubclassBaseSubVert
-    extends JoinSubclassBase {
-
-    private int baseSubVertField;
-
-    public int getBaseSubVertField() {
-        return this.baseSubVertField;
-    }
-
-    public void setBaseSubVertField(int baseSubVertField) {
-        this.baseSubVertField = baseSubVertField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class JoinSubclassBaseSubVert
+    extends JoinSubclassBase {
+
+    private int baseSubVertField;
+
+    public int getBaseSubVertField() {
+        return this.baseSubVertField;
+    }
+
+    public void setBaseSubVertField(int baseSubVertField) {
+        this.baseSubVertField = baseSubVertField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinTableMapPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinTableMapPC.java
index 53abbf3..9eb0c1e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinTableMapPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/JoinTableMapPC.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-@Entity
-public class JoinTableMapPC
-    implements MappedByMapPC {
-
-    private String name;
-    private Map helpers = new HashMap();
-
-    public Map getHelpers() {
-        return this.helpers;
-    }
-
-    public void setHelpers(Map helpers) {
-        this.helpers = helpers;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+@Entity
+public class JoinTableMapPC
+    implements MappedByMapPC {
+
+    private String name;
+    private Map helpers = new HashMap();
+
+    public Map getHelpers() {
+        return this.helpers;
+    }
+
+    public void setHelpers(Map helpers) {
+        this.helpers = helpers;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSCompoundPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSCompoundPC.java
index 2c6bf65..c146048 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSCompoundPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSCompoundPC.java
@@ -1,114 +1,114 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type with a compound primary key and LRS fields.</p>
- *
- * @author Abe White
- */
-@Entity
-public class LRSCompoundPC
-    implements LRSPCIntf {
-
-    private static int idGen = 0;
-
-    private int id1;
-    private int id2;
-
-    private String stringField;
-    private Set stringSet = new HashSet();
-    private Set relSet = new HashSet();
-    private Collection stringCollection = new ArrayList();
-    private Collection relCollection = new ArrayList();
-    private Map stringMap = new HashMap();
-    private Map relMap = new HashMap();
-
-    private LRSCompoundPC() {
-    }
-
-    public LRSCompoundPC(String str) {
-        id1 = idGen++;
-        id2 = idGen++;
-        stringField = str;
-    }
-
-    public LRSPCIntf newInstance(String stringField) {
-        return new LRSCompoundPC(stringField);
-    }
-
-    public Set getStringSet() {
-        return this.stringSet;
-    }
-
-    public void setStringSet(Set stringSet) {
-        this.stringSet = stringSet;
-    }
-
-    public Set getRelSet() {
-        return this.relSet;
-    }
-
-    public void setRelSet(Set relSet) {
-        this.relSet = relSet;
-    }
-
-    public Collection getStringCollection() {
-        return this.stringCollection;
-    }
-
-    public void setStringCollection(Collection stringCollection) {
-        this.stringCollection = stringCollection;
-    }
-
-    public Collection getRelCollection() {
-        return this.relCollection;
-    }
-
-    public void setRelCollection(Collection relCollection) {
-        this.relCollection = relCollection;
-    }
-
-    public Map getStringMap() {
-        return this.stringMap;
-    }
-
-    public void setStringMap(Map stringMap) {
-        this.stringMap = stringMap;
-    }
-
-    public Map getRelMap() {
-        return this.relMap;
-    }
-
-    public void setRelMap(Map relMap) {
-        this.relMap = relMap;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public int compareTo(Object other) {
-        return stringField.compareTo(((LRSCompoundPC) other).stringField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type with a compound primary key and LRS fields.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class LRSCompoundPC
+    implements LRSPCIntf {
+
+    private static int idGen = 0;
+
+    private int id1;
+    private int id2;
+
+    private String stringField;
+    private Set stringSet = new HashSet();
+    private Set relSet = new HashSet();
+    private Collection stringCollection = new ArrayList();
+    private Collection relCollection = new ArrayList();
+    private Map stringMap = new HashMap();
+    private Map relMap = new HashMap();
+
+    private LRSCompoundPC() {
+    }
+
+    public LRSCompoundPC(String str) {
+        id1 = idGen++;
+        id2 = idGen++;
+        stringField = str;
+    }
+
+    public LRSPCIntf newInstance(String stringField) {
+        return new LRSCompoundPC(stringField);
+    }
+
+    public Set getStringSet() {
+        return this.stringSet;
+    }
+
+    public void setStringSet(Set stringSet) {
+        this.stringSet = stringSet;
+    }
+
+    public Set getRelSet() {
+        return this.relSet;
+    }
+
+    public void setRelSet(Set relSet) {
+        this.relSet = relSet;
+    }
+
+    public Collection getStringCollection() {
+        return this.stringCollection;
+    }
+
+    public void setStringCollection(Collection stringCollection) {
+        this.stringCollection = stringCollection;
+    }
+
+    public Collection getRelCollection() {
+        return this.relCollection;
+    }
+
+    public void setRelCollection(Collection relCollection) {
+        this.relCollection = relCollection;
+    }
+
+    public Map getStringMap() {
+        return this.stringMap;
+    }
+
+    public void setStringMap(Map stringMap) {
+        this.stringMap = stringMap;
+    }
+
+    public Map getRelMap() {
+        return this.relMap;
+    }
+
+    public void setRelMap(Map relMap) {
+        this.relMap = relMap;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public int compareTo(Object other) {
+        return stringField.compareTo(((LRSCompoundPC) other).stringField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPC.java
index 982cc2a..4de6968 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPC.java
@@ -1,107 +1,107 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type with LRS fields.</p>
- *
- * @author Abe White
- */
-@Entity
-public class LRSPC
-    implements LRSPCIntf {
-
-    private String stringField;
-    private Set stringSet = new HashSet();
-    private Set relSet = new HashSet();
-    private Collection stringCollection = new ArrayList();
-    private Collection relCollection = new ArrayList();
-    private Map stringMap = new HashMap();
-    private Map relMap = new HashMap();
-
-    private LRSPC() {
-    }
-
-    public LRSPC(String str) {
-        stringField = str;
-    }
-
-    public LRSPCIntf newInstance(String stringField) {
-        return new LRSPC(stringField);
-    }
-
-    public Set getStringSet() {
-        return this.stringSet;
-    }
-
-    public void setStringSet(Set stringSet) {
-        this.stringSet = stringSet;
-    }
-
-    public Set getRelSet() {
-        return this.relSet;
-    }
-
-    public void setRelSet(Set relSet) {
-        this.relSet = relSet;
-    }
-
-    public Collection getStringCollection() {
-        return this.stringCollection;
-    }
-
-    public void setStringCollection(Collection stringCollection) {
-        this.stringCollection = stringCollection;
-    }
-
-    public Collection getRelCollection() {
-        return this.relCollection;
-    }
-
-    public void setRelCollection(Collection relCollection) {
-        this.relCollection = relCollection;
-    }
-
-    public Map getStringMap() {
-        return this.stringMap;
-    }
-
-    public void setStringMap(Map stringMap) {
-        this.stringMap = stringMap;
-    }
-
-    public Map getRelMap() {
-        return this.relMap;
-    }
-
-    public void setRelMap(Map relMap) {
-        this.relMap = relMap;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public int compareTo(Object other) {
-        return stringField.compareTo(((LRSPC) other).stringField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type with LRS fields.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class LRSPC
+    implements LRSPCIntf {
+
+    private String stringField;
+    private Set stringSet = new HashSet();
+    private Set relSet = new HashSet();
+    private Collection stringCollection = new ArrayList();
+    private Collection relCollection = new ArrayList();
+    private Map stringMap = new HashMap();
+    private Map relMap = new HashMap();
+
+    private LRSPC() {
+    }
+
+    public LRSPC(String str) {
+        stringField = str;
+    }
+
+    public LRSPCIntf newInstance(String stringField) {
+        return new LRSPC(stringField);
+    }
+
+    public Set getStringSet() {
+        return this.stringSet;
+    }
+
+    public void setStringSet(Set stringSet) {
+        this.stringSet = stringSet;
+    }
+
+    public Set getRelSet() {
+        return this.relSet;
+    }
+
+    public void setRelSet(Set relSet) {
+        this.relSet = relSet;
+    }
+
+    public Collection getStringCollection() {
+        return this.stringCollection;
+    }
+
+    public void setStringCollection(Collection stringCollection) {
+        this.stringCollection = stringCollection;
+    }
+
+    public Collection getRelCollection() {
+        return this.relCollection;
+    }
+
+    public void setRelCollection(Collection relCollection) {
+        this.relCollection = relCollection;
+    }
+
+    public Map getStringMap() {
+        return this.stringMap;
+    }
+
+    public void setStringMap(Map stringMap) {
+        this.stringMap = stringMap;
+    }
+
+    public Map getRelMap() {
+        return this.relMap;
+    }
+
+    public void setRelMap(Map relMap) {
+        this.relMap = relMap;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public int compareTo(Object other) {
+        return stringField.compareTo(((LRSPC) other).stringField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPCIntf.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPCIntf.java
index a29bcbd..36b8171 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPCIntf.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LRSPCIntf.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-/**
- * <p>Common interface for persistent types used in LRS testing.</p>
- *
- * @author Abe White
- */
-public interface LRSPCIntf
-    extends Comparable {
-
-    public Set getStringSet();
-
-    public void setStringSet(Set stringSet);
-
-    public Set getRelSet();
-
-    public void setRelSet(Set relSet);
-
-    public Collection getStringCollection();
-
-    public void setStringCollection(Collection stringCollection);
-
-    public Collection getRelCollection();
-
-    public void setRelCollection(Collection relCollection);
-
-    public Map getStringMap();
-
-    public void setStringMap(Map stringMap);
-
-    public Map getRelMap();
-
-    public void setRelMap(Map relMap);
-
-    public String getStringField();
-
-    public LRSPCIntf newInstance(String stringField);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+/**
+ * <p>Common interface for persistent types used in LRS testing.</p>
+ *
+ * @author Abe White
+ */
+public interface LRSPCIntf
+    extends Comparable {
+
+    public Set getStringSet();
+
+    public void setStringSet(Set stringSet);
+
+    public Set getRelSet();
+
+    public void setRelSet(Set relSet);
+
+    public Collection getStringCollection();
+
+    public void setStringCollection(Collection stringCollection);
+
+    public Collection getRelCollection();
+
+    public void setRelCollection(Collection relCollection);
+
+    public Map getStringMap();
+
+    public void setStringMap(Map stringMap);
+
+    public Map getRelMap();
+
+    public void setRelMap(Map relMap);
+
+    public String getStringField();
+
+    public LRSPCIntf newInstance(String stringField);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LocatorTestObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LocatorTestObject.java
index 38b3999..77893d8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LocatorTestObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LocatorTestObject.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-public class LocatorTestObject {
-
-    private byte[] bytes;
-    private String clobString;
-
-    public void setBytes(byte[] bytes) {
-        this.bytes = bytes;
-    }
-
-    public byte[] getBytes() {
-        return bytes;
-    }
-
-    public void setClobString(String val) {
-        clobString = val;
-    }
-
-    public String getClobString() {
-        return clobString;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+public class LocatorTestObject {
+
+    private byte[] bytes;
+    private String clobString;
+
+    public void setBytes(byte[] bytes) {
+        this.bytes = bytes;
+    }
+
+    public byte[] getBytes() {
+        return bytes;
+    }
+
+    public void setClobString(String val) {
+        clobString = val;
+    }
+
+    public String getClobString() {
+        return clobString;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LockGroupSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LockGroupSubclass.java
index f9f5900..6b40b1f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LockGroupSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/LockGroupSubclass.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class LockGroupSubclass
-    extends HorizB {
-
-    private String nonDefaultLockGroupField;
-    private String defaultLockGroupField;
-
-    public String getDefaultLockGroupField() {
-        return defaultLockGroupField;
-    }
-
-    public void setDefaultLockGroupField(String defaultLockGroupField) {
-        this.defaultLockGroupField = defaultLockGroupField;
-    }
-
-    public String getNonDefaultLockGroupField() {
-        return nonDefaultLockGroupField;
-    }
-
-    public void setNonDefaultLockGroupField(String nonDefaultLockGroupField) {
-        this.nonDefaultLockGroupField = nonDefaultLockGroupField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class LockGroupSubclass
+    extends HorizB {
+
+    private String nonDefaultLockGroupField;
+    private String defaultLockGroupField;
+
+    public String getDefaultLockGroupField() {
+        return defaultLockGroupField;
+    }
+
+    public void setDefaultLockGroupField(String defaultLockGroupField) {
+        this.defaultLockGroupField = defaultLockGroupField;
+    }
+
+    public String getNonDefaultLockGroupField() {
+        return nonDefaultLockGroupField;
+    }
+
+    public void setNonDefaultLockGroupField(String nonDefaultLockGroupField) {
+        this.nonDefaultLockGroupField = nonDefaultLockGroupField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappedByMapPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappedByMapPC.java
index 5236115..6c2c991 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappedByMapPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappedByMapPC.java
@@ -1,29 +1,29 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public interface MappedByMapPC {
-
-    /**
-     * Map of string to {@link HelperPC}.
-     */
-    public Map getHelpers();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public interface MappedByMapPC {
+
+    /**
+     * Map of string to {@link HelperPC}.
+     */
+    public Map getHelpers();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest1.java
index 08322bc..bacc415 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest1.java
@@ -1,254 +1,254 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.util.*;
-import javax.persistence.Entity;
-
-/**
- *	<p>Persistent type used for testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-public class MappingTest1
-{
-	private int				value					= 0;
-	private int				otherTableValue			= 0;
-	private Object 			blob					= null;
-	private MappingTest2 	oneOne					= null;
-	private MappingTest1 	selfOneOne				= null;
-	private MappingTest2 	otherTableOneOne		= null;
-	private MappingTest2	inverseOwnerOneOne		= null;
-	private MappingTest2	inverseOneOne			= null;
-	private Set				collection				= new HashSet ();
-	private Set				inverseOwnerOneMany		= new HashSet ();
-	private Set				oneMany					= new HashSet ();
-	private List			manyMany				= new LinkedList ();
-	private Set				inverseOwnerManyMany	= new HashSet ();
-	private Map				map						= new HashMap ();
-	private Map				nManyMap				= new HashMap ();
-	private Map				manyManyMap				= new HashMap ();
-	private int				transactionalValue		= 0;
-
-
-	public int getValue ()
-	{
-		return this.value;
-	}
-
-
-	public void setValue (int value)
-	{
-		this.value = value;
-	}
-
-
-	public int getOtherTableValue ()
-	{
-		return this.otherTableValue;
-	}
-
-
-	public void setOtherTableValue (int otherTableValue)
-	{
-		this.otherTableValue = otherTableValue;
-	}
-
-
-	public Object getBlob ()
-	{
-		return this.blob;
-	}
-
-
-	public void setBlob (Object blob)
-	{
-		this.blob = blob;
-	}
-
-
-	public MappingTest2 getOneOne ()
-	{
-		return this.oneOne;
-	}
-
-
-	public void setOneOne (MappingTest2 oneOne)
-	{
-		this.oneOne = oneOne;
-	}
-
-
-	public MappingTest1 getSelfOneOne ()
-	{
-		return this.selfOneOne;
-	}
-
-
-	public void setSelfOneOne (MappingTest1 selfOneOne)
-	{
-		this.selfOneOne = selfOneOne;
-	}
-
-
-	public MappingTest2 getOtherTableOneOne ()
-	{
-		return this.otherTableOneOne;
-	}
-
-
-	public void setOtherTableOneOne (MappingTest2 otherTableOneOne)
-	{
-		this.otherTableOneOne = otherTableOneOne;
-	}
-
-
-	public MappingTest2 getInverseOwnerOneOne ()
-	{
-		return this.inverseOwnerOneOne;
-	}
-
-
-	public void setInverseOwnerOneOne (MappingTest2 inverseOwnerOneOne)
-	{
-		this.inverseOwnerOneOne = inverseOwnerOneOne;
-	}
-
-
-	public MappingTest2 getInverseOneOne ()
-	{
-		return this.inverseOneOne;
-	}
-
-
-	public void setInverseOneOne (MappingTest2 inverseOneOne)
-	{
-		this.inverseOneOne = inverseOneOne;
-	}
-
-
-	public Set getCollection ()
-	{
-		return this.collection;
-	}
-
-
-	public void setCollection (Set collection)
-	{
-		this.collection = collection;
-	}
-
-
-	public Set getInverseOwnerOneMany ()
-	{
-		return this.inverseOwnerOneMany;
-	}
-
-
-	public void setInverseOwnerOneMany (Set inverseOwnerOneMany)
-	{
-		this.inverseOwnerOneMany = inverseOwnerOneMany;
-	}
-
-
-	public Set getOneMany ()
-	{
-		return this.oneMany;
-	}
-
-
-	public void setOneMany (Set oneMany)
-	{
-		this.oneMany = oneMany;
-	}
-
-
-	public List getManyMany ()
-	{
-		return this.manyMany;
-	}
-
-
-	public void setManyMany (List manyMany)
-	{
-		this.manyMany = manyMany;
-	}
-
-
-	public Set getInverseOwnerManyMany ()
-	{
-		return this.inverseOwnerManyMany;
-	}
-
-
-	public void setInverseOwnerManyMany (Set inverseOwnerManyMany)
-	{
-		this.inverseOwnerManyMany = inverseOwnerManyMany;
-	}
-
-
-	public Map getMap ()
-	{
-		return this.map;
-	}
-
-
-	public void setMap (Map map)
-	{
-		this.map = map;
-	}
-
-
-	public Map getNManyMap ()
-	{
-		return this.nManyMap;
-	}
-
-
-	public void setNManyMap (Map nManyMap)
-	{
-		this.nManyMap = nManyMap;
-	}
-
-
-	public Map getManyManyMap ()
-	{
-		return this.manyManyMap;
-	}
-
-
-	public void setManyManyMap (Map manyManyMap)
-	{
-		this.manyManyMap = manyManyMap;
-	}
-
-
-	public int getTransactionalValue ()
-	{
-		return this.transactionalValue;
-	}
-
-
-	public void setTransactionalValue (int transactionalValue)
-	{
-		this.transactionalValue = transactionalValue;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.util.*;
+import javax.persistence.Entity;
+
+/**
+ *	<p>Persistent type used for testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+public class MappingTest1
+{
+	private int				value					= 0;
+	private int				otherTableValue			= 0;
+	private Object 			blob					= null;
+	private MappingTest2 	oneOne					= null;
+	private MappingTest1 	selfOneOne				= null;
+	private MappingTest2 	otherTableOneOne		= null;
+	private MappingTest2	inverseOwnerOneOne		= null;
+	private MappingTest2	inverseOneOne			= null;
+	private Set				collection				= new HashSet ();
+	private Set				inverseOwnerOneMany		= new HashSet ();
+	private Set				oneMany					= new HashSet ();
+	private List			manyMany				= new LinkedList ();
+	private Set				inverseOwnerManyMany	= new HashSet ();
+	private Map				map						= new HashMap ();
+	private Map				nManyMap				= new HashMap ();
+	private Map				manyManyMap				= new HashMap ();
+	private int				transactionalValue		= 0;
+
+
+	public int getValue ()
+	{
+		return this.value;
+	}
+
+
+	public void setValue (int value)
+	{
+		this.value = value;
+	}
+
+
+	public int getOtherTableValue ()
+	{
+		return this.otherTableValue;
+	}
+
+
+	public void setOtherTableValue (int otherTableValue)
+	{
+		this.otherTableValue = otherTableValue;
+	}
+
+
+	public Object getBlob ()
+	{
+		return this.blob;
+	}
+
+
+	public void setBlob (Object blob)
+	{
+		this.blob = blob;
+	}
+
+
+	public MappingTest2 getOneOne ()
+	{
+		return this.oneOne;
+	}
+
+
+	public void setOneOne (MappingTest2 oneOne)
+	{
+		this.oneOne = oneOne;
+	}
+
+
+	public MappingTest1 getSelfOneOne ()
+	{
+		return this.selfOneOne;
+	}
+
+
+	public void setSelfOneOne (MappingTest1 selfOneOne)
+	{
+		this.selfOneOne = selfOneOne;
+	}
+
+
+	public MappingTest2 getOtherTableOneOne ()
+	{
+		return this.otherTableOneOne;
+	}
+
+
+	public void setOtherTableOneOne (MappingTest2 otherTableOneOne)
+	{
+		this.otherTableOneOne = otherTableOneOne;
+	}
+
+
+	public MappingTest2 getInverseOwnerOneOne ()
+	{
+		return this.inverseOwnerOneOne;
+	}
+
+
+	public void setInverseOwnerOneOne (MappingTest2 inverseOwnerOneOne)
+	{
+		this.inverseOwnerOneOne = inverseOwnerOneOne;
+	}
+
+
+	public MappingTest2 getInverseOneOne ()
+	{
+		return this.inverseOneOne;
+	}
+
+
+	public void setInverseOneOne (MappingTest2 inverseOneOne)
+	{
+		this.inverseOneOne = inverseOneOne;
+	}
+
+
+	public Set getCollection ()
+	{
+		return this.collection;
+	}
+
+
+	public void setCollection (Set collection)
+	{
+		this.collection = collection;
+	}
+
+
+	public Set getInverseOwnerOneMany ()
+	{
+		return this.inverseOwnerOneMany;
+	}
+
+
+	public void setInverseOwnerOneMany (Set inverseOwnerOneMany)
+	{
+		this.inverseOwnerOneMany = inverseOwnerOneMany;
+	}
+
+
+	public Set getOneMany ()
+	{
+		return this.oneMany;
+	}
+
+
+	public void setOneMany (Set oneMany)
+	{
+		this.oneMany = oneMany;
+	}
+
+
+	public List getManyMany ()
+	{
+		return this.manyMany;
+	}
+
+
+	public void setManyMany (List manyMany)
+	{
+		this.manyMany = manyMany;
+	}
+
+
+	public Set getInverseOwnerManyMany ()
+	{
+		return this.inverseOwnerManyMany;
+	}
+
+
+	public void setInverseOwnerManyMany (Set inverseOwnerManyMany)
+	{
+		this.inverseOwnerManyMany = inverseOwnerManyMany;
+	}
+
+
+	public Map getMap ()
+	{
+		return this.map;
+	}
+
+
+	public void setMap (Map map)
+	{
+		this.map = map;
+	}
+
+
+	public Map getNManyMap ()
+	{
+		return this.nManyMap;
+	}
+
+
+	public void setNManyMap (Map nManyMap)
+	{
+		this.nManyMap = nManyMap;
+	}
+
+
+	public Map getManyManyMap ()
+	{
+		return this.manyManyMap;
+	}
+
+
+	public void setManyManyMap (Map manyManyMap)
+	{
+		this.manyManyMap = manyManyMap;
+	}
+
+
+	public int getTransactionalValue ()
+	{
+		return this.transactionalValue;
+	}
+
+
+	public void setTransactionalValue (int transactionalValue)
+	{
+		this.transactionalValue = transactionalValue;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2.java
index 30cd9e5..24fc671 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.util.*;
-import javax.persistence.*;
-
-/**
- *	<p>Persistent class used in testing.</p>
- *
- *	@author		Abe White
- */
-
-@Entity
-public class MappingTest2
-{
-	private int				pk1				= 0;
-	private int				pk2				= 0;
-	private MappingTest1	oneOneOwner		= null;
-	private MappingTest1	oneManyOwner	= null;
-	private Set				manyManyOwner	= new HashSet ();
-
-
-	public int getPk1 ()
-	{
-		return this.pk1;
-	}
-
-
-	public void setPk1 (int pk1)
-	{
-		this.pk1 = pk1;
-	}
-
-
-	public int getPk2 ()
-	{
-		return this.pk2;
-	}
-
-
-	public void setPk2 (int pk2)
-	{
-		this.pk2 = pk2;
-	}
-
-
-	public MappingTest1 getOneOneOwner ()
-	{
-		return this.oneOneOwner;
-	}
-
-
-	public void setOneOneOwner (MappingTest1 oneOneOwner)
-	{
-		this.oneOneOwner = oneOneOwner;
-	}
-
-
-	public MappingTest1 getOneManyOwner ()
-	{
-		return this.oneManyOwner;
-	}
-
-
-	public void setOneManyOwner (MappingTest1 oneManyOwner)
-	{
-		this.oneManyOwner = oneManyOwner;
-	}
-
-
-	public Set getManyManyOwner ()
-	{
-		return this.manyManyOwner;
-	}
-
-
-	public void setManyManyOwner (Set manyManyOwner)
-	{
-		this.manyManyOwner = manyManyOwner;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.util.*;
+import javax.persistence.*;
+
+/**
+ *	<p>Persistent class used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+
+@Entity
+public class MappingTest2
+{
+	private int				pk1				= 0;
+	private int				pk2				= 0;
+	private MappingTest1	oneOneOwner		= null;
+	private MappingTest1	oneManyOwner	= null;
+	private Set				manyManyOwner	= new HashSet ();
+
+
+	public int getPk1 ()
+	{
+		return this.pk1;
+	}
+
+
+	public void setPk1 (int pk1)
+	{
+		this.pk1 = pk1;
+	}
+
+
+	public int getPk2 ()
+	{
+		return this.pk2;
+	}
+
+
+	public void setPk2 (int pk2)
+	{
+		this.pk2 = pk2;
+	}
+
+
+	public MappingTest1 getOneOneOwner ()
+	{
+		return this.oneOneOwner;
+	}
+
+
+	public void setOneOneOwner (MappingTest1 oneOneOwner)
+	{
+		this.oneOneOwner = oneOneOwner;
+	}
+
+
+	public MappingTest1 getOneManyOwner ()
+	{
+		return this.oneManyOwner;
+	}
+
+
+	public void setOneManyOwner (MappingTest1 oneManyOwner)
+	{
+		this.oneManyOwner = oneManyOwner;
+	}
+
+
+	public Set getManyManyOwner ()
+	{
+		return this.manyManyOwner;
+	}
+
+
+	public void setManyManyOwner (Set manyManyOwner)
+	{
+		this.manyManyOwner = manyManyOwner;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2ID.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2ID.java
index 18b1fd1..11c93b0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2ID.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest2ID.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import java.io.*;
-import java.math.*;
-import java.text.*;
-import java.util.*;
-
-
-/**
- *	Application object ID class for MappingTest2.
- *	Auto-generated by kodo.enhance.ApplicationIdTool.
- */
-@SuppressWarnings("serial")
-public class MappingTest2ID	implements Serializable
-{
-	// each pk field in MappingTest2
-	// must be listed as a public field here
-	public int         pk1;
-	public int         pk2;
-
-
-	/**
-	 *	Default constructor.
-	 */
-	public MappingTest2ID ()
-	{
-	}
-
-
-	/**
-	 *	String constructor.
-	 */
-	public MappingTest2ID (String str)
-	{
-		StringTokenizer toke = new StringTokenizer (str, "::");
-
-		str = toke.nextToken ();
-		this.pk1 = Integer.parseInt (str);
-		str = toke.nextToken ();
-		this.pk2 = Integer.parseInt (str);
-	}
-
-
-	/**
-	 *	Implementation of equals method.
-	 */
-	public boolean equals (Object ob)
-	{
-		if (this == ob)
-			return true;
-		if (!(ob instanceof MappingTest2ID))
-			return false;
-
-		MappingTest2ID other = (MappingTest2ID) ob;
-		return (this.pk1 == other.pk1)
-			&& (this.pk2 == other.pk2);
-	}
-
-
-	/**
-	 *	Implementation of hashCode method that supports the
-	 *	equals-hashCode contract.
-	 */
-	public int hashCode ()
-	{
-		return (int) this.pk1
-			+ (int) this.pk2;
-	}
-
-
-	/**
-	 *	Implementation of toString that outputs this object id's
-	 *	primary key values.
-	 */
-	public String toString ()
-	{
-		return String.valueOf (this.pk1)
-			+ "::" + String.valueOf (this.pk2);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import java.io.*;
+import java.math.*;
+import java.text.*;
+import java.util.*;
+
+
+/**
+ *	Application object ID class for MappingTest2.
+ *	Auto-generated by kodo.enhance.ApplicationIdTool.
+ */
+@SuppressWarnings("serial")
+public class MappingTest2ID	implements Serializable
+{
+	// each pk field in MappingTest2
+	// must be listed as a public field here
+	public int         pk1;
+	public int         pk2;
+
+
+	/**
+	 *	Default constructor.
+	 */
+	public MappingTest2ID ()
+	{
+	}
+
+
+	/**
+	 *	String constructor.
+	 */
+	public MappingTest2ID (String str)
+	{
+		StringTokenizer toke = new StringTokenizer (str, "::");
+
+		str = toke.nextToken ();
+		this.pk1 = Integer.parseInt (str);
+		str = toke.nextToken ();
+		this.pk2 = Integer.parseInt (str);
+	}
+
+
+	/**
+	 *	Implementation of equals method.
+	 */
+	public boolean equals (Object ob)
+	{
+		if (this == ob)
+			return true;
+		if (!(ob instanceof MappingTest2ID))
+			return false;
+
+		MappingTest2ID other = (MappingTest2ID) ob;
+		return (this.pk1 == other.pk1)
+			&& (this.pk2 == other.pk2);
+	}
+
+
+	/**
+	 *	Implementation of hashCode method that supports the
+	 *	equals-hashCode contract.
+	 */
+	public int hashCode ()
+	{
+		return (int) this.pk1
+			+ (int) this.pk2;
+	}
+
+
+	/**
+	 *	Implementation of toString that outputs this object id's
+	 *	primary key values.
+	 */
+	public String toString ()
+	{
+		return String.valueOf (this.pk1)
+			+ "::" + String.valueOf (this.pk2);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest3.java
index 77d0ae4..1c66b16 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest3.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-public class MappingTest3
-	extends MappingTest1
-{
-	private int verticalValue = 0;
-
-
-	public int getVerticalValue ()
-	{
-		return this.verticalValue;
-	}
-
-
-	public void setVerticalValue (int verticalValue)
-	{
-		this.verticalValue = verticalValue;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+public class MappingTest3
+	extends MappingTest1
+{
+	private int verticalValue = 0;
+
+
+	public int getVerticalValue ()
+	{
+		return this.verticalValue;
+	}
+
+
+	public void setVerticalValue (int verticalValue)
+	{
+		this.verticalValue = verticalValue;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest4.java
index 0724249..741272a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest4.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- *	<p>Persistent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-
-public class MappingTest4
-	extends MappingTest3
-{
-	private int flatValue = 0;
-
-
-	public int getFlatValue ()
-	{
-		return this.flatValue;
-	}
-
-
-	public void setFlatValue (int flatValue)
-	{
-		this.flatValue = flatValue;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ *	<p>Persistent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+
+public class MappingTest4
+	extends MappingTest3
+{
+	private int flatValue = 0;
+
+
+	public int getFlatValue ()
+	{
+		return this.flatValue;
+	}
+
+
+	public void setFlatValue (int flatValue)
+	{
+		this.flatValue = flatValue;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest5.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest5.java
index 2333fa5..6c4999b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest5.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MappingTest5.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class MappingTest5
-    extends MappingTest2 {
-
-    private int vertValue = 0;
-    private MappingTest5 vertRel = null;
-
-    public int getVertValue() {
-        return this.vertValue;
-    }
-
-    public void setVertValue(int vertValue) {
-        this.vertValue = vertValue;
-    }
-
-    public MappingTest5 getVertRel() {
-        return this.vertRel;
-    }
-
-    public void setVertRel(MappingTest5 vertRel) {
-        this.vertRel = vertRel;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class MappingTest5
+    extends MappingTest2 {
+
+    private int vertValue = 0;
+    private MappingTest5 vertRel = null;
+
+    public int getVertValue() {
+        return this.vertValue;
+    }
+
+    public void setVertValue(int vertValue) {
+        this.vertValue = vertValue;
+    }
+
+    public MappingTest5 getVertRel() {
+        return this.vertRel;
+    }
+
+    public void setVertRel(MappingTest5 vertRel) {
+        this.vertRel = vertRel;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiA.java
index 288fada..6d94fd1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiA.java
@@ -1,72 +1,72 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class MultiA {
-
-    private String string0;
-    private String string1;
-
-    private int aint0;
-    private int aint1;
-
-    private Set multiCs = new HashSet();
-
-    public void setString0(String val) {
-        string0 = val;
-    }
-
-    public String getString0() {
-        return string0;
-    }
-
-    public void setInt0(int val) {
-        aint0 = val;
-    }
-
-    public void setString1(String val) {
-        string1 = val;
-    }
-
-    public String getString1() {
-        return string1;
-    }
-
-    public int getInt0() {
-        return aint0;
-    }
-
-    public void setInt1(int val) {
-        aint1 = val;
-    }
-
-    public int getInt1() {
-        return aint1;
-    }
-
-    public void setMultiCs(Set val) {
-        multiCs = val;
-    }
-
-    public Set getMultiCs() {
-        return multiCs;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class MultiA {
+
+    private String string0;
+    private String string1;
+
+    private int aint0;
+    private int aint1;
+
+    private Set multiCs = new HashSet();
+
+    public void setString0(String val) {
+        string0 = val;
+    }
+
+    public String getString0() {
+        return string0;
+    }
+
+    public void setInt0(int val) {
+        aint0 = val;
+    }
+
+    public void setString1(String val) {
+        string1 = val;
+    }
+
+    public String getString1() {
+        return string1;
+    }
+
+    public int getInt0() {
+        return aint0;
+    }
+
+    public void setInt1(int val) {
+        aint1 = val;
+    }
+
+    public int getInt1() {
+        return aint1;
+    }
+
+    public void setMultiCs(Set val) {
+        multiCs = val;
+    }
+
+    public Set getMultiCs() {
+        return multiCs;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiB.java
index b5a2007..1d98590 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiB.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class MultiB
-    extends MultiA {
-
-    private String bString;
-    private int bInt;
-
-    public void setBString(String val) {
-        bString = val;
-    }
-
-    public String getBString() {
-        return bString;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class MultiB
+    extends MultiA {
+
+    private String bString;
+    private int bInt;
+
+    public void setBString(String val) {
+        bString = val;
+    }
+
+    public String getBString() {
+        return bString;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiC.java
index f79b98f..d245e59 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiC.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class MultiC
-    extends MultiB {
-
-    private String cString0;
-    private String cString1;
-
-    private int cInt;
-
-    private Set multiAs = new HashSet();
-
-    public void setCString0(String val) {
-        cString0 = val;
-    }
-
-    public String getCString0() {
-        return cString0;
-    }
-
-    public void setMultiAs(Set val) {
-        multiAs = val;
-    }
-
-    public Set getMultiAs() {
-        return multiAs;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class MultiC
+    extends MultiB {
+
+    private String cString0;
+    private String cString1;
+
+    private int cInt;
+
+    private Set multiAs = new HashSet();
+
+    public void setCString0(String val) {
+        cString0 = val;
+    }
+
+    public String getCString0() {
+        return cString0;
+    }
+
+    public void setMultiAs(Set val) {
+        multiAs = val;
+    }
+
+    public Set getMultiAs() {
+        return multiAs;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiD.java
index e95ffa1..ca9209d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiD.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class MultiD
-    extends MultiB {
-
-    private String dString0;
-    private String dString1;
-
-    private int dInt;
-
-    private MultiA a;
-
-    public void setDString0(String val) {
-        dString0 = val;
-    }
-
-    public String getDString0() {
-        return dString0;
-    }
-
-    public void setDString1(String val) {
-        dString1 = val;
-    }
-
-    public String getDString1() {
-        return dString1;
-    }
-
-    public void setA(MultiA val) {
-        a = val;
-    }
-
-    public MultiA getA() {
-        return a;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class MultiD
+    extends MultiB {
+
+    private String dString0;
+    private String dString1;
+
+    private int dInt;
+
+    private MultiA a;
+
+    public void setDString0(String val) {
+        dString0 = val;
+    }
+
+    public String getDString0() {
+        return dString0;
+    }
+
+    public void setDString1(String val) {
+        dString1 = val;
+    }
+
+    public String getDString1() {
+        return dString1;
+    }
+
+    public void setA(MultiA val) {
+        a = val;
+    }
+
+    public MultiA getA() {
+        return a;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiE.java
index 6b748c7..c0dd698 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiE.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class MultiE {
-
-    private String string0;
-
-    public void setString0(String val) {
-        string0 = val;
-    }
-
-    public String getString0() {
-        return string0;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class MultiE {
+
+    private String string0;
+
+    public void setString0(String val) {
+        string0 = val;
+    }
+
+    public String getString0() {
+        return string0;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiF.java
index 17d6e67..9d5bbc1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/MultiF.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class MultiF
-    extends MultiE {
-
-    private String string1;
-
-    public void setString1(String val) {
-        string1 = val;
-    }
-
-    public String getString1() {
-        return string1;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class MultiF
+    extends MultiE {
+
+    private String string1;
+
+    public void setString1(String val) {
+        string1 = val;
+    }
+
+    public String getString1() {
+        return string1;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NamedSQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NamedSQL.java
index c6273d7..182e0aa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NamedSQL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NamedSQL.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class NamedSQL {
-
-    private int num;
-    private int num2;
-
-    public int getNum() {
-        return num;
-    }
-
-    public void setNum(int i) {
-        num = i;
-    }
-
-    public int getNum2() {
-        return num2;
-    }
-
-    public void setNum2(int i) {
-        num2 = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class NamedSQL {
+
+    private int num;
+    private int num2;
+
+    public int getNum() {
+        return num;
+    }
+
+    public void setNum(int i) {
+        num = i;
+    }
+
+    public int getNum2() {
+        return num2;
+    }
+
+    public void setNum2(int i) {
+        num2 = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NoClassColumn.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NoClassColumn.java
index fcd75f2..e2d9011 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NoClassColumn.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NoClassColumn.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class NoClassColumn {
-
-    private String test;
-
-    public String getTest() {
-        return test;
-    }
-
-    public void setTest(String val) {
-        test = val;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class NoClassColumn {
+
+    private String test;
+
+    public String getTest() {
+        return test;
+    }
+
+    public void setTest(String val) {
+        test = val;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC.java
index a595577..bb57f31 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class NonPKJoinPC {
-
-    private int id1;
-    private int id2;
-    private PartialJoinPC partial;
-    private Set partials = new HashSet();
-    private ConstantJoinPC constant;
-
-    public PartialJoinPC getPartial() {
-        return this.partial;
-    }
-
-    public void setPartial(PartialJoinPC partial) {
-        this.partial = partial;
-    }
-
-    public int getId1() {
-        return this.id1;
-    }
-
-    public void setId1(int id1) {
-        this.id1 = id1;
-    }
-
-    public int getId2() {
-        return this.id2;
-    }
-
-    public void setId2(int id2) {
-        this.id2 = id2;
-    }
-
-    public Set getPartials() {
-        return this.partials;
-    }
-
-    public void setPartials(Set partials) {
-        this.partials = partials;
-    }
-
-    public ConstantJoinPC getConstant() {
-        return this.constant;
-    }
-
-    public void setConstant(ConstantJoinPC constant) {
-        this.constant = constant;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class NonPKJoinPC {
+
+    private int id1;
+    private int id2;
+    private PartialJoinPC partial;
+    private Set partials = new HashSet();
+    private ConstantJoinPC constant;
+
+    public PartialJoinPC getPartial() {
+        return this.partial;
+    }
+
+    public void setPartial(PartialJoinPC partial) {
+        this.partial = partial;
+    }
+
+    public int getId1() {
+        return this.id1;
+    }
+
+    public void setId1(int id1) {
+        this.id1 = id1;
+    }
+
+    public int getId2() {
+        return this.id2;
+    }
+
+    public void setId2(int id2) {
+        this.id2 = id2;
+    }
+
+    public Set getPartials() {
+        return this.partials;
+    }
+
+    public void setPartials(Set partials) {
+        this.partials = partials;
+    }
+
+    public ConstantJoinPC getConstant() {
+        return this.constant;
+    }
+
+    public void setConstant(ConstantJoinPC constant) {
+        this.constant = constant;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC2.java
index 4ddcd60..fab2325 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC2.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class NonPKJoinPC2
-    extends NonPKJoinPC {
-
-    private String stringField;
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class NonPKJoinPC2
+    extends NonPKJoinPC {
+
+    private String stringField;
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC3.java
index 1baf1bc..72da97f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/NonPKJoinPC3.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class NonPKJoinPC3
-    extends NonPKJoinPC2 {
-
-    private PartialJoinPC3 partial3;
-    private Set partial2s = new HashSet();
-
-    public PartialJoinPC3 getPartial3() {
-        return this.partial3;
-    }
-
-    public void setPartial3(PartialJoinPC3 partial3) {
-        this.partial3 = partial3;
-    }
-
-    public Set getPartial2s() {
-        return this.partial2s;
-    }
-
-    public void setPartial2s(Set partial2s) {
-        this.partial2s = partial2s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class NonPKJoinPC3
+    extends NonPKJoinPC2 {
+
+    private PartialJoinPC3 partial3;
+    private Set partial2s = new HashSet();
+
+    public PartialJoinPC3 getPartial3() {
+        return this.partial3;
+    }
+
+    public void setPartial3(PartialJoinPC3 partial3) {
+        this.partial3 = partial3;
+    }
+
+    public Set getPartial2s() {
+        return this.partial2s;
+    }
+
+    public void setPartial2s(Set partial2s) {
+        this.partial2s = partial2s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrder.java
index bfcd160..100e9d2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrder.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-import java.util.*;
-
-
-
-public interface OpOrder {
-
-
-    public long getId();
-
-    public OpOrder getRel();
-
-    public OpOrder getOwner();
-
-    public String getSecondary();
-
-    public String getSub();
-
-    public List getRelList();
-
-    public List getMappedRelList();
-
-    public List getInverseKeyRelList();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+import java.util.*;
+
+
+
+public interface OpOrder {
+
+
+    public long getId();
+
+    public OpOrder getRel();
+
+    public OpOrder getOwner();
+
+    public String getSecondary();
+
+    public String getSub();
+
+    public List getRelList();
+
+    public List getMappedRelList();
+
+    public List getInverseKeyRelList();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPC.java
index cb52e81..e12e5d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPC.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-import java.util.*;
-
-
-@Entity
-public class OpOrderPC {
-
-	@Id
-    private long id;
-    private OpOrderPC rel;
-    private OpOrderPC owner;
-    private String secondary;
-    private List relList = new ArrayList();
-    private List mappedRelList = new ArrayList();
-    private List inverseKeyRelList = new ArrayList();
-
-    public long getId() {
-        return id;
-    }
-
-    public OpOrder getRel() {
-        return (OpOrder) rel;
-    }
-
-    public void setRel(OpOrderPC rel) {
-        this.rel = rel;
-    }
-
-    public OpOrder getOwner() {
-        return (OpOrder) owner;
-    }
-
-    public void setOwner(OpOrderPC owner) {
-        this.owner = owner;
-    }
-
-    public String getSecondary() {
-        return secondary;
-    }
-
-    public void setSecondary(String secondary) {
-        this.secondary = secondary;
-    }
-
-    public List getRelList() {
-        return relList;
-    }
-
-    public List getMappedRelList() {
-        return mappedRelList;
-    }
-
-    public List getInverseKeyRelList() {
-        return inverseKeyRelList;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+import java.util.*;
+
+
+@Entity
+public class OpOrderPC {
+
+	@Id
+    private long id;
+    private OpOrderPC rel;
+    private OpOrderPC owner;
+    private String secondary;
+    private List relList = new ArrayList();
+    private List mappedRelList = new ArrayList();
+    private List inverseKeyRelList = new ArrayList();
+
+    public long getId() {
+        return id;
+    }
+
+    public OpOrder getRel() {
+        return (OpOrder) rel;
+    }
+
+    public void setRel(OpOrderPC rel) {
+        this.rel = rel;
+    }
+
+    public OpOrder getOwner() {
+        return (OpOrder) owner;
+    }
+
+    public void setOwner(OpOrderPC owner) {
+        this.owner = owner;
+    }
+
+    public String getSecondary() {
+        return secondary;
+    }
+
+    public void setSecondary(String secondary) {
+        this.secondary = secondary;
+    }
+
+    public List getRelList() {
+        return relList;
+    }
+
+    public List getMappedRelList() {
+        return mappedRelList;
+    }
+
+    public List getInverseKeyRelList() {
+        return inverseKeyRelList;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPCSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPCSub.java
index e883d04..b3d4d39 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPCSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/OpOrderPCSub.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-import java.util.*;
-
-@Entity
-public class OpOrderPCSub
-    extends OpOrderPC
-    implements OpOrder {
-
-	@Id
-    private String sub;
-
-    public String getSub() {
-        return sub;
-    }
-
-    public void setSub(String sub) {
-        this.sub = sub;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+import java.util.*;
+
+@Entity
+public class OpOrderPCSub
+    extends OpOrderPC
+    implements OpOrder {
+
+	@Id
+    private String sub;
+
+    public String getSub() {
+        return sub;
+    }
+
+    public void setSub(String sub) {
+        this.sub = sub;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingAppIdPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingAppIdPC.java
index 0d5820b..d77d1b0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingAppIdPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingAppIdPC.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Persistent type used in testing paging + eager fetching.</p>
- *
-
- */
-@Entity
-public class PagingAppIdPC {
-
-    private int intField;
-    private long longField;
-    private PagingHelperPC rel;
-    private List rels = new ArrayList();
-
-	public PagingAppIdPC() { }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public long getLongField() {
-        return this.longField;
-    }
-
-    public void setLongField(long longField) {
-        this.longField = longField;
-    }
-
-    public PagingHelperPC getRel() {
-        return this.rel;
-    }
-
-    public void setRel(PagingHelperPC rel) {
-        this.rel = rel;
-    }
-
-    public List getRels() {
-        return this.rels;
-    }
-
-    public void setRels(List rels) {
-        this.rels = rels;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Persistent type used in testing paging + eager fetching.</p>
+ *
+
+ */
+@Entity
+public class PagingAppIdPC {
+
+    private int intField;
+    private long longField;
+    private PagingHelperPC rel;
+    private List rels = new ArrayList();
+
+	public PagingAppIdPC() { }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public long getLongField() {
+        return this.longField;
+    }
+
+    public void setLongField(long longField) {
+        this.longField = longField;
+    }
+
+    public PagingHelperPC getRel() {
+        return this.rel;
+    }
+
+    public void setRel(PagingHelperPC rel) {
+        this.rel = rel;
+    }
+
+    public List getRels() {
+        return this.rels;
+    }
+
+    public void setRels(List rels) {
+        this.rels = rels;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingHelperPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingHelperPC.java
index d3f1e97..3aaba4e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingHelperPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingHelperPC.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Persistent type used in testing paging + eager fetching.</p>
- *
-
- */
-@Entity
-public class PagingHelperPC {
-	
-	public PagingHelperPC() {}
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Persistent type used in testing paging + eager fetching.</p>
+ *
+
+ */
+@Entity
+public class PagingHelperPC {
+	
+	public PagingHelperPC() {}
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingPC.java
index 8da5a4c..7e169ef 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PagingPC.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Persistent type used in testing paging + eager fetching.</p>
- *
- */
-@Entity
-public class PagingPC {
-	
-    private int intField;
-    private PagingHelperPC rel;
-    private List rels = new ArrayList();
-
-	public PagingPC() { }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public PagingHelperPC getRel() {
-        return this.rel;
-    }
-
-    public void setRel(PagingHelperPC rel) {
-        this.rel = rel;
-    }
-
-    public List getRels() {
-        return this.rels;
-    }
-
-    public void setRels(List rels) {
-        this.rels = rels;
-    }
-
-    public String toString() {
-        return "PagingPC: " + intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Persistent type used in testing paging + eager fetching.</p>
+ *
+ */
+@Entity
+public class PagingPC {
+	
+    private int intField;
+    private PagingHelperPC rel;
+    private List rels = new ArrayList();
+
+	public PagingPC() { }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public PagingHelperPC getRel() {
+        return this.rel;
+    }
+
+    public void setRel(PagingHelperPC rel) {
+        this.rel = rel;
+    }
+
+    public List getRels() {
+        return this.rels;
+    }
+
+    public void setRels(List rels) {
+        this.rels = rels;
+    }
+
+    public String toString() {
+        return "PagingPC: " + intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC.java
index ca0e27e..6678d3d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC.java
@@ -1,61 +1,61 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class PartialJoinPC {
-
-    private int pk1;
-    private int pk2;
-    private NonPKJoinPC nonPK;
-    private Set nonPKs = new HashSet();
-
-    public int getPk1() {
-        return this.pk1;
-    }
-
-    public void setPk1(int pk1) {
-        this.pk1 = pk1;
-    }
-
-    public int getPk2() {
-        return this.pk2;
-    }
-
-    public void setPk2(int pk2) {
-        this.pk2 = pk2;
-    }
-
-    public NonPKJoinPC getNonPK() {
-        return this.nonPK;
-    }
-
-    public void setNonPK(NonPKJoinPC nonPK) {
-        this.nonPK = nonPK;
-    }
-
-    public Set getNonPKs() {
-        return this.nonPKs;
-    }
-
-    public void setNonPKs(Set nonPKs) {
-        this.nonPKs = nonPKs;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class PartialJoinPC {
+
+    private int pk1;
+    private int pk2;
+    private NonPKJoinPC nonPK;
+    private Set nonPKs = new HashSet();
+
+    public int getPk1() {
+        return this.pk1;
+    }
+
+    public void setPk1(int pk1) {
+        this.pk1 = pk1;
+    }
+
+    public int getPk2() {
+        return this.pk2;
+    }
+
+    public void setPk2(int pk2) {
+        this.pk2 = pk2;
+    }
+
+    public NonPKJoinPC getNonPK() {
+        return this.nonPK;
+    }
+
+    public void setNonPK(NonPKJoinPC nonPK) {
+        this.nonPK = nonPK;
+    }
+
+    public Set getNonPKs() {
+        return this.nonPKs;
+    }
+
+    public void setNonPKs(Set nonPKs) {
+        this.nonPKs = nonPKs;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC2.java
index 7115632..924e12f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC2.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class PartialJoinPC2
-    extends PartialJoinPC {
-
-    private String stringField;
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class PartialJoinPC2
+    extends PartialJoinPC {
+
+    private String stringField;
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC3.java
index d3a3590..b5f5d19 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PartialJoinPC3.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class PartialJoinPC3
-    extends PartialJoinPC2 {
-
-    private NonPKJoinPC3 nonPK3;
-    private Set nonPK2s = new HashSet();
-
-    public NonPKJoinPC3 getNonPK3() {
-        return this.nonPK3;
-    }
-
-    public void setNonPK3(NonPKJoinPC3 nonPK3) {
-        this.nonPK3 = nonPK3;
-    }
-
-    public Set getNonPK2s() {
-        return this.nonPK2s;
-    }
-
-    public void setNonPK2s(Set nonPK2s) {
-        this.nonPK2s = nonPK2s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class PartialJoinPC3
+    extends PartialJoinPC2 {
+
+    private NonPKJoinPC3 nonPK3;
+    private Set nonPK2s = new HashSet();
+
+    public NonPKJoinPC3 getNonPK3() {
+        return this.nonPK3;
+    }
+
+    public void setNonPK3(NonPKJoinPC3 nonPK3) {
+        this.nonPK3 = nonPK3;
+    }
+
+    public Set getNonPK2s() {
+        return this.nonPK2s;
+    }
+
+    public void setNonPK2s(Set nonPK2s) {
+        this.nonPK2s = nonPK2s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject.java
index aa825bb..a322ac7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class PerClassTestObject {
-
-    private String stringField;
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class PerClassTestObject {
+
+    private String stringField;
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject2.java
index eabdb3e..f48a789 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject2.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;	
-
-/**
- * <p>Application identity type with a custom sequence factory used in
- * testing.</p>
- *
- * @author Abe White
- */
-public class PerClassTestObject2 {
-
-    private String name;
-    private String age;
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getAge() {
-        return this.age;
-    }
-
-    public void setAge(String age) {
-        this.age = age;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;	
+
+/**
+ * <p>Application identity type with a custom sequence factory used in
+ * testing.</p>
+ *
+ * @author Abe White
+ */
+public class PerClassTestObject2 {
+
+    private String name;
+    private String age;
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getAge() {
+        return this.age;
+    }
+
+    public void setAge(String age) {
+        this.age = age;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject3.java
index 7d3227b..7a06f48 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PerClassTestObject3.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * <p>Application identity type with a per-class sequence factory used in
- * testing.</p>
- *
- * @author Abe White
- */
-public class PerClassTestObject3 {
-
-    private long id;
-    private int data;
-
-    public long getId() {
-        return id;
-    }
-
-    public int getData() {
-        return data;
-    }
-
-    public void setData(int data) {
-        this.data = data;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * <p>Application identity type with a per-class sequence factory used in
+ * testing.</p>
+ *
+ * @author Abe White
+ */
+public class PerClassTestObject3 {
+
+    private long id;
+    private int data;
+
+    public long getId() {
+        return id;
+    }
+
+    public int getData() {
+        return data;
+    }
+
+    public void setData(int data) {
+        this.data = data;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesA.java
index c675dde..126c2d4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesA.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class PlaceholderTypesA {
-
-    private int intA;
-
-    public int getIntA() {
-        return intA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class PlaceholderTypesA {
+
+    private int intA;
+
+    public int getIntA() {
+        return intA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesB.java
index 0a30996..4ebbaf3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PlaceholderTypesB.java
@@ -1,96 +1,96 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class PlaceholderTypesB
-    extends PlaceholderTypesA {
-
-    private boolean booleanB;
-    private byte byteB;
-    private char charB;
-    private float floatB;
-    private int intB;
-    private String stringB;
-    private String clobB;
-    private Object blobB;
-
-    public boolean getBooleanB() {
-        return booleanB;
-    }
-
-    public void setBooleanB(boolean booleanB) {
-        this.booleanB = booleanB;
-    }
-
-    public byte getByteB() {
-        return byteB;
-    }
-
-    public void setByteB(byte byteB) {
-        this.byteB = byteB;
-    }
-
-    public char getCharB() {
-        return charB;
-    }
-
-    public void setCharB(char charB) {
-        this.charB = charB;
-    }
-
-    public float getFloatB() {
-        return floatB;
-    }
-
-    public void setFloatB(float floatB) {
-        this.floatB = floatB;
-    }
-
-    public int getIntB() {
-        return intB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public String getStringB() {
-        return stringB;
-    }
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getClobB() {
-        return clobB;
-    }
-
-    public void setClobB(String clobB) {
-        this.clobB = clobB;
-    }
-
-    public Object getBlobB() {
-        return blobB;
-    }
-
-    public void setBlobB(Object blobB) {
-        this.blobB = blobB;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class PlaceholderTypesB
+    extends PlaceholderTypesA {
+
+    private boolean booleanB;
+    private byte byteB;
+    private char charB;
+    private float floatB;
+    private int intB;
+    private String stringB;
+    private String clobB;
+    private Object blobB;
+
+    public boolean getBooleanB() {
+        return booleanB;
+    }
+
+    public void setBooleanB(boolean booleanB) {
+        this.booleanB = booleanB;
+    }
+
+    public byte getByteB() {
+        return byteB;
+    }
+
+    public void setByteB(byte byteB) {
+        this.byteB = byteB;
+    }
+
+    public char getCharB() {
+        return charB;
+    }
+
+    public void setCharB(char charB) {
+        this.charB = charB;
+    }
+
+    public float getFloatB() {
+        return floatB;
+    }
+
+    public void setFloatB(float floatB) {
+        this.floatB = floatB;
+    }
+
+    public int getIntB() {
+        return intB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public String getStringB() {
+        return stringB;
+    }
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getClobB() {
+        return clobB;
+    }
+
+    public void setClobB(String clobB) {
+        this.clobB = clobB;
+    }
+
+    public Object getBlobB() {
+        return blobB;
+    }
+
+    public void setBlobB(Object blobB) {
+        this.blobB = blobB;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostAttachCallback.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostAttachCallback.java
index e17815e..e7060fe 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostAttachCallback.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostAttachCallback.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Kodo 3.x callback.</p>
- *
- * @deprecated
- */
-public interface PostAttachCallback {
-
-    /**
-     * Invoked on the managed persistent instance after it has
-     * been the subject of an attach process.
-     *
-     * @param detached the detached instance that corresponds to
-     * this managed instance
-     */
-    public void jdoPostAttach(Object detached);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Kodo 3.x callback.</p>
+ *
+ * @deprecated
+ */
+public interface PostAttachCallback {
+
+    /**
+     * Invoked on the managed persistent instance after it has
+     * been the subject of an attach process.
+     *
+     * @param detached the detached instance that corresponds to
+     * this managed instance
+     */
+    public void jdoPostAttach(Object detached);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostDetachCallback.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostDetachCallback.java
index 6423162..5ce64b2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostDetachCallback.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PostDetachCallback.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Kodo 3.x callback.</p>
- *
- * @deprecated
- */
-public interface PostDetachCallback {
-
-    /**
-     * Invoked on the detached copy of the persistent instance
-     * after it has been detached. This method will only be called once
-     * the entire graph of objects for a single detach operation has
-     * been completed.
-     *
-     * @param managed the managed instance that was the
-     * source of the detached instance
-     */
-    public void jdoPostDetach(Object managed);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Kodo 3.x callback.</p>
+ *
+ * @deprecated
+ */
+public interface PostDetachCallback {
+
+    /**
+     * Invoked on the detached copy of the persistent instance
+     * after it has been detached. This method will only be called once
+     * the entire graph of objects for a single detach operation has
+     * been completed.
+     *
+     * @param managed the managed instance that was the
+     * source of the detached instance
+     */
+    public void jdoPostDetach(Object managed);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreAttachCallback.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreAttachCallback.java
index 034a595..611a66a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreAttachCallback.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreAttachCallback.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Kodo 3.x callback.</p>
- *
- * @deprecated
- */
-public interface PreAttachCallback {
-
-    /**
-     * Invoked on the detached instance immediately before it is
-     * to be attached.
-     */
-    public void jdoPreAttach();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Kodo 3.x callback.</p>
+ *
+ * @deprecated
+ */
+public interface PreAttachCallback {
+
+    /**
+     * Invoked on the detached instance immediately before it is
+     * to be attached.
+     */
+    public void jdoPreAttach();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreDetachCallback.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreDetachCallback.java
index 6d3c52d..8d091b0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreDetachCallback.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/PreDetachCallback.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-
-/**
- * <p>Kodo 3.x callback.</p>
- *
- * @deprecated
- */
-public interface PreDetachCallback {
-
-    /**
-     * Invoked on the persistent instance before it is detached.
-     */
-    public void jdoPreDetach();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * <p>Kodo 3.x callback.</p>
+ *
+ * @deprecated
+ */
+public interface PreDetachCallback {
+
+    /**
+     * Invoked on the persistent instance before it is detached.
+     */
+    public void jdoPreDetach();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/QueryTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/QueryTest1.java
index 407a8e1..ad80635 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/QueryTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/QueryTest1.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-/**
- * <p>Used in testing; should be enhanced.</p>
- *
- * @author Abe White
- */
-public class QueryTest1 {
-
-    public static final long FIVE = 5L;
-
-    private long num = 0L;
-    private String string = null;
-    private String clobField = null;
-    private boolean bool = false;
-    private float decimal = 0F;
-    private char character = ' ';
-    private Date date = null;
-    private Collection manyToMany = null;
-
-    public long getNum() {
-        return num;
-    }
-
-    public void setNum(long val) {
-        num = val;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public void setString(String val) {
-        string = val;
-    }
-
-    public String getClob() {
-        return clobField;
-    }
-
-    public void setClob(String val) {
-        clobField = val;
-    }
-
-    public boolean getBool() {
-        return bool;
-    }
-
-    public void setBool(boolean val) {
-        bool = val;
-    }
-
-    public float getDecimal() {
-        return decimal;
-    }
-
-    public void setDecimal(float val) {
-        decimal = val;
-    }
-
-    public char getCharacter() {
-        return character;
-    }
-
-    public void setCharacter(char val) {
-        character = val;
-    }
-
-    public void setDate(Date val) {
-        date = val;
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public Collection getManyToMany() {
-        return manyToMany;
-    }
-
-    public void setManyToMany(Collection val) {
-        manyToMany = val;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+/**
+ * <p>Used in testing; should be enhanced.</p>
+ *
+ * @author Abe White
+ */
+public class QueryTest1 {
+
+    public static final long FIVE = 5L;
+
+    private long num = 0L;
+    private String string = null;
+    private String clobField = null;
+    private boolean bool = false;
+    private float decimal = 0F;
+    private char character = ' ';
+    private Date date = null;
+    private Collection manyToMany = null;
+
+    public long getNum() {
+        return num;
+    }
+
+    public void setNum(long val) {
+        num = val;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public void setString(String val) {
+        string = val;
+    }
+
+    public String getClob() {
+        return clobField;
+    }
+
+    public void setClob(String val) {
+        clobField = val;
+    }
+
+    public boolean getBool() {
+        return bool;
+    }
+
+    public void setBool(boolean val) {
+        bool = val;
+    }
+
+    public float getDecimal() {
+        return decimal;
+    }
+
+    public void setDecimal(float val) {
+        decimal = val;
+    }
+
+    public char getCharacter() {
+        return character;
+    }
+
+    public void setCharacter(char val) {
+        character = val;
+    }
+
+    public void setDate(Date val) {
+        date = val;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public Collection getManyToMany() {
+        return manyToMany;
+    }
+
+    public void setManyToMany(Collection val) {
+        manyToMany = val;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawField.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawField.java
index c4dfa23..01cdf26 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawField.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawField.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.sql.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.meta.strats.*;
-
-public class RawField {
-
-    private String str;
-
-    public void setString(String s) {
-        str = s;
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public static class RawMapping
-        extends ImmutableValueHandler {
-
-        public Object toDataStoreValue(ValueMapping vm, Object val,
-            JDBCStore store) {
-            return new Raw("'" + val + "FOO'");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.sql.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.meta.strats.*;
+
+public class RawField {
+
+    private String str;
+
+    public void setString(String s) {
+        str = s;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public static class RawMapping
+        extends ImmutableValueHandler {
+
+        public Object toDataStoreValue(ValueMapping vm, Object val,
+            JDBCStore store) {
+            return new Raw("'" + val + "FOO'");
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawSQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawSQL.java
index 9818bbc..c51ba11 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawSQL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RawSQL.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-public class RawSQL {
-    
-    @Id
-    private String stringField = null;
-    private int intField = 0;
-
-    protected RawSQL() {
-    }
-
-    public RawSQL(String s, int i) {
-        stringField = s;
-        intField = i;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public String toString() {
-        return "stringField: " + stringField + "; intField: " + intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+public class RawSQL {
+    
+    @Id
+    private String stringField = null;
+    private int intField = 0;
+
+    protected RawSQL() {
+    }
+
+    public RawSQL(String s, int i) {
+        stringField = s;
+        intField = i;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public String toString() {
+        return "stringField: " + stringField + "; intField: " + intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RecursivelyEmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RecursivelyEmbeddedPC.java
index 32e4037..9d21f16 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RecursivelyEmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RecursivelyEmbeddedPC.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Embedded type used in testing.</p>
- *
- * @author Abe White
- */
-
-@Entity
-public class RecursivelyEmbeddedPC {
-
-    private EmbeddedPC embedded;
-
-    public EmbeddedPC getEmbedded() {
-        return this.embedded;
-    }
-
-    public void setEmbedded(EmbeddedPC embedded) {
-        this.embedded = embedded;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Embedded type used in testing.</p>
+ *
+ * @author Abe White
+ */
+
+@Entity
+public class RecursivelyEmbeddedPC {
+
+    private EmbeddedPC embedded;
+
+    public EmbeddedPC getEmbedded() {
+        return this.embedded;
+    }
+
+    public void setEmbedded(EmbeddedPC embedded) {
+        this.embedded = embedded;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Relations.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Relations.java
index 11b8d5b..7c83884 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Relations.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/Relations.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.util.*;
-
-public class Relations {
-
-    private Base base;
-    private Base nullBase;
-    private BaseSub1 baseSub1;
-    private BaseSub1Sub2 baseSub1Sub2;
-    private List baseList = new ArrayList();
-    private List emptyBaseList = new ArrayList();
-    private List baseSub1List = new ArrayList();
-    private List baseSub1Sub2List = new ArrayList();
-
-    public Base getBase() {
-        return this.base;
-    }
-
-    public void setBase(Base base) {
-        this.base = base;
-    }
-
-    public BaseSub1 getBaseSub1() {
-        return this.baseSub1;
-    }
-
-    public void setBaseSub1(BaseSub1 baseSub1) {
-        this.baseSub1 = baseSub1;
-    }
-
-    public BaseSub1Sub2 getBaseSub1Sub2() {
-        return this.baseSub1Sub2;
-    }
-
-    public void setBaseSub1Sub2(BaseSub1Sub2 baseSub1Sub2) {
-        this.baseSub1Sub2 = baseSub1Sub2;
-    }
-
-    public List getBaseList() {
-        return this.baseList;
-    }
-
-    public void setBaseList(List baseList) {
-        this.baseList = baseList;
-    }
-
-    public List getBaseSub1List() {
-        return this.baseSub1List;
-    }
-
-    public void setBaseSub1List(List baseSub1List) {
-        this.baseSub1List = baseSub1List;
-    }
-
-    public List getBaseSub1Sub2List() {
-        return this.baseSub1Sub2List;
-    }
-
-    public void setBaseSub1Sub2List(List baseSub1Sub2List) {
-        this.baseSub1Sub2List = baseSub1Sub2List;
-    }
-
-    public Base getNullBase() {
-        return this.nullBase;
-    }
-
-    public void setNullBase(Base nullBase) {
-        this.nullBase = nullBase;
-    }
-
-    public List getEmptyBaseList() {
-        return this.emptyBaseList;
-    }
-
-    public void setEmptyBaseList(List emptyBaseList) {
-        this.emptyBaseList = emptyBaseList;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.util.*;
+
+public class Relations {
+
+    private Base base;
+    private Base nullBase;
+    private BaseSub1 baseSub1;
+    private BaseSub1Sub2 baseSub1Sub2;
+    private List baseList = new ArrayList();
+    private List emptyBaseList = new ArrayList();
+    private List baseSub1List = new ArrayList();
+    private List baseSub1Sub2List = new ArrayList();
+
+    public Base getBase() {
+        return this.base;
+    }
+
+    public void setBase(Base base) {
+        this.base = base;
+    }
+
+    public BaseSub1 getBaseSub1() {
+        return this.baseSub1;
+    }
+
+    public void setBaseSub1(BaseSub1 baseSub1) {
+        this.baseSub1 = baseSub1;
+    }
+
+    public BaseSub1Sub2 getBaseSub1Sub2() {
+        return this.baseSub1Sub2;
+    }
+
+    public void setBaseSub1Sub2(BaseSub1Sub2 baseSub1Sub2) {
+        this.baseSub1Sub2 = baseSub1Sub2;
+    }
+
+    public List getBaseList() {
+        return this.baseList;
+    }
+
+    public void setBaseList(List baseList) {
+        this.baseList = baseList;
+    }
+
+    public List getBaseSub1List() {
+        return this.baseSub1List;
+    }
+
+    public void setBaseSub1List(List baseSub1List) {
+        this.baseSub1List = baseSub1List;
+    }
+
+    public List getBaseSub1Sub2List() {
+        return this.baseSub1Sub2List;
+    }
+
+    public void setBaseSub1Sub2List(List baseSub1Sub2List) {
+        this.baseSub1Sub2List = baseSub1Sub2List;
+    }
+
+    public Base getNullBase() {
+        return this.nullBase;
+    }
+
+    public void setNullBase(Base nullBase) {
+        this.nullBase = nullBase;
+    }
+
+    public List getEmptyBaseList() {
+        return this.emptyBaseList;
+    }
+
+    public void setEmptyBaseList(List emptyBaseList) {
+        this.emptyBaseList = emptyBaseList;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest1.java
index 706f627..00d0938 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest1.java
@@ -1,131 +1,131 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import java.io.*;
-import java.math.*;
-import java.util.*;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-
-/**
- *	<p>Persitent type used in testing.</p>
- *
- *	@author		Abe White
- */
-@Entity
-        @Table(name="rtest1")
-        @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-        public class RuntimeTest1 implements Serializable {
-    
-    private static final long serialVersionUID = 1L;
-    
-    @Transient
-            public static final String someStaticField = "someField";
-    
-    private Locale		localeField;
-    
-    @Id
-            private int			intField;
-    
-    @Column(length=35)
-    private String		stringField;
-    
-    // transactional only
-    @Column(length=35)
-    public String		transString;
-    
-    // relations
-    //@Transient
-    @OneToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.REMOVE})
-    private RuntimeTest1	selfOneOne;
-    
-    @Transient
-            private Set		selfOneMany = new HashSet();
-    
-    
-    public RuntimeTest1() {
-    }
-    
-    public RuntimeTest1(int key) {
-        this.intField = key;
-    }
-    
-    public RuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-    }
-    
-    public int getIntField() {
-        return this.intField;
-    }
-    
-    
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-    
-    public String getStringField() {
-        return this.stringField;
-    }
-    
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-    
-    public RuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-    
-    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-    
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-    
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-    
-    public String toString() {
-        return "IntField: "+intField+", StringField: "+stringField+" .";
-    }
-    
-    public Locale getLocaleField() {
-        return localeField;
-    }
-    
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+
+/**
+ *	<p>Persitent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+        @Table(name="rtest1")
+        @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+        public class RuntimeTest1 implements Serializable {
+    
+    private static final long serialVersionUID = 1L;
+    
+    @Transient
+            public static final String someStaticField = "someField";
+    
+    private Locale		localeField;
+    
+    @Id
+            private int			intField;
+    
+    @Column(length=35)
+    private String		stringField;
+    
+    // transactional only
+    @Column(length=35)
+    public String		transString;
+    
+    // relations
+    //@Transient
+    @OneToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+    private RuntimeTest1	selfOneOne;
+    
+    @Transient
+            private Set		selfOneMany = new HashSet();
+    
+    
+    public RuntimeTest1() {
+    }
+    
+    public RuntimeTest1(int key) {
+        this.intField = key;
+    }
+    
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+    }
+    
+    public int getIntField() {
+        return this.intField;
+    }
+    
+    
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+    
+    public String getStringField() {
+        return this.stringField;
+    }
+    
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+    
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+    
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+    
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+    
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+    
+    public String toString() {
+        return "IntField: "+intField+", StringField: "+stringField+" .";
+    }
+    
+    public Locale getLocaleField() {
+        return localeField;
+    }
+    
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest2.java
index de47fac..4f24564 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest2.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-import org.apache.openjpa.kernel.*;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class RuntimeTest2
-    extends RuntimeTest1 {
-
-    private int intField2;
-
-    public RuntimeTest2() {
-    }
-
-    public RuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+import org.apache.openjpa.kernel.*;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class RuntimeTest2
+    extends RuntimeTest1 {
+
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest3.java
index 45cd0e1..ab66855 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/RuntimeTest3.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-import org.apache.openjpa.kernel.*;
-
-import java.util.*;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-
-@Entity
-public class RuntimeTest3
-    extends RuntimeTest2 {
-
-    private int intField3;
-
-    public RuntimeTest3() {
-    }
-
-    public RuntimeTest3(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField3() {
-        return this.intField3;
-    }
-
-    public void setIntField3(int intField3) {
-        this.intField3 = intField3;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+
+@Entity
+public class RuntimeTest3
+    extends RuntimeTest2 {
+
+    private int intField3;
+
+    public RuntimeTest3() {
+    }
+
+    public RuntimeTest3(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField3() {
+        return this.intField3;
+    }
+
+    public void setIntField3(int intField3) {
+        this.intField3 = intField3;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqA.java
index 78d0a98..92360a4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqA.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class SeqA {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class SeqA {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqB.java
index 66507ad..0bfaea3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqB.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class SeqB extends SeqA {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class SeqB extends SeqA {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqC.java
index aed3028..592010e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqC.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class SeqC extends SeqA {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class SeqC extends SeqA {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqD.java
index 685736f..3f978e9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqD.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class SeqD {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class SeqD {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqE.java
index 10b686e..6432fe0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqE.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public abstract class SeqE {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public abstract class SeqE {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqF.java
index 302edb0..5f7b004 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqF.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class SeqF extends SeqE {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class SeqF extends SeqE {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqG.java
index 69b5625..1401dcb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/SeqG.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class SeqG extends SeqE {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class SeqG extends SeqE {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC.java
index ebe7e47..1a0c52b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-public class StateImagePC {
-
-    private int intField;
-    private StateImagePC stateImage;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public StateImagePC getStateImage() {
-        return this.stateImage;
-    }
-
-    public void setStateImage(StateImagePC stateImage) {
-        this.stateImage = stateImage;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+public class StateImagePC {
+
+    private int intField;
+    private StateImagePC stateImage;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public StateImagePC getStateImage() {
+        return this.stateImage;
+    }
+
+    public void setStateImage(StateImagePC stateImage) {
+        this.stateImage = stateImage;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC2.java
index b008fe4..0a64cbf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC2.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-public class StateImagePC2
-    extends StateImagePC {
-
-    private String stringField;
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+public class StateImagePC2
+    extends StateImagePC {
+
+    private String stringField;
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC3.java
index 57fe2be..c42e119 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/StateImagePC3.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-public class StateImagePC3 {
-
-    private int lockField;
-    private int nolockField;
-
-    public int getLockField() {
-        return lockField;
-    }
-
-    public void setLockField(int i) {
-        lockField = i;
-    }
-
-    public int getNoLockField() {
-        return nolockField;
-    }
-
-    public void setNoLockField(int i) {
-        nolockField = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+public class StateImagePC3 {
+
+    private int lockField;
+    private int nolockField;
+
+    public int getLockField() {
+        return lockField;
+    }
+
+    public void setLockField(int i) {
+        lockField = i;
+    }
+
+    public int getNoLockField() {
+        return nolockField;
+    }
+
+    public void setNoLockField(int i) {
+        nolockField = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/TransactionalClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/TransactionalClassPC.java
index 5cab5f5..eb85b68 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/TransactionalClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/TransactionalClassPC.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import org.apache.openjpa.kernel.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.lang.annotation.Annotation;
-
-/**
- * <p>Transactional type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class TransactionalClassPC {
-	@Id
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+/**
+ * <p>Transactional type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class TransactionalClassPC {
+	@Id
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java
index afd66df..55930aa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java
@@ -1,61 +1,61 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-/**
- * Entity which is traget of a unidirectional one-to-one relation.
- * 
- * Used in
- * @see org.apache.openjpa.persistence.query.TestProjectionQueryWithIdenticalResult
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class UnidirectionalOneToOneOwned {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	private String marker;
-	
-	@Version
-	private int version;
-	
-	public String getMarker() {
-		return marker;
-	}
-
-	public void setMarker(String marker) {
-		this.marker = marker;
-	}
-
-	public long getId() {
-		return id;
-	}
-
-	public int getVersion() {
-		return version;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * Entity which is traget of a unidirectional one-to-one relation.
+ * 
+ * Used in
+ * @see org.apache.openjpa.persistence.query.TestProjectionQueryWithIdenticalResult
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class UnidirectionalOneToOneOwned {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	private String marker;
+	
+	@Version
+	private int version;
+	
+	public String getMarker() {
+		return marker;
+	}
+
+	public void setMarker(String marker) {
+		this.marker = marker;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public int getVersion() {
+		return version;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java
index bb45cda..2b20acc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java
@@ -1,74 +1,74 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Version;
-
-/**
- * Persistent entity with unidirectional one-to-one relation.
- * 
- * Used in
- * @see org.apache.openjpa.persistence.query.TestProjectionQueryWithIdenticalResult
- *  
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class UnidirectionalOneToOneOwner {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	private String marker;
-	
-	@Version
-	private int version;
-	
-	@OneToOne(cascade=CascadeType.ALL)
-	private UnidirectionalOneToOneOwned owned;
-
-	public String getMarker() {
-		return marker;
-	}
-
-	public void setMarker(String marker) {
-		this.marker = marker;
-	}
-
-	public UnidirectionalOneToOneOwned getOwned() {
-		return owned;
-	}
-
-	public void setOwned(UnidirectionalOneToOneOwned owned) {
-		this.owned = owned;
-	}
-
-	public long getId() {
-		return id;
-	}
-
-	public int getVersion() {
-		return version;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+/**
+ * Persistent entity with unidirectional one-to-one relation.
+ * 
+ * Used in
+ * @see org.apache.openjpa.persistence.query.TestProjectionQueryWithIdenticalResult
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class UnidirectionalOneToOneOwner {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	private String marker;
+	
+	@Version
+	private int version;
+	
+	@OneToOne(cascade=CascadeType.ALL)
+	private UnidirectionalOneToOneOwned owned;
+
+	public String getMarker() {
+		return marker;
+	}
+
+	public void setMarker(String marker) {
+		this.marker = marker;
+	}
+
+	public UnidirectionalOneToOneOwned getOwned() {
+		return owned;
+	}
+
+	public void setOwned(UnidirectionalOneToOneOwned owned) {
+		this.owned = owned;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public int getVersion() {
+		return version;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnknownSubclassParent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnknownSubclassParent.java
index a1debdc..bcf9846 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnknownSubclassParent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnknownSubclassParent.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps;
-
-public class UnknownSubclassParent {
-
-    private String parentString;
-
-    public void setParentString(String parentString) {
-        this.parentString = parentString;
-    }
-
-    public String getParentString() {
-        return this.parentString;
-    }
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps;
+
+public class UnknownSubclassParent {
+
+    private String parentString;
+
+    public void setParentString(String parentString) {
+        this.parentString = parentString;
+    }
+
+    public String getParentString() {
+        return this.parentString;
+    }
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/CompositeId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/CompositeId.java
index 1c1ad65..606de59 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/CompositeId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/CompositeId.java
@@ -1,89 +1,89 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-/** Denotes a composite identity combining a String and Integer field.
- * 
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- *
- */
-public class CompositeId implements Serializable {
-	public Integer id;
-	public String  name;
-	
-	public CompositeId () 
-	{
-	}
-
-	public CompositeId (String idString)
-	{
-		int index = idString.indexOf(':');
-		id = Integer.parseInt(idString.substring(0,index));
-		name = idString.substring(index+1);
-	}
-
-	public CompositeId (Integer id, String name)
-	{
-		this.id   = id;
-		this.name = name;
-	}
-
-	public Integer getId()
-	{
-		return id;
-	}
-
-	public void setId(Integer id)
-	{
-		this.id = id;
-	}
-
-	public String getName()
-	{
-		return name;
-	}
-
-	public void setName(String name)
-	{
-		this.name = name;
-	}
-	
-	public String toString() 
-	{
-		return id + ":" + name;
-	}
-	
-	@Override
-	public boolean equals (Object other)
-	{
-		if (other instanceof CompositeId==false)
-			return false;
-		
-		CompositeId that = (CompositeId) other;
-		return id.equals(that.id) && name.equals(that.name);
-	}
-	
-	@Override
-	public int hashCode () 
-	{
-		return id.hashCode()+name.hashCode();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+/** Denotes a composite identity combining a String and Integer field.
+ * 
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ *
+ */
+public class CompositeId implements Serializable {
+	public Integer id;
+	public String  name;
+	
+	public CompositeId () 
+	{
+	}
+
+	public CompositeId (String idString)
+	{
+		int index = idString.indexOf(':');
+		id = Integer.parseInt(idString.substring(0,index));
+		name = idString.substring(index+1);
+	}
+
+	public CompositeId (Integer id, String name)
+	{
+		this.id   = id;
+		this.name = name;
+	}
+
+	public Integer getId()
+	{
+		return id;
+	}
+
+	public void setId(Integer id)
+	{
+		this.id = id;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+	
+	public String toString() 
+	{
+		return id + ":" + name;
+	}
+	
+	@Override
+	public boolean equals (Object other)
+	{
+		if (other instanceof CompositeId==false)
+			return false;
+		
+		CompositeId that = (CompositeId) other;
+		return id.equals(that.id) && name.equals(that.name);
+	}
+	
+	@Override
+	public int hashCode () 
+	{
+		return id.hashCode()+name.hashCode();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity1.java
index adc2b7a..9e94256 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity1.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-
-@Entity
-@Table(name="entity_1")
-@Inheritance(strategy=InheritanceType.JOINED)
-@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
-public class Entity1 implements Serializable
-{
-	private static final long serialVersionUID = 2882935803066041165L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
-	protected Entity2 entity2Field;
-
-	@Version
-	protected int versionField;
-
-	public Entity1()
-	{}
-
-	public Entity1 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-
-	public void setEntity2Field (Entity2 val)
-	{
-		entity2Field = val;
-	}
-
-
-	public Entity2 getEntity2Field ()
-	{
-		return entity2Field;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+
+@Entity
+@Table(name="entity_1")
+@Inheritance(strategy=InheritanceType.JOINED)
+@SqlResultSetMapping(name="NativeTestResult", entities=@EntityResult(entityClass=Entity1.class))
+public class Entity1 implements Serializable
+{
+	private static final long serialVersionUID = 2882935803066041165L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	@OneToOne(cascade={CascadeType.REMOVE, CascadeType.PERSIST})
+	protected Entity2 entity2Field;
+
+	@Version
+	protected int versionField;
+
+	public Entity1()
+	{}
+
+	public Entity1 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+
+	public void setEntity2Field (Entity2 val)
+	{
+		entity2Field = val;
+	}
+
+
+	public Entity2 getEntity2Field ()
+	{
+		return entity2Field;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity2.java
index 0adc7bc..1e47ca4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/Entity2.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-
-//@Entity(name="entity2ExplicitName")
-//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-/**FIX-ME 
- * 
- * It should complain if i uncomment the above strategies...but it does
- */
-@Entity
-public class Entity2 implements Serializable
-{
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 4723739219953167343L;
-
-	@Id
-	protected long pk;
-
-	@Basic
-	@Column(length=35)
-	protected String stringField;
-
-	@Basic
-	protected int intField;
-
-	public Entity2()
-	{}
-
-
-	public Entity2 (long pk, String stringField, int intField)
-	{
-		this.pk = pk;
-		this.stringField = stringField;
-		this.intField = intField;
-	}
-
-
-	public long getPk ()
-	{
-		return pk;
-	}
-
-
-	public void setStringField (String val)
-	{
-		stringField = val;
-	}
-
-
-	public String getStringField ()
-	{
-		return stringField;
-	}
-
-	public void setIntField (int val)
-	{
-		intField = val;
-	}
-
-
-	public int getIntField ()
-	{
-		return intField;
-	}
-
-	public String toString()
-	{
-		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+
+//@Entity(name="entity2ExplicitName")
+//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+/**FIX-ME 
+ * 
+ * It should complain if i uncomment the above strategies...but it does
+ */
+@Entity
+public class Entity2 implements Serializable
+{
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 4723739219953167343L;
+
+	@Id
+	protected long pk;
+
+	@Basic
+	@Column(length=35)
+	protected String stringField;
+
+	@Basic
+	protected int intField;
+
+	public Entity2()
+	{}
+
+
+	public Entity2 (long pk, String stringField, int intField)
+	{
+		this.pk = pk;
+		this.stringField = stringField;
+		this.intField = intField;
+	}
+
+
+	public long getPk ()
+	{
+		return pk;
+	}
+
+
+	public void setStringField (String val)
+	{
+		stringField = val;
+	}
+
+
+	public String getStringField ()
+	{
+		return stringField;
+	}
+
+	public void setIntField (int val)
+	{
+		intField = val;
+	}
+
+
+	public int getIntField ()
+	{
+		return intField;
+	}
+
+	public String toString()
+	{
+		return("PK: "+pk+" StringField: "+stringField+" IntField: "+intField);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/EntityWithCompositeId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/EntityWithCompositeId.java
index 05ea6b0..a928dda 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/EntityWithCompositeId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/EntityWithCompositeId.java
@@ -1,68 +1,68 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import javax.persistence.*;
-
-@Entity
-@IdClass(CompositeId.class)
-@Table(name="COMPOSITE_ID")
-public class EntityWithCompositeId {
-	private Integer id;   // this must match the field in CompositeId
-	private String  name; // this must match the field in CompositeId
-	private String  value;
-	
-	public EntityWithCompositeId() {
-		super();
-	}
-	
-	@Id
-	@Column(name="ID")
-	public Integer getId () 
-	{
-		return id;
-	}
-
-	@Id
-	@Column(name="NAME")
-	public String getName () {
-		return name;
-	}
-	
-	
-	@Column(name="VALUE")
-	public String getValue () 
-	{
-		return value;
-	}
-	
-	public void setId (Integer id) {
-		this.id = id;
-	}
-	
-	public void setName (String name) 
-	{
-		this.name = name;
-	}
-	
-	public void setValue (String value)
-	{
-		this.value = value;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import javax.persistence.*;
+
+@Entity
+@IdClass(CompositeId.class)
+@Table(name="COMPOSITE_ID")
+public class EntityWithCompositeId {
+	private Integer id;   // this must match the field in CompositeId
+	private String  name; // this must match the field in CompositeId
+	private String  value;
+	
+	public EntityWithCompositeId() {
+		super();
+	}
+	
+	@Id
+	@Column(name="ID")
+	public Integer getId () 
+	{
+		return id;
+	}
+
+	@Id
+	@Column(name="NAME")
+	public String getName () {
+		return name;
+	}
+	
+	
+	@Column(name="VALUE")
+	public String getValue () 
+	{
+		return value;
+	}
+	
+	public void setId (Integer id) {
+		this.id = id;
+	}
+	
+	public void setName (String name) 
+	{
+		this.name = name;
+	}
+	
+	public void setValue (String value)
+	{
+		this.value = value;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/OwnerOfEntityWithCompositeId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/OwnerOfEntityWithCompositeId.java
index 9c77809..f36b358 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/OwnerOfEntityWithCompositeId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/OwnerOfEntityWithCompositeId.java
@@ -1,118 +1,118 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import javax.persistence.*;
-
-@SqlResultSetMappings(value={
-@SqlResultSetMapping(name="SQLSelectsBothEndOfTheRelation",
-		entities={
-			@EntityResult(entityClass=OwnerOfEntityWithCompositeId.class,
-				fields={
-				@FieldResult(name="name",          column="OWNER_NAME"),
-				@FieldResult(name="relation.id",   column="REL_ID"),
-				@FieldResult(name="relation.name", column="REL_NAME")
-				}
-			),
-			@EntityResult(entityClass=EntityWithCompositeId.class,
-				fields={
-					@FieldResult(name="id",  column="C_ID"),
-					@FieldResult(name="name", column="C_NAME"),
-					@FieldResult(name="value", column="C_VALUE")
-				}
-			)
-		}
-),
-@SqlResultSetMapping(name="SQLSelectsOnlyOneEndOfTheRelation",
-		entities={
-			@EntityResult(entityClass=OwnerOfEntityWithCompositeId.class,
-				fields={
-				@FieldResult(name="name",          column="OWNER_NAME"),
-				@FieldResult(name="relation.id",   column="REL_ID"),
-				@FieldResult(name="relation.name", column="REL_NAME")
-				}
-			)
-		}
-),
-@SqlResultSetMapping(name="SQLSelectsUnrelatedInstances",
-		entities={
-			@EntityResult(entityClass=OwnerOfEntityWithCompositeId.class,
-				fields={
-				@FieldResult(name="name",          column="OWNER_NAME"),
-				@FieldResult(name="relation.id",   column="REL_ID"),
-				@FieldResult(name="relation.name", column="REL_NAME")
-				}
-			),
-			@EntityResult(entityClass=EntityWithCompositeId.class,
-				fields={
-					@FieldResult(name="id",    column="C_ID"),
-					@FieldResult(name="name",  column="C_NAME"),
-					@FieldResult(name="value", column="C_VALUE")
-				}
-			)
-		}
-)
-
-})
-
-@Entity
-@Table(name="OWNER_OF_COMPOSITE_ID")
-public class OwnerOfEntityWithCompositeId {
-	
-	private String                 name;
-	private EntityWithCompositeId  relation;
-	
-	public OwnerOfEntityWithCompositeId() {
-		super();
-	}
-	
-	public OwnerOfEntityWithCompositeId (String name)
-	{
-		setName (name);
-	}
-	
-	@Id
-	@Column(name="NAME")
-	public String getName () 
-	{
-		return name;
-	}
-	
-	@OneToOne(cascade=CascadeType.ALL)
-	@JoinColumns({
-		@JoinColumn(name="RELATION_ID",referencedColumnName="ID"),
-		@JoinColumn(name="RELATION_NAME", referencedColumnName="NAME")
-	})
-	
-	public EntityWithCompositeId getRelation()
-	{
-		return relation;
-	}
-	
-	
-	public void setName (String name)
-	{
-		this.name = name;
-	}
-	
-	public void setRelation (EntityWithCompositeId relation)
-	{
-		this.relation = relation;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import javax.persistence.*;
+
+@SqlResultSetMappings(value={
+@SqlResultSetMapping(name="SQLSelectsBothEndOfTheRelation",
+		entities={
+			@EntityResult(entityClass=OwnerOfEntityWithCompositeId.class,
+				fields={
+				@FieldResult(name="name",          column="OWNER_NAME"),
+				@FieldResult(name="relation.id",   column="REL_ID"),
+				@FieldResult(name="relation.name", column="REL_NAME")
+				}
+			),
+			@EntityResult(entityClass=EntityWithCompositeId.class,
+				fields={
+					@FieldResult(name="id",  column="C_ID"),
+					@FieldResult(name="name", column="C_NAME"),
+					@FieldResult(name="value", column="C_VALUE")
+				}
+			)
+		}
+),
+@SqlResultSetMapping(name="SQLSelectsOnlyOneEndOfTheRelation",
+		entities={
+			@EntityResult(entityClass=OwnerOfEntityWithCompositeId.class,
+				fields={
+				@FieldResult(name="name",          column="OWNER_NAME"),
+				@FieldResult(name="relation.id",   column="REL_ID"),
+				@FieldResult(name="relation.name", column="REL_NAME")
+				}
+			)
+		}
+),
+@SqlResultSetMapping(name="SQLSelectsUnrelatedInstances",
+		entities={
+			@EntityResult(entityClass=OwnerOfEntityWithCompositeId.class,
+				fields={
+				@FieldResult(name="name",          column="OWNER_NAME"),
+				@FieldResult(name="relation.id",   column="REL_ID"),
+				@FieldResult(name="relation.name", column="REL_NAME")
+				}
+			),
+			@EntityResult(entityClass=EntityWithCompositeId.class,
+				fields={
+					@FieldResult(name="id",    column="C_ID"),
+					@FieldResult(name="name",  column="C_NAME"),
+					@FieldResult(name="value", column="C_VALUE")
+				}
+			)
+		}
+)
+
+})
+
+@Entity
+@Table(name="OWNER_OF_COMPOSITE_ID")
+public class OwnerOfEntityWithCompositeId {
+	
+	private String                 name;
+	private EntityWithCompositeId  relation;
+	
+	public OwnerOfEntityWithCompositeId() {
+		super();
+	}
+	
+	public OwnerOfEntityWithCompositeId (String name)
+	{
+		setName (name);
+	}
+	
+	@Id
+	@Column(name="NAME")
+	public String getName () 
+	{
+		return name;
+	}
+	
+	@OneToOne(cascade=CascadeType.ALL)
+	@JoinColumns({
+		@JoinColumn(name="RELATION_ID",referencedColumnName="ID"),
+		@JoinColumn(name="RELATION_NAME", referencedColumnName="NAME")
+	})
+	
+	public EntityWithCompositeId getRelation()
+	{
+		return relation;
+	}
+	
+	
+	public void setName (String name)
+	{
+		this.name = name;
+	}
+	
+	public void setRelation (EntityWithCompositeId relation)
+	{
+		this.relation = relation;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/RecursiveEntityWithCompositeId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/RecursiveEntityWithCompositeId.java
index 1a5ef39..15757f5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/RecursiveEntityWithCompositeId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/RecursiveEntityWithCompositeId.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import javax.persistence.*;
-
-@SqlResultSetMappings(value={
-	@SqlResultSetMapping(name="SQLSelectsChainedRelation",
-		entities={
-			@EntityResult(entityClass=RecursiveEntityWithCompositeId.class,
-				fields={
-				
-				@FieldResult(name="id",                   column="T0_ID"),
-				@FieldResult(name="name",                 column="T0_NAME"),
-				@FieldResult(name="relation.id",          column="T0_REL_ID"),
-				@FieldResult(name="relation.name",        column="T0_REL_NAME"),
-				@FieldResult(name="relation.relation.id", column="T1_REL_ID"),
-				@FieldResult(name="relation.relation.name", column="T1_REL_NAME"),
-				@FieldResult(name="relation.relation.relation.id", column="T2_REL_ID"),
-				@FieldResult(name="relation.relation.relation.name", column="T2_REL_NAME")
-				
-				}
-			)
-		}
-	)
-  }
-)
- 
-@Entity
-@IdClass(CompositeId.class)
-@Table(name="RECURSIVE_ENTITY")
-
-public class RecursiveEntityWithCompositeId {
-	private Integer id;   // this must match the field in CompositeId
-	private String  name; // this must match the field in CompositeId
-	private int     value;// a non-primary key field 
-	private RecursiveEntityWithCompositeId  relation; // self-related
-	
-	public RecursiveEntityWithCompositeId() {
-		super();
-	}
-	
-	@Id
-	@Column(name="ID")
-	public Integer getId () 
-	{
-		return id;
-	}
-
-	@Id
-	@Column(name="NAME")
-	public String getName () {
-		return name;
-	}
-	
-	@Column(name="VALUE")
-	public int getValue(){
-	   return value;	
-	}
-	
-	@OneToOne(cascade=CascadeType.ALL)
-	@JoinColumns({
-		@JoinColumn(name="RELATION_ID",   referencedColumnName="ID"),
-		@JoinColumn(name="RELATION_NAME", referencedColumnName="NAME")
-	})
-	public RecursiveEntityWithCompositeId getRelation() 
-	{
-		return relation;
-	}
-	
-	public void setId (Integer id) {
-		this.id = id;
-	}
-	
-	public void setName (String name) 
-	{
-		this.name = name;
-	}
-	public void setValue (int value) 
-	{
-		this.value = value;
-	}
-	
-	public void setRelation (RecursiveEntityWithCompositeId relation)
-	{
-		this.relation = relation;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import javax.persistence.*;
+
+@SqlResultSetMappings(value={
+	@SqlResultSetMapping(name="SQLSelectsChainedRelation",
+		entities={
+			@EntityResult(entityClass=RecursiveEntityWithCompositeId.class,
+				fields={
+				
+				@FieldResult(name="id",                   column="T0_ID"),
+				@FieldResult(name="name",                 column="T0_NAME"),
+				@FieldResult(name="relation.id",          column="T0_REL_ID"),
+				@FieldResult(name="relation.name",        column="T0_REL_NAME"),
+				@FieldResult(name="relation.relation.id", column="T1_REL_ID"),
+				@FieldResult(name="relation.relation.name", column="T1_REL_NAME"),
+				@FieldResult(name="relation.relation.relation.id", column="T2_REL_ID"),
+				@FieldResult(name="relation.relation.relation.name", column="T2_REL_NAME")
+				
+				}
+			)
+		}
+	)
+  }
+)
+ 
+@Entity
+@IdClass(CompositeId.class)
+@Table(name="RECURSIVE_ENTITY")
+
+public class RecursiveEntityWithCompositeId {
+	private Integer id;   // this must match the field in CompositeId
+	private String  name; // this must match the field in CompositeId
+	private int     value;// a non-primary key field 
+	private RecursiveEntityWithCompositeId  relation; // self-related
+	
+	public RecursiveEntityWithCompositeId() {
+		super();
+	}
+	
+	@Id
+	@Column(name="ID")
+	public Integer getId () 
+	{
+		return id;
+	}
+
+	@Id
+	@Column(name="NAME")
+	public String getName () {
+		return name;
+	}
+	
+	@Column(name="VALUE")
+	public int getValue(){
+	   return value;	
+	}
+	
+	@OneToOne(cascade=CascadeType.ALL)
+	@JoinColumns({
+		@JoinColumn(name="RELATION_ID",   referencedColumnName="ID"),
+		@JoinColumn(name="RELATION_NAME", referencedColumnName="NAME")
+	})
+	public RecursiveEntityWithCompositeId getRelation() 
+	{
+		return relation;
+	}
+	
+	public void setId (Integer id) {
+		this.id = id;
+	}
+	
+	public void setName (String name) 
+	{
+		this.name = name;
+	}
+	public void setValue (int value) 
+	{
+		this.value = value;
+	}
+	
+	public void setRelation (RecursiveEntityWithCompositeId relation)
+	{
+		this.relation = relation;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapAddress.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapAddress.java
index d8b0885..4e38c41 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapAddress.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapAddress.java
@@ -1,177 +1,177 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-import javax.persistence.*;
-
-/** This domain class uses a all possible nature of annotations. Nature of
- * annotation from the point of view of nature of result they produce are
- * the following
- * <pre>
- * #entity-result      #column-result       nature
- * 0                     1+                 SCALAR_ONLY
- * 1                     0                  SINGLE_CLASS
- * 1                     1+                 SINGLE_CLASS_AND_SCALAR
- * 1+                    0                  MULTI_CLASS
- * 1+                    1+                 MULTI_CLASS_AND_SCALAR
- * </pre> 
- * 
- */
-@SqlResultSetMappings(value={
-		/** Specifies only scalars and no entity.
-		 * 
-		 */		
-				@SqlResultSetMapping(name="SCALAR_ONLY",
-				    columns={
-						@ColumnResult(name="NAME")
-					}
-				),
-		/** Specifies one entity and no scalar.
-		 * 
-		 */		
-				@SqlResultSetMapping(name="SINGLE_CLASS",
-					entities={
-						@EntityResult(entityClass=SQLMapPerson.class)
-					}
-				),
-				
-				/** Specifies one entity and one or more scalar.
-				 * 
-				 */				
-				@SqlResultSetMapping(name="SINGLE_CLASS_AND_SCALAR",
-					entities={
-						@EntityResult(entityClass=SQLMapPerson.class)
-					},
-					columns={
-						@ColumnResult(name="name")
-					}
-				),
-				
-				/** Specifies more than one entity and no scalar.
-				 * 
-				 */				
-				@SqlResultSetMapping(name="MULTI_CLASS",
-					entities={
-						@EntityResult(entityClass=SQLMapPerson.class),
-						@EntityResult(entityClass=SQLMapAddress.class)
-					}
-				),
-				
-				/** Specifies more than one entity and one or more scalar.
-				 * 
-				 */				
-				@SqlResultSetMapping(name="MULTI_CLASS_AND_SCALAR",
-					entities={
-						@EntityResult(entityClass=SQLMapPerson.class),
-						@EntityResult(entityClass=SQLMapAddress.class)
-					},
-					columns={
-						@ColumnResult(name="name"),
-						@ColumnResult(name="state")
-					}
-				),
-
-				@SqlResultSetMapping(name="MappingWithTraversal",
-					entities={
-						@EntityResult(entityClass=SQLMapAddress.class,
-					    fields={
-							@FieldResult(name="id",    column="ADDR_ID"),
-							@FieldResult(name="street",column="ADDR_STREET"),
-							@FieldResult(name="state", column="ADDR_STATE"),
-							@FieldResult(name="zip",   column="ADDR_ZIP")
-						}),
-						@EntityResult(entityClass=SQLMapPerson.class,
-						 fields={
-							@FieldResult(name="name",    column="MY_NAME"),
-							@FieldResult(name="address", column="MY_ADDRESS")
-						 }
-						)
-					}
-				)
-				
-				
-			}
-		) 
-
-
-@Entity
-@Table(name = "SQLMAP_ADDRESS")
-public class SQLMapAddress implements Serializable {
-	private int    id;
-	private String street;
-	private String state;
-	private int    zip;
-
-	protected SQLMapAddress() {
-
-	}
-
-	public SQLMapAddress(int id, String street, String state, int zip) {
-		this.id = id;
-		setStreet(street);
-		setState(state);
-		setZip(zip);
-	}
-
-	@Id
-	public int getId ()
-	{
-		return id;
-	}
-
-	public void setId (int id)
-	{
-		this.id = id;
-	}
-
-	@Column(name="STATE")
-	public String getState() {
-		return state;
-	}
-
-	public void setState(String state) {
-		this.state = state;
-	}
-
-	@Column(name="STREET")
-	public String getStreet() {
-		return street;
-	}
-
-	public void setStreet(String street) {
-		this.street = street;
-	}
-
-	public int getZip() {
-		return zip;
-	}
-
-	@Column(name="ZIP")
-	public void setZip(int zip) {
-		this.zip = zip;
-	}
-	
-	@PostLoad
-	protected void inform() {
-		System.out.println("Loaded" + this);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+/** This domain class uses a all possible nature of annotations. Nature of
+ * annotation from the point of view of nature of result they produce are
+ * the following
+ * <pre>
+ * #entity-result      #column-result       nature
+ * 0                     1+                 SCALAR_ONLY
+ * 1                     0                  SINGLE_CLASS
+ * 1                     1+                 SINGLE_CLASS_AND_SCALAR
+ * 1+                    0                  MULTI_CLASS
+ * 1+                    1+                 MULTI_CLASS_AND_SCALAR
+ * </pre> 
+ * 
+ */
+@SqlResultSetMappings(value={
+		/** Specifies only scalars and no entity.
+		 * 
+		 */		
+				@SqlResultSetMapping(name="SCALAR_ONLY",
+				    columns={
+						@ColumnResult(name="NAME")
+					}
+				),
+		/** Specifies one entity and no scalar.
+		 * 
+		 */		
+				@SqlResultSetMapping(name="SINGLE_CLASS",
+					entities={
+						@EntityResult(entityClass=SQLMapPerson.class)
+					}
+				),
+				
+				/** Specifies one entity and one or more scalar.
+				 * 
+				 */				
+				@SqlResultSetMapping(name="SINGLE_CLASS_AND_SCALAR",
+					entities={
+						@EntityResult(entityClass=SQLMapPerson.class)
+					},
+					columns={
+						@ColumnResult(name="name")
+					}
+				),
+				
+				/** Specifies more than one entity and no scalar.
+				 * 
+				 */				
+				@SqlResultSetMapping(name="MULTI_CLASS",
+					entities={
+						@EntityResult(entityClass=SQLMapPerson.class),
+						@EntityResult(entityClass=SQLMapAddress.class)
+					}
+				),
+				
+				/** Specifies more than one entity and one or more scalar.
+				 * 
+				 */				
+				@SqlResultSetMapping(name="MULTI_CLASS_AND_SCALAR",
+					entities={
+						@EntityResult(entityClass=SQLMapPerson.class),
+						@EntityResult(entityClass=SQLMapAddress.class)
+					},
+					columns={
+						@ColumnResult(name="name"),
+						@ColumnResult(name="state")
+					}
+				),
+
+				@SqlResultSetMapping(name="MappingWithTraversal",
+					entities={
+						@EntityResult(entityClass=SQLMapAddress.class,
+					    fields={
+							@FieldResult(name="id",    column="ADDR_ID"),
+							@FieldResult(name="street",column="ADDR_STREET"),
+							@FieldResult(name="state", column="ADDR_STATE"),
+							@FieldResult(name="zip",   column="ADDR_ZIP")
+						}),
+						@EntityResult(entityClass=SQLMapPerson.class,
+						 fields={
+							@FieldResult(name="name",    column="MY_NAME"),
+							@FieldResult(name="address", column="MY_ADDRESS")
+						 }
+						)
+					}
+				)
+				
+				
+			}
+		) 
+
+
+@Entity
+@Table(name = "SQLMAP_ADDRESS")
+public class SQLMapAddress implements Serializable {
+	private int    id;
+	private String street;
+	private String state;
+	private int    zip;
+
+	protected SQLMapAddress() {
+
+	}
+
+	public SQLMapAddress(int id, String street, String state, int zip) {
+		this.id = id;
+		setStreet(street);
+		setState(state);
+		setZip(zip);
+	}
+
+	@Id
+	public int getId ()
+	{
+		return id;
+	}
+
+	public void setId (int id)
+	{
+		this.id = id;
+	}
+
+	@Column(name="STATE")
+	public String getState() {
+		return state;
+	}
+
+	public void setState(String state) {
+		this.state = state;
+	}
+
+	@Column(name="STREET")
+	public String getStreet() {
+		return street;
+	}
+
+	public void setStreet(String street) {
+		this.street = street;
+	}
+
+	public int getZip() {
+		return zip;
+	}
+
+	@Column(name="ZIP")
+	public void setZip(int zip) {
+		this.zip = zip;
+	}
+	
+	@PostLoad
+	protected void inform() {
+		System.out.println("Loaded" + this);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapItem.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapItem.java
index 1b25a97..625413f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapItem.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapItem.java
@@ -1,157 +1,157 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-import javax.persistence.*;
-
-
-/** This simple domain class without any relationship is for testing basic 
- * SQL Result Set mapping functionality.
- * This class uses Application Identity.
- * The annotation specified herein examplifies test cases of accessing
- * with or without identity fields, aliased column names etc. 
- */ 
-@SqlResultSetMappings(value = {
-	/**
-	 *  This mapping is the same as the native query that
-	 *  takes a class argument.
-	 *  <code>SELECT id,name,price FROM ITEM WHERE name='WINE'</code>
-	 */ 		
-	@SqlResultSetMapping(name = "MappingEquivalentToClassQuery", 
-		entities = { @EntityResult(entityClass = SQLMapItem.class) 
-	}),
-
-	/**
-	 * This mapping is similar to the native query that takes a class argument
-	 * but the query specifies aliases for the projection columns.
-	 *  <code>SELECT id AS ITEM_ID,name AS ITEM_NAME FROM ITEM
-	 *  WHERE NAME='WINE'</code>
-	 */				
-	@SqlResultSetMapping(name = "MappingWithAliasedColumnName", 
-		entities = { @EntityResult(entityClass = SQLMapItem.class, 
-			fields = {
-				@FieldResult(name = "id",   column = "ITEM_ID"),
-				@FieldResult(name = "name", column = "ITEM_NAME") }) 
-			}),
-
-	/**
-	 * This mapping specifes only few fields of the application class.
-	 * 
-	 */ 		
-	@SqlResultSetMapping(name="MappingWithPartialFields",
-		entities={@EntityResult(entityClass=SQLMapItem.class,
-			fields={
-				@FieldResult(name="id", column="id")
-			})
-		}),
-
-	@SqlResultSetMapping(name="MappingWithPartialFieldsExcludingIdField",
-		entities={@EntityResult(entityClass=SQLMapItem.class,
-			fields={
-				@FieldResult(name="name", column="name")
-				})
-	
-		})
-})
-
-@Entity
-@Table(name = "SQLMAP_ITEM")
-public class SQLMapItem
-	implements Serializable
-{
-
-	private int id;
-	private String name;
-	private float  price;
-
-
-	protected SQLMapItem()
-	{
-	}
-
-
-	public SQLMapItem(int id)
-	{
-		this.id = id;
-	}
-
-
-	public SQLMapItem(int id, String name)
-	{
-		this.id = id;
-		this.name = name;
-	}
-
-
-	public SQLMapItem(int id, String name, int price)
-	{
-		this.id = id;
-		this.name = name;
-		this.price = price;
-	}
-
-
-	public String toString()
-	{
-		return getId() + ":"+getName();
-		//System.identityHashCode(this) + ":[" + id + "." + name + "]";
-	}
-
-
-	@Id
-	@Column(name="ID")
-	public int getId()
-	{
-		return id;
-	}
-
-	public void setId(int id)
-	{
-		System.out.println("setId " + id);
-		this.id = id;
-	}
-
-	@Column(name="NAME")
-	public String getName()
-	{
-		return name;
-	}
-
-
-	public void setName(String name)
-	{
-		System.out.println("setName " + name);
-		this.name = name;
-	}
-
-
-	@Column(name="PRICE")
-	public float getPrice()
-	{
-		return price;
-	}
-
-
-	public void setPrice(float price)
-	{
-		this.price = price;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+
+/** This simple domain class without any relationship is for testing basic 
+ * SQL Result Set mapping functionality.
+ * This class uses Application Identity.
+ * The annotation specified herein examplifies test cases of accessing
+ * with or without identity fields, aliased column names etc. 
+ */ 
+@SqlResultSetMappings(value = {
+	/**
+	 *  This mapping is the same as the native query that
+	 *  takes a class argument.
+	 *  <code>SELECT id,name,price FROM ITEM WHERE name='WINE'</code>
+	 */ 		
+	@SqlResultSetMapping(name = "MappingEquivalentToClassQuery", 
+		entities = { @EntityResult(entityClass = SQLMapItem.class) 
+	}),
+
+	/**
+	 * This mapping is similar to the native query that takes a class argument
+	 * but the query specifies aliases for the projection columns.
+	 *  <code>SELECT id AS ITEM_ID,name AS ITEM_NAME FROM ITEM
+	 *  WHERE NAME='WINE'</code>
+	 */				
+	@SqlResultSetMapping(name = "MappingWithAliasedColumnName", 
+		entities = { @EntityResult(entityClass = SQLMapItem.class, 
+			fields = {
+				@FieldResult(name = "id",   column = "ITEM_ID"),
+				@FieldResult(name = "name", column = "ITEM_NAME") }) 
+			}),
+
+	/**
+	 * This mapping specifes only few fields of the application class.
+	 * 
+	 */ 		
+	@SqlResultSetMapping(name="MappingWithPartialFields",
+		entities={@EntityResult(entityClass=SQLMapItem.class,
+			fields={
+				@FieldResult(name="id", column="id")
+			})
+		}),
+
+	@SqlResultSetMapping(name="MappingWithPartialFieldsExcludingIdField",
+		entities={@EntityResult(entityClass=SQLMapItem.class,
+			fields={
+				@FieldResult(name="name", column="name")
+				})
+	
+		})
+})
+
+@Entity
+@Table(name = "SQLMAP_ITEM")
+public class SQLMapItem
+	implements Serializable
+{
+
+	private int id;
+	private String name;
+	private float  price;
+
+
+	protected SQLMapItem()
+	{
+	}
+
+
+	public SQLMapItem(int id)
+	{
+		this.id = id;
+	}
+
+
+	public SQLMapItem(int id, String name)
+	{
+		this.id = id;
+		this.name = name;
+	}
+
+
+	public SQLMapItem(int id, String name, int price)
+	{
+		this.id = id;
+		this.name = name;
+		this.price = price;
+	}
+
+
+	public String toString()
+	{
+		return getId() + ":"+getName();
+		//System.identityHashCode(this) + ":[" + id + "." + name + "]";
+	}
+
+
+	@Id
+	@Column(name="ID")
+	public int getId()
+	{
+		return id;
+	}
+
+	public void setId(int id)
+	{
+		System.out.println("setId " + id);
+		this.id = id;
+	}
+
+	@Column(name="NAME")
+	public String getName()
+	{
+		return name;
+	}
+
+
+	public void setName(String name)
+	{
+		System.out.println("setName " + name);
+		this.name = name;
+	}
+
+
+	@Column(name="PRICE")
+	public float getPrice()
+	{
+		return price;
+	}
+
+
+	public void setPrice(float price)
+	{
+		this.price = price;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapOrder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapOrder.java
index 1b9da31..fd546a1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapOrder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapOrder.java
@@ -1,89 +1,89 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-import javax.persistence.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-/** Exemplifies a mapping that is overwritten in orm.xml file.
- * 
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- *
- */
-@SqlResultSetMapping(name="Overwritten by Descriptor",
-		entities={
-			@EntityResult(entityClass=SQLMapOrder.class)
-		},
-		columns={
-			@ColumnResult(name="id")
-		}
-	)
-
-@Entity
-@Table(name = "SQLMAP_ORDER")
-public class SQLMapOrder implements Serializable {
-	@Id
-	int id;
-
-	int quantity;
-
-	@OneToOne
-	SQLMapItem item;
-
-	protected SQLMapOrder() {
-	}
-
-	public SQLMapOrder(int id) {
-		this(id, 1);
-	}
-
-	public SQLMapOrder(int id, int quantity) {
-		this.id = id;
-		this.quantity = 1;
-		this.item = null;
-	}
-
-	public SQLMapItem getItem() {
-		return item;
-	}
-
-	public void setItem(SQLMapItem item) {
-		this.item = item;
-	}
-
-	public int getQuantity() {
-		return quantity;
-	}
-
-	public void setQuantity(int quantity) {
-		this.quantity = quantity;
-	}
-
-	public int getId() {
-		return id;
-	}
-	@PostLoad
-	protected void inform() {
-		System.out.println("Loaded" + this);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+/** Exemplifies a mapping that is overwritten in orm.xml file.
+ * 
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ *
+ */
+@SqlResultSetMapping(name="Overwritten by Descriptor",
+		entities={
+			@EntityResult(entityClass=SQLMapOrder.class)
+		},
+		columns={
+			@ColumnResult(name="id")
+		}
+	)
+
+@Entity
+@Table(name = "SQLMAP_ORDER")
+public class SQLMapOrder implements Serializable {
+	@Id
+	int id;
+
+	int quantity;
+
+	@OneToOne
+	SQLMapItem item;
+
+	protected SQLMapOrder() {
+	}
+
+	public SQLMapOrder(int id) {
+		this(id, 1);
+	}
+
+	public SQLMapOrder(int id, int quantity) {
+		this.id = id;
+		this.quantity = 1;
+		this.item = null;
+	}
+
+	public SQLMapItem getItem() {
+		return item;
+	}
+
+	public void setItem(SQLMapItem item) {
+		this.item = item;
+	}
+
+	public int getQuantity() {
+		return quantity;
+	}
+
+	public void setQuantity(int quantity) {
+		this.quantity = quantity;
+	}
+
+	public int getId() {
+		return id;
+	}
+	@PostLoad
+	protected void inform() {
+		System.out.println("Loaded" + this);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapPerson.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapPerson.java
index cfe0bce..652cd93 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapPerson.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/SQLMapPerson.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
-
-import java.io.Serializable;
-
-import javax.persistence.*;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-/** 
- * @author ppoddar
- *
- */
-
-@SqlResultSetMapping (name="MappingWithSelfJoin",
-		columns={
-			@ColumnResult(name="MY_NAME"),
-			@ColumnResult(name="PARTNER_NAME")
-		}
-)
-@Entity
-@Table(name = "SQLMAP_PERSON")
-public class SQLMapPerson implements Serializable {
-	private String name;
-	private SQLMapAddress address;
-	private SQLMapPerson partner;
-
-
-	protected SQLMapPerson() {
-	}
-
-	public SQLMapPerson(String name) {
-		this.name = name;
-	}
-
-	public SQLMapPerson(String name, SQLMapAddress address) {
-		this.name = name;
-		setAddress(address);
-	}
-
-	@Id
-	public String getName() {
-		return name;
-	}
-	
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	@OneToOne(cascade=CascadeType.ALL)
-	@JoinColumn(name="ADDRESS_ID")
-	public SQLMapAddress getAddress() {
-		return address;
-	}
-
-	public void setAddress(SQLMapAddress address) {
-		this.address = address;
-	}
-
-
-	@OneToOne
-	public SQLMapPerson getPartner() {
-		return partner;
-	}
-
-	public void setPartner(SQLMapPerson partner) {
-		this.partner = partner;
-	}
-//	@PostLoad
-//	protected void inform() {
-//		System.out.println("Loaded" + this);
-//	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.common.apps.mappingApp;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+/** 
+ * @author ppoddar
+ *
+ */
+
+@SqlResultSetMapping (name="MappingWithSelfJoin",
+		columns={
+			@ColumnResult(name="MY_NAME"),
+			@ColumnResult(name="PARTNER_NAME")
+		}
+)
+@Entity
+@Table(name = "SQLMAP_PERSON")
+public class SQLMapPerson implements Serializable {
+	private String name;
+	private SQLMapAddress address;
+	private SQLMapPerson partner;
+
+
+	protected SQLMapPerson() {
+	}
+
+	public SQLMapPerson(String name) {
+		this.name = name;
+	}
+
+	public SQLMapPerson(String name, SQLMapAddress address) {
+		this.name = name;
+		setAddress(address);
+	}
+
+	@Id
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@OneToOne(cascade=CascadeType.ALL)
+	@JoinColumn(name="ADDRESS_ID")
+	public SQLMapAddress getAddress() {
+		return address;
+	}
+
+	public void setAddress(SQLMapAddress address) {
+		this.address = address;
+	}
+
+
+	@OneToOne
+	public SQLMapPerson getPartner() {
+		return partner;
+	}
+
+	public void setPartner(SQLMapPerson partner) {
+		this.partner = partner;
+	}
+//	@PostLoad
+//	protected void inform() {
+//		System.out.println("Loaded" + this);
+//	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/BaseJDBCTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/BaseJDBCTest.java
index 210e846..f87f5d3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/BaseJDBCTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/BaseJDBCTest.java
@@ -1,191 +1,191 @@
-/*
- * BaseJDBCTest.java
- *
- * Created on October 9, 2006, 12:56 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.*;
-import javax.management.IntrospectionException;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-
-public class BaseJDBCTest extends org.apache.openjpa.persistence.common.utils.AbstractTestCase{
-    
-    
-    private static Map _sysprops = new HashMap();
-    
-    
-    /** Creates a new instance of BaseJDBCTest */
-    public BaseJDBCTest() {
-    }
-    
-    public BaseJDBCTest(String name) 
-    {
-        super(name, "jdbccactusapp");
-    }
-
-    @Override
-    protected String defaultPersistenceXmlResource() {
-        return "org/apache/openjpa/persistence/jdbc/common" +
-            "/apps/META-INF/persistence.xml";
-    }
-    
-    protected OpenJPAEntityManager getPM() {
-        return (OpenJPAEntityManager)currentEntityManager();
-    }
-    
-    protected OpenJPAEntityManager getPM(boolean optimistic,boolean retainValues) {
-        OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-        em.setNontransactionalRead(true);
-        em.setRetainState(retainValues);
-        em.setOptimistic(optimistic);
-        return em;
-    }
-    
-    /**
-     * Delete all instances of the given class.
-     */
-    protected  int deleteAll(Broker broker, Class clazz) {
-        return deleteAll(broker, clazz, true);
-    }
-    
-    /**
-     * Delete all instances of the given class.
-     */
-    protected int deleteAll(Broker broker, Class clazz,
-            boolean subclasses) {
-        final boolean useDeleteByQuery = false;
-        
-        if (useDeleteByQuery) {
-            org.apache.openjpa.kernel.Query query = broker.newQuery(
-                    JPQLParser.LANG_JPQL, clazz, "");
-            query.setCandidateType(clazz, subclasses);
-            return (int) query.deleteAll();
-        } else {
-            org.apache.openjpa.kernel.Extent extent =
-                    broker.newExtent(clazz, subclasses);
-            List list = extent.list();
-            int size = list.size();
-            broker.deleteAll(list, null);
-            return size;
-        }
-    }
-    
-    /**
-     * Delete all instances of the given class.
-     */
-    protected int deleteAll(OpenJPAEntityManager pm, Class clazz) {
-        return deleteAll(JPAFacadeHelper.toBroker(pm), clazz);
-    }
-    
-    /**
-     * Delete all instances of the given class.
-     */
-    protected int deleteAll(OpenJPAEntityManager pm, Class clazz,
-            boolean subclasses) {
-        return deleteAll(JPAFacadeHelper.toBroker(pm), clazz, subclasses);
-    }
-    
-    
-    protected Object persist(Object ob) {
-        Broker broker = getBrokerFactory().newBroker();
-        broker.begin();
-        broker.persist(ob, null);
-        Object id = broker.getObjectId(ob);
-        broker.commit();
-        broker.close();
-        return id;
-    }
-    
-    protected Properties getProperties() {
-        return getProperties(null);
-    }
-    
-    /**
-     * Return the runtime properties, optionally overriding or setting
-     * some via the given array, which should be in the form
-     * { key, val, key, val, ... }.
-     */
-    protected synchronized Properties getProperties(String[] props) {
-        Properties p = new Properties(System.getProperties());
-        String str = p.getProperty("openjpa.properties", "kodo.properties");
-        if (str != null && str.length() > 0) {
-            // cache system properties to reduce load on file system
-            Properties loaded = (Properties) _sysprops.get(str);
-            if (loaded == null) {
-                loaded = new Properties();
-                ConfigurationProvider cp = (ConfigurationProvider) Configurations.getProperty(str, null);
-                
-                if (cp != null)
-                    loaded.putAll(cp.getProperties());
-                _sysprops.put(str, loaded);
-            }
-            p.putAll(loaded);
-        }
-        
-        for (int i = 0; props != null && i < props.length; i += 2) {
-            if (props[i + 1] != null) {
-                // remove any duplicate kodo/openjpa property so we don't clash
-                if (props[i].startsWith("openjpa."))
-                    p.remove("openjpa." + props[i].substring(5));
-                else if (props[i].startsWith("openjpa."))
-                    p.remove("openjpa." + props[i].substring(8));
-                
-                p.setProperty(props[i], props[i + 1]);
-            } else {
-                p.remove(props[i]);
-            }
-        }
-        return p;
-    }
-    
-    
-    
-    
-    
-}
+/*
+ * BaseJDBCTest.java
+ *
+ * Created on October 9, 2006, 12:56 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+import javax.management.IntrospectionException;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+
+public class BaseJDBCTest extends org.apache.openjpa.persistence.common.utils.AbstractTestCase{
+    
+    
+    private static Map _sysprops = new HashMap();
+    
+    
+    /** Creates a new instance of BaseJDBCTest */
+    public BaseJDBCTest() {
+    }
+    
+    public BaseJDBCTest(String name) 
+    {
+        super(name, "jdbccactusapp");
+    }
+
+    @Override
+    protected String defaultPersistenceXmlResource() {
+        return "org/apache/openjpa/persistence/jdbc/common" +
+            "/apps/META-INF/persistence.xml";
+    }
+    
+    protected OpenJPAEntityManager getPM() {
+        return (OpenJPAEntityManager)currentEntityManager();
+    }
+    
+    protected OpenJPAEntityManager getPM(boolean optimistic,boolean retainValues) {
+        OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+        em.setNontransactionalRead(true);
+        em.setRetainState(retainValues);
+        em.setOptimistic(optimistic);
+        return em;
+    }
+    
+    /**
+     * Delete all instances of the given class.
+     */
+    protected  int deleteAll(Broker broker, Class clazz) {
+        return deleteAll(broker, clazz, true);
+    }
+    
+    /**
+     * Delete all instances of the given class.
+     */
+    protected int deleteAll(Broker broker, Class clazz,
+            boolean subclasses) {
+        final boolean useDeleteByQuery = false;
+        
+        if (useDeleteByQuery) {
+            org.apache.openjpa.kernel.Query query = broker.newQuery(
+                    JPQLParser.LANG_JPQL, clazz, "");
+            query.setCandidateType(clazz, subclasses);
+            return (int) query.deleteAll();
+        } else {
+            org.apache.openjpa.kernel.Extent extent =
+                    broker.newExtent(clazz, subclasses);
+            List list = extent.list();
+            int size = list.size();
+            broker.deleteAll(list, null);
+            return size;
+        }
+    }
+    
+    /**
+     * Delete all instances of the given class.
+     */
+    protected int deleteAll(OpenJPAEntityManager pm, Class clazz) {
+        return deleteAll(JPAFacadeHelper.toBroker(pm), clazz);
+    }
+    
+    /**
+     * Delete all instances of the given class.
+     */
+    protected int deleteAll(OpenJPAEntityManager pm, Class clazz,
+            boolean subclasses) {
+        return deleteAll(JPAFacadeHelper.toBroker(pm), clazz, subclasses);
+    }
+    
+    
+    protected Object persist(Object ob) {
+        Broker broker = getBrokerFactory().newBroker();
+        broker.begin();
+        broker.persist(ob, null);
+        Object id = broker.getObjectId(ob);
+        broker.commit();
+        broker.close();
+        return id;
+    }
+    
+    protected Properties getProperties() {
+        return getProperties(null);
+    }
+    
+    /**
+     * Return the runtime properties, optionally overriding or setting
+     * some via the given array, which should be in the form
+     * { key, val, key, val, ... }.
+     */
+    protected synchronized Properties getProperties(String[] props) {
+        Properties p = new Properties(System.getProperties());
+        String str = p.getProperty("openjpa.properties", "kodo.properties");
+        if (str != null && str.length() > 0) {
+            // cache system properties to reduce load on file system
+            Properties loaded = (Properties) _sysprops.get(str);
+            if (loaded == null) {
+                loaded = new Properties();
+                ConfigurationProvider cp = (ConfigurationProvider) Configurations.getProperty(str, null);
+                
+                if (cp != null)
+                    loaded.putAll(cp.getProperties());
+                _sysprops.put(str, loaded);
+            }
+            p.putAll(loaded);
+        }
+        
+        for (int i = 0; props != null && i < props.length; i += 2) {
+            if (props[i + 1] != null) {
+                // remove any duplicate kodo/openjpa property so we don't clash
+                if (props[i].startsWith("openjpa."))
+                    p.remove("openjpa." + props[i].substring(5));
+                else if (props[i].startsWith("openjpa."))
+                    p.remove("openjpa." + props[i].substring(8));
+                
+                p.setProperty(props[i], props[i + 1]);
+            } else {
+                p.remove(props[i]);
+            }
+        }
+        return p;
+    }
+    
+    
+    
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/JDBCTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/JDBCTestCase.java
index bdfd662..6e03bd5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/JDBCTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/JDBCTestCase.java
@@ -1,72 +1,72 @@
-/*
- * JDBCTestCase.java
- *
- * Created on September 29, 2006, 3:23 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import java.util.*;
-import org.apache.openjpa.conf.*;
-import org.apache.openjpa.util.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.kernel.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.meta.strats.*;
-
-
-
-
-public abstract class JDBCTestCase extends BaseJDBCTest {
-    
-    /** Creates a new instance of JDBCTestCase */
-    public JDBCTestCase() {
-    }
-    
-    public JDBCTestCase(String name) {
-        super(name);
-    }
-    public Class getDefaultInheritanceStrategy() {
-        return getClassMapping(RuntimeTest2.class).getStrategy().getClass();
-    }
-
-    public ClassMapping getClassMapping(Class c) {
-        
-        OpenJPAConfiguration jdoConf = getConfiguration();
-        return ((JDBCConfiguration) jdoConf).getMappingRepositoryInstance().
-            getMapping(c, getClass().getClassLoader(), true);
-    }
-
-    public FieldMapping getFieldMapping(Class c, String field) {
-        return getClassMapping(c).getFieldMapping(field);
-    }
-
-    public boolean isInheritanceStrategyVertical() {
-        return VerticalClassStrategy.class.
-            isAssignableFrom(getDefaultInheritanceStrategy());
-    }
-}
+/*
+ * JDBCTestCase.java
+ *
+ * Created on September 29, 2006, 3:23 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import java.util.*;
+import org.apache.openjpa.conf.*;
+import org.apache.openjpa.util.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.kernel.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.meta.strats.*;
+
+
+
+
+public abstract class JDBCTestCase extends BaseJDBCTest {
+    
+    /** Creates a new instance of JDBCTestCase */
+    public JDBCTestCase() {
+    }
+    
+    public JDBCTestCase(String name) {
+        super(name);
+    }
+    public Class getDefaultInheritanceStrategy() {
+        return getClassMapping(RuntimeTest2.class).getStrategy().getClass();
+    }
+
+    public ClassMapping getClassMapping(Class c) {
+        
+        OpenJPAConfiguration jdoConf = getConfiguration();
+        return ((JDBCConfiguration) jdoConf).getMappingRepositoryInstance().
+            getMapping(c, getClass().getClassLoader(), true);
+    }
+
+    public FieldMapping getFieldMapping(Class c, String field) {
+        return getClassMapping(c).getFieldMapping(field);
+    }
+
+    public boolean isInheritanceStrategyVertical() {
+        return VerticalClassStrategy.class.
+            isAssignableFrom(getDefaultInheritanceStrategy());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestByteArrayAppId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestByteArrayAppId.java
index 8338c35..d54d1b9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestByteArrayAppId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestByteArrayAppId.java
@@ -1,373 +1,373 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-/*
- * TestByteArrayAppId.java
- *
- * Created on October 2, 2006, 10:56 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import java.util.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.jdbc.meta.MappingTool;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.kernel.Extent;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.Query;
-
-
-public class TestByteArrayAppId extends BaseJDBCTest {
-    
-    private static boolean _init = false;
-    private OpenJPAEntityManagerFactory _pmf = null;
-    
-    
-    /** Creates a new instance of TestByteArrayAppId */
-    public TestByteArrayAppId(String name) 
-    {
-    	super(name);
-    }
-    
-    public boolean skipTest() {
-        return getCurrentPlatform() != AbstractTestCase.Platform.DB2;
-    }
-    
-    public void setUp()
-    throws Exception {
-        // we have to use getbytes/setbytes for byte arrays to work properly
-        _pmf =(OpenJPAEntityManagerFactory) getEmf(getProps());
-        
-        if (!_init) {
-            initialize((JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(_pmf)).getConfiguration());
-            _init = true;
-        }
-        EntityManager pm = _pmf.createEntityManager();
-        startTx(pm);
-        
-       deleteAll(ByteArrayPKPC.class,pm);
-        endTx(pm);
-        pm.close();
-        pm = currentEntityManager();
-        startTx(pm);
-        ByteArrayPKPC2 testBytes = new ByteArrayPKPC2(new byte[]{ 1, 2 },
-                "child");
-        testBytes.setSubfield("sub");
-        testBytes.setParent(new ByteArrayPKPC(new byte[]{ 3, 4 }, "parent"));
-        pm.persist(testBytes);
-        endTx(pm);
-        pm.close();
-    }
-    
-    public void tearDown()
-    throws Exception {
-        // closing the pmf every time slows things down too much b/c
-        // schema reflection is so slow on DB2
-        //	try { _pmf.close (); } catch (Exception e) {}
-        
-        super.tearDown();
-    }
-    
-    private void initialize(JDBCConfiguration conf)
-    throws Exception {
-        
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        //JDBCConfiguration conf = (JDBCConfiguration) kem.getConfiguration();        
-        
-        MappingTool tool = new MappingTool((JDBCConfiguration)
-        		((OpenJPAEntityManagerSPI) kem).getConfiguration(), MappingTool.ACTION_REFRESH, false);
-        tool.run(ByteArrayPKPC.class);
-        tool.run(ByteArrayPKPC2.class);
-        tool.record();
-    }
-    
-    /**
-     * Tests that application identity classes are returned correctly.
-     */
-    public void testGetObjectIdClass() {
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager pm = OpenJPAPersistence.cast (em);
-
-        
-        assertEquals(ByteArrayPKPCId.class,
-                pm.getObjectIdClass(ByteArrayPKPC.class));
-        assertEquals(ByteArrayPKPCId.class,
-                pm.getObjectIdClass(ByteArrayPKPC2.class));
-        pm.close();
-        em.close();
-    }
-    
-    /**
-     * Tests finding an instance by a manually-created id value.
-     */
-    public void testGetSubclassObjectById() {
-        ByteArrayPKPC2 bytes2 = getChild();
-        assertNotNull(bytes2);
-        assertEquals(1, bytes2.getPK()[0]);
-        assertEquals(2, bytes2.getPK()[1]);
-        assertEquals("child", bytes2.getStringField());
-        assertEquals("sub", bytes2.getSubfield());
-        assertNotNull(bytes2.getParent());
-        assertEquals(3, bytes2.getParent().getPK()[0]);
-        assertEquals(4, bytes2.getParent().getPK()[1]);
-        assertEquals("parent", bytes2.getParent().getStringField());
-        assertNull(bytes2.getParent().getParent());
-        //FIXME next line commented 
-        //JDOHelper.getPersistenceManager(bytes2).close();
-    }
-    
-    /**
-     * Tests finding an instance by a manually-created id value.
-     */
-    public void testGetObjectById() {
-        ByteArrayPKPC bytes = getParent();
-        assertNotNull(bytes);
-        assertEquals(3, bytes.getPK()[0]);
-        assertEquals(4, bytes.getPK()[1]);
-        assertEquals("parent", bytes.getStringField());
-        assertNull(bytes.getParent());
-        //FIXME next line commented 
-        //JDOHelper.getPersistenceManager(bytes).close();
-    }
-    
-    /**
-     * Tests that the oid instances returned from the pm are copied to
-     * prevent by-reference modification by the user.
-     */
-    public void testGetObjectId() {
-        
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        if (! ((OpenJPAEntityManagerSPI) kem).getConfiguration().getCompatibilityInstance().getCopyObjectIds())
-            return;
-        
-        ByteArrayPKPCId oid = new ByteArrayPKPCId();
-        oid.pk = new byte[]{ 1, 2 };
-        ByteArrayPKPC bytes = (ByteArrayPKPC) kem.getObjectId(oid);
-        ByteArrayPKPCId oidCopy = (ByteArrayPKPCId) kem.getObjectId(bytes);
-        assertTrue("Oid not copied.", oid != oidCopy);
-        assertEquals(1, oidCopy.pk[0]);
-        assertEquals(2, oidCopy.pk[1]);
-        
-        em.close();
-        kem.close();
-    }
-    
-    /**
-     * Tests that changing primary key values will fail.
-     */
-    public void testChangeIdentity() {
-        ByteArrayPKPC2 bytes = getChild();
-        OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(bytes);
-        startTx(pm);
-        
-        // make sure setting to same value is OK
-        bytes.setPK(bytes.getPK());
-        try {
-            bytes.setPK(new byte[]{ 5, 6 });
-            fail("Allowed changing of pk.");
-        } catch (Exception je) {
-        }
-        rollbackTx(pm);
-        pm.close();
-    }
-    
-    /**
-     * Tests that pk fields are retained on state transition to hollow.
-     */
-    public void testPKRetain() {
-        ByteArrayPKPC2 bytes = getChild();
-        OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(bytes);
-        
-        //FIXME next line commented .... need substitute API
-        //pm.currentTransaction().setNontransactionalRead(false);
-        
-        startTx(pm);
-        bytes.setParent(null);
-        endTx(pm);        
-        
-        // bytes should still allow access to oid fields
-        assertEquals(1, bytes.getPK()[0]);
-        assertEquals(2, bytes.getPK()[1]);
-        try {
-            bytes.getParent();
-            fail("Allowed read of non-pk value outside of transaction.");
-        } catch (Exception je) {
-        }
-        try {
-            bytes.setPK(new byte[]{ 5, 6 });
-            fail("Allowed setting of pk value outside of transaction.");
-        } catch (Exception je) {
-        }
-        pm.close();
-    }
-    
-    public void testDeleteAndInsert() {
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        
-        startTx(kem);
-       
-        for (int i = 0; i < 20; i++) {
-            ByteArrayPKPC bytes = new ByteArrayPKPC(new byte[]
-            { (byte) (i + 5), (byte) (i + 6) }, String.valueOf(i));
-            kem.persist(bytes);
-        }
-        endTx(kem);        
-        
-        kem.close();
-        
-        kem = _pmf.createEntityManager();
-        startTx(kem);
-        Extent extent = (Extent) kem.createExtent(ByteArrayPKPC.class,false);
-        kem.detachAll(extent.list());
-        extent.closeAll();
-        
-        ByteArrayPKPC owner = new ByteArrayPKPC();
-        kem.persist(owner);
-        owner.setPK(new byte[]{ 100, 101 });
-        owner.setStringField("owner");
-        
-        // make new instances with same oids persistent
-        for (int i = 0; i < 20; i++) {
-            ByteArrayPKPC bytes = new ByteArrayPKPC(new byte[]
-            { (byte) (i + 5), (byte) (i + 6) }, String.valueOf(i));
-            kem.persist(bytes);
-            assertEquals(bytes, getStateManager(bytes, kem).getManagedInstance());
-            owner.getRels().add(bytes);
-        }
-        
-        endTx(kem);  
-        
-        Object oid = kem.getObjectId(owner);
-        assertOwner(kem, oid);
-        kem.close();
-        
-        kem = _pmf.createEntityManager();
-        assertOwner(kem, oid);
-        em.close();
-        kem.close();
-    }
-    
-    public void testQuery() {
-        EntityManager pm = _pmf.createEntityManager();
-        //FIXME jthomas - partly commented 
-        //Query q = pm.newQuery(ByteArrayPKPC.class, "pk == bytes");
-        Query q =null;//= pm.newQuery(ByteArrayPKPC.class, "pk == bytes");
-        q.declareParameters("byte[] bytes");
-        //FIXME jthomas - no execute for byte 
-        //Collection results = (Collection) q.execute(new byte[]{ 1, 2 });
-        Collection results =null;//= (Collection) q.execute(new byte[]{ 1, 2 });
-        assertEquals(1, results.size());
-        ByteArrayPKPC2 child = (ByteArrayPKPC2) results.iterator().next();
-        assertEquals("child", child.getStringField());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testConflictingIds() {
-        OpenJPAEntityManager pm = _pmf.createEntityManager();
-        startTx(pm);     
-        
-        // make a bunch of objects persistent with the same initial pk values
-        ByteArrayPKPC owner = new ByteArrayPKPC();
-        pm.persist(owner);
-        owner.setPK(new byte[]{ 100, 101 });
-        owner.setStringField("owner");
-        for (int i = 0; i < 20; i++) {
-            ByteArrayPKPC bytes = new ByteArrayPKPC();
-            pm.persist(bytes);
-            assertEquals(bytes, getStateManager(bytes, pm).
-                    getManagedInstance());
-            bytes.setPK(new byte[]{ (byte) (i + 5), (byte) (i + 6) });
-            bytes.setStringField(String.valueOf(i));
-            owner.getRels().add(bytes);
-        }
-        endTx(pm);
-        Object oid = pm.getObjectId(owner);
-        assertOwner(pm, oid);
-        pm.close();
-        
-        pm = _pmf.createEntityManager();
-        assertOwner(pm, oid);
-        pm.close();
-    }
-    
-    private void assertOwner(OpenJPAEntityManager pm, Object oid) {
-        ByteArrayPKPC owner = (ByteArrayPKPC) pm.getObjectId(oid);
-        assertEquals(100, owner.getPK()[0]);
-        assertEquals(101, owner.getPK()[1]);
-        assertEquals("owner", owner.getStringField());
-        List rels = owner.getRels();
-        assertEquals(20, rels.size());
-        for (int i = 0; i < rels.size(); i++) {
-            ByteArrayPKPC bytes = (ByteArrayPKPC) rels.get(i);
-            assertEquals(i + 5, bytes.getPK()[0]);
-            assertEquals(i + 6, bytes.getPK()[1]);
-            assertEquals(String.valueOf(i), bytes.getStringField());
-        }
-    }
-    
-    private ByteArrayPKPC getParent() {
-        ByteArrayPKPCId oid = new ByteArrayPKPCId();
-        oid.pk = new byte[]{ 3, 4 };
-        OpenJPAEntityManager pm = _pmf.createEntityManager();
-        return (ByteArrayPKPC) pm.getObjectId(oid);
-    }
-    
-    private ByteArrayPKPC2 getChild() {
-        ByteArrayPKPCId oid = new ByteArrayPKPCId();
-        oid.pk = new byte[]{ 1, 2 };
-        OpenJPAEntityManager pm = _pmf.createEntityManager();
-        return (ByteArrayPKPC2) pm.getObjectId(oid);
-    }
-    
-    public static void main(String[] args) {
-       // main();
-    }
-    
-    private Map getProps() {
-        Map props=new HashMap();
-        props.put("openjpa.jdbc.DBDictionary", "");
-        props.put("UseGetBytesForBlobs", "true");
-        props.put("UseSetBytesForBlobs", "true");
-        props.put("BatchLimit", "0");
-        
-        return props;
-    }
-    
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+/*
+ * TestByteArrayAppId.java
+ *
+ * Created on October 2, 2006, 10:56 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import java.util.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.jdbc.meta.MappingTool;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.kernel.Extent;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.Query;
+
+
+public class TestByteArrayAppId extends BaseJDBCTest {
+    
+    private static boolean _init = false;
+    private OpenJPAEntityManagerFactory _pmf = null;
+    
+    
+    /** Creates a new instance of TestByteArrayAppId */
+    public TestByteArrayAppId(String name) 
+    {
+    	super(name);
+    }
+    
+    public boolean skipTest() {
+        return getCurrentPlatform() != AbstractTestCase.Platform.DB2;
+    }
+    
+    public void setUp()
+    throws Exception {
+        // we have to use getbytes/setbytes for byte arrays to work properly
+        _pmf =(OpenJPAEntityManagerFactory) getEmf(getProps());
+        
+        if (!_init) {
+            initialize((JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(_pmf)).getConfiguration());
+            _init = true;
+        }
+        EntityManager pm = _pmf.createEntityManager();
+        startTx(pm);
+        
+       deleteAll(ByteArrayPKPC.class,pm);
+        endTx(pm);
+        pm.close();
+        pm = currentEntityManager();
+        startTx(pm);
+        ByteArrayPKPC2 testBytes = new ByteArrayPKPC2(new byte[]{ 1, 2 },
+                "child");
+        testBytes.setSubfield("sub");
+        testBytes.setParent(new ByteArrayPKPC(new byte[]{ 3, 4 }, "parent"));
+        pm.persist(testBytes);
+        endTx(pm);
+        pm.close();
+    }
+    
+    public void tearDown()
+    throws Exception {
+        // closing the pmf every time slows things down too much b/c
+        // schema reflection is so slow on DB2
+        //	try { _pmf.close (); } catch (Exception e) {}
+        
+        super.tearDown();
+    }
+    
+    private void initialize(JDBCConfiguration conf)
+    throws Exception {
+        
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        //JDBCConfiguration conf = (JDBCConfiguration) kem.getConfiguration();        
+        
+        MappingTool tool = new MappingTool((JDBCConfiguration)
+        		((OpenJPAEntityManagerSPI) kem).getConfiguration(), MappingTool.ACTION_REFRESH, false);
+        tool.run(ByteArrayPKPC.class);
+        tool.run(ByteArrayPKPC2.class);
+        tool.record();
+    }
+    
+    /**
+     * Tests that application identity classes are returned correctly.
+     */
+    public void testGetObjectIdClass() {
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager pm = OpenJPAPersistence.cast (em);
+
+        
+        assertEquals(ByteArrayPKPCId.class,
+                pm.getObjectIdClass(ByteArrayPKPC.class));
+        assertEquals(ByteArrayPKPCId.class,
+                pm.getObjectIdClass(ByteArrayPKPC2.class));
+        pm.close();
+        em.close();
+    }
+    
+    /**
+     * Tests finding an instance by a manually-created id value.
+     */
+    public void testGetSubclassObjectById() {
+        ByteArrayPKPC2 bytes2 = getChild();
+        assertNotNull(bytes2);
+        assertEquals(1, bytes2.getPK()[0]);
+        assertEquals(2, bytes2.getPK()[1]);
+        assertEquals("child", bytes2.getStringField());
+        assertEquals("sub", bytes2.getSubfield());
+        assertNotNull(bytes2.getParent());
+        assertEquals(3, bytes2.getParent().getPK()[0]);
+        assertEquals(4, bytes2.getParent().getPK()[1]);
+        assertEquals("parent", bytes2.getParent().getStringField());
+        assertNull(bytes2.getParent().getParent());
+        //FIXME next line commented 
+        //JDOHelper.getPersistenceManager(bytes2).close();
+    }
+    
+    /**
+     * Tests finding an instance by a manually-created id value.
+     */
+    public void testGetObjectById() {
+        ByteArrayPKPC bytes = getParent();
+        assertNotNull(bytes);
+        assertEquals(3, bytes.getPK()[0]);
+        assertEquals(4, bytes.getPK()[1]);
+        assertEquals("parent", bytes.getStringField());
+        assertNull(bytes.getParent());
+        //FIXME next line commented 
+        //JDOHelper.getPersistenceManager(bytes).close();
+    }
+    
+    /**
+     * Tests that the oid instances returned from the pm are copied to
+     * prevent by-reference modification by the user.
+     */
+    public void testGetObjectId() {
+        
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        if (! ((OpenJPAEntityManagerSPI) kem).getConfiguration().getCompatibilityInstance().getCopyObjectIds())
+            return;
+        
+        ByteArrayPKPCId oid = new ByteArrayPKPCId();
+        oid.pk = new byte[]{ 1, 2 };
+        ByteArrayPKPC bytes = (ByteArrayPKPC) kem.getObjectId(oid);
+        ByteArrayPKPCId oidCopy = (ByteArrayPKPCId) kem.getObjectId(bytes);
+        assertTrue("Oid not copied.", oid != oidCopy);
+        assertEquals(1, oidCopy.pk[0]);
+        assertEquals(2, oidCopy.pk[1]);
+        
+        em.close();
+        kem.close();
+    }
+    
+    /**
+     * Tests that changing primary key values will fail.
+     */
+    public void testChangeIdentity() {
+        ByteArrayPKPC2 bytes = getChild();
+        OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(bytes);
+        startTx(pm);
+        
+        // make sure setting to same value is OK
+        bytes.setPK(bytes.getPK());
+        try {
+            bytes.setPK(new byte[]{ 5, 6 });
+            fail("Allowed changing of pk.");
+        } catch (Exception je) {
+        }
+        rollbackTx(pm);
+        pm.close();
+    }
+    
+    /**
+     * Tests that pk fields are retained on state transition to hollow.
+     */
+    public void testPKRetain() {
+        ByteArrayPKPC2 bytes = getChild();
+        OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(bytes);
+        
+        //FIXME next line commented .... need substitute API
+        //pm.currentTransaction().setNontransactionalRead(false);
+        
+        startTx(pm);
+        bytes.setParent(null);
+        endTx(pm);        
+        
+        // bytes should still allow access to oid fields
+        assertEquals(1, bytes.getPK()[0]);
+        assertEquals(2, bytes.getPK()[1]);
+        try {
+            bytes.getParent();
+            fail("Allowed read of non-pk value outside of transaction.");
+        } catch (Exception je) {
+        }
+        try {
+            bytes.setPK(new byte[]{ 5, 6 });
+            fail("Allowed setting of pk value outside of transaction.");
+        } catch (Exception je) {
+        }
+        pm.close();
+    }
+    
+    public void testDeleteAndInsert() {
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        
+        startTx(kem);
+       
+        for (int i = 0; i < 20; i++) {
+            ByteArrayPKPC bytes = new ByteArrayPKPC(new byte[]
+            { (byte) (i + 5), (byte) (i + 6) }, String.valueOf(i));
+            kem.persist(bytes);
+        }
+        endTx(kem);        
+        
+        kem.close();
+        
+        kem = _pmf.createEntityManager();
+        startTx(kem);
+        Extent extent = (Extent) kem.createExtent(ByteArrayPKPC.class,false);
+        kem.detachAll(extent.list());
+        extent.closeAll();
+        
+        ByteArrayPKPC owner = new ByteArrayPKPC();
+        kem.persist(owner);
+        owner.setPK(new byte[]{ 100, 101 });
+        owner.setStringField("owner");
+        
+        // make new instances with same oids persistent
+        for (int i = 0; i < 20; i++) {
+            ByteArrayPKPC bytes = new ByteArrayPKPC(new byte[]
+            { (byte) (i + 5), (byte) (i + 6) }, String.valueOf(i));
+            kem.persist(bytes);
+            assertEquals(bytes, getStateManager(bytes, kem).getManagedInstance());
+            owner.getRels().add(bytes);
+        }
+        
+        endTx(kem);  
+        
+        Object oid = kem.getObjectId(owner);
+        assertOwner(kem, oid);
+        kem.close();
+        
+        kem = _pmf.createEntityManager();
+        assertOwner(kem, oid);
+        em.close();
+        kem.close();
+    }
+    
+    public void testQuery() {
+        EntityManager pm = _pmf.createEntityManager();
+        //FIXME jthomas - partly commented 
+        //Query q = pm.newQuery(ByteArrayPKPC.class, "pk == bytes");
+        Query q =null;//= pm.newQuery(ByteArrayPKPC.class, "pk == bytes");
+        q.declareParameters("byte[] bytes");
+        //FIXME jthomas - no execute for byte 
+        //Collection results = (Collection) q.execute(new byte[]{ 1, 2 });
+        Collection results =null;//= (Collection) q.execute(new byte[]{ 1, 2 });
+        assertEquals(1, results.size());
+        ByteArrayPKPC2 child = (ByteArrayPKPC2) results.iterator().next();
+        assertEquals("child", child.getStringField());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testConflictingIds() {
+        OpenJPAEntityManager pm = _pmf.createEntityManager();
+        startTx(pm);     
+        
+        // make a bunch of objects persistent with the same initial pk values
+        ByteArrayPKPC owner = new ByteArrayPKPC();
+        pm.persist(owner);
+        owner.setPK(new byte[]{ 100, 101 });
+        owner.setStringField("owner");
+        for (int i = 0; i < 20; i++) {
+            ByteArrayPKPC bytes = new ByteArrayPKPC();
+            pm.persist(bytes);
+            assertEquals(bytes, getStateManager(bytes, pm).
+                    getManagedInstance());
+            bytes.setPK(new byte[]{ (byte) (i + 5), (byte) (i + 6) });
+            bytes.setStringField(String.valueOf(i));
+            owner.getRels().add(bytes);
+        }
+        endTx(pm);
+        Object oid = pm.getObjectId(owner);
+        assertOwner(pm, oid);
+        pm.close();
+        
+        pm = _pmf.createEntityManager();
+        assertOwner(pm, oid);
+        pm.close();
+    }
+    
+    private void assertOwner(OpenJPAEntityManager pm, Object oid) {
+        ByteArrayPKPC owner = (ByteArrayPKPC) pm.getObjectId(oid);
+        assertEquals(100, owner.getPK()[0]);
+        assertEquals(101, owner.getPK()[1]);
+        assertEquals("owner", owner.getStringField());
+        List rels = owner.getRels();
+        assertEquals(20, rels.size());
+        for (int i = 0; i < rels.size(); i++) {
+            ByteArrayPKPC bytes = (ByteArrayPKPC) rels.get(i);
+            assertEquals(i + 5, bytes.getPK()[0]);
+            assertEquals(i + 6, bytes.getPK()[1]);
+            assertEquals(String.valueOf(i), bytes.getStringField());
+        }
+    }
+    
+    private ByteArrayPKPC getParent() {
+        ByteArrayPKPCId oid = new ByteArrayPKPCId();
+        oid.pk = new byte[]{ 3, 4 };
+        OpenJPAEntityManager pm = _pmf.createEntityManager();
+        return (ByteArrayPKPC) pm.getObjectId(oid);
+    }
+    
+    private ByteArrayPKPC2 getChild() {
+        ByteArrayPKPCId oid = new ByteArrayPKPCId();
+        oid.pk = new byte[]{ 1, 2 };
+        OpenJPAEntityManager pm = _pmf.createEntityManager();
+        return (ByteArrayPKPC2) pm.getObjectId(oid);
+    }
+    
+    public static void main(String[] args) {
+       // main();
+    }
+    
+    private Map getProps() {
+        Map props=new HashMap();
+        props.put("openjpa.jdbc.DBDictionary", "");
+        props.put("UseGetBytesForBlobs", "true");
+        props.put("UseSetBytesForBlobs", "true");
+        props.put("BatchLimit", "0");
+        
+        return props;
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestCircularFK.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestCircularFK.java
index a3264be..5427d81 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestCircularFK.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestCircularFK.java
@@ -1,139 +1,139 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestCircularFK extends BaseJDBCTest{
-    
-    private Object _oid1 = null;
-    private Object _oid2 = null;
-    
-    public TestCircularFK(String name) {
-        super(name);
-    }
-    
-    /** Creates a new instance of TestCircularFK */
-    public TestCircularFK() {
-    }
-    
-    public void setUp() {
-        OpenJPAEntityManager pm = getPM();
-        
-        startTx(pm);
-       deleteAll(CircularFKPC.class,pm);
-       deleteAll(CircularFKPC2.class,pm);
-        endTx(pm);
-        endEm(pm);
-        
-        
-        CircularFKPC pc1 = new CircularFKPC();
-        pc1.setStringField("pc1");
-        CircularFKPC2 pc2 = new CircularFKPC2();
-        pc2.setStringField("pc2");
-        pc1.setFKField(pc2);
-        pc2.setFKField(pc1);
-        
-        pm = getPM();
-        startTx(pm);
-        pm.persist(pc1);
-        endTx(pm);
-        _oid1 = pm.getObjectId(pc1);
-        _oid2 = pm.getObjectId(pc2);
-        endEm(pm);
-    }
-    
-    public void testInsert() {
-        // inserts are tested in setup; just make sure the inserts
-        // actually worked
-        OpenJPAEntityManager pm = getPM();
-        CircularFKPC pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
-        CircularFKPC2 pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
-        assertNotNull(pc1);
-        assertNotNull(pc2);
-        assertEquals("pc1", pc1.getStringField());
-        assertEquals("pc2", pc2.getStringField());
-        assertEquals(pc2, pc1.getFKField());
-        assertEquals(pc1, pc2.getFKField());
-        pm.close();
-    }
-    
-    public void testDelete() {
-        OpenJPAEntityManager pm = getPM();
-        CircularFKPC pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
-        CircularFKPC2 pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
-        startTx(pm);
-        pm.remove(pc1);
-        pm.remove(pc2);
-        endTx(pm);
-        endEm(pm);
-        
-        pm = getPM();
-        try {
-            pm.find(CircularFKPC.class,_oid1);
-            fail("PC1 still exists!");
-        } catch (Exception jdse) {
-        }
-        try {
-            pm.find(CircularFKPC2.class,_oid2);
-            fail("PC2 still exists!");
-        } catch (Exception jdse) {
-        }
-        endEm(pm);
-    }
-    
-    public void testUpdate() {
-        OpenJPAEntityManager pm = getPM();
-        CircularFKPC pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
-        CircularFKPC2 pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
-        
-        startTx(pm);;
-        CircularFKPC2 pc3 = new CircularFKPC2();
-        pc3.setStringField("pc3");
-        pc3.setFKField(pc1);
-        pc1.setFKField(pc3);
-        pc2.setFKField(null);
-        endTx(pm);;
-        pm.close();
-        
-        pm = getPM();
-        pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
-        pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
-        assertNotNull(pc1);
-        assertNotNull(pc2);
-        assertEquals("pc1", pc1.getStringField());
-        assertEquals("pc2", pc2.getStringField());
-        assertNotNull(pc1.getFKField());
-        assertEquals("pc3", pc1.getFKField().getStringField());
-        assertEquals(pc1, pc1.getFKField().getFKField());
-        assertNull(pc2.getFKField());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestCircularFK extends BaseJDBCTest{
+    
+    private Object _oid1 = null;
+    private Object _oid2 = null;
+    
+    public TestCircularFK(String name) {
+        super(name);
+    }
+    
+    /** Creates a new instance of TestCircularFK */
+    public TestCircularFK() {
+    }
+    
+    public void setUp() {
+        OpenJPAEntityManager pm = getPM();
+        
+        startTx(pm);
+       deleteAll(CircularFKPC.class,pm);
+       deleteAll(CircularFKPC2.class,pm);
+        endTx(pm);
+        endEm(pm);
+        
+        
+        CircularFKPC pc1 = new CircularFKPC();
+        pc1.setStringField("pc1");
+        CircularFKPC2 pc2 = new CircularFKPC2();
+        pc2.setStringField("pc2");
+        pc1.setFKField(pc2);
+        pc2.setFKField(pc1);
+        
+        pm = getPM();
+        startTx(pm);
+        pm.persist(pc1);
+        endTx(pm);
+        _oid1 = pm.getObjectId(pc1);
+        _oid2 = pm.getObjectId(pc2);
+        endEm(pm);
+    }
+    
+    public void testInsert() {
+        // inserts are tested in setup; just make sure the inserts
+        // actually worked
+        OpenJPAEntityManager pm = getPM();
+        CircularFKPC pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
+        CircularFKPC2 pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
+        assertNotNull(pc1);
+        assertNotNull(pc2);
+        assertEquals("pc1", pc1.getStringField());
+        assertEquals("pc2", pc2.getStringField());
+        assertEquals(pc2, pc1.getFKField());
+        assertEquals(pc1, pc2.getFKField());
+        pm.close();
+    }
+    
+    public void testDelete() {
+        OpenJPAEntityManager pm = getPM();
+        CircularFKPC pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
+        CircularFKPC2 pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
+        startTx(pm);
+        pm.remove(pc1);
+        pm.remove(pc2);
+        endTx(pm);
+        endEm(pm);
+        
+        pm = getPM();
+        try {
+            pm.find(CircularFKPC.class,_oid1);
+            fail("PC1 still exists!");
+        } catch (Exception jdse) {
+        }
+        try {
+            pm.find(CircularFKPC2.class,_oid2);
+            fail("PC2 still exists!");
+        } catch (Exception jdse) {
+        }
+        endEm(pm);
+    }
+    
+    public void testUpdate() {
+        OpenJPAEntityManager pm = getPM();
+        CircularFKPC pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
+        CircularFKPC2 pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
+        
+        startTx(pm);;
+        CircularFKPC2 pc3 = new CircularFKPC2();
+        pc3.setStringField("pc3");
+        pc3.setFKField(pc1);
+        pc1.setFKField(pc3);
+        pc2.setFKField(null);
+        endTx(pm);;
+        pm.close();
+        
+        pm = getPM();
+        pc1 = (CircularFKPC) pm.find(CircularFKPC.class,_oid1);
+        pc2 = (CircularFKPC2) pm.find(CircularFKPC2.class,_oid2);
+        assertNotNull(pc1);
+        assertNotNull(pc2);
+        assertEquals("pc1", pc1.getStringField());
+        assertEquals("pc2", pc2.getStringField());
+        assertNotNull(pc1.getFKField());
+        assertEquals("pc3", pc1.getFKField().getStringField());
+        assertEquals(pc1, pc1.getFKField().getFKField());
+        assertNull(pc2.getFKField());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestDataStoreTrips.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestDataStoreTrips.java
index 240a1da..acc5341 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestDataStoreTrips.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestDataStoreTrips.java
@@ -1,199 +1,199 @@
-/*
- * TestDataStoreTrips.java
- *
- * Created on September 29, 2006, 4:48 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
-import org.apache.openjpa.lib.jdbc.JDBCEvent;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.persistence.Extent;
-
-
-
-public class TestDataStoreTrips extends BaseJDBCTest{
-
-
-//    private boolean  = true;//Boolean.valueOf(bool);
-	
-    private OpenJPAEntityManagerFactory _factory = null;
-    private Object _oid = null;
-    private SelectCounter _counter = null;
-    
-    /** Creates a new instance of TestDataStoreTrips */
-    public TestDataStoreTrips() {
-    }
-    public TestDataStoreTrips(String name) {
-        super(name);
-    }
-    
-    public void setUp()
-        throws Exception {
-       deleteAll(DataStoreTripsPC.class);
-
-        // figure out what table to look for in SQL statements
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) kem).getConfiguration();        
-
-        ClassMapping mapping = conf.getMappingRepositoryInstance().getMapping
-            (DataStoreTripsPC.class, null, true);
-        String table = conf.getDBDictionaryInstance()
-            .getFullName(mapping.getTable(), false);
-
-        // get factory with counter listener
-        _factory = getEmf();
-/*                getPMFactory(new String[]{
-            "openjpa.jdbc.JDBCListeners",
-            SelectCounter.class.getName() + "(Table=" + table + ")",
-            "openjpa.Compatibility",
-            "ValidateTrueChecksStore=true"
-        });
-*/
-        
-        OpenJPAEntityManager pm = _factory.createEntityManager();
-        startTx(pm);
-        
-        DataStoreTripsPC pc = new DataStoreTripsPC(0);
-        pm.persist(pc);
-        _oid = pm.getObjectId(pc);
-
-        for (int i = 1; i < 10; i++)
-              pm.persist(new DataStoreTripsPC(i));
-        endTx(pm);
-        em.close();
-
-        // do a query so that the subclass list will get initialized and
-        // won't count as a select
-        pm = _factory.createEntityManager();
-        pm.getObjectId(_oid);
-        pm.close();
-
-        _counter = (SelectCounter) ((JDBCConfiguration)
-        		((OpenJPAEntityManagerFactorySPI) _factory).getConfiguration()).getJDBCListenerInstances()[0];
-        _counter.selects = 0;
-        _counter.counts = 0;
-    }
-
-    public void testTrips() {
-        OpenJPAEntityManager pm = _factory.createEntityManager();
-        Extent ext = pm.createExtent(DataStoreTripsPC.class, true);
-        for (Iterator itr = ext.iterator(); itr.hasNext();)
-            itr.next();
-        ext.closeAll();
-        pm.close();
-
-        // there might be more than 1 trip if subclasses need to be
-        // initialized and so forth, but make sure there isn't more than
-        // 1 + # objects trips to the DB
-        assertTrue(_counter.selects > 0);
-        assertTrue("Should have been 1-3 trips to the data store; got "
-            + _counter.selects, _counter.selects < 5);
-    }
-
-    public void testExistsCalls() {
-        OpenJPAEntityManager pm = _factory.createEntityManager();
-
-        // first time there shouldn't be any call to exists b/c the data
-        // needs to be loaded
-        pm.getObjectId(_oid);
-        assertEquals(0, _counter.counts);
-        assertEquals(1, _counter.selects);
-
-        // this time there should be a call b/c data is already loaded but
-        // we're still asking to validate
-        pm.getObjectId(_oid);
-        assertEquals(1, _counter.counts);
-        assertEquals(2, _counter.selects);
-        pm.getObjectId(_oid);
-        assertEquals(2, _counter.counts);
-        assertEquals(3, _counter.selects);
-
-        // shouldn't be a call if validate is false; no select b/c data loaded
-        pm.getObjectId(_oid);
-        assertEquals(2, _counter.counts);
-        assertEquals(3, _counter.selects);
-
-        // this will hollow the object
-        //FIXME jthomas ...need to find a substitute
-        //pm.currentTransaction().setOptimistic(false);
-        startTx(pm);
-        
-
-        // no count call b/c loading data
-        pm.getObjectId(_oid);
-        assertEquals(2, _counter.counts);
-        assertEquals(4, _counter.selects);
-
-        // no count call b/c transactional; no select b/c data loaded
-        pm.getObjectId(_oid);
-        assertEquals(2, _counter.counts);
-        assertEquals(4, _counter.selects);
-
-        rollbackTx(pm);
-        pm.close();
-    }
-
-    public static class SelectCounter
-        extends AbstractJDBCListener {
-
-        public int selects = 0;
-        public int counts = 0;
-
-        private String _table = null;
-
-        public void setTable(String table) {
-            _table = table;
-        }
-
-        public void beforeExecuteStatement(JDBCEvent event) {
-            if (event.getSQL().indexOf(_table) != -1)
-                selects++;
-            {
-                if (event.getSQL().indexOf(" COUNT(") != -1)
-                    counts++;
-            }
-        }
-    }
-    
-    
-}
+/*
+ * TestDataStoreTrips.java
+ *
+ * Created on September 29, 2006, 4:48 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
+import org.apache.openjpa.lib.jdbc.JDBCEvent;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.persistence.Extent;
+
+
+
+public class TestDataStoreTrips extends BaseJDBCTest{
+
+
+//    private boolean  = true;//Boolean.valueOf(bool);
+	
+    private OpenJPAEntityManagerFactory _factory = null;
+    private Object _oid = null;
+    private SelectCounter _counter = null;
+    
+    /** Creates a new instance of TestDataStoreTrips */
+    public TestDataStoreTrips() {
+    }
+    public TestDataStoreTrips(String name) {
+        super(name);
+    }
+    
+    public void setUp()
+        throws Exception {
+       deleteAll(DataStoreTripsPC.class);
+
+        // figure out what table to look for in SQL statements
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) kem).getConfiguration();        
+
+        ClassMapping mapping = conf.getMappingRepositoryInstance().getMapping
+            (DataStoreTripsPC.class, null, true);
+        String table = conf.getDBDictionaryInstance()
+            .getFullName(mapping.getTable(), false);
+
+        // get factory with counter listener
+        _factory = getEmf();
+/*                getPMFactory(new String[]{
+            "openjpa.jdbc.JDBCListeners",
+            SelectCounter.class.getName() + "(Table=" + table + ")",
+            "openjpa.Compatibility",
+            "ValidateTrueChecksStore=true"
+        });
+*/
+        
+        OpenJPAEntityManager pm = _factory.createEntityManager();
+        startTx(pm);
+        
+        DataStoreTripsPC pc = new DataStoreTripsPC(0);
+        pm.persist(pc);
+        _oid = pm.getObjectId(pc);
+
+        for (int i = 1; i < 10; i++)
+              pm.persist(new DataStoreTripsPC(i));
+        endTx(pm);
+        em.close();
+
+        // do a query so that the subclass list will get initialized and
+        // won't count as a select
+        pm = _factory.createEntityManager();
+        pm.getObjectId(_oid);
+        pm.close();
+
+        _counter = (SelectCounter) ((JDBCConfiguration)
+        		((OpenJPAEntityManagerFactorySPI) _factory).getConfiguration()).getJDBCListenerInstances()[0];
+        _counter.selects = 0;
+        _counter.counts = 0;
+    }
+
+    public void testTrips() {
+        OpenJPAEntityManager pm = _factory.createEntityManager();
+        Extent ext = pm.createExtent(DataStoreTripsPC.class, true);
+        for (Iterator itr = ext.iterator(); itr.hasNext();)
+            itr.next();
+        ext.closeAll();
+        pm.close();
+
+        // there might be more than 1 trip if subclasses need to be
+        // initialized and so forth, but make sure there isn't more than
+        // 1 + # objects trips to the DB
+        assertTrue(_counter.selects > 0);
+        assertTrue("Should have been 1-3 trips to the data store; got "
+            + _counter.selects, _counter.selects < 5);
+    }
+
+    public void testExistsCalls() {
+        OpenJPAEntityManager pm = _factory.createEntityManager();
+
+        // first time there shouldn't be any call to exists b/c the data
+        // needs to be loaded
+        pm.getObjectId(_oid);
+        assertEquals(0, _counter.counts);
+        assertEquals(1, _counter.selects);
+
+        // this time there should be a call b/c data is already loaded but
+        // we're still asking to validate
+        pm.getObjectId(_oid);
+        assertEquals(1, _counter.counts);
+        assertEquals(2, _counter.selects);
+        pm.getObjectId(_oid);
+        assertEquals(2, _counter.counts);
+        assertEquals(3, _counter.selects);
+
+        // shouldn't be a call if validate is false; no select b/c data loaded
+        pm.getObjectId(_oid);
+        assertEquals(2, _counter.counts);
+        assertEquals(3, _counter.selects);
+
+        // this will hollow the object
+        //FIXME jthomas ...need to find a substitute
+        //pm.currentTransaction().setOptimistic(false);
+        startTx(pm);
+        
+
+        // no count call b/c loading data
+        pm.getObjectId(_oid);
+        assertEquals(2, _counter.counts);
+        assertEquals(4, _counter.selects);
+
+        // no count call b/c transactional; no select b/c data loaded
+        pm.getObjectId(_oid);
+        assertEquals(2, _counter.counts);
+        assertEquals(4, _counter.selects);
+
+        rollbackTx(pm);
+        pm.close();
+    }
+
+    public static class SelectCounter
+        extends AbstractJDBCListener {
+
+        public int selects = 0;
+        public int counts = 0;
+
+        private String _table = null;
+
+        public void setTable(String table) {
+            _table = table;
+        }
+
+        public void beforeExecuteStatement(JDBCEvent event) {
+            if (event.getSQL().indexOf(_table) != -1)
+                selects++;
+            {
+                if (event.getSQL().indexOf(" COUNT(") != -1)
+                    counts++;
+            }
+        }
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEJBAutoIncrement.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEJBAutoIncrement.java
index cc89f21..96cafa7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEJBAutoIncrement.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEJBAutoIncrement.java
@@ -1,238 +1,238 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC1;
-import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC2;
-import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3;
-import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3Id;
-
-import junit.framework.*;
-
-public class TestEJBAutoIncrement extends BaseJDBCTest
-{
-
-//	private boolean  = Boolean.valueOf(bool);
-
-	private int oid2;
-	private long oid3;
-	private long oid4, oid2a, oid2b, oid3b;
-	private long oid3a;
-
-	public TestEJBAutoIncrement(String name)
-	{
-		super(name);
-	}
-
-	public void setUp()
-	{
-		deleteAll(AutoIncrementPC1.class);
-		deleteAll(AutoIncrementPC2.class);
-		deleteAll(AutoIncrementPC3.class);
-	}
-
-	@SuppressWarnings("unchecked")
-	public void testInsert ()
-	{
-		AutoIncrementPC2 pc1 = new AutoIncrementPC2 (1);
-		pc1.setStringField ("pc1");
-		pc1.setIntField (1);
-		pc1.getSetField ().add ("string1");
-		pc1.getSetField ().add ("string2");
-
-		AutoIncrementPC2 pc2 = new AutoIncrementPC2 (2);
-		pc2.setStringField ("pc2");
-		pc2.setIntField (2);
-		pc2.getSetField ().add ("string3");
-		pc2.getSetField ().add ("string4");
-
-		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (3);
-		pc3.setStringField ("pc3");
-		pc3.getSetField ().add ("string5");
-		pc3.getSetField ().add ("string6");
-
-		AutoIncrementPC3 pc4 = new AutoIncrementPC3 (4);
-		pc4.setStringField ("pc4");
-		pc4.getSetField ().add ("string7");
-		pc4.getSetField ().add ("string8");
-
-		EntityManager em = currentEntityManager();
-		startTx(em);
-		em.persist(pc1);
-		em.persist(pc2);
-		em.persist(pc3);
-		em.persist(pc4);
-		oid2 = pc2.getId();
-		oid4 = pc4.getId();
-
-		assertEquals (pc2, em.find(AutoIncrementPC2.class, oid2));
-		assertEquals (pc4, em.find(AutoIncrementPC3.class, oid4));
-		endTx(em);
-		endEm(em);
-
-		em = currentEntityManager();
-		startTx(em);
-		pc2 = em.find(AutoIncrementPC2.class, 2);
-		pc4 = em.find(AutoIncrementPC3.class, 4);
-		assertEquals ("pc2", pc2.getStringField ());
-		assertEquals (2, pc2.getIntField ());
-		assertEquals ("pc4", pc4.getStringField ());
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testUpdate ()
-	{
-		AutoIncrementPC2 pc2 = new AutoIncrementPC2 (1);
-		pc2.setStringField ("pc2");
-		pc2.setIntField (2);
-		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (2);
-		pc3.setStringField ("pc3");
-
-		EntityManager em = currentEntityManager();
-		startTx(em);
-		em.persist (pc2);
-		em.persist (pc3);
-		endTx(em);
-
-		oid2 = pc2.getId();
-		oid3 = pc3.getId();
-		endEm(em);
-
-		em = currentEntityManager();
-		startTx(em);
-		pc2 = em.find(AutoIncrementPC2.class, oid2);
-		pc3 = em.find(AutoIncrementPC3.class, oid3);
-		assertEquals ("pc2", pc2.getStringField ());
-		assertEquals (2, pc2.getIntField ());
-		assertEquals ("pc3", pc3.getStringField ());
-		pc2.setStringField ("pc2a");
-		pc2.setIntField (3);
-		pc3.setStringField ("pc3a");
-		endTx(em);
-		endEm(em);
-
-		em = currentEntityManager();
-		startTx(em);
-		pc2 = em.find(AutoIncrementPC2.class, oid2);
-		pc3 = em.find(AutoIncrementPC3.class, oid3);
-		assertEquals ("pc2a", pc2.getStringField ());
-		assertEquals (3, pc2.getIntField ());
-		assertEquals ("pc3a", pc3.getStringField ());
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testCircularReferences ()
-	{
-		AutoIncrementPC2 pc2a = new AutoIncrementPC2 (1);
-		pc2a.setStringField ("pc2a");
-		pc2a.setIntField (1);
-		AutoIncrementPC2 pc2b = new AutoIncrementPC2 (2);
-		pc2b.setStringField ("pc2b");
-		pc2b.setIntField (2);
-		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (3);
-		pc3.setStringField ("pc3");
-
-		pc2a.setOneOne (pc2b);
-		pc2b.setOneOne (pc2a);
-		pc3.setOneOne (pc3);
-
-		EntityManager em = currentEntityManager();
-		startTx(em);
-		em.persist (pc2a);
-		em.persist (pc2b);
-		em.persist (pc3);
-		endTx(em);
-		oid2a = pc2a.getId();
-		oid2b = pc2b.getId();
-	    oid3 = pc3.getId();
-		endEm(em);
-
-		em = currentEntityManager();
-		startTx(em);
-		pc2a = em.find(AutoIncrementPC2.class, oid2a);
-		pc2b = em.find(AutoIncrementPC2.class, oid2b);
-		pc3 = em.find(AutoIncrementPC3.class, oid3);
-		assertEquals ("pc2a", pc2a.getStringField ());
-		assertEquals (1, pc2a.getIntField ());
-		assertEquals ("pc2b", pc2b.getStringField ());
-		assertEquals (2, pc2b.getIntField ());
-		assertEquals ("pc3", pc3.getStringField ());
-		assertEquals (pc2b, pc2a.getOneOne ());
-		assertEquals (pc2a, pc2b.getOneOne ());
-		assertEquals (pc3, pc3.getOneOne ());
-		endTx(em);
-		endEm(em);
-	}
-
-	public void testMultipleFlushes ()
-	{
-		AutoIncrementPC2 pc2 = new AutoIncrementPC2 (1);
-		pc2.setStringField ("pc2");
-		pc2.setIntField (2);
-		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (2);
-		pc3.setStringField ("pc3");
-
-		EntityManager em = currentEntityManager();
-		startTx(em);
-		em.persist (pc2);
-		em.persist (pc3);
-		oid2 = pc2.getId();
-		oid3 = pc3.getId();
-		em.flush ();
-
-	    oid2a = pc2.getId();
-		oid3a = pc3.getId();
-		assertEquals (oid2, oid2a);
-		assertEquals (oid3, oid3a);
-		long id = pc3.getId ();
-		assertEquals (pc2, em.find(AutoIncrementPC2.class, oid2a));
-		assertEquals (pc3, em.find(AutoIncrementPC3.class, oid3a));
-		pc2.setStringField ("pc2a");
-		pc2.setIntField (3);
-		pc3.setStringField ("pc3a");
-		em.flush ();
-
-		oid2b = pc2.getId();
-		oid3b = pc3.getId();
-		assertEquals (oid2, oid2b);
-		assertEquals (oid3, oid3b);
-		assertEquals (id, pc3.getId ());
-		assertEquals (pc2, em.find(AutoIncrementPC2.class, oid2b));
-		assertEquals (pc3, em.find(AutoIncrementPC3.class, oid3b));
-		endTx(em);
-		endEm(em);
-
-		em = currentEntityManager();
-		startTx(em);
-		pc2 = em.find(AutoIncrementPC2.class, oid2b);
-		pc3 = em.find(AutoIncrementPC3.class, oid3b);
-		assertEquals ("pc2a", pc2.getStringField ());
-		assertEquals (3, pc2.getIntField ());
-		assertEquals ("pc3a", pc3.getStringField ());
-		assertEquals (id, pc3.getId ());
-		endTx(em);
-		endEm(em);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC1;
+import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC2;
+import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3;
+import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3Id;
+
+import junit.framework.*;
+
+public class TestEJBAutoIncrement extends BaseJDBCTest
+{
+
+//	private boolean  = Boolean.valueOf(bool);
+
+	private int oid2;
+	private long oid3;
+	private long oid4, oid2a, oid2b, oid3b;
+	private long oid3a;
+
+	public TestEJBAutoIncrement(String name)
+	{
+		super(name);
+	}
+
+	public void setUp()
+	{
+		deleteAll(AutoIncrementPC1.class);
+		deleteAll(AutoIncrementPC2.class);
+		deleteAll(AutoIncrementPC3.class);
+	}
+
+	@SuppressWarnings("unchecked")
+	public void testInsert ()
+	{
+		AutoIncrementPC2 pc1 = new AutoIncrementPC2 (1);
+		pc1.setStringField ("pc1");
+		pc1.setIntField (1);
+		pc1.getSetField ().add ("string1");
+		pc1.getSetField ().add ("string2");
+
+		AutoIncrementPC2 pc2 = new AutoIncrementPC2 (2);
+		pc2.setStringField ("pc2");
+		pc2.setIntField (2);
+		pc2.getSetField ().add ("string3");
+		pc2.getSetField ().add ("string4");
+
+		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (3);
+		pc3.setStringField ("pc3");
+		pc3.getSetField ().add ("string5");
+		pc3.getSetField ().add ("string6");
+
+		AutoIncrementPC3 pc4 = new AutoIncrementPC3 (4);
+		pc4.setStringField ("pc4");
+		pc4.getSetField ().add ("string7");
+		pc4.getSetField ().add ("string8");
+
+		EntityManager em = currentEntityManager();
+		startTx(em);
+		em.persist(pc1);
+		em.persist(pc2);
+		em.persist(pc3);
+		em.persist(pc4);
+		oid2 = pc2.getId();
+		oid4 = pc4.getId();
+
+		assertEquals (pc2, em.find(AutoIncrementPC2.class, oid2));
+		assertEquals (pc4, em.find(AutoIncrementPC3.class, oid4));
+		endTx(em);
+		endEm(em);
+
+		em = currentEntityManager();
+		startTx(em);
+		pc2 = em.find(AutoIncrementPC2.class, 2);
+		pc4 = em.find(AutoIncrementPC3.class, 4);
+		assertEquals ("pc2", pc2.getStringField ());
+		assertEquals (2, pc2.getIntField ());
+		assertEquals ("pc4", pc4.getStringField ());
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testUpdate ()
+	{
+		AutoIncrementPC2 pc2 = new AutoIncrementPC2 (1);
+		pc2.setStringField ("pc2");
+		pc2.setIntField (2);
+		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (2);
+		pc3.setStringField ("pc3");
+
+		EntityManager em = currentEntityManager();
+		startTx(em);
+		em.persist (pc2);
+		em.persist (pc3);
+		endTx(em);
+
+		oid2 = pc2.getId();
+		oid3 = pc3.getId();
+		endEm(em);
+
+		em = currentEntityManager();
+		startTx(em);
+		pc2 = em.find(AutoIncrementPC2.class, oid2);
+		pc3 = em.find(AutoIncrementPC3.class, oid3);
+		assertEquals ("pc2", pc2.getStringField ());
+		assertEquals (2, pc2.getIntField ());
+		assertEquals ("pc3", pc3.getStringField ());
+		pc2.setStringField ("pc2a");
+		pc2.setIntField (3);
+		pc3.setStringField ("pc3a");
+		endTx(em);
+		endEm(em);
+
+		em = currentEntityManager();
+		startTx(em);
+		pc2 = em.find(AutoIncrementPC2.class, oid2);
+		pc3 = em.find(AutoIncrementPC3.class, oid3);
+		assertEquals ("pc2a", pc2.getStringField ());
+		assertEquals (3, pc2.getIntField ());
+		assertEquals ("pc3a", pc3.getStringField ());
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testCircularReferences ()
+	{
+		AutoIncrementPC2 pc2a = new AutoIncrementPC2 (1);
+		pc2a.setStringField ("pc2a");
+		pc2a.setIntField (1);
+		AutoIncrementPC2 pc2b = new AutoIncrementPC2 (2);
+		pc2b.setStringField ("pc2b");
+		pc2b.setIntField (2);
+		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (3);
+		pc3.setStringField ("pc3");
+
+		pc2a.setOneOne (pc2b);
+		pc2b.setOneOne (pc2a);
+		pc3.setOneOne (pc3);
+
+		EntityManager em = currentEntityManager();
+		startTx(em);
+		em.persist (pc2a);
+		em.persist (pc2b);
+		em.persist (pc3);
+		endTx(em);
+		oid2a = pc2a.getId();
+		oid2b = pc2b.getId();
+	    oid3 = pc3.getId();
+		endEm(em);
+
+		em = currentEntityManager();
+		startTx(em);
+		pc2a = em.find(AutoIncrementPC2.class, oid2a);
+		pc2b = em.find(AutoIncrementPC2.class, oid2b);
+		pc3 = em.find(AutoIncrementPC3.class, oid3);
+		assertEquals ("pc2a", pc2a.getStringField ());
+		assertEquals (1, pc2a.getIntField ());
+		assertEquals ("pc2b", pc2b.getStringField ());
+		assertEquals (2, pc2b.getIntField ());
+		assertEquals ("pc3", pc3.getStringField ());
+		assertEquals (pc2b, pc2a.getOneOne ());
+		assertEquals (pc2a, pc2b.getOneOne ());
+		assertEquals (pc3, pc3.getOneOne ());
+		endTx(em);
+		endEm(em);
+	}
+
+	public void testMultipleFlushes ()
+	{
+		AutoIncrementPC2 pc2 = new AutoIncrementPC2 (1);
+		pc2.setStringField ("pc2");
+		pc2.setIntField (2);
+		AutoIncrementPC3 pc3 = new AutoIncrementPC3 (2);
+		pc3.setStringField ("pc3");
+
+		EntityManager em = currentEntityManager();
+		startTx(em);
+		em.persist (pc2);
+		em.persist (pc3);
+		oid2 = pc2.getId();
+		oid3 = pc3.getId();
+		em.flush ();
+
+	    oid2a = pc2.getId();
+		oid3a = pc3.getId();
+		assertEquals (oid2, oid2a);
+		assertEquals (oid3, oid3a);
+		long id = pc3.getId ();
+		assertEquals (pc2, em.find(AutoIncrementPC2.class, oid2a));
+		assertEquals (pc3, em.find(AutoIncrementPC3.class, oid3a));
+		pc2.setStringField ("pc2a");
+		pc2.setIntField (3);
+		pc3.setStringField ("pc3a");
+		em.flush ();
+
+		oid2b = pc2.getId();
+		oid3b = pc3.getId();
+		assertEquals (oid2, oid2b);
+		assertEquals (oid3, oid3b);
+		assertEquals (id, pc3.getId ());
+		assertEquals (pc2, em.find(AutoIncrementPC2.class, oid2b));
+		assertEquals (pc3, em.find(AutoIncrementPC3.class, oid3b));
+		endTx(em);
+		endEm(em);
+
+		em = currentEntityManager();
+		startTx(em);
+		pc2 = em.find(AutoIncrementPC2.class, oid2b);
+		pc3 = em.find(AutoIncrementPC3.class, oid3b);
+		assertEquals ("pc2a", pc2.getStringField ());
+		assertEquals (3, pc2.getIntField ());
+		assertEquals ("pc3a", pc3.getStringField ());
+		assertEquals (id, pc3.getId ());
+		endTx(em);
+		endEm(em);
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEfficientAttach.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEfficientAttach.java
index f871f9a..188724b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEfficientAttach.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEfficientAttach.java
@@ -1,121 +1,121 @@
-/*
- * TestEfficientAttach.java
- *
- * Created on September 29, 2006, 6:00 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.meta.ClassMetaData;
-
-public class TestEfficientAttach extends TestSQLListenerTestCase {
-
-
-//    private boolean  = true;//Boolean.valueOf(bool);
-    
-    /** Creates a new instance of TestEfficientAttach */
-    public TestEfficientAttach(String name) 
-    {
-    	super(name);
-    }
-    
-    public void testAttachWithDetachedStateManager() {
-        Class[] clss = new Class[]{
-            AttachA.class, AttachB.class, AttachC.class, AttachD.class,
-            AttachE.class, AttachF.class,
-        };
-        String[] detachedStateFields = new String[clss.length];
-
-        // null any declared detached state fields so we know we're using
-        // synthetic state managers
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) kem).getConfiguration();
-
-        MetaDataRepository repos = conf.getMappingRepositoryInstance();
-        ClassMetaData meta;
-        for (int i = 0; i < clss.length; i++) {
-            meta = repos.getMetaData(clss[i], null, true);
-            detachedStateFields[i] = meta.getDetachedState();
-            meta.setDetachedState(null);
-
-           deleteAll(clss[i]);
-        }
-
-        try {
-            attachTest();
-        } finally {
-            // set detached state back
-            for (int i = 0; i < clss.length; i++)
-                repos.getMetaData(clss[i], null, true).setDetachedState
-                    (detachedStateFields[i]);
-        }
-    }
-
-    private void attachTest() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);;
-        AttachE e = new AttachE();
-        e.setB(new AttachB());
-        pm.persist(e);
-        endTx(pm);;
-        //FIXME jthomas - could not find equivalent for detachCopy() attachCopy() etc
-/*      
-        e = (AttachE) pm.detachCopy(e);
-        pm.close();
-
-        pm = getPM();
-        pm.begin();
-        sql.clear();
-        e = (AttachE) pm.attachCopy(e, false);
-        assertNotNull(e);
-        assertNotNull(e.getB());
-        assertSize(0, sql);
-        pm.commit();
-        assertSize(2, sql);
-        pm.close();
- */
-    }
-
-
-    public static void main(String[] args) {
-        //main();
-    }
-    
-}
+/*
+ * TestEfficientAttach.java
+ *
+ * Created on September 29, 2006, 6:00 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.meta.ClassMetaData;
+
+public class TestEfficientAttach extends TestSQLListenerTestCase {
+
+
+//    private boolean  = true;//Boolean.valueOf(bool);
+    
+    /** Creates a new instance of TestEfficientAttach */
+    public TestEfficientAttach(String name) 
+    {
+    	super(name);
+    }
+    
+    public void testAttachWithDetachedStateManager() {
+        Class[] clss = new Class[]{
+            AttachA.class, AttachB.class, AttachC.class, AttachD.class,
+            AttachE.class, AttachF.class,
+        };
+        String[] detachedStateFields = new String[clss.length];
+
+        // null any declared detached state fields so we know we're using
+        // synthetic state managers
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) kem).getConfiguration();
+
+        MetaDataRepository repos = conf.getMappingRepositoryInstance();
+        ClassMetaData meta;
+        for (int i = 0; i < clss.length; i++) {
+            meta = repos.getMetaData(clss[i], null, true);
+            detachedStateFields[i] = meta.getDetachedState();
+            meta.setDetachedState(null);
+
+           deleteAll(clss[i]);
+        }
+
+        try {
+            attachTest();
+        } finally {
+            // set detached state back
+            for (int i = 0; i < clss.length; i++)
+                repos.getMetaData(clss[i], null, true).setDetachedState
+                    (detachedStateFields[i]);
+        }
+    }
+
+    private void attachTest() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);;
+        AttachE e = new AttachE();
+        e.setB(new AttachB());
+        pm.persist(e);
+        endTx(pm);;
+        //FIXME jthomas - could not find equivalent for detachCopy() attachCopy() etc
+/*      
+        e = (AttachE) pm.detachCopy(e);
+        pm.close();
+
+        pm = getPM();
+        pm.begin();
+        sql.clear();
+        e = (AttachE) pm.attachCopy(e, false);
+        assertNotNull(e);
+        assertNotNull(e.getB());
+        assertSize(0, sql);
+        pm.commit();
+        assertSize(2, sql);
+        pm.close();
+ */
+    }
+
+
+    public static void main(String[] args) {
+        //main();
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEmbeddedPessimisticLocking.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEmbeddedPessimisticLocking.java
index 0688cd9..4df2e5d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEmbeddedPessimisticLocking.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestEmbeddedPessimisticLocking.java
@@ -1,285 +1,285 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-import java.util.*;
-import org.apache.openjpa.kernel.*;
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.FetchPlan;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase; 
-
-
-/**
- * Test various bits of embedded-field functionality.
- * <p/>
- * ##### this should test embedded-element collections, maps, at least to ensure
- * ##### that the state managers of values in embedded collections, maps do not
- * ##### have owners. Not relevant in 3.x; will be important in 4.0.
- */
-public class TestEmbeddedPessimisticLocking
-    extends TestSQLListenerTestCase {
-
-
-    private boolean supportsLocking;
-    private Object oid;
-    private OpenJPAEntityManagerFactory emf;
-    
-    public TestEmbeddedPessimisticLocking(String name)
-    {
-    	super(name);
-    }
-
-	public void setUp() throws Exception{
-		super.setUp();
-		emf = (OpenJPAEntityManagerFactory)getEmf(getProps());
-	}
-
-
-
-    public void setUpTestCase() {
-
-		JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf)).getConfiguration();
-
-        supportsLocking = conf.getDBDictionaryInstance().supportsSelectForUpdate;
-
-       deleteAll(EmbeddedOwnerPC.class);
-
-        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-        startTx(em);
-        EmbeddedOwnerPC owner = new EmbeddedOwnerPC(10, 20);
-        em.persist(owner);
-
-        EmbeddedPC embedded = new EmbeddedPC();
-        embedded.setIntField(4);
-        embedded.setStringField("foo");
-        owner.setEmbedded(embedded);
-
-        EmbeddedPC embedded2 = new EmbeddedPC();
-        embedded2.setIntField(8);
-        embedded2.setStringField("bar");
-        ComplexEmbeddedPC complex = new ComplexEmbeddedPC();
-        complex.setStringField("complex");
-        complex.setEmbedded(embedded2);
-        owner.setComplexEmbedded(complex);
-
-        endTx(em);
-
-        oid = em.getObjectId(owner);
-        em.close();
-    }
-
-    private void prepareEMF(OpenJPAEntityManagerFactory emf) {
-        // do this to ensure that the SELECT DISTINCT gets performed here.
-        OpenJPAEntityManager em = emf.createEntityManager();
-
-        //FIXME jthomas commenting this since setOptimistic is not available for userTx
-        //em.getTransaction().setOptimistic(false);
-        startTx(em);
-
-        try {
-            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
-        } finally {
-            rollbackTx(em);
-            em.close();
-        }
-    }
-
-    public void testEmbeddedFieldsWithLockedParent() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-        prepareEMF(em.getEntityManagerFactory());
-        ((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "embedded");
-//FIXME jthomas commenting this since setOptimistic is not available for userTx
-//        pm.currentTransaction().setOptimistic(false);
-        startTx(em);
-        try {
-            sql.clear();
-            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
-            assertEquals(1, sql.size());
-
-            pc.getEmbedded().setStringField
-                (pc.getEmbedded().getStringField() + "bar");
-            // should not go to the db for another lock; we use <=, since
-            // some databases (like HSQL) don't support locking at all
-            assertTrue(sql.size() <= 1);
-        } finally {
-            rollbackTx(em);
-            em.close();
-        }
-    }
-
-    public void testEmbeddedFieldsWithUnlockedParent() {
-		OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-		prepareEMF(em.getEntityManagerFactory());
-		((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "embedded");
-
-
-//FIXME jthomas commenting this since setOptimistic is not available for userTx
-//        pm.currentTransaction().setOptimistic(false);
-        startTx(em);
-
-        try {
-
-            //FIXME jthomas - no equivalent found for LockLevels.LOCK_NONE
-            //((FetchPlan) pm.getFetchPlan()).setReadLockMode(LockLevels.LOCK_NONE);
-
-            sql.clear();
-            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
-            EmbeddedPC embedded = pc.getEmbedded();
-
-            assertNull(getStateManager(pc, em).getLock());
-            assertNull(getStateManager(embedded, em).getLock());
-            assertEquals(1, sql.size());
-            sql.clear();
-
-            embedded.setStringField(embedded.getStringField() + "bar");
-            // should not go to the db for another lock -- should have gotten
-            // one along with the embedded field's lock
-            assertTrue(sql.size() <= 1);
-            assertNotNull(getStateManager(pc, em).getLock());
-
-            // embeddeds don't get locks at all.
-            assertNull(getStateManager(embedded, em).getLock());
-
-            // owner is dirtied when embedded record is changed
-            assertTrue(getStateManager(pc, em).isDirty());
-            assertTrue(getStateManager(embedded, em).isDirty());
-
-            pc.setStringField(pc.getStringField() + "bar");
-            // should not go to the db for another lock.
-            assertTrue(sql.size() <= 1);
-        } finally {
-            rollbackTx(em);
-            em.close();
-        }
-    }
-
-    public void testComplexEmbeddedFieldsWithLockedParent() {
-
-		OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-		prepareEMF(em.getEntityManagerFactory());
-		em.getFetchPlan().setMaxFetchDepth(-1);
-		((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "complexEmbedded");
-		((FetchPlan) em.getFetchPlan()).addField(RecursivelyEmbeddedPC.class, "embedded");
-
-//FIXME jthomas commenting this since setOptimistic is not available for userTx
-//        pm.currentTransaction().setOptimistic(false);
-        startTx(em);
-        try {
-            sql.clear();
-            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
-            assertEquals(1, sql.size());
-
-            pc.getComplexEmbedded().getEmbedded().setStringField
-                (pc.getComplexEmbedded().getEmbedded().getStringField() +
-                    "bar");
-            // should not go to the db for another lock.
-            assertTrue(sql.size() <= 1);
-        } finally {
-            rollbackTx(em);
-            em.close();
-        }
-    }
-
-    public void testComplexEmbeddedFieldsWithUnlockedParent() {
-        // doing this because setting the read lock level
-        // does not seem to be disabling FOR UPDATE.
-
-
-		OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-		prepareEMF(em.getEntityManagerFactory());
-		em.getFetchPlan().setMaxFetchDepth(-1);
-		((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "complexEmbedded");
-		((FetchPlan) em.getFetchPlan()).addField(RecursivelyEmbeddedPC.class, "embedded");
-
-
-
-//FIXME jthomas commenting this since setOptimistic is not available for userTx
-//        pm.currentTransaction().setOptimistic(false);
-        startTx(em);
-
-        try {
-            //FIXME jthomas FetchPlan.LOCK_NONE??
-            //((FetchPlan) em.getFetchPlan()).setReadLockLevel
-            //    (FetchPlan.LOCK_NONE);
-
-            sql.clear();
-            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
-            ComplexEmbeddedPC complex = pc.getComplexEmbedded();
-            EmbeddedPC embedded = complex.getEmbedded();
-
-            assertNull(getStateManager(pc, em).getLock());
-            assertNull(getStateManager(complex, em).getLock());
-            assertNull(getStateManager(embedded, em).getLock());
-            assertEquals(1, sql.size());
-            sql.clear();
-
-            embedded.setStringField(embedded.getStringField() + "bar");
-            // should not go to the db for another lock -- should have gotten
-            // one along with the embedded field's lock
-            assertTrue(sql.size() <= 1);
-            assertNotNull(getStateManager(pc, em).getLock());
-
-            // embeddeds don't get locks at all.
-            assertNull(getStateManager(complex, em).getLock());
-            assertNull(getStateManager(embedded, em).getLock());
-
-            // owner is dirtied when embedded record is changed
-            assertTrue(getStateManager(pc, em).isDirty());
-            assertTrue(getStateManager(complex, em).isDirty());
-            assertTrue(getStateManager(embedded, em).isDirty());
-
-            complex.setStringField(complex.getStringField() + "bar");
-            // should not go to the db for another lock.
-            assertTrue(sql.size() <= 1);
-
-            pc.setStringField(pc.getStringField() + "bar");
-            // should not go to the db for another lock.
-            assertTrue(sql.size() <= 1);
-        } finally {
-            rollbackTx(em);
-            em.close();
-        }
-    }
-
-	private Map getProps() {
-		Map props=new HashMap();
-		props.put("openjpa.DataCache", "true");
-		props.put("openjpa.RemoteCommitProvider", "sjvm");
-		props.put("openjpa.FlushBeforeQueries", "true");
-		props.put("javax.jdo.option.IgnoreCache", "false");
-		//propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
-		return props;
-	}
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+import java.util.*;
+import org.apache.openjpa.kernel.*;
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.FetchPlan;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase; 
+
+
+/**
+ * Test various bits of embedded-field functionality.
+ * <p/>
+ * ##### this should test embedded-element collections, maps, at least to ensure
+ * ##### that the state managers of values in embedded collections, maps do not
+ * ##### have owners. Not relevant in 3.x; will be important in 4.0.
+ */
+public class TestEmbeddedPessimisticLocking
+    extends TestSQLListenerTestCase {
+
+
+    private boolean supportsLocking;
+    private Object oid;
+    private OpenJPAEntityManagerFactory emf;
+    
+    public TestEmbeddedPessimisticLocking(String name)
+    {
+    	super(name);
+    }
+
+	public void setUp() throws Exception{
+		super.setUp();
+		emf = (OpenJPAEntityManagerFactory)getEmf(getProps());
+	}
+
+
+
+    public void setUpTestCase() {
+
+		JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf)).getConfiguration();
+
+        supportsLocking = conf.getDBDictionaryInstance().supportsSelectForUpdate;
+
+       deleteAll(EmbeddedOwnerPC.class);
+
+        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+        startTx(em);
+        EmbeddedOwnerPC owner = new EmbeddedOwnerPC(10, 20);
+        em.persist(owner);
+
+        EmbeddedPC embedded = new EmbeddedPC();
+        embedded.setIntField(4);
+        embedded.setStringField("foo");
+        owner.setEmbedded(embedded);
+
+        EmbeddedPC embedded2 = new EmbeddedPC();
+        embedded2.setIntField(8);
+        embedded2.setStringField("bar");
+        ComplexEmbeddedPC complex = new ComplexEmbeddedPC();
+        complex.setStringField("complex");
+        complex.setEmbedded(embedded2);
+        owner.setComplexEmbedded(complex);
+
+        endTx(em);
+
+        oid = em.getObjectId(owner);
+        em.close();
+    }
+
+    private void prepareEMF(OpenJPAEntityManagerFactory emf) {
+        // do this to ensure that the SELECT DISTINCT gets performed here.
+        OpenJPAEntityManager em = emf.createEntityManager();
+
+        //FIXME jthomas commenting this since setOptimistic is not available for userTx
+        //em.getTransaction().setOptimistic(false);
+        startTx(em);
+
+        try {
+            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
+        } finally {
+            rollbackTx(em);
+            em.close();
+        }
+    }
+
+    public void testEmbeddedFieldsWithLockedParent() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+        prepareEMF(em.getEntityManagerFactory());
+        ((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "embedded");
+//FIXME jthomas commenting this since setOptimistic is not available for userTx
+//        pm.currentTransaction().setOptimistic(false);
+        startTx(em);
+        try {
+            sql.clear();
+            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
+            assertEquals(1, sql.size());
+
+            pc.getEmbedded().setStringField
+                (pc.getEmbedded().getStringField() + "bar");
+            // should not go to the db for another lock; we use <=, since
+            // some databases (like HSQL) don't support locking at all
+            assertTrue(sql.size() <= 1);
+        } finally {
+            rollbackTx(em);
+            em.close();
+        }
+    }
+
+    public void testEmbeddedFieldsWithUnlockedParent() {
+		OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+		prepareEMF(em.getEntityManagerFactory());
+		((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "embedded");
+
+
+//FIXME jthomas commenting this since setOptimistic is not available for userTx
+//        pm.currentTransaction().setOptimistic(false);
+        startTx(em);
+
+        try {
+
+            //FIXME jthomas - no equivalent found for LockLevels.LOCK_NONE
+            //((FetchPlan) pm.getFetchPlan()).setReadLockMode(LockLevels.LOCK_NONE);
+
+            sql.clear();
+            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
+            EmbeddedPC embedded = pc.getEmbedded();
+
+            assertNull(getStateManager(pc, em).getLock());
+            assertNull(getStateManager(embedded, em).getLock());
+            assertEquals(1, sql.size());
+            sql.clear();
+
+            embedded.setStringField(embedded.getStringField() + "bar");
+            // should not go to the db for another lock -- should have gotten
+            // one along with the embedded field's lock
+            assertTrue(sql.size() <= 1);
+            assertNotNull(getStateManager(pc, em).getLock());
+
+            // embeddeds don't get locks at all.
+            assertNull(getStateManager(embedded, em).getLock());
+
+            // owner is dirtied when embedded record is changed
+            assertTrue(getStateManager(pc, em).isDirty());
+            assertTrue(getStateManager(embedded, em).isDirty());
+
+            pc.setStringField(pc.getStringField() + "bar");
+            // should not go to the db for another lock.
+            assertTrue(sql.size() <= 1);
+        } finally {
+            rollbackTx(em);
+            em.close();
+        }
+    }
+
+    public void testComplexEmbeddedFieldsWithLockedParent() {
+
+		OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+		prepareEMF(em.getEntityManagerFactory());
+		em.getFetchPlan().setMaxFetchDepth(-1);
+		((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "complexEmbedded");
+		((FetchPlan) em.getFetchPlan()).addField(RecursivelyEmbeddedPC.class, "embedded");
+
+//FIXME jthomas commenting this since setOptimistic is not available for userTx
+//        pm.currentTransaction().setOptimistic(false);
+        startTx(em);
+        try {
+            sql.clear();
+            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
+            assertEquals(1, sql.size());
+
+            pc.getComplexEmbedded().getEmbedded().setStringField
+                (pc.getComplexEmbedded().getEmbedded().getStringField() +
+                    "bar");
+            // should not go to the db for another lock.
+            assertTrue(sql.size() <= 1);
+        } finally {
+            rollbackTx(em);
+            em.close();
+        }
+    }
+
+    public void testComplexEmbeddedFieldsWithUnlockedParent() {
+        // doing this because setting the read lock level
+        // does not seem to be disabling FOR UPDATE.
+
+
+		OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+		prepareEMF(em.getEntityManagerFactory());
+		em.getFetchPlan().setMaxFetchDepth(-1);
+		((FetchPlan) em.getFetchPlan()).addField(EmbeddedOwnerPC.class, "complexEmbedded");
+		((FetchPlan) em.getFetchPlan()).addField(RecursivelyEmbeddedPC.class, "embedded");
+
+
+
+//FIXME jthomas commenting this since setOptimistic is not available for userTx
+//        pm.currentTransaction().setOptimistic(false);
+        startTx(em);
+
+        try {
+            //FIXME jthomas FetchPlan.LOCK_NONE??
+            //((FetchPlan) em.getFetchPlan()).setReadLockLevel
+            //    (FetchPlan.LOCK_NONE);
+
+            sql.clear();
+            EmbeddedOwnerPC pc = (EmbeddedOwnerPC) em.getObjectId(oid);
+            ComplexEmbeddedPC complex = pc.getComplexEmbedded();
+            EmbeddedPC embedded = complex.getEmbedded();
+
+            assertNull(getStateManager(pc, em).getLock());
+            assertNull(getStateManager(complex, em).getLock());
+            assertNull(getStateManager(embedded, em).getLock());
+            assertEquals(1, sql.size());
+            sql.clear();
+
+            embedded.setStringField(embedded.getStringField() + "bar");
+            // should not go to the db for another lock -- should have gotten
+            // one along with the embedded field's lock
+            assertTrue(sql.size() <= 1);
+            assertNotNull(getStateManager(pc, em).getLock());
+
+            // embeddeds don't get locks at all.
+            assertNull(getStateManager(complex, em).getLock());
+            assertNull(getStateManager(embedded, em).getLock());
+
+            // owner is dirtied when embedded record is changed
+            assertTrue(getStateManager(pc, em).isDirty());
+            assertTrue(getStateManager(complex, em).isDirty());
+            assertTrue(getStateManager(embedded, em).isDirty());
+
+            complex.setStringField(complex.getStringField() + "bar");
+            // should not go to the db for another lock.
+            assertTrue(sql.size() <= 1);
+
+            pc.setStringField(pc.getStringField() + "bar");
+            // should not go to the db for another lock.
+            assertTrue(sql.size() <= 1);
+        } finally {
+            rollbackTx(em);
+            em.close();
+        }
+    }
+
+	private Map getProps() {
+		Map props=new HashMap();
+		props.put("openjpa.DataCache", "true");
+		props.put("openjpa.RemoteCommitProvider", "sjvm");
+		props.put("openjpa.FlushBeforeQueries", "true");
+		props.put("javax.jdo.option.IgnoreCache", "false");
+		//propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
+		return props;
+	}
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestIncrementalJDBCFlushes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestIncrementalJDBCFlushes.java
index 095be1c..7c3a4d1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestIncrementalJDBCFlushes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestIncrementalJDBCFlushes.java
@@ -1,112 +1,112 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-import java.sql.*;
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import javax.persistence.Persistence;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.kernel.StoreManager;
-import org.apache.openjpa.kernel.DelegatingStoreManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-
-public class TestIncrementalJDBCFlushes
-        extends BaseJDBCTest {
-    
-    private EntityManagerFactory emf;
-    
-
-//    private boolean  = true;
-//    
-    
-    public TestIncrementalJDBCFlushes(String str) {
-        super(str);
-    }
-    
-    
-    public void setUp() {
-        emf = getEmf(getProps());
-        
-        EntityManager em =emf.createEntityManager();
-       deleteAll(RuntimeTest1.class,em);
-        
-    }
-    
-    
-    public void testFlushHappened() throws java.sql.SQLException{
-        
-        
-        
-        EntityManager em =emf.createEntityManager();
-        startTx(em);
-        RuntimeTest1 a = new RuntimeTest1("a-name", 10);
-        em.persist(a);
-        em.flush();
-        JDBCStore store = (JDBCStore) getStoreManager(em, true);
-        Connection conn = store.getConnection();
-        ClassMapping mapping = store.getConfiguration().
-                getMappingRepositoryInstance().getMapping(RuntimeTest1.class,
-                null, true);
-        FieldMapping fm = mapping.getFieldMapping("stringField");
-        String tableName = store.getConfiguration().getDBDictionaryInstance().getFullName(fm.getTable(), false);
-        String colName = fm.getColumns()[0].getName();
-        Statement st = conn.createStatement();
-        ResultSet rs = st.executeQuery("SELECT " + colName + " FROM "
-                + tableName + " WHERE " + colName + " = 'a-name'");
-        int count = 0;
-        while (rs.next())
-            count++;
-        assertEquals(1, count);
-        rollbackTx(em);
-        endEm(em);
-        
-        
-    }
-    
-    private StoreManager getStoreManager(EntityManager em, boolean innermost) {
-        DelegatingStoreManager mgr = JPAFacadeHelper.toBroker(em).getStoreManager();
-        if (innermost)
-            return mgr.getInnermostDelegate();
-        return mgr;
-    }
-    
-    private Map getProps() {
-        Map props=new HashMap();
-        props.put("openjpa.DataCache", "true");
-        props.put("openjpa.RemoteCommitProvider", "sjvm");
-        props.put("openjpa.FlushBeforeQueries", "true");
-        props.put("javax.jdo.option.IgnoreCache", "false");
-        //propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
-        return props;
-    }
-    
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+import java.sql.*;
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import javax.persistence.Persistence;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.kernel.DelegatingStoreManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+
+public class TestIncrementalJDBCFlushes
+        extends BaseJDBCTest {
+    
+    private EntityManagerFactory emf;
+    
+
+//    private boolean  = true;
+//    
+    
+    public TestIncrementalJDBCFlushes(String str) {
+        super(str);
+    }
+    
+    
+    public void setUp() {
+        emf = getEmf(getProps());
+        
+        EntityManager em =emf.createEntityManager();
+       deleteAll(RuntimeTest1.class,em);
+        
+    }
+    
+    
+    public void testFlushHappened() throws java.sql.SQLException{
+        
+        
+        
+        EntityManager em =emf.createEntityManager();
+        startTx(em);
+        RuntimeTest1 a = new RuntimeTest1("a-name", 10);
+        em.persist(a);
+        em.flush();
+        JDBCStore store = (JDBCStore) getStoreManager(em, true);
+        Connection conn = store.getConnection();
+        ClassMapping mapping = store.getConfiguration().
+                getMappingRepositoryInstance().getMapping(RuntimeTest1.class,
+                null, true);
+        FieldMapping fm = mapping.getFieldMapping("stringField");
+        String tableName = store.getConfiguration().getDBDictionaryInstance().getFullName(fm.getTable(), false);
+        String colName = fm.getColumns()[0].getName();
+        Statement st = conn.createStatement();
+        ResultSet rs = st.executeQuery("SELECT " + colName + " FROM "
+                + tableName + " WHERE " + colName + " = 'a-name'");
+        int count = 0;
+        while (rs.next())
+            count++;
+        assertEquals(1, count);
+        rollbackTx(em);
+        endEm(em);
+        
+        
+    }
+    
+    private StoreManager getStoreManager(EntityManager em, boolean innermost) {
+        DelegatingStoreManager mgr = JPAFacadeHelper.toBroker(em).getStoreManager();
+        if (innermost)
+            return mgr.getInnermostDelegate();
+        return mgr;
+    }
+    
+    private Map getProps() {
+        Map props=new HashMap();
+        props.put("openjpa.DataCache", "true");
+        props.put("openjpa.RemoteCommitProvider", "sjvm");
+        props.put("openjpa.FlushBeforeQueries", "true");
+        props.put("javax.jdo.option.IgnoreCache", "false");
+        //propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
+        return props;
+    }
+    
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestOperationOrderUpdateManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestOperationOrderUpdateManager.java
index 03cdf9a..a62a7c6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestOperationOrderUpdateManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestOperationOrderUpdateManager.java
@@ -1,319 +1,319 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.*;
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-
-public class TestOperationOrderUpdateManager
-    extends AbstractTestCase {
-
-
-//	private boolean  = true;//Boolean.valueOf(bool);
-
-
-    private static boolean _mapped = false;
-
-    private EntityManagerFactory emf;
-
-    /*protected boolean skipTest() {
-        if (!getName().startsWith("testAuto"))
-            return false;
-
-		emf = getEmf();
-
-		JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf)).getConfiguration();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        return !dict.supportsAutoAssign;
-    }
-*/
-    public TestOperationOrderUpdateManager(String name)
-    {
-    	super(name);
-    }
-
-    private void insertTest(boolean autoAssign) {
-        OpOrder oid = (autoAssign) ? insertAutoAssign() : insert();
-
-        EntityManager em = currentEntityManager();
-
-        OpOrder pc = (OpOrder) em.find(OpOrder.class,oid.getId());
-        assertEquals("pc", pc.getSecondary());
-        assertEquals("pcsub", pc.getSub());
-        assertNotNull(pc.getRel());
-        assertEquals("rel", pc.getRel().getSecondary());
-        assertEquals(2, pc.getRelList().size());
-        assertTrue(((OpOrder) pc.getRelList().iterator().next()).
-            getSecondary().startsWith("child"));
-        assertEquals(2, pc.getMappedRelList().size());
-        assertTrue(((OpOrder) pc.getMappedRelList().iterator().next()).
-            getSecondary().startsWith("mapped"));
-        assertEquals(2, pc.getInverseKeyRelList().size());
-        assertTrue(((OpOrder) pc.getInverseKeyRelList().iterator().
-            next()).getSecondary().startsWith("inverse"));
-        em.close();
-    }
-
-
-
-    private OpOrder insert() {
-        OpOrderPCSub pc = new OpOrderPCSub();
-        pc.setSecondary("pc");
-        pc.setSub("pcsub");
-        OpOrderPCSub rel = new OpOrderPCSub();
-        rel.setSecondary("rel");
-        pc.setRel(rel);
-        for (int i = 0; i < 2; i++) {
-            OpOrderPCSub child = new OpOrderPCSub();
-            child.setSecondary("child" + i);
-            pc.getRelList().add(child);
-
-            OpOrderPCSub mapped = new OpOrderPCSub();
-            mapped.setSecondary("mapped" + i);
-            mapped.setOwner(pc);
-            pc.getMappedRelList().add(mapped);
-
-            OpOrderPCSub inverse = new OpOrderPCSub();
-            inverse.setSecondary("inverse" + i);
-            pc.getInverseKeyRelList().add(inverse);
-        }
-
-        EntityManager em = currentEntityManager();
-		startTx(em);
-        em.persist(rel);
-        persistAll(em,pc.getInverseKeyRelList());
-        em.persist(pc);
-        endTx(em);
-        OpOrder oid = em.find(OpOrder.class,pc.getId());
-        //em.getObjectId(pc);
-        em.close();
-        return oid;
-    }
-
-    private OpOrder insertAutoAssign() {
-        AutoIncrementOpOrderPCSub pc = new AutoIncrementOpOrderPCSub();
-        pc.setSecondary("pc");
-        pc.setSub("pcsub");
-        AutoIncrementOpOrderPCSub rel = new AutoIncrementOpOrderPCSub();
-        rel.setSecondary("rel");
-        pc.setRel(rel);
-        for (int i = 0; i < 2; i++) {
-            AutoIncrementOpOrderPCSub child = new AutoIncrementOpOrderPCSub();
-            child.setSecondary("child" + i);
-            pc.getRelList().add(child);
-
-            AutoIncrementOpOrderPCSub mapped = new AutoIncrementOpOrderPCSub();
-            mapped.setSecondary("mapped" + i);
-            mapped.setOwner(pc);
-            pc.getMappedRelList().add(mapped);
-
-            AutoIncrementOpOrderPCSub inverse = new AutoIncrementOpOrderPCSub();
-            inverse.setSecondary("inverse" + i);
-            pc.getInverseKeyRelList().add(inverse);
-        }
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        em.persist(rel);
-        persistAll(em,pc.getInverseKeyRelList());
-        em.persist(pc);
-        endTx(em);
-        OpOrder oid = em.find(AutoIncrementOpOrderPCSub.class,pc.getId());
-        em.close();
-        return oid;
-    }
-
-
-    private void insertCircularConstraintTest(boolean autoAssign) {
-        OpOrder oid = (autoAssign) ? insertCircularAutoAssign()
-            : insertCircular();
-
-        EntityManager em = currentEntityManager();
-        OpOrder pc1 = (OpOrder) em.find(OpOrder.class,oid.getId());
-        assertEquals("pc1", pc1.getSecondary());
-        assertNotNull(pc1.getRel());
-        assertEquals("pc2", pc1.getRel().getSecondary());
-        assertNotNull(pc1.getRel().getRel());
-        assertEquals(pc1, pc1.getRel().getRel());
-        em.close();
-    }
-
-    private OpOrder insertCircular() {
-        OpOrderPCSub pc1 = new OpOrderPCSub();
-        pc1.setSecondary("pc1");
-        pc1.setSub("pcsub");
-        OpOrderPCSub pc2 = new OpOrderPCSub();
-        pc2.setSecondary("pc2");
-        pc1.setRel(pc2);
-        pc2.setRel(pc1);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        em.persist(pc1);
-        em.persist(pc2);
-        endTx(em);
-        OpOrder oid = em.find(OpOrder.class,pc1.getId());
-        em.close();
-        return oid;
-    }
-
-    private OpOrder insertCircularAutoAssign() {
-        AutoIncrementOpOrderPCSub pc1 = new AutoIncrementOpOrderPCSub();
-        pc1.setSecondary("pc1");
-        pc1.setSub("pcsub");
-        AutoIncrementOpOrderPCSub pc2 = new AutoIncrementOpOrderPCSub();
-        pc2.setSecondary("pc2");
-        pc1.setRel(pc2);
-        pc2.setRel(pc1);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        em.persist(pc1);
-        em.persist(pc2);
-        endTx(em);
-        OpOrder oid = em.find(OpOrder.class,pc1.getId());
-        em.close();
-        return oid;
-    }
-
-
-    private void deleteCircularTest(boolean autoAssign) {
-        OpOrder oid = (autoAssign) ? insertCircularAutoAssign()
-            : insertCircular();
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        OpOrder pc1 = (OpOrder) em.find(OpOrder.class,oid.getId());
-        em.remove(pc1.getRel());
-        em.remove(pc1);
-        endTx(em);
-        em.close();
-
-/*        pm = _pmf.getPersistenceManager();
-        if (autoAssign)
-            assertEquals(0, ((KodoExtent) pm.getExtent
-                (AutoIncrementOpOrderPCSub.class, true)).list().size());
-        else
-            assertEquals(0, ((KodoExtent) pm.getExtent(OpOrderPC.class,
-                true)).list().size());
-        pm.close();
-*/
-    }
-
-    private void deleteTest(boolean autoAssign) {
-        OpOrder oid = (autoAssign) ? insertAutoAssign() : insert();
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        OpOrder pc = (OpOrder) em.find(OpOrder.class,oid.getId());
-        removeAll(em,pc.getMappedRelList());
-        removeAll(em,pc.getInverseKeyRelList());
-        removeAll(em,pc.getRelList());
-        em.remove(pc.getRel());
-        em.remove(pc);
-        endTx(em);
-        em.close();
-/*
-        pm = _pmf.getPersistenceManager();
-        if (autoAssign)
-            assertEquals(0, ((KodoExtent) pm.getExtent
-                (AutoIncrementOpOrderPCSub.class, true)).list().size());
-        else
-            assertEquals(0, ((KodoExtent) pm.getExtent(OpOrderPC.class,
-                true)).list().size());
-        pm.close();
-*/
-    }
-
-
-    public void testInsert() {
-        insertTest(false);
-    }
-
-    public void testAutoAssignInsert() {
-        insertTest(true);
-    }
-
-
-    public void testDeleteCircular() {
-        deleteCircularTest(false);
-    }
-
-    public void testAutoAssignDeleteCircular() {
-        deleteCircularTest(true);
-    }
-
-    public void testDelete() {
-        deleteTest(false);
-    }
-
-    public void testAutoAssignDelete() {
-        deleteTest(true);
-    }
-
-
-    public void testInsertCircularConstraint() {
-        insertCircularConstraintTest(false);
-    }
-
-    public void testAutoAssignInsertCircularConstraint() {
-        insertCircularConstraintTest(true);
-    }
-
-
-
-    private void persistAll(EntityManager em, List list) {
-
-		Iterator i = list.iterator();
-		while(i.hasNext()) {
-			Object o = i.next();
-			em.persist(o);
-		}
-	}
-
-
-	private void removeAll(EntityManager em, List list) {
-
-		Iterator i = list.iterator();
-		while(i.hasNext()) {
-			Object o = i.next();
-			em.remove(o);
-		}
-	}
-
-
-
-
-
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.*;
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+
+public class TestOperationOrderUpdateManager
+    extends AbstractTestCase {
+
+
+//	private boolean  = true;//Boolean.valueOf(bool);
+
+
+    private static boolean _mapped = false;
+
+    private EntityManagerFactory emf;
+
+    /*protected boolean skipTest() {
+        if (!getName().startsWith("testAuto"))
+            return false;
+
+		emf = getEmf();
+
+		JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf)).getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        return !dict.supportsAutoAssign;
+    }
+*/
+    public TestOperationOrderUpdateManager(String name)
+    {
+    	super(name);
+    }
+
+    private void insertTest(boolean autoAssign) {
+        OpOrder oid = (autoAssign) ? insertAutoAssign() : insert();
+
+        EntityManager em = currentEntityManager();
+
+        OpOrder pc = (OpOrder) em.find(OpOrder.class,oid.getId());
+        assertEquals("pc", pc.getSecondary());
+        assertEquals("pcsub", pc.getSub());
+        assertNotNull(pc.getRel());
+        assertEquals("rel", pc.getRel().getSecondary());
+        assertEquals(2, pc.getRelList().size());
+        assertTrue(((OpOrder) pc.getRelList().iterator().next()).
+            getSecondary().startsWith("child"));
+        assertEquals(2, pc.getMappedRelList().size());
+        assertTrue(((OpOrder) pc.getMappedRelList().iterator().next()).
+            getSecondary().startsWith("mapped"));
+        assertEquals(2, pc.getInverseKeyRelList().size());
+        assertTrue(((OpOrder) pc.getInverseKeyRelList().iterator().
+            next()).getSecondary().startsWith("inverse"));
+        em.close();
+    }
+
+
+
+    private OpOrder insert() {
+        OpOrderPCSub pc = new OpOrderPCSub();
+        pc.setSecondary("pc");
+        pc.setSub("pcsub");
+        OpOrderPCSub rel = new OpOrderPCSub();
+        rel.setSecondary("rel");
+        pc.setRel(rel);
+        for (int i = 0; i < 2; i++) {
+            OpOrderPCSub child = new OpOrderPCSub();
+            child.setSecondary("child" + i);
+            pc.getRelList().add(child);
+
+            OpOrderPCSub mapped = new OpOrderPCSub();
+            mapped.setSecondary("mapped" + i);
+            mapped.setOwner(pc);
+            pc.getMappedRelList().add(mapped);
+
+            OpOrderPCSub inverse = new OpOrderPCSub();
+            inverse.setSecondary("inverse" + i);
+            pc.getInverseKeyRelList().add(inverse);
+        }
+
+        EntityManager em = currentEntityManager();
+		startTx(em);
+        em.persist(rel);
+        persistAll(em,pc.getInverseKeyRelList());
+        em.persist(pc);
+        endTx(em);
+        OpOrder oid = em.find(OpOrder.class,pc.getId());
+        //em.getObjectId(pc);
+        em.close();
+        return oid;
+    }
+
+    private OpOrder insertAutoAssign() {
+        AutoIncrementOpOrderPCSub pc = new AutoIncrementOpOrderPCSub();
+        pc.setSecondary("pc");
+        pc.setSub("pcsub");
+        AutoIncrementOpOrderPCSub rel = new AutoIncrementOpOrderPCSub();
+        rel.setSecondary("rel");
+        pc.setRel(rel);
+        for (int i = 0; i < 2; i++) {
+            AutoIncrementOpOrderPCSub child = new AutoIncrementOpOrderPCSub();
+            child.setSecondary("child" + i);
+            pc.getRelList().add(child);
+
+            AutoIncrementOpOrderPCSub mapped = new AutoIncrementOpOrderPCSub();
+            mapped.setSecondary("mapped" + i);
+            mapped.setOwner(pc);
+            pc.getMappedRelList().add(mapped);
+
+            AutoIncrementOpOrderPCSub inverse = new AutoIncrementOpOrderPCSub();
+            inverse.setSecondary("inverse" + i);
+            pc.getInverseKeyRelList().add(inverse);
+        }
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        em.persist(rel);
+        persistAll(em,pc.getInverseKeyRelList());
+        em.persist(pc);
+        endTx(em);
+        OpOrder oid = em.find(AutoIncrementOpOrderPCSub.class,pc.getId());
+        em.close();
+        return oid;
+    }
+
+
+    private void insertCircularConstraintTest(boolean autoAssign) {
+        OpOrder oid = (autoAssign) ? insertCircularAutoAssign()
+            : insertCircular();
+
+        EntityManager em = currentEntityManager();
+        OpOrder pc1 = (OpOrder) em.find(OpOrder.class,oid.getId());
+        assertEquals("pc1", pc1.getSecondary());
+        assertNotNull(pc1.getRel());
+        assertEquals("pc2", pc1.getRel().getSecondary());
+        assertNotNull(pc1.getRel().getRel());
+        assertEquals(pc1, pc1.getRel().getRel());
+        em.close();
+    }
+
+    private OpOrder insertCircular() {
+        OpOrderPCSub pc1 = new OpOrderPCSub();
+        pc1.setSecondary("pc1");
+        pc1.setSub("pcsub");
+        OpOrderPCSub pc2 = new OpOrderPCSub();
+        pc2.setSecondary("pc2");
+        pc1.setRel(pc2);
+        pc2.setRel(pc1);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        em.persist(pc1);
+        em.persist(pc2);
+        endTx(em);
+        OpOrder oid = em.find(OpOrder.class,pc1.getId());
+        em.close();
+        return oid;
+    }
+
+    private OpOrder insertCircularAutoAssign() {
+        AutoIncrementOpOrderPCSub pc1 = new AutoIncrementOpOrderPCSub();
+        pc1.setSecondary("pc1");
+        pc1.setSub("pcsub");
+        AutoIncrementOpOrderPCSub pc2 = new AutoIncrementOpOrderPCSub();
+        pc2.setSecondary("pc2");
+        pc1.setRel(pc2);
+        pc2.setRel(pc1);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        em.persist(pc1);
+        em.persist(pc2);
+        endTx(em);
+        OpOrder oid = em.find(OpOrder.class,pc1.getId());
+        em.close();
+        return oid;
+    }
+
+
+    private void deleteCircularTest(boolean autoAssign) {
+        OpOrder oid = (autoAssign) ? insertCircularAutoAssign()
+            : insertCircular();
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        OpOrder pc1 = (OpOrder) em.find(OpOrder.class,oid.getId());
+        em.remove(pc1.getRel());
+        em.remove(pc1);
+        endTx(em);
+        em.close();
+
+/*        pm = _pmf.getPersistenceManager();
+        if (autoAssign)
+            assertEquals(0, ((KodoExtent) pm.getExtent
+                (AutoIncrementOpOrderPCSub.class, true)).list().size());
+        else
+            assertEquals(0, ((KodoExtent) pm.getExtent(OpOrderPC.class,
+                true)).list().size());
+        pm.close();
+*/
+    }
+
+    private void deleteTest(boolean autoAssign) {
+        OpOrder oid = (autoAssign) ? insertAutoAssign() : insert();
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        OpOrder pc = (OpOrder) em.find(OpOrder.class,oid.getId());
+        removeAll(em,pc.getMappedRelList());
+        removeAll(em,pc.getInverseKeyRelList());
+        removeAll(em,pc.getRelList());
+        em.remove(pc.getRel());
+        em.remove(pc);
+        endTx(em);
+        em.close();
+/*
+        pm = _pmf.getPersistenceManager();
+        if (autoAssign)
+            assertEquals(0, ((KodoExtent) pm.getExtent
+                (AutoIncrementOpOrderPCSub.class, true)).list().size());
+        else
+            assertEquals(0, ((KodoExtent) pm.getExtent(OpOrderPC.class,
+                true)).list().size());
+        pm.close();
+*/
+    }
+
+
+    public void testInsert() {
+        insertTest(false);
+    }
+
+    public void testAutoAssignInsert() {
+        insertTest(true);
+    }
+
+
+    public void testDeleteCircular() {
+        deleteCircularTest(false);
+    }
+
+    public void testAutoAssignDeleteCircular() {
+        deleteCircularTest(true);
+    }
+
+    public void testDelete() {
+        deleteTest(false);
+    }
+
+    public void testAutoAssignDelete() {
+        deleteTest(true);
+    }
+
+
+    public void testInsertCircularConstraint() {
+        insertCircularConstraintTest(false);
+    }
+
+    public void testAutoAssignInsertCircularConstraint() {
+        insertCircularConstraintTest(true);
+    }
+
+
+
+    private void persistAll(EntityManager em, List list) {
+
+		Iterator i = list.iterator();
+		while(i.hasNext()) {
+			Object o = i.next();
+			em.persist(o);
+		}
+	}
+
+
+	private void removeAll(EntityManager em, List list) {
+
+		Iterator i = list.iterator();
+		while(i.hasNext()) {
+			Object o = i.next();
+			em.remove(o);
+		}
+	}
+
+
+
+
+
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestPagingResultObjectProvider.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestPagingResultObjectProvider.java
index e6186ab..5a6ddfd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestPagingResultObjectProvider.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestPagingResultObjectProvider.java
@@ -1,656 +1,656 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.jdbc.meta.*;
-import org.apache.openjpa.jdbc.sql.*;
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-//import org.apache.openjpa.kernel.Extent;
-import org.apache.openjpa.persistence.Extent;
-
-/**
- * <p>Test large result, to-many eager paging.</p>
- *
- */
-public class TestPagingResultObjectProvider
-    extends TestSQLListenerTestCase {
-
-	private OpenJPAEntityManagerFactory emf;
-
-	public TestPagingResultObjectProvider(String name)
-	{
-		super(name);
-	}
-
-    public void setUp() throws Exception{
-		super.setUp();
-		emf = getEmf(getProps());
-    	EntityManager em =currentEntityManager();
-    }
-
-
-
-    public boolean skipTest() {
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf)).getConfiguration();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        if (dict.joinSyntax == Join.SYNTAX_TRADITIONAL)
-            return true;
-
-        // skip test case that requires subselect for DBs that don't support it
-        if ("testPagingRangeQuery".equals(getName())
-            || "testNonPagingRangeQuery".equals(getName())) {
-            if (!conf.getDBDictionaryInstance().supportsSubselect)
-                return true;
-        }
-
-        return false;
-    }
-
-
-    public void testNonPagingExtent() {
-        initializePagingPCs();
-
-        EntityManager em= currentEntityManager();
-        //EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        Extent extent = kem.createExtent(PagingPC.class, true);
-
-        extent.getFetchPlan().setFetchBatchSize(0);
-        extent.getFetchPlan().addFetchGroup("rel");
-
-        // if we only access the rel field, we should only have used 1 select
-        List list = extent.list();
-        assertEquals(4, list.size());
-        assertRel(list, 4);
-        assertEquals(sql.toString(), 1, sql.size());
-        sql.clear();
-
-        // now accessing the rels collection should add selects
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 4, sql.size());
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testNonPagingQuery()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
-
-		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
-
-        //OpenJPAQuery q = kem.createQuery(PagingPC.class.getSimpleName(), "intField >= 0");
-        OpenJPAQuery q = kem.createQuery(theQuery);
-
-        q.getFetchPlan().setFetchBatchSize(0);
-        q.getFetchPlan().addFetchGroups("rel");
-
-        // if we only access the rel field, we should only have used two
-        // selects: one for the query and one for the size
-        List list = (List) q.getResultList();
-        assertEquals(4, list.size());
-        assertRel(list, 4);
-        assertEquals(sql.toString(), 2, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        assertTrue((String) sql.get(1),
-            matches(" COUNT", (String) sql.get(1)));
-        sql.clear();
-
-        // now accessing the rels collection should add selects
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 4, sql.size());
-        sql.clear();
-
-        em.close();
-    }
-
-    /**
-     * Check that the rel field was retrieved correctly.
-     */
-   private void assertRel(List pcs, int size) {
-        PagingPC pc;
-        for (int i = 0; i < size; i++) {
-            pc = (PagingPC) pcs.get(i);
-            assertNotNull(pc.getRel());
-            assertEquals(pc.getIntField() + 1, pc.getRel().getIntField());
-        }
-        try {
-            pcs.get(size + 1);
-            fail("Retrieved past end of list");
-        } catch (Exception e) {
-        }
-    }
-
-    /**
-     * Check that the rels field was retrieved correctly.
-     */
-    private void assertRels(List pcs, int size) {
-        PagingPC pc;
-        for (int i = 0; i < size; i++) {
-            pc = (PagingPC) pcs.get(i);
-            assertEquals(2, pc.getRels().size());
-            assertEquals(pc.getIntField() + 1, ((PagingHelperPC)
-                pc.getRels().get(0)).getIntField());
-            assertEquals(pc.getIntField() + 2, ((PagingHelperPC)
-                pc.getRels().get(1)).getIntField());
-        }
-        try {
-            pcs.get(size + 1);
-            fail("Retrieved past end of list");
-        } catch (Exception e) {
-        }
-    }
-
-    public void testPagingExtent()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        Extent extent = kem.createExtent(PagingPC.class, true);
-        extent.getFetchPlan().setFetchBatchSize(0);
-        extent.getFetchPlan().addFetchGroup("rel");
-        extent.getFetchPlan().addFetchGroup("rels");
-
-
-        // we should get two selects: the initial select and the IN eager stmnt
-        List list = extent.list();
-        assertEquals(4, list.size());
-        assertRel(list, 4);
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 2, sql.size());
-        assertTrue((String) sql.get(1),
-            matches(" IN ", (String) sql.get(1)));
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testPagingQuery()
-        throws Exception {
-        initializePagingPCs();
-
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-
-		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
-        OpenJPAQuery q = kem.createQuery(theQuery);
-        q.getFetchPlan().setFetchBatchSize(0);
-        q.getFetchPlan().addFetchGroups("rel");
-        q.getFetchPlan().addFetchGroups("rels");
-
-
-        // we should get three selects: the initial select, the COUNT for the
-        // size, and the IN eager stmnt
-        List list = (List) q.getResultList();
-        assertEquals(4, list.size());
-        assertRel(list, 4);
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 3, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        assertTrue((String) sql.get(1),
-            matches(" COUNT", (String) sql.get(1)));
-        assertTrue((String) sql.get(2),
-            matches(" IN ", (String) sql.get(2)));
-        assertFalse((String) sql.get(2),
-            matches(" >= ", (String) sql.get(2)));
-        sql.clear();
-
-        // if we execute and traverse a result before getting the size, we
-        // should only get 2 selects, since the caching of the page should
-        // reach the end of the list and therefore know the total size
-        list = (List) q.getResultList();
-        list.get(0);
-        assertEquals(4, list.size());
-        assertRel(list, 4);
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 2, sql.size());
-        assertTrue((String) sql.get(1),
-            matches(" IN ", (String) sql.get(1)));
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testPagingAppIdExtent()
-        throws Exception {
-        initializePagingAppIdPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        Extent extent = kem.createExtent(PagingAppIdPC.class, true);
-
-        extent.getFetchPlan().setFetchBatchSize(0);
-        extent.getFetchPlan().addFetchGroup("rel");
-        extent.getFetchPlan().addFetchGroup("rels");
-
-        // we should get two selects: the initial select and the IN eager stmnt
-        List list = extent.list();
-        assertEquals(4, list.size());
-        assertAppIdRel(list, 4);
-        assertAppIdRels(list, 4);
-        assertEquals(sql.toString(), 2, sql.size());
-        assertTrue((String) sql.get(1),
-            matches(" OR ", (String) sql.get(1)));
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testPagingAppIdQuery()
-        throws Exception {
-        initializePagingAppIdPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
-
-		String theQuery="select a FROM "+PagingAppIdPC.class.getSimpleName()+" a where a.intField >= 0";
-        OpenJPAQuery q = kem.createQuery(theQuery);
-
-
-        q.getFetchPlan().setFetchBatchSize(0);
-        q.getFetchPlan().addFetchGroups("rel");
-        q.getFetchPlan().addFetchGroups("rels");
-
-        // we should get three selects: the initial select, the COUNT for the
-        // size, and the OR eager stmnt
-        List list = (List) q.getResultList();
-        assertEquals(4, list.size());
-        assertAppIdRel(list, 4);
-        assertAppIdRels(list, 4);
-        assertEquals(sql.toString(), 3, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        assertTrue((String) sql.get(1),
-            matches(" COUNT", (String) sql.get(1)));
-        assertTrue((String) sql.get(2),
-            matches(" OR ", (String) sql.get(2)));
-        assertFalse((String) sql.get(2),
-            matches(" >= ", (String) sql.get(2)));
-        sql.clear();
-
-        em.close();
-    }
-
-    /**
-     * Check that the rel field was retrieved correctly.
-     */
-    private void assertAppIdRel(List pcs, int size) {
-        PagingAppIdPC pc;
-        for (int i = 0; i < size; i++) {
-            pc = (PagingAppIdPC) pcs.get(i);
-            assertNotNull(pc.getRel());
-            assertEquals(pc.getIntField() + 1, pc.getRel().getIntField());
-        }
-        try {
-            pcs.get(size + 1);
-            fail("Retrieved past end of list");
-        } catch (Exception e) {
-        }
-    }
-
-    /**
-     * Check that the rels field was retrieved correctly.
-     */
-    private void assertAppIdRels(List pcs, int size) {
-        PagingAppIdPC pc;
-        for (int i = 0; i < size; i++) {
-            pc = (PagingAppIdPC) pcs.get(i);
-            assertEquals(2, pc.getRels().size());
-            assertEquals(pc.getIntField() + 1, ((PagingHelperPC)
-                pc.getRels().get(0)).getIntField());
-            assertEquals(pc.getIntField() + 2, ((PagingHelperPC)
-                pc.getRels().get(1)).getIntField());
-        }
-        try {
-            pcs.get(size + 1);
-            fail("Retrieved past end of list");
-        } catch (Exception e) {
-        }
-    }
-
-    public void testMultiPageExtent()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
-        Extent extent = kem.createExtent(PagingPC.class, true);
-
-        extent.getFetchPlan().setFetchBatchSize(2);    // 2 pages of 2
-        extent.getFetchPlan().addFetchGroup("rel");
-        extent.getFetchPlan().addFetchGroup("rels");
-
-        // we should get two selects: the initial select and the IN eager stmnt
-        List list = extent.list();
-        assertEquals(list.toString(), 4, list.size());
-        assertRel(list, 4);
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 3, sql.size());
-        assertTrue((String) sql.get(1),
-            matches(" IN ", (String) sql.get(1)));
-        assertTrue((String) sql.get(2),
-            matches(" IN ", (String) sql.get(2)));
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testMultiPageQuery()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
-
-		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
-        OpenJPAQuery q = kem.createQuery(theQuery);
-
-
-		//FIXME jthomas commenting till we find how ordering can be done
-        //q.setOrdering("intField ascending");
-        q.getFetchPlan().setFetchBatchSize(2);    // 2 pages of 2
-        q.getFetchPlan().addFetchGroup("rel");
-        q.getFetchPlan().addFetchGroup("rels");
-
-        // we should get four selects: the initial select, the count, and the
-        // two IN eager stmnts
-        List list = (List) q.getResultList();
-        assertEquals(list.toString(), 4, list.size());
-        // so we don't have to re-execute to move back to beginning
-        list = new ArrayList(list);
-        assertRel(list, 4);
-        assertRels(list, 4);
-
-        assertEquals(sql.toString(), 4, sql.size());
-        assertTrue((String) sql.get(1),
-            matches(" COUNT", (String) sql.get(1)));
-        assertTrue((String) sql.get(2),
-            matches(" IN ", (String) sql.get(2)));
-        assertTrue((String) sql.get(3),
-            matches(" IN ", (String) sql.get(3)));
-        sql.clear();
-
-        // if we access a result object on the second page, we should get only
-        // three selects: the initial select, the count, and the IN eager stmnt
-        // for page 2
-        list = (List) q.getResultList();
-        assertEquals(list.toString(), 4, list.size());
-        PagingPC pc = (PagingPC) list.get(2);
-        assertEquals(2, pc.getIntField());
-        assertEquals(sql.toString(), 3, sql.size());
-        assertTrue((String) sql.get(2),
-            matches(" IN", (String) sql.get(2)));
-
-        assertRel(list, 4);
-        assertRels(list, 4);
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testLastPageQuery()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
-
-		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
-        OpenJPAQuery q = kem.createQuery(theQuery);
-
-
-        //FIXME jthomas commenting till we find how ordering can be done
-        //q.setOrdering("intField ascending");
-        q.getFetchPlan().setFetchBatchSize(3);    // 1 on page 2
-        q.getFetchPlan().addFetchGroups("rel");
-        q.getFetchPlan().addFetchGroups("rels");
-
-        // if we access a result object on the second page, we should get only
-        // two selects: the initial select and the eager stmnt for page
-        List list = (List) q.getResultList();
-        PagingPC pc = (PagingPC) list.get(3);
-        assertEquals(3, pc.getIntField());
-        assertEquals(list.toString(), 4, list.size());
-        assertEquals(sql.toString(), 2, sql.size());
-        // for single result, should use standard select, not IN
-        assertFalse((String) sql.get(1),
-            matches(" IN ", (String) sql.get(1)));
-        sql.clear();
-
-        em.close();
-    }
-
-    public void testSingleResultPage()
-        throws Exception {
-        initializePagingPCs();
-
-	    EntityManager em =currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        Extent extent = kem.createExtent(PagingPC.class, true);
-        extent.getFetchPlan().setFetchBatchSize(3);    // 1 on page 2
-        extent.getFetchPlan().addFetchGroup("rel");
-        extent.getFetchPlan().addFetchGroup("rels");
-
-        // we should get two selects: the initial select and the IN eager stmnt
-        List list = extent.list();
-        assertEquals(list.toString(), 4, list.size());
-        assertRel(list, 4);
-        assertRels(list, 4);
-        assertEquals(sql.toString(), 3, sql.size());
-        assertTrue((String) sql.get(1),
-            matches(" IN ", (String) sql.get(1)));
-        assertFalse((String) sql.get(2),
-            matches(" IN ", (String) sql.get(2)));
-        sql.clear();
-
-        em.close();
-    }
-
-  /*  public void testNonPagingRangeQuery()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        Query q = em.newQuery(PagingPC.class, "intField >= 0");
-
-        //FIXME jthomas commenting till we find how ordering can be done
-        //q.setOrdering("intField ascending");
-        q.setRange(1, 3);
-        q.getFetchPlan().setFetchSize(0);
-        q.getFetchPlan().addGroup("rel");
-
-        // if we only access the rel field, we should only have used one
-        // select; there won't be a size select since the range will be
-        // greedily consumed as it's so small
-        List list = (List) q.execute();
-        assertEquals(2, list.size());
-        assertRel(list, 2);
-        assertEquals(sql.toString(), 1, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        sql.clear();
-
-        // now accessing the rels collection should add selects
-        assertRels(list, 2);
-        assertEquals(sql.toString(), 2, sql.size());
-        sql.clear();
-
-        // now execute with a big range and small fetch size and bigger range
-        // and this time we should get a select for the size too
-        q.getFetchPlan().setFetchSize(2);
-        q.setRange(1, 4);
-        list = (List) q.execute();
-        assertEquals(3, list.size());
-        // so we don't have to re-execute to move back to beginning
-        list = new ArrayList(list);
-        assertRel(list, 3);
-        assertEquals(sql.toString(), 2, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        assertTrue((String) sql.get(1),
-            matches(" COUNT", (String) sql.get(1)));
-        sql.clear();
-
-        em.close();
-    }
-/*
-    public void testPagingRangeQuery()
-        throws Exception {
-        initializePagingPCs();
-
-        EntityManager em =currentEntityManager();
-        Query q = em.newQuery(PagingPC.class, "intField >= 0");
-
-        //FIXME jthomas commenting till we find how ordering can be done
-        //q.setOrdering("intField ascending");
-        q.setRange(1, 3);
-        q.getFetchPlan().setFetchSize(0);
-        q.getFetchPlan().addGroup("rel");
-        q.getFetchPlan().addGroup("rels");
-
-        // expect two selects: the primary select and the IN select; no size
-        // select expected because the range will be consumed greedily since
-        // it's so small
-        List list = (List) q.execute();
-        assertEquals(2, list.size());
-        assertRel(list, 2);
-        assertRels(list, 2);
-        assertEquals(sql.toString(), 2, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        assertTrue(sql + "",
-            matches(" IN ", (String) sql.get(1)));
-        sql.clear();
-
-        // now execute with a big range and small fetch size and bigger range
-        // and this time we should get a select for the size too
-        q.getFetchPlan().setFetchSize(2);
-        q.setRange(1, 4);
-        list = (List) q.execute();
-        assertEquals(3, list.size());
-        // so we don't have to re-execute to move back to beginning
-        list = new ArrayList(list);
-        assertRel(list, 3);
-        assertRels(list, 3);
-        assertEquals(sql.toString(), 4, sql.size());
-        assertTrue((String) sql.get(0),
-            matches(" >= ", (String) sql.get(0)));
-        assertTrue((String) sql.get(1),
-            matches(" COUNT", (String) sql.get(1)));
-        assertTrue((String) sql.get(2),
-            matches(" IN ", (String) sql.get(2)));
-        assertFalse((String) sql.get(3),
-            matches(" IN ", (String) sql.get(3)));
-        sql.clear();
-
-        em.close();
-    }
-*/
-    private void initializePagingPCs() {
-        EntityManager em =currentEntityManager();
-        startTx(em);
-
-       deleteAll(PagingPC.class,em);
-       deleteAll(PagingHelperPC.class,em);
-
-        endTx(em);
-
-        startTx(em);
-        PagingPC pc;
-        PagingHelperPC rel;
-        for (int i = 0; i < 4; i++) {
-            pc = new PagingPC();
-            pc.setIntField(i);
-            rel = new PagingHelperPC();
-            rel.setIntField(i + 1);
-            pc.setRel(rel);
-            pc.getRels().add(rel);
-            rel = new PagingHelperPC();
-            rel.setIntField(i + 2);
-            pc.getRels().add(rel);
-            em.persist(pc);
-        }
-
-        endTx(em);
-        em.close();
-        sql.clear();
-    }
-
-    private void initializePagingAppIdPCs() {
-        EntityManager em =currentEntityManager();
-        startTx(em);
-       deleteAll(PagingAppIdPC.class,em);
-       deleteAll(PagingHelperPC.class,em);
-        startTx(em);
-
-        startTx(em);
-        PagingAppIdPC pc;
-        PagingHelperPC rel;
-        for (int i = 0; i < 4; i++) {
-            pc = new PagingAppIdPC();
-            pc.setIntField(i);
-            pc.setLongField(i + 100);
-            rel = new PagingHelperPC();
-            rel.setIntField(i + 1);
-            pc.setRel(rel);
-            pc.getRels().add(rel);
-            rel = new PagingHelperPC();
-            rel.setIntField(i + 2);
-            pc.getRels().add(rel);
-            em.persist(pc);
-        }
-
-        endTx(em);
-     	em.close();
-        sql.clear ();
-	}
-
-	private Map getProps() {
-		Map props=new HashMap();
-		props.put("openjpa.DataCache", "true");
-		props.put("openjpa.RemoteCommitProvider", "sjvm");
-		props.put("openjpa.FlushBeforeQueries", "true");
-		props.put("javax.jdo.option.IgnoreCache", "false");
-		//propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
-		return props;
-	}
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.jdbc.meta.*;
+import org.apache.openjpa.jdbc.sql.*;
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+//import org.apache.openjpa.kernel.Extent;
+import org.apache.openjpa.persistence.Extent;
+
+/**
+ * <p>Test large result, to-many eager paging.</p>
+ *
+ */
+public class TestPagingResultObjectProvider
+    extends TestSQLListenerTestCase {
+
+	private OpenJPAEntityManagerFactory emf;
+
+	public TestPagingResultObjectProvider(String name)
+	{
+		super(name);
+	}
+
+    public void setUp() throws Exception{
+		super.setUp();
+		emf = getEmf(getProps());
+    	EntityManager em =currentEntityManager();
+    }
+
+
+
+    public boolean skipTest() {
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf)).getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        if (dict.joinSyntax == Join.SYNTAX_TRADITIONAL)
+            return true;
+
+        // skip test case that requires subselect for DBs that don't support it
+        if ("testPagingRangeQuery".equals(getName())
+            || "testNonPagingRangeQuery".equals(getName())) {
+            if (!conf.getDBDictionaryInstance().supportsSubselect)
+                return true;
+        }
+
+        return false;
+    }
+
+
+    public void testNonPagingExtent() {
+        initializePagingPCs();
+
+        EntityManager em= currentEntityManager();
+        //EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        Extent extent = kem.createExtent(PagingPC.class, true);
+
+        extent.getFetchPlan().setFetchBatchSize(0);
+        extent.getFetchPlan().addFetchGroup("rel");
+
+        // if we only access the rel field, we should only have used 1 select
+        List list = extent.list();
+        assertEquals(4, list.size());
+        assertRel(list, 4);
+        assertEquals(sql.toString(), 1, sql.size());
+        sql.clear();
+
+        // now accessing the rels collection should add selects
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 4, sql.size());
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testNonPagingQuery()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+
+		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
+
+        //OpenJPAQuery q = kem.createQuery(PagingPC.class.getSimpleName(), "intField >= 0");
+        OpenJPAQuery q = kem.createQuery(theQuery);
+
+        q.getFetchPlan().setFetchBatchSize(0);
+        q.getFetchPlan().addFetchGroups("rel");
+
+        // if we only access the rel field, we should only have used two
+        // selects: one for the query and one for the size
+        List list = (List) q.getResultList();
+        assertEquals(4, list.size());
+        assertRel(list, 4);
+        assertEquals(sql.toString(), 2, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        assertTrue((String) sql.get(1),
+            matches(" COUNT", (String) sql.get(1)));
+        sql.clear();
+
+        // now accessing the rels collection should add selects
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 4, sql.size());
+        sql.clear();
+
+        em.close();
+    }
+
+    /**
+     * Check that the rel field was retrieved correctly.
+     */
+   private void assertRel(List pcs, int size) {
+        PagingPC pc;
+        for (int i = 0; i < size; i++) {
+            pc = (PagingPC) pcs.get(i);
+            assertNotNull(pc.getRel());
+            assertEquals(pc.getIntField() + 1, pc.getRel().getIntField());
+        }
+        try {
+            pcs.get(size + 1);
+            fail("Retrieved past end of list");
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * Check that the rels field was retrieved correctly.
+     */
+    private void assertRels(List pcs, int size) {
+        PagingPC pc;
+        for (int i = 0; i < size; i++) {
+            pc = (PagingPC) pcs.get(i);
+            assertEquals(2, pc.getRels().size());
+            assertEquals(pc.getIntField() + 1, ((PagingHelperPC)
+                pc.getRels().get(0)).getIntField());
+            assertEquals(pc.getIntField() + 2, ((PagingHelperPC)
+                pc.getRels().get(1)).getIntField());
+        }
+        try {
+            pcs.get(size + 1);
+            fail("Retrieved past end of list");
+        } catch (Exception e) {
+        }
+    }
+
+    public void testPagingExtent()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        Extent extent = kem.createExtent(PagingPC.class, true);
+        extent.getFetchPlan().setFetchBatchSize(0);
+        extent.getFetchPlan().addFetchGroup("rel");
+        extent.getFetchPlan().addFetchGroup("rels");
+
+
+        // we should get two selects: the initial select and the IN eager stmnt
+        List list = extent.list();
+        assertEquals(4, list.size());
+        assertRel(list, 4);
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 2, sql.size());
+        assertTrue((String) sql.get(1),
+            matches(" IN ", (String) sql.get(1)));
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testPagingQuery()
+        throws Exception {
+        initializePagingPCs();
+
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+
+		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
+        OpenJPAQuery q = kem.createQuery(theQuery);
+        q.getFetchPlan().setFetchBatchSize(0);
+        q.getFetchPlan().addFetchGroups("rel");
+        q.getFetchPlan().addFetchGroups("rels");
+
+
+        // we should get three selects: the initial select, the COUNT for the
+        // size, and the IN eager stmnt
+        List list = (List) q.getResultList();
+        assertEquals(4, list.size());
+        assertRel(list, 4);
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 3, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        assertTrue((String) sql.get(1),
+            matches(" COUNT", (String) sql.get(1)));
+        assertTrue((String) sql.get(2),
+            matches(" IN ", (String) sql.get(2)));
+        assertFalse((String) sql.get(2),
+            matches(" >= ", (String) sql.get(2)));
+        sql.clear();
+
+        // if we execute and traverse a result before getting the size, we
+        // should only get 2 selects, since the caching of the page should
+        // reach the end of the list and therefore know the total size
+        list = (List) q.getResultList();
+        list.get(0);
+        assertEquals(4, list.size());
+        assertRel(list, 4);
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 2, sql.size());
+        assertTrue((String) sql.get(1),
+            matches(" IN ", (String) sql.get(1)));
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testPagingAppIdExtent()
+        throws Exception {
+        initializePagingAppIdPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        Extent extent = kem.createExtent(PagingAppIdPC.class, true);
+
+        extent.getFetchPlan().setFetchBatchSize(0);
+        extent.getFetchPlan().addFetchGroup("rel");
+        extent.getFetchPlan().addFetchGroup("rels");
+
+        // we should get two selects: the initial select and the IN eager stmnt
+        List list = extent.list();
+        assertEquals(4, list.size());
+        assertAppIdRel(list, 4);
+        assertAppIdRels(list, 4);
+        assertEquals(sql.toString(), 2, sql.size());
+        assertTrue((String) sql.get(1),
+            matches(" OR ", (String) sql.get(1)));
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testPagingAppIdQuery()
+        throws Exception {
+        initializePagingAppIdPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+
+		String theQuery="select a FROM "+PagingAppIdPC.class.getSimpleName()+" a where a.intField >= 0";
+        OpenJPAQuery q = kem.createQuery(theQuery);
+
+
+        q.getFetchPlan().setFetchBatchSize(0);
+        q.getFetchPlan().addFetchGroups("rel");
+        q.getFetchPlan().addFetchGroups("rels");
+
+        // we should get three selects: the initial select, the COUNT for the
+        // size, and the OR eager stmnt
+        List list = (List) q.getResultList();
+        assertEquals(4, list.size());
+        assertAppIdRel(list, 4);
+        assertAppIdRels(list, 4);
+        assertEquals(sql.toString(), 3, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        assertTrue((String) sql.get(1),
+            matches(" COUNT", (String) sql.get(1)));
+        assertTrue((String) sql.get(2),
+            matches(" OR ", (String) sql.get(2)));
+        assertFalse((String) sql.get(2),
+            matches(" >= ", (String) sql.get(2)));
+        sql.clear();
+
+        em.close();
+    }
+
+    /**
+     * Check that the rel field was retrieved correctly.
+     */
+    private void assertAppIdRel(List pcs, int size) {
+        PagingAppIdPC pc;
+        for (int i = 0; i < size; i++) {
+            pc = (PagingAppIdPC) pcs.get(i);
+            assertNotNull(pc.getRel());
+            assertEquals(pc.getIntField() + 1, pc.getRel().getIntField());
+        }
+        try {
+            pcs.get(size + 1);
+            fail("Retrieved past end of list");
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * Check that the rels field was retrieved correctly.
+     */
+    private void assertAppIdRels(List pcs, int size) {
+        PagingAppIdPC pc;
+        for (int i = 0; i < size; i++) {
+            pc = (PagingAppIdPC) pcs.get(i);
+            assertEquals(2, pc.getRels().size());
+            assertEquals(pc.getIntField() + 1, ((PagingHelperPC)
+                pc.getRels().get(0)).getIntField());
+            assertEquals(pc.getIntField() + 2, ((PagingHelperPC)
+                pc.getRels().get(1)).getIntField());
+        }
+        try {
+            pcs.get(size + 1);
+            fail("Retrieved past end of list");
+        } catch (Exception e) {
+        }
+    }
+
+    public void testMultiPageExtent()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+        Extent extent = kem.createExtent(PagingPC.class, true);
+
+        extent.getFetchPlan().setFetchBatchSize(2);    // 2 pages of 2
+        extent.getFetchPlan().addFetchGroup("rel");
+        extent.getFetchPlan().addFetchGroup("rels");
+
+        // we should get two selects: the initial select and the IN eager stmnt
+        List list = extent.list();
+        assertEquals(list.toString(), 4, list.size());
+        assertRel(list, 4);
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 3, sql.size());
+        assertTrue((String) sql.get(1),
+            matches(" IN ", (String) sql.get(1)));
+        assertTrue((String) sql.get(2),
+            matches(" IN ", (String) sql.get(2)));
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testMultiPageQuery()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+
+		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
+        OpenJPAQuery q = kem.createQuery(theQuery);
+
+
+		//FIXME jthomas commenting till we find how ordering can be done
+        //q.setOrdering("intField ascending");
+        q.getFetchPlan().setFetchBatchSize(2);    // 2 pages of 2
+        q.getFetchPlan().addFetchGroup("rel");
+        q.getFetchPlan().addFetchGroup("rels");
+
+        // we should get four selects: the initial select, the count, and the
+        // two IN eager stmnts
+        List list = (List) q.getResultList();
+        assertEquals(list.toString(), 4, list.size());
+        // so we don't have to re-execute to move back to beginning
+        list = new ArrayList(list);
+        assertRel(list, 4);
+        assertRels(list, 4);
+
+        assertEquals(sql.toString(), 4, sql.size());
+        assertTrue((String) sql.get(1),
+            matches(" COUNT", (String) sql.get(1)));
+        assertTrue((String) sql.get(2),
+            matches(" IN ", (String) sql.get(2)));
+        assertTrue((String) sql.get(3),
+            matches(" IN ", (String) sql.get(3)));
+        sql.clear();
+
+        // if we access a result object on the second page, we should get only
+        // three selects: the initial select, the count, and the IN eager stmnt
+        // for page 2
+        list = (List) q.getResultList();
+        assertEquals(list.toString(), 4, list.size());
+        PagingPC pc = (PagingPC) list.get(2);
+        assertEquals(2, pc.getIntField());
+        assertEquals(sql.toString(), 3, sql.size());
+        assertTrue((String) sql.get(2),
+            matches(" IN", (String) sql.get(2)));
+
+        assertRel(list, 4);
+        assertRels(list, 4);
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testLastPageQuery()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+
+		String theQuery="select a FROM "+PagingPC.class.getSimpleName()+" a where a.intField >= 0";
+        OpenJPAQuery q = kem.createQuery(theQuery);
+
+
+        //FIXME jthomas commenting till we find how ordering can be done
+        //q.setOrdering("intField ascending");
+        q.getFetchPlan().setFetchBatchSize(3);    // 1 on page 2
+        q.getFetchPlan().addFetchGroups("rel");
+        q.getFetchPlan().addFetchGroups("rels");
+
+        // if we access a result object on the second page, we should get only
+        // two selects: the initial select and the eager stmnt for page
+        List list = (List) q.getResultList();
+        PagingPC pc = (PagingPC) list.get(3);
+        assertEquals(3, pc.getIntField());
+        assertEquals(list.toString(), 4, list.size());
+        assertEquals(sql.toString(), 2, sql.size());
+        // for single result, should use standard select, not IN
+        assertFalse((String) sql.get(1),
+            matches(" IN ", (String) sql.get(1)));
+        sql.clear();
+
+        em.close();
+    }
+
+    public void testSingleResultPage()
+        throws Exception {
+        initializePagingPCs();
+
+	    EntityManager em =currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        Extent extent = kem.createExtent(PagingPC.class, true);
+        extent.getFetchPlan().setFetchBatchSize(3);    // 1 on page 2
+        extent.getFetchPlan().addFetchGroup("rel");
+        extent.getFetchPlan().addFetchGroup("rels");
+
+        // we should get two selects: the initial select and the IN eager stmnt
+        List list = extent.list();
+        assertEquals(list.toString(), 4, list.size());
+        assertRel(list, 4);
+        assertRels(list, 4);
+        assertEquals(sql.toString(), 3, sql.size());
+        assertTrue((String) sql.get(1),
+            matches(" IN ", (String) sql.get(1)));
+        assertFalse((String) sql.get(2),
+            matches(" IN ", (String) sql.get(2)));
+        sql.clear();
+
+        em.close();
+    }
+
+  /*  public void testNonPagingRangeQuery()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        Query q = em.newQuery(PagingPC.class, "intField >= 0");
+
+        //FIXME jthomas commenting till we find how ordering can be done
+        //q.setOrdering("intField ascending");
+        q.setRange(1, 3);
+        q.getFetchPlan().setFetchSize(0);
+        q.getFetchPlan().addGroup("rel");
+
+        // if we only access the rel field, we should only have used one
+        // select; there won't be a size select since the range will be
+        // greedily consumed as it's so small
+        List list = (List) q.execute();
+        assertEquals(2, list.size());
+        assertRel(list, 2);
+        assertEquals(sql.toString(), 1, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        sql.clear();
+
+        // now accessing the rels collection should add selects
+        assertRels(list, 2);
+        assertEquals(sql.toString(), 2, sql.size());
+        sql.clear();
+
+        // now execute with a big range and small fetch size and bigger range
+        // and this time we should get a select for the size too
+        q.getFetchPlan().setFetchSize(2);
+        q.setRange(1, 4);
+        list = (List) q.execute();
+        assertEquals(3, list.size());
+        // so we don't have to re-execute to move back to beginning
+        list = new ArrayList(list);
+        assertRel(list, 3);
+        assertEquals(sql.toString(), 2, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        assertTrue((String) sql.get(1),
+            matches(" COUNT", (String) sql.get(1)));
+        sql.clear();
+
+        em.close();
+    }
+/*
+    public void testPagingRangeQuery()
+        throws Exception {
+        initializePagingPCs();
+
+        EntityManager em =currentEntityManager();
+        Query q = em.newQuery(PagingPC.class, "intField >= 0");
+
+        //FIXME jthomas commenting till we find how ordering can be done
+        //q.setOrdering("intField ascending");
+        q.setRange(1, 3);
+        q.getFetchPlan().setFetchSize(0);
+        q.getFetchPlan().addGroup("rel");
+        q.getFetchPlan().addGroup("rels");
+
+        // expect two selects: the primary select and the IN select; no size
+        // select expected because the range will be consumed greedily since
+        // it's so small
+        List list = (List) q.execute();
+        assertEquals(2, list.size());
+        assertRel(list, 2);
+        assertRels(list, 2);
+        assertEquals(sql.toString(), 2, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        assertTrue(sql + "",
+            matches(" IN ", (String) sql.get(1)));
+        sql.clear();
+
+        // now execute with a big range and small fetch size and bigger range
+        // and this time we should get a select for the size too
+        q.getFetchPlan().setFetchSize(2);
+        q.setRange(1, 4);
+        list = (List) q.execute();
+        assertEquals(3, list.size());
+        // so we don't have to re-execute to move back to beginning
+        list = new ArrayList(list);
+        assertRel(list, 3);
+        assertRels(list, 3);
+        assertEquals(sql.toString(), 4, sql.size());
+        assertTrue((String) sql.get(0),
+            matches(" >= ", (String) sql.get(0)));
+        assertTrue((String) sql.get(1),
+            matches(" COUNT", (String) sql.get(1)));
+        assertTrue((String) sql.get(2),
+            matches(" IN ", (String) sql.get(2)));
+        assertFalse((String) sql.get(3),
+            matches(" IN ", (String) sql.get(3)));
+        sql.clear();
+
+        em.close();
+    }
+*/
+    private void initializePagingPCs() {
+        EntityManager em =currentEntityManager();
+        startTx(em);
+
+       deleteAll(PagingPC.class,em);
+       deleteAll(PagingHelperPC.class,em);
+
+        endTx(em);
+
+        startTx(em);
+        PagingPC pc;
+        PagingHelperPC rel;
+        for (int i = 0; i < 4; i++) {
+            pc = new PagingPC();
+            pc.setIntField(i);
+            rel = new PagingHelperPC();
+            rel.setIntField(i + 1);
+            pc.setRel(rel);
+            pc.getRels().add(rel);
+            rel = new PagingHelperPC();
+            rel.setIntField(i + 2);
+            pc.getRels().add(rel);
+            em.persist(pc);
+        }
+
+        endTx(em);
+        em.close();
+        sql.clear();
+    }
+
+    private void initializePagingAppIdPCs() {
+        EntityManager em =currentEntityManager();
+        startTx(em);
+       deleteAll(PagingAppIdPC.class,em);
+       deleteAll(PagingHelperPC.class,em);
+        startTx(em);
+
+        startTx(em);
+        PagingAppIdPC pc;
+        PagingHelperPC rel;
+        for (int i = 0; i < 4; i++) {
+            pc = new PagingAppIdPC();
+            pc.setIntField(i);
+            pc.setLongField(i + 100);
+            rel = new PagingHelperPC();
+            rel.setIntField(i + 1);
+            pc.setRel(rel);
+            pc.getRels().add(rel);
+            rel = new PagingHelperPC();
+            rel.setIntField(i + 2);
+            pc.getRels().add(rel);
+            em.persist(pc);
+        }
+
+        endTx(em);
+     	em.close();
+        sql.clear ();
+	}
+
+	private Map getProps() {
+		Map props=new HashMap();
+		props.put("openjpa.DataCache", "true");
+		props.put("openjpa.RemoteCommitProvider", "sjvm");
+		props.put("openjpa.FlushBeforeQueries", "true");
+		props.put("javax.jdo.option.IgnoreCache", "false");
+		//propsMap.put("openjpa.BrokerImpl", "kodo.datacache.CacheTestBroker");//CacheTestBroker.class.getName ());
+		return props;
+	}
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestRawSQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestRawSQL.java
index a92a4a6..ef66634 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestRawSQL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestRawSQL.java
@@ -1,180 +1,180 @@
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import java.sql.*;
-import java.util.*;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.sql.ResultSetResult;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.jdbc.kernel.GenericResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultList;
-import org.apache.openjpa.lib.rop.EagerResultList;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.kernel.AbstractPCResultObjectProvider;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.FetchConfiguration;
-/**
- *
- */
-
-
-public class TestRawSQL extends BaseJDBCTest {
-    
-    /** Creates a new instance of TestRawSQL */
-    private Object[] _oids = new Object[3];
-    private String[] _strings = new String[]{ "a", "b", "c" };
-    private int[] _ints = new int[]{ 1, 2, 3 };
-
-    public TestRawSQL(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-       deleteAll(RawSQL.class);
-        EntityManager em = currentEntityManager();
-        Broker broker = JPAFacadeHelper.toBroker(em);
-
-        broker.begin();
-        RawSQL raw;
-        for (int i = 0; i < _oids.length; i++) {
-            raw = new RawSQL(_strings[i], _ints[i]);
-            broker.persist(raw, null);
-            _oids[i] = broker.getUserObject(raw);
-        }
-        broker.commit();
-        broker.close();
-        em.close();
-    }
-
-    public void testLoadWithResult()
-        throws Exception {
-        
-        EntityManager em = currentEntityManager();
-        Broker broker = JPAFacadeHelper.toBroker(em);
-       
-        JDBCStore store = (JDBCStore)broker.getStoreManager();
-
-        Connection conn = store.getConnection();
-        Statement stmnt = conn.createStatement();
-        ResultSet rs = stmnt.executeQuery("SELECT * FROM RAWSQL "
-        + "ORDER BY INTFIELD");
-        ResultSetResult res = new ResultSetResult(rs,
-        store.getConfiguration().getDBDictionaryInstance());
-        ResultObjectProvider rop = new GenericResultObjectProvider
-        (RawSQL.class, store, null, res);
-        ResultList rl = new EagerResultList(rop);
-        check(rl, broker);
-        rl.close();
-        broker.close();
-        em.close();
-    }
-
-        public void testLoadWithPCROP()
-        throws Exception {
-            
-        EntityManager em = currentEntityManager();    
-        Broker broker = JPAFacadeHelper.toBroker(em);
-        ResultObjectProvider rop = new AbstractPCResultObjectProvider(broker) {
-            private int _row = -1;
-
-            public boolean supportsRandomAccess() {
-                return true;
-            }
-
-            public boolean next() {
-                return ++_row < _oids.length;
-            }
-
-            public boolean absolute(int pos) {
-                _row = pos;
-                return _row < _oids.length;
-            }
-
-            public int size() {
-                return _oids.length;
-            }
-
-            public void close() {
-            }
-
-            public void handleCheckedException(Exception e) {
-                throw new RuntimeException(e.toString());
-            }
-
-            protected Object getObjectId(ClassMetaData meta) {
-                return _oids[_row];
-            }
-
-            protected Class getPCType() {
-                return RawSQL.class;
-            }
-
-            protected void load(OpenJPAStateManager sm, 
-                FetchConfiguration fetch) {
-                ClassMetaData meta = sm.getMetaData();
-                sm.storeStringField(meta.getField("stringField").getIndex(),
-                    _strings[_row]);
-                sm.storeIntField(meta.getField("intField").getIndex(),
-                    _ints[_row]);
-
-                // note that we're not loading version info here, so the system
-                // will go out and get it after this intial load; kinda neat
-            }
-        };
-        ResultList rl = new EagerResultList(rop);
-        check(rl, broker);
-        rl.close();
-        broker.close();
-    }
-
-    
-    
-    private void check(ResultList rl, Broker broker) {
-        RawSQL raw;
-        int i = 0;
-        for (Iterator itr = rl.iterator(); itr.hasNext(); i++) {
-            raw = (RawSQL) itr.next();
-            assertTrue(broker.getStateManager(raw).getLoaded().get(0));
-            assertTrue(broker.getStateManager(raw).getLoaded().get(1));
-            if (i < _oids.length) {
-                assertEquals(_strings[i], raw.getStringField());
-                assertEquals(_ints[i], raw.getIntField());
-            }
-        }
-        assertEquals(_oids.length, i);
-        assertEquals(_oids.length, rl.size());
-    }
-    
-    
-}
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import java.sql.*;
+import java.util.*;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.sql.ResultSetResult;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.jdbc.kernel.GenericResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultList;
+import org.apache.openjpa.lib.rop.EagerResultList;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.kernel.AbstractPCResultObjectProvider;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.FetchConfiguration;
+/**
+ *
+ */
+
+
+public class TestRawSQL extends BaseJDBCTest {
+    
+    /** Creates a new instance of TestRawSQL */
+    private Object[] _oids = new Object[3];
+    private String[] _strings = new String[]{ "a", "b", "c" };
+    private int[] _ints = new int[]{ 1, 2, 3 };
+
+    public TestRawSQL(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+       deleteAll(RawSQL.class);
+        EntityManager em = currentEntityManager();
+        Broker broker = JPAFacadeHelper.toBroker(em);
+
+        broker.begin();
+        RawSQL raw;
+        for (int i = 0; i < _oids.length; i++) {
+            raw = new RawSQL(_strings[i], _ints[i]);
+            broker.persist(raw, null);
+            _oids[i] = broker.getUserObject(raw);
+        }
+        broker.commit();
+        broker.close();
+        em.close();
+    }
+
+    public void testLoadWithResult()
+        throws Exception {
+        
+        EntityManager em = currentEntityManager();
+        Broker broker = JPAFacadeHelper.toBroker(em);
+       
+        JDBCStore store = (JDBCStore)broker.getStoreManager();
+
+        Connection conn = store.getConnection();
+        Statement stmnt = conn.createStatement();
+        ResultSet rs = stmnt.executeQuery("SELECT * FROM RAWSQL "
+        + "ORDER BY INTFIELD");
+        ResultSetResult res = new ResultSetResult(rs,
+        store.getConfiguration().getDBDictionaryInstance());
+        ResultObjectProvider rop = new GenericResultObjectProvider
+        (RawSQL.class, store, null, res);
+        ResultList rl = new EagerResultList(rop);
+        check(rl, broker);
+        rl.close();
+        broker.close();
+        em.close();
+    }
+
+        public void testLoadWithPCROP()
+        throws Exception {
+            
+        EntityManager em = currentEntityManager();    
+        Broker broker = JPAFacadeHelper.toBroker(em);
+        ResultObjectProvider rop = new AbstractPCResultObjectProvider(broker) {
+            private int _row = -1;
+
+            public boolean supportsRandomAccess() {
+                return true;
+            }
+
+            public boolean next() {
+                return ++_row < _oids.length;
+            }
+
+            public boolean absolute(int pos) {
+                _row = pos;
+                return _row < _oids.length;
+            }
+
+            public int size() {
+                return _oids.length;
+            }
+
+            public void close() {
+            }
+
+            public void handleCheckedException(Exception e) {
+                throw new RuntimeException(e.toString());
+            }
+
+            protected Object getObjectId(ClassMetaData meta) {
+                return _oids[_row];
+            }
+
+            protected Class getPCType() {
+                return RawSQL.class;
+            }
+
+            protected void load(OpenJPAStateManager sm, 
+                FetchConfiguration fetch) {
+                ClassMetaData meta = sm.getMetaData();
+                sm.storeStringField(meta.getField("stringField").getIndex(),
+                    _strings[_row]);
+                sm.storeIntField(meta.getField("intField").getIndex(),
+                    _ints[_row]);
+
+                // note that we're not loading version info here, so the system
+                // will go out and get it after this intial load; kinda neat
+            }
+        };
+        ResultList rl = new EagerResultList(rop);
+        check(rl, broker);
+        rl.close();
+        broker.close();
+    }
+
+    
+    
+    private void check(ResultList rl, Broker broker) {
+        RawSQL raw;
+        int i = 0;
+        for (Iterator itr = rl.iterator(); itr.hasNext(); i++) {
+            raw = (RawSQL) itr.next();
+            assertTrue(broker.getStateManager(raw).getLoaded().get(0));
+            assertTrue(broker.getStateManager(raw).getLoaded().get(1));
+            if (i < _oids.length) {
+                assertEquals(_strings[i], raw.getStringField());
+                assertEquals(_ints[i], raw.getIntField());
+            }
+        }
+        assertEquals(_oids.length, i);
+        assertEquals(_oids.length, rl.size());
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestSQLListenerTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestSQLListenerTestCase.java
index a49f806..432b80f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestSQLListenerTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestSQLListenerTestCase.java
@@ -1,176 +1,176 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-import java.util.*;
-
-
-import org.apache.openjpa.kernel.*;
-
-
-
-import org.apache.openjpa.lib.jdbc.*;
-
-/**
- * Test case that provides access to all the SQL that is executed.
- *
- */
-public abstract class TestSQLListenerTestCase
-    extends BaseJDBCTest {
-
-    protected static final Collection brokers = new HashSet();
-    public static List sql = new ArrayList();
-
-    public TestSQLListenerTestCase() {
-    }
-
-    public TestSQLListenerTestCase(String name) {
-        super(name);
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-        setUpTestCase();
-        sql.clear();
-    }
-
-    /**
-     * Override for setUp() behavior.
-     */
-    public void setUpTestCase() {
-    }
-
-    public final void tearDown()
-        throws Exception {
-        super.tearDown();
-        tearDownTestCase();
-        sql.clear();
-    }
-
-    /**
-     * Override for tearDown() behavior.
-     */
-    public void tearDownTestCase() {
-    }
-
-    /**
-     * Confirm that the specified SQL has been executed.
-     *
-     * @param sqlExp the SQL expression. E.g., "SELECT FOO .*"
-     */
-    public void assertSQL(String sqlExp)
-        throws Exception {
-        for (Iterator i = sql.iterator(); i.hasNext();) {
-            String statement = (String) i.next();
-            if (matches(sqlExp, statement))
-                return;
-        }
-
-        fail("Expected regular expression <" + sqlExp + "> to have"
-            + " existed in SQL statements: " + sql);
-    }
-
-    /**
-     * Confirm that the specified SQL has not been executed.
-     *
-     * @param sqlExp the SQL expression. E.g., "SELECT BADCOLUMN .*"
-     */
-    public void assertNotSQL(String sqlExp)
-        throws Exception {
-        boolean failed = false;
-
-        for (Iterator i = sql.iterator(); i.hasNext();) {
-            String statement = (String) i.next();
-            if (matches(sqlExp, statement))
-                failed = true;
-        }
-
-        if (failed)
-            fail("Regular expression <" + sqlExp + ">"
-                + " should not have been executed in SQL statements: " + sql);
-    }
-/*
-
-    public KodoPersistenceManager getPM() {
-        KodoPersistenceManager pm = (KodoPersistenceManager) getPMFactory().
-            getPersistenceManager();
-        brokers.add(KodoJDOHelper.toBroker(pm));
-        return pm;
-    }
-
-    public KodoPersistenceManagerFactory getPMFactory() {
-        return getPMFactory(null);
-    }
-    public BrokerFactory getBrokerFactory(String[] props) {
-        String[] builtin = new String[]{
-            "openjpa.jdbc.JDBCListeners", Listener.class.getName()
-        };
-
-        if (props == null)
-            props = builtin;
-        else {
-            String[] tmp = new String[props.length + builtin.length];
-            System.arraycopy(props, 0, tmp, 0, props.length);
-            System.arraycopy(builtin, 0, tmp, props.length, builtin.length);
-            props = tmp;
-        }
-
-        return super.getBrokerFactory(props);
-    }
-    public KodoPersistenceManagerFactory getPMFactory(String[] props) {
-        String[] builtin = new String[]{
-            "openjpa.jdbc.JDBCListeners", Listener.class.getName()
-        };
-
-        if (props == null)
-            props = builtin;
-        else {
-            String[] tmp = new String[props.length + builtin.length];
-            System.arraycopy(props, 0, tmp, 0, props.length);
-            System.arraycopy(builtin, 0, tmp, props.length, builtin.length);
-            props = tmp;
-        }
-
-        return super.getPMFactory(props);
-    }
-
-    public Broker getBroker() {
-        Broker broker = getBrokerFactory().newBroker();
-        brokers.add(broker);
-        return broker;
-    }
-
-    public BrokerFactory getBrokerFactory() {
-        return getBrokerFactory(null);
-    }
-
-*/
-
-
-
-    public static class Listener
-        extends AbstractJDBCListener {
-
-        public void beforeExecuteStatement(JDBCEvent event) {
-            if (event.getSQL() != null)
-                sql.add(event.getSQL());
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+import java.util.*;
+
+
+import org.apache.openjpa.kernel.*;
+
+
+
+import org.apache.openjpa.lib.jdbc.*;
+
+/**
+ * Test case that provides access to all the SQL that is executed.
+ *
+ */
+public abstract class TestSQLListenerTestCase
+    extends BaseJDBCTest {
+
+    protected static final Collection brokers = new HashSet();
+    public static List sql = new ArrayList();
+
+    public TestSQLListenerTestCase() {
+    }
+
+    public TestSQLListenerTestCase(String name) {
+        super(name);
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+        setUpTestCase();
+        sql.clear();
+    }
+
+    /**
+     * Override for setUp() behavior.
+     */
+    public void setUpTestCase() {
+    }
+
+    public final void tearDown()
+        throws Exception {
+        super.tearDown();
+        tearDownTestCase();
+        sql.clear();
+    }
+
+    /**
+     * Override for tearDown() behavior.
+     */
+    public void tearDownTestCase() {
+    }
+
+    /**
+     * Confirm that the specified SQL has been executed.
+     *
+     * @param sqlExp the SQL expression. E.g., "SELECT FOO .*"
+     */
+    public void assertSQL(String sqlExp)
+        throws Exception {
+        for (Iterator i = sql.iterator(); i.hasNext();) {
+            String statement = (String) i.next();
+            if (matches(sqlExp, statement))
+                return;
+        }
+
+        fail("Expected regular expression <" + sqlExp + "> to have"
+            + " existed in SQL statements: " + sql);
+    }
+
+    /**
+     * Confirm that the specified SQL has not been executed.
+     *
+     * @param sqlExp the SQL expression. E.g., "SELECT BADCOLUMN .*"
+     */
+    public void assertNotSQL(String sqlExp)
+        throws Exception {
+        boolean failed = false;
+
+        for (Iterator i = sql.iterator(); i.hasNext();) {
+            String statement = (String) i.next();
+            if (matches(sqlExp, statement))
+                failed = true;
+        }
+
+        if (failed)
+            fail("Regular expression <" + sqlExp + ">"
+                + " should not have been executed in SQL statements: " + sql);
+    }
+/*
+
+    public KodoPersistenceManager getPM() {
+        KodoPersistenceManager pm = (KodoPersistenceManager) getPMFactory().
+            getPersistenceManager();
+        brokers.add(KodoJDOHelper.toBroker(pm));
+        return pm;
+    }
+
+    public KodoPersistenceManagerFactory getPMFactory() {
+        return getPMFactory(null);
+    }
+    public BrokerFactory getBrokerFactory(String[] props) {
+        String[] builtin = new String[]{
+            "openjpa.jdbc.JDBCListeners", Listener.class.getName()
+        };
+
+        if (props == null)
+            props = builtin;
+        else {
+            String[] tmp = new String[props.length + builtin.length];
+            System.arraycopy(props, 0, tmp, 0, props.length);
+            System.arraycopy(builtin, 0, tmp, props.length, builtin.length);
+            props = tmp;
+        }
+
+        return super.getBrokerFactory(props);
+    }
+    public KodoPersistenceManagerFactory getPMFactory(String[] props) {
+        String[] builtin = new String[]{
+            "openjpa.jdbc.JDBCListeners", Listener.class.getName()
+        };
+
+        if (props == null)
+            props = builtin;
+        else {
+            String[] tmp = new String[props.length + builtin.length];
+            System.arraycopy(props, 0, tmp, 0, props.length);
+            System.arraycopy(builtin, 0, tmp, props.length, builtin.length);
+            props = tmp;
+        }
+
+        return super.getPMFactory(props);
+    }
+
+    public Broker getBroker() {
+        Broker broker = getBrokerFactory().newBroker();
+        brokers.add(broker);
+        return broker;
+    }
+
+    public BrokerFactory getBrokerFactory() {
+        return getBrokerFactory(null);
+    }
+
+*/
+
+
+
+    public static class Listener
+        extends AbstractJDBCListener {
+
+        public void beforeExecuteStatement(JDBCEvent event) {
+            if (event.getSQL() != null)
+                sql.add(event.getSQL());
+		}
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestUnknownSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestUnknownSubclass.java
index 7ee7b49..a8ed49f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestUnknownSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/kernel/TestUnknownSubclass.java
@@ -1,138 +1,138 @@
-/*
- * TestUnknownSubclass.java
- *
- * Created on September 29, 2006, 3:55 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.kernel;
-
-
-import java.sql.*;
-import javax.sql.*;
-import org.apache.openjpa.jdbc.conf.*;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-
-public class TestUnknownSubclass  extends JDBCTestCase {
-
-    private String parentName =
-        "openjpa.jdbc.kernel.UnknownSubclassParent";
-    private String childName =
-        "openjpa.jdbc.kernel.UnknownSubclassChild";
-
-    /** Creates a new instance of TestUnknownSubclass */
-    public TestUnknownSubclass() {
-    }
- 
-    public TestUnknownSubclass(String name) {
-        super(name);
-    }
-    public void setUp()
-        throws Exception {
-        // pcl: in the new (registration-less) system, this should not
-        // matter.
-        //assertNotRegistered (parentName);
-        //assertNotRegistered (childName);
-
-        EntityManager em= currentEntityManager();
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
-        
-        
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) kem).getConfiguration();
-        boolean flat = !isInheritanceStrategyVertical();
-
-        DataSource ds = (DataSource) conf.getConnectionFactory();
-        Connection c = ds.getConnection(conf.getConnectionUserName(),
-            conf.getConnectionPassword());
-        if (c.getAutoCommit())
-            c.setAutoCommit(false);
-
-        c.createStatement()
-            .executeUpdate("DELETE FROM UNKNOWNSUBCLASSPARENT");
-        if (!flat)
-            c.createStatement()
-                .executeUpdate("DELETE FROM UNKNOWNSUBCLASSCHILD");
-
-        String insert = "INSERT INTO UNKNOWNSUBCLASSPARENT"
-            + "(TYP, ID, VERSN) VALUES (";
-
-        c.createStatement().executeUpdate(insert
-            + "'" + parentName + "', 1, 1)");
-        c.createStatement().executeUpdate(insert
-            + "'" + childName + "', 2, 1)");
-
-        if (!flat) {
-            insert = "INSERT INTO UNKNOWNSUBCLASSCHILD (ID) VALUES (";
-            c.createStatement().executeUpdate(insert + "1)");
-            c.createStatement().executeUpdate(insert + "2)");
-        }
-
-        c.commit();
-        em.close();
-        kem.close();
-    }
-
-        public void testUnknownSubclass()
-        throws Exception {
-        // assertNotRegistered (parentName);
-        // assertNotRegistered (childName);
-
-        Class c = UnknownSubclassParent.class;
-
-        // assertNotRegistered (childName);
-
-        EntityManager em= currentEntityManager();            
-        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
-
-        
-        startTx(em);
-        // c = UnknownSubclassChild.class;
-
-        //FIXME jthomas conversion incomplete 
-        /*
-        assertSize(1, kem.createExtent(UnknownSubclassParent.class, false));
-        assertSize(1, kem.newQuery(
-            kem.createExtent(UnknownSubclassParent.class, false), ""));
-
-        assertSize(2, kem.createExtent(UnknownSubclassParent.class, true));
-        assertSize(2, kem.createQuery(kem.createExtent(UnknownSubclassParent.class, true), ""));
-        */
-        endTx(em);
-        
-        em.close();
-        kem.close();
-    }
-    
-    
-}
+/*
+ * TestUnknownSubclass.java
+ *
+ * Created on September 29, 2006, 3:55 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.kernel;
+
+
+import java.sql.*;
+import javax.sql.*;
+import org.apache.openjpa.jdbc.conf.*;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+
+public class TestUnknownSubclass  extends JDBCTestCase {
+
+    private String parentName =
+        "openjpa.jdbc.kernel.UnknownSubclassParent";
+    private String childName =
+        "openjpa.jdbc.kernel.UnknownSubclassChild";
+
+    /** Creates a new instance of TestUnknownSubclass */
+    public TestUnknownSubclass() {
+    }
+ 
+    public TestUnknownSubclass(String name) {
+        super(name);
+    }
+    public void setUp()
+        throws Exception {
+        // pcl: in the new (registration-less) system, this should not
+        // matter.
+        //assertNotRegistered (parentName);
+        //assertNotRegistered (childName);
+
+        EntityManager em= currentEntityManager();
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+        
+        
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) kem).getConfiguration();
+        boolean flat = !isInheritanceStrategyVertical();
+
+        DataSource ds = (DataSource) conf.getConnectionFactory();
+        Connection c = ds.getConnection(conf.getConnectionUserName(),
+            conf.getConnectionPassword());
+        if (c.getAutoCommit())
+            c.setAutoCommit(false);
+
+        c.createStatement()
+            .executeUpdate("DELETE FROM UNKNOWNSUBCLASSPARENT");
+        if (!flat)
+            c.createStatement()
+                .executeUpdate("DELETE FROM UNKNOWNSUBCLASSCHILD");
+
+        String insert = "INSERT INTO UNKNOWNSUBCLASSPARENT"
+            + "(TYP, ID, VERSN) VALUES (";
+
+        c.createStatement().executeUpdate(insert
+            + "'" + parentName + "', 1, 1)");
+        c.createStatement().executeUpdate(insert
+            + "'" + childName + "', 2, 1)");
+
+        if (!flat) {
+            insert = "INSERT INTO UNKNOWNSUBCLASSCHILD (ID) VALUES (";
+            c.createStatement().executeUpdate(insert + "1)");
+            c.createStatement().executeUpdate(insert + "2)");
+        }
+
+        c.commit();
+        em.close();
+        kem.close();
+    }
+
+        public void testUnknownSubclass()
+        throws Exception {
+        // assertNotRegistered (parentName);
+        // assertNotRegistered (childName);
+
+        Class c = UnknownSubclassParent.class;
+
+        // assertNotRegistered (childName);
+
+        EntityManager em= currentEntityManager();            
+        OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+
+        
+        startTx(em);
+        // c = UnknownSubclassChild.class;
+
+        //FIXME jthomas conversion incomplete 
+        /*
+        assertSize(1, kem.createExtent(UnknownSubclassParent.class, false));
+        assertSize(1, kem.newQuery(
+            kem.createExtent(UnknownSubclassParent.class, false), ""));
+
+        assertSize(2, kem.createExtent(UnknownSubclassParent.class, true));
+        assertSize(2, kem.createQuery(kem.createExtent(UnknownSubclassParent.class, true), ""));
+        */
+        endTx(em);
+        
+        em.close();
+        kem.close();
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestCompositeIdTraversalInSQLMapping.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestCompositeIdTraversalInSQLMapping.java
index a6abc3a..518adfa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestCompositeIdTraversalInSQLMapping.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestCompositeIdTraversalInSQLMapping.java
@@ -1,264 +1,264 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.mapping;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.*;
-import org.apache.openjpa.persistence.common.utils.*;
-import junit.framework.*;
-
-
-public class TestCompositeIdTraversalInSQLMapping extends AbstractTestCase 
-{
-	
-	
-	public TestCompositeIdTraversalInSQLMapping(String name)
-	{
-		super(name, "jdbccactusapp");
-	}
-
-	
-	public void setUp()
-	{
-		deleteAll(OwnerOfEntityWithCompositeId.class);
-		deleteAll(EntityWithCompositeId.class);
-	}
-	private void persist(Integer uniqueId, String uniqueName, String relName)
-	{
-		OwnerOfEntityWithCompositeId owner = new OwnerOfEntityWithCompositeId();
-		EntityWithCompositeId relative = new EntityWithCompositeId();
-		owner.setName(uniqueName);
-		relative.setId(uniqueId);
-		relative.setName(relName);
-		relative.setValue("foo");
-		owner.setRelation(relative);
-		
-		EntityManager em = currentEntityManager();
-		startTx(em);
-		em.persist(owner);
-		endTx(em);
-		endEm(em);
-	}
-	public void testTraversalWhenSQLSelectsBothEndOfTheRelation ()
-	{
-		EntityManager em = currentEntityManager();
-		Integer uid  = new Integer((int) (System.currentTimeMillis()%100000));
-		String uName = "P"+uid;
-		String rName = "R"+uName;
-		
-		persist(uid, uName, rName);
-		
-		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," +
-		             "a.RELATION_NAME as REL_NAME, b.ID as C_ID," +
-					 "b.NAME as C_NAME, b.VALUE as C_VALUE " +
-		             "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " +
-		             "WHERE a.RELATION_ID=b.ID AND a.RELATION_NAME=b.NAME " +
-		             "AND a.NAME='" + uName + "'";
-		
-		Query query = em.createNativeQuery(sql, 
-			"SQLSelectsBothEndOfTheRelation");
-		
-		List result = query.getResultList();
-		
-		assertEquals(1,result.size());
-		Object object = result.get(0);
-		assertEquals(Object[].class, object.getClass());
-		Object[] array = (Object[])object;
-		assertEquals(2,array.length);
-		assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass());
-		assertEquals(EntityWithCompositeId.class,array[1].getClass());
-		
-		OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId)
-			array[0];
-		
-		EntityWithCompositeId relative = (EntityWithCompositeId)array[1];
-		
-		assertEquals(uName, owner.getName());
-		assertEquals(owner.getRelation(), relative);
-		assertEquals(relative.getId(),uid);
-		assertEquals(relative.getName(), rName);
-		assertEquals("foo", relative.getValue());
-		endEm(em);
-	}
-
-	public void testTraversalWhenSQLSelectsOnlyOneEndOfTheRelation ()
-	{
-		EntityManager em = currentEntityManager();
-		Integer uid  = new Integer((int) (System.currentTimeMillis()%100000));
-		String uName = "P"+uid;
-		String rName = "R"+uName;
-		
-		persist (uid, uName, rName);
-		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," +
-		             "a.RELATION_NAME as REL_NAME "+
-		             "FROM OWNER_OF_COMPOSITE_ID a " +
-		             "WHERE  a.NAME='" + uName + "'";
-		
-		Query query = em.createNativeQuery(sql, 
-			"SQLSelectsOnlyOneEndOfTheRelation");
-		
-		List result = query.getResultList();
-		
-		assertEquals(1,result.size());
-		Object object = result.get(0);
-		assertEquals(OwnerOfEntityWithCompositeId.class,object.getClass());
-		
-		OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId)
-			object;
-		
-		EntityWithCompositeId relative = owner.getRelation();
-		
-		assertEquals(uName, owner.getName());
-		assertEquals(relative.getId(),uid);
-		assertEquals(relative.getName(), rName);
-		assertEquals("foo", relative.getValue());
-		endEm(em);
-	}
-	public void testTraversalWhenSQLSelectsUnrelatedInstances ()
-	{
-		EntityManager em = currentEntityManager();
-		Integer uid1  = new Integer((int) (System.currentTimeMillis()%100000));
-		Integer uid2  = new Integer(uid1.intValue()+1);
-		String uName1 = "P"+uid1;
-		String rName1 = "R"+uName1;
-		String uName2 = "P"+uid2;
-		String rName2 = "R"+uName2;
-		
-		persist(uid1, uName1, rName1);
-		persist(uid2, uName2, rName2);
-		
-		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID AS REL_ID," +
-        "a.RELATION_NAME AS REL_NAME, " +
-        "b.ID AS C_ID, b.NAME AS C_NAME, b.VALUE AS C_VALUE "+
-        "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " +
-        "WHERE b.NAME='"+ rName2 +"' " +
-        "AND a.NAME='" + uName1 + "'";
-		
-		Query query = em.createNativeQuery(sql, 
-				"SQLSelectsUnrelatedInstances");
-		
-		List result = query.getResultList();
-		
-		assertEquals(1,result.size());
-		Object object = result.get(0);
-		assertEquals(Object[].class, object.getClass());
-		Object[] array = (Object[])object;
-		assertEquals(2,array.length);
-		assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass());
-		assertEquals(EntityWithCompositeId.class,array[1].getClass());
-		
-		OwnerOfEntityWithCompositeId owner1 = (OwnerOfEntityWithCompositeId)
-			array[0];
-		EntityWithCompositeId relative1 = owner1.getRelation();
-		
-		EntityWithCompositeId relative2 = (EntityWithCompositeId)array[1];
-		
-		assertEquals(uName1, owner1.getName());
-		assertEquals(uid1, relative1.getId());
-		assertEquals(rName1, relative1.getName());
-		assertEquals(uid2, relative2.getId());
-		assertEquals(rName2, relative2.getName());
-		endEm(em); 
-	}
-	
-	public void testRecursiveTraversal () 
-	{
-		Integer rootId  = new Integer((int)(System.currentTimeMillis()%100000));
-		
-		int depth = 3;
-		persistChainedRelative(rootId, depth);
-		
-		String sql = createSelfJoinSQL("RECURSIVE_ENTITY",
-				depth,rootId);
-		
-		EntityManager em = currentEntityManager();
-		Query query = em.createNativeQuery(sql, "SQLSelectsChainedRelation");
-
-		List result = query.getResultList();
-		
-		assertEquals(1, result.size());
-		assertEquals(RecursiveEntityWithCompositeId.class,
-				result.get(0).getClass());
-		
-		RecursiveEntityWithCompositeId root = (RecursiveEntityWithCompositeId)
-												result.get(0);
-		assertEquals(rootId,root.getId());
-		assertEquals("P"+rootId,root.getName());
-		for (int i=1; i<depth;i++){
-			RecursiveEntityWithCompositeId relative = root.getRelation();
-			Integer expecetedId = root.getId()+1;
-			assertEquals (expecetedId,relative.getId());
-			assertEquals ("P"+expecetedId, relative.getName());
-			root = relative;
-		}
-		 
-	}
-	
-	void persistChainedRelative(Integer rootId, int depth)
-	{
-		RecursiveEntityWithCompositeId root = 
-			new RecursiveEntityWithCompositeId();
-		root.setId(rootId);
-		root.setName("P"+rootId);
-		RecursiveEntityWithCompositeId head = root;
-		for (int i=1; i<=depth; i++)
-		{
-			RecursiveEntityWithCompositeId relation = 
-				new RecursiveEntityWithCompositeId();
-			relation.setId(rootId+i);
-			relation.setName("P"+(rootId+i));
-			head.setRelation(relation);
-			head = relation;
-		}
-		EntityManager em = currentEntityManager();
-		startTx(em);
-		em.persist(root);
-		endTx(em);
-		endEm(em);
-	}
-	
-	String createSelfJoinSQL(String table, int depth, int id)
-	{
-		
-		StringBuffer sql = new StringBuffer("SELECT ");
-		for (int i=0; i<depth; i++)
-			sql.append("t"+i+".ID AS T"+i+"_ID, ")
-			   .append("t"+i+".NAME AS T"+i+"_NAME, ")
-			   .append("t"+i+".RELATION_ID AS T"+i+"_REL_ID, ")
-			   .append("t"+i+".RELATION_NAME AS T"+i+"_REL_NAME")
-			   .append((i==(depth-1))?" " : ", ");
-		
-		sql.append(" FROM ");
-		for (int i=0; i<depth; i++)
-			sql.append(table + " t"+i)
-			   .append((i==(depth-1))?" " : ", ");
-		
-		sql.append(" WHERE ");
-		for (int i=0; i<(depth-1); i++)
-			sql.append("t"+i+".RELATION_ID=t"+(i+1)+".ID AND ")
-			   .append("t"+i+".RELATION_NAME=t"+(i+1)+".NAME AND " );
-		
-		sql.append("t0.ID="+id);
-		
-		return sql.toString();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.mapping;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.*;
+import org.apache.openjpa.persistence.common.utils.*;
+import junit.framework.*;
+
+
+public class TestCompositeIdTraversalInSQLMapping extends AbstractTestCase 
+{
+	
+	
+	public TestCompositeIdTraversalInSQLMapping(String name)
+	{
+		super(name, "jdbccactusapp");
+	}
+
+	
+	public void setUp()
+	{
+		deleteAll(OwnerOfEntityWithCompositeId.class);
+		deleteAll(EntityWithCompositeId.class);
+	}
+	private void persist(Integer uniqueId, String uniqueName, String relName)
+	{
+		OwnerOfEntityWithCompositeId owner = new OwnerOfEntityWithCompositeId();
+		EntityWithCompositeId relative = new EntityWithCompositeId();
+		owner.setName(uniqueName);
+		relative.setId(uniqueId);
+		relative.setName(relName);
+		relative.setValue("foo");
+		owner.setRelation(relative);
+		
+		EntityManager em = currentEntityManager();
+		startTx(em);
+		em.persist(owner);
+		endTx(em);
+		endEm(em);
+	}
+	public void testTraversalWhenSQLSelectsBothEndOfTheRelation ()
+	{
+		EntityManager em = currentEntityManager();
+		Integer uid  = new Integer((int) (System.currentTimeMillis()%100000));
+		String uName = "P"+uid;
+		String rName = "R"+uName;
+		
+		persist(uid, uName, rName);
+		
+		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," +
+		             "a.RELATION_NAME as REL_NAME, b.ID as C_ID," +
+					 "b.NAME as C_NAME, b.VALUE as C_VALUE " +
+		             "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " +
+		             "WHERE a.RELATION_ID=b.ID AND a.RELATION_NAME=b.NAME " +
+		             "AND a.NAME='" + uName + "'";
+		
+		Query query = em.createNativeQuery(sql, 
+			"SQLSelectsBothEndOfTheRelation");
+		
+		List result = query.getResultList();
+		
+		assertEquals(1,result.size());
+		Object object = result.get(0);
+		assertEquals(Object[].class, object.getClass());
+		Object[] array = (Object[])object;
+		assertEquals(2,array.length);
+		assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass());
+		assertEquals(EntityWithCompositeId.class,array[1].getClass());
+		
+		OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId)
+			array[0];
+		
+		EntityWithCompositeId relative = (EntityWithCompositeId)array[1];
+		
+		assertEquals(uName, owner.getName());
+		assertEquals(owner.getRelation(), relative);
+		assertEquals(relative.getId(),uid);
+		assertEquals(relative.getName(), rName);
+		assertEquals("foo", relative.getValue());
+		endEm(em);
+	}
+
+	public void testTraversalWhenSQLSelectsOnlyOneEndOfTheRelation ()
+	{
+		EntityManager em = currentEntityManager();
+		Integer uid  = new Integer((int) (System.currentTimeMillis()%100000));
+		String uName = "P"+uid;
+		String rName = "R"+uName;
+		
+		persist (uid, uName, rName);
+		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," +
+		             "a.RELATION_NAME as REL_NAME "+
+		             "FROM OWNER_OF_COMPOSITE_ID a " +
+		             "WHERE  a.NAME='" + uName + "'";
+		
+		Query query = em.createNativeQuery(sql, 
+			"SQLSelectsOnlyOneEndOfTheRelation");
+		
+		List result = query.getResultList();
+		
+		assertEquals(1,result.size());
+		Object object = result.get(0);
+		assertEquals(OwnerOfEntityWithCompositeId.class,object.getClass());
+		
+		OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId)
+			object;
+		
+		EntityWithCompositeId relative = owner.getRelation();
+		
+		assertEquals(uName, owner.getName());
+		assertEquals(relative.getId(),uid);
+		assertEquals(relative.getName(), rName);
+		assertEquals("foo", relative.getValue());
+		endEm(em);
+	}
+	public void testTraversalWhenSQLSelectsUnrelatedInstances ()
+	{
+		EntityManager em = currentEntityManager();
+		Integer uid1  = new Integer((int) (System.currentTimeMillis()%100000));
+		Integer uid2  = new Integer(uid1.intValue()+1);
+		String uName1 = "P"+uid1;
+		String rName1 = "R"+uName1;
+		String uName2 = "P"+uid2;
+		String rName2 = "R"+uName2;
+		
+		persist(uid1, uName1, rName1);
+		persist(uid2, uName2, rName2);
+		
+		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID AS REL_ID," +
+        "a.RELATION_NAME AS REL_NAME, " +
+        "b.ID AS C_ID, b.NAME AS C_NAME, b.VALUE AS C_VALUE "+
+        "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " +
+        "WHERE b.NAME='"+ rName2 +"' " +
+        "AND a.NAME='" + uName1 + "'";
+		
+		Query query = em.createNativeQuery(sql, 
+				"SQLSelectsUnrelatedInstances");
+		
+		List result = query.getResultList();
+		
+		assertEquals(1,result.size());
+		Object object = result.get(0);
+		assertEquals(Object[].class, object.getClass());
+		Object[] array = (Object[])object;
+		assertEquals(2,array.length);
+		assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass());
+		assertEquals(EntityWithCompositeId.class,array[1].getClass());
+		
+		OwnerOfEntityWithCompositeId owner1 = (OwnerOfEntityWithCompositeId)
+			array[0];
+		EntityWithCompositeId relative1 = owner1.getRelation();
+		
+		EntityWithCompositeId relative2 = (EntityWithCompositeId)array[1];
+		
+		assertEquals(uName1, owner1.getName());
+		assertEquals(uid1, relative1.getId());
+		assertEquals(rName1, relative1.getName());
+		assertEquals(uid2, relative2.getId());
+		assertEquals(rName2, relative2.getName());
+		endEm(em); 
+	}
+	
+	public void testRecursiveTraversal () 
+	{
+		Integer rootId  = new Integer((int)(System.currentTimeMillis()%100000));
+		
+		int depth = 3;
+		persistChainedRelative(rootId, depth);
+		
+		String sql = createSelfJoinSQL("RECURSIVE_ENTITY",
+				depth,rootId);
+		
+		EntityManager em = currentEntityManager();
+		Query query = em.createNativeQuery(sql, "SQLSelectsChainedRelation");
+
+		List result = query.getResultList();
+		
+		assertEquals(1, result.size());
+		assertEquals(RecursiveEntityWithCompositeId.class,
+				result.get(0).getClass());
+		
+		RecursiveEntityWithCompositeId root = (RecursiveEntityWithCompositeId)
+												result.get(0);
+		assertEquals(rootId,root.getId());
+		assertEquals("P"+rootId,root.getName());
+		for (int i=1; i<depth;i++){
+			RecursiveEntityWithCompositeId relative = root.getRelation();
+			Integer expecetedId = root.getId()+1;
+			assertEquals (expecetedId,relative.getId());
+			assertEquals ("P"+expecetedId, relative.getName());
+			root = relative;
+		}
+		 
+	}
+	
+	void persistChainedRelative(Integer rootId, int depth)
+	{
+		RecursiveEntityWithCompositeId root = 
+			new RecursiveEntityWithCompositeId();
+		root.setId(rootId);
+		root.setName("P"+rootId);
+		RecursiveEntityWithCompositeId head = root;
+		for (int i=1; i<=depth; i++)
+		{
+			RecursiveEntityWithCompositeId relation = 
+				new RecursiveEntityWithCompositeId();
+			relation.setId(rootId+i);
+			relation.setName("P"+(rootId+i));
+			head.setRelation(relation);
+			head = relation;
+		}
+		EntityManager em = currentEntityManager();
+		startTx(em);
+		em.persist(root);
+		endTx(em);
+		endEm(em);
+	}
+	
+	String createSelfJoinSQL(String table, int depth, int id)
+	{
+		
+		StringBuffer sql = new StringBuffer("SELECT ");
+		for (int i=0; i<depth; i++)
+			sql.append("t"+i+".ID AS T"+i+"_ID, ")
+			   .append("t"+i+".NAME AS T"+i+"_NAME, ")
+			   .append("t"+i+".RELATION_ID AS T"+i+"_REL_ID, ")
+			   .append("t"+i+".RELATION_NAME AS T"+i+"_REL_NAME")
+			   .append((i==(depth-1))?" " : ", ");
+		
+		sql.append(" FROM ");
+		for (int i=0; i<depth; i++)
+			sql.append(table + " t"+i)
+			   .append((i==(depth-1))?" " : ", ");
+		
+		sql.append(" WHERE ");
+		for (int i=0; i<(depth-1); i++)
+			sql.append("t"+i+".RELATION_ID=t"+(i+1)+".ID AND ")
+			   .append("t"+i+".RELATION_NAME=t"+(i+1)+".NAME AND " );
+		
+		sql.append("t0.ID="+id);
+		
+		return sql.toString();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestNativeQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestNativeQueries.java
index 809b8c7..17d957c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestNativeQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestNativeQueries.java
@@ -1,170 +1,170 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.mapping;
-
-
-import javax.persistence.*;
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.*;
-import org.apache.openjpa.persistence.common.utils.*;
-import junit.framework.*;
-
-
-public class TestNativeQueries	extends AbstractTestCase
-{
-	
-	public TestNativeQueries(String name)
-	{
-		super(name, "jdbccactusapp");
-	}
-
-    public void setUp ()
-	{
-		deleteAll (Entity1.class);
-	}
-
-	public void testSimple ()
-	{
-		deleteAll (Entity1.class);
-
-		// test create
-		{
-			EntityManager em = currentEntityManager( );
-			startTx(em);
-			em.persist (new Entity1 (0, "testSimple", 12));
-			endTx(em);
-			endEm(em);
-		}
-
-		// test Query
-		{
-/*			JDBCConfiguration conf = (JDBCConfiguration)getConfiguration ();
-			DBDictionary dict = conf.getDBDictionaryInstance ();*/
-
-/*			String tableName = dict.getFullName (conf.getMappingRepository ().
-				getMapping (Entity1.class, getClass ().getClassLoader (), true).
-				getTable (), false);*/
-
-			EntityManager em = currentEntityManager( );
-			startTx(em);
-			String tableName = "entity_1";
-			assertSize (1, em.createNativeQuery
-				("SELECT * FROM " + tableName, Entity1.class).
-				getResultList ());
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = 12", Entity1.class).
-				getResultList ());
-
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = ?1", Entity1.class).
-				setParameter (1, 12).
-				getResultList ());
-
-			// make sure that out-of-order parameters work
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = ?2 AND STRINGFIELD = ?1", Entity1.class).
-				setParameter (2, 12).
-				setParameter (1, "testSimple").
-				getResultList ());
-
-			// make sure duplicate parameters work
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = ?1 AND INTFIELD = ?1", Entity1.class).
-				setParameter (1, 12).
-				getResultList ());
-
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = ?1 OR INTFIELD = ?2", Entity1.class).
-				setParameter (1, 12).
-				setParameter (2, 13).
-				getResultList ());
-
-			// make sure that quoted parameters are ignored as expected
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = ?1 OR STRINGFIELD = '?5'", Entity1.class).
-				setParameter (1, 12).
-				getResultList ());
-
-			// test without spaces
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD=?1 OR STRINGFIELD='?5'", Entity1.class).
-				setParameter (1, 12).
-				getResultList ());
-
-/*			assertSize (1, ((QueryImpl)em.createNativeQuery
-				("SELECT * FROM " + tableName
-					+ " WHERE INTFIELD = ?1 OR INTFIELD = ?2", Entity1.class)).
-				setParameters (12, 1).
-				getResultList ());
-
-			assertSize (0, ((QueryImpl)em.createNativeQuery
-				("SELECT * FROM " + tableName
-					+ " WHERE INTFIELD = ?1 AND INTFIELD = ?2", Entity1.class)).
-				setParameters (12, 1).
-				getResultList ());
-*/
-			assertSize (0, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = ?1 AND INTFIELD = ?2", Entity1.class).
-				setParameter (1, 12).
-				setParameter (2, 13).
-				getResultList ());
-
-			try
-			{
-				em.createNativeQuery ("SELECT * FROM " + tableName
-					+ " WHERE INTFIELD = ?1", Entity1.class).
-					setParameter (0, 12).
-					getResultList ();
-				fail ("Should not have been able to use param index 0");
-			}
-			catch (Exception e)
-			{
-				// as expected
-			}
-
-
-			/*
-			 * Named parameters are not supported according to 19 June 3.5.2:
-			 *
-			 * The use of named parameters is not defined for
-			 * native queries. Only positional parameter binding
-			 * for SQL queries may be used by portable applications.
-			 *
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = :p",  Entity1.class).
-				setParameter ("p", 12).
-				getResultList ());
-			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
-				+ " WHERE INTFIELD = :p OR INTFIELD = :p", Entity1.class).
-				setParameter ("p", 12).
-				getResultList ());
-			*/
-
-			endTx(em);
-			endEm(em);
-		}
-	}
-	
-	public boolean assertSize(int num, List l)
-	{
-		return(num == l.size());
-	}
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.mapping;
+
+
+import javax.persistence.*;
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.*;
+import org.apache.openjpa.persistence.common.utils.*;
+import junit.framework.*;
+
+
+public class TestNativeQueries	extends AbstractTestCase
+{
+	
+	public TestNativeQueries(String name)
+	{
+		super(name, "jdbccactusapp");
+	}
+
+    public void setUp ()
+	{
+		deleteAll (Entity1.class);
+	}
+
+	public void testSimple ()
+	{
+		deleteAll (Entity1.class);
+
+		// test create
+		{
+			EntityManager em = currentEntityManager( );
+			startTx(em);
+			em.persist (new Entity1 (0, "testSimple", 12));
+			endTx(em);
+			endEm(em);
+		}
+
+		// test Query
+		{
+/*			JDBCConfiguration conf = (JDBCConfiguration)getConfiguration ();
+			DBDictionary dict = conf.getDBDictionaryInstance ();*/
+
+/*			String tableName = dict.getFullName (conf.getMappingRepository ().
+				getMapping (Entity1.class, getClass ().getClassLoader (), true).
+				getTable (), false);*/
+
+			EntityManager em = currentEntityManager( );
+			startTx(em);
+			String tableName = "entity_1";
+			assertSize (1, em.createNativeQuery
+				("SELECT * FROM " + tableName, Entity1.class).
+				getResultList ());
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = 12", Entity1.class).
+				getResultList ());
+
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = ?1", Entity1.class).
+				setParameter (1, 12).
+				getResultList ());
+
+			// make sure that out-of-order parameters work
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = ?2 AND STRINGFIELD = ?1", Entity1.class).
+				setParameter (2, 12).
+				setParameter (1, "testSimple").
+				getResultList ());
+
+			// make sure duplicate parameters work
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = ?1 AND INTFIELD = ?1", Entity1.class).
+				setParameter (1, 12).
+				getResultList ());
+
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = ?1 OR INTFIELD = ?2", Entity1.class).
+				setParameter (1, 12).
+				setParameter (2, 13).
+				getResultList ());
+
+			// make sure that quoted parameters are ignored as expected
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = ?1 OR STRINGFIELD = '?5'", Entity1.class).
+				setParameter (1, 12).
+				getResultList ());
+
+			// test without spaces
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD=?1 OR STRINGFIELD='?5'", Entity1.class).
+				setParameter (1, 12).
+				getResultList ());
+
+/*			assertSize (1, ((QueryImpl)em.createNativeQuery
+				("SELECT * FROM " + tableName
+					+ " WHERE INTFIELD = ?1 OR INTFIELD = ?2", Entity1.class)).
+				setParameters (12, 1).
+				getResultList ());
+
+			assertSize (0, ((QueryImpl)em.createNativeQuery
+				("SELECT * FROM " + tableName
+					+ " WHERE INTFIELD = ?1 AND INTFIELD = ?2", Entity1.class)).
+				setParameters (12, 1).
+				getResultList ());
+*/
+			assertSize (0, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = ?1 AND INTFIELD = ?2", Entity1.class).
+				setParameter (1, 12).
+				setParameter (2, 13).
+				getResultList ());
+
+			try
+			{
+				em.createNativeQuery ("SELECT * FROM " + tableName
+					+ " WHERE INTFIELD = ?1", Entity1.class).
+					setParameter (0, 12).
+					getResultList ();
+				fail ("Should not have been able to use param index 0");
+			}
+			catch (Exception e)
+			{
+				// as expected
+			}
+
+
+			/*
+			 * Named parameters are not supported according to 19 June 3.5.2:
+			 *
+			 * The use of named parameters is not defined for
+			 * native queries. Only positional parameter binding
+			 * for SQL queries may be used by portable applications.
+			 *
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = :p",  Entity1.class).
+				setParameter ("p", 12).
+				getResultList ());
+			assertSize (1, em.createNativeQuery ("SELECT * FROM " + tableName
+				+ " WHERE INTFIELD = :p OR INTFIELD = :p", Entity1.class).
+				setParameter ("p", 12).
+				getResultList ());
+			*/
+
+			endTx(em);
+			endEm(em);
+		}
+	}
+	
+	public boolean assertSize(int num, List l)
+	{
+		return(num == l.size());
+	}
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestBuildSchema.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestBuildSchema.java
index ffa9a1c..779286e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestBuildSchema.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestBuildSchema.java
@@ -1,91 +1,91 @@
-/*
- * TestBuildSchema.java
- *
- * Created on October 4, 2006, 4:52 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-
-import org.apache.regexp.REUtil;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.MappingTool;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-public class TestBuildSchema extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-       
-    /** Creates a new instance of TestBuildSchema */
-    public TestBuildSchema() {
-    }
-    public TestBuildSchema(String test) {
-        super(test);
-    }
-
-    public void testSchema()
-        throws Exception {
-        StringWriter out = new StringWriter();
-
-        MappingTool tool = new MappingTool((JDBCConfiguration)
-            getConfiguration(), MappingTool.ACTION_BUILD_SCHEMA, false);
-        tool.setMappingWriter(new StringWriter());    // throw away
-        tool.setSchemaWriter(out);
-        tool.run(BuildSchemaPC.class);
-        tool.record();
-
-        BufferedReader in = new BufferedReader(new InputStreamReader
-            (getClass().getResourceAsStream("TestBuildSchema-schema.rsrc")));
-        StringBuffer buf = new StringBuffer();
-        for (int ch; (ch = in.read()) != -1;)
-            buf.append((char) ch);
-        in.close();
-
-        // the <schema> sometimes has a name (depending on whether the database
-        // reports a schema name or not). If there is a
-        // <scheme name="something">, then replace it with <schema> so
-        // the match is successful.
-        String schema = out.toString();
-        schema = REUtil.createRE
-            ("<schema name=\"*\">").subst(schema, "<schema>");
-
-        // convert CRLF to CR so we pass on Windows
-        assertEquals(fixNewline(buf.toString()).trim(),
-            fixNewline(schema).trim());
-    }
-
-    private String fixNewline(String str) {
-        //FIXME 
-        /*
-        return serp.util.Strings.join
-            (serp.util.Strings.split
-                (str, "\r\n", -1), "\n");
-         */
-        return "";
-    }
-    
-}
+/*
+ * TestBuildSchema.java
+ *
+ * Created on October 4, 2006, 4:52 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+
+import org.apache.regexp.REUtil;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.MappingTool;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+public class TestBuildSchema extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+       
+    /** Creates a new instance of TestBuildSchema */
+    public TestBuildSchema() {
+    }
+    public TestBuildSchema(String test) {
+        super(test);
+    }
+
+    public void testSchema()
+        throws Exception {
+        StringWriter out = new StringWriter();
+
+        MappingTool tool = new MappingTool((JDBCConfiguration)
+            getConfiguration(), MappingTool.ACTION_BUILD_SCHEMA, false);
+        tool.setMappingWriter(new StringWriter());    // throw away
+        tool.setSchemaWriter(out);
+        tool.run(BuildSchemaPC.class);
+        tool.record();
+
+        BufferedReader in = new BufferedReader(new InputStreamReader
+            (getClass().getResourceAsStream("TestBuildSchema-schema.rsrc")));
+        StringBuffer buf = new StringBuffer();
+        for (int ch; (ch = in.read()) != -1;)
+            buf.append((char) ch);
+        in.close();
+
+        // the <schema> sometimes has a name (depending on whether the database
+        // reports a schema name or not). If there is a
+        // <scheme name="something">, then replace it with <schema> so
+        // the match is successful.
+        String schema = out.toString();
+        schema = REUtil.createRE
+            ("<schema name=\"*\">").subst(schema, "<schema>");
+
+        // convert CRLF to CR so we pass on Windows
+        assertEquals(fixNewline(buf.toString()).trim(),
+            fixNewline(schema).trim());
+    }
+
+    private String fixNewline(String str) {
+        //FIXME 
+        /*
+        return serp.util.Strings.join
+            (serp.util.Strings.split
+                (str, "\r\n", -1), "\n");
+         */
+        return "";
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestDFG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestDFG.java
index 67bb8e5..4f15408 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestDFG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestDFG.java
@@ -1,115 +1,115 @@
-/*
- * TestDFG.java
- *
- * Created on October 2, 2006, 5:55 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import javax.persistence.EntityTransaction;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.FieldMetaData;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-
-public class TestDFG extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    private Object oid;
-    /** Creates a new instance of TestDFG */
-    public TestDFG(String name)
-    {
-    	super(name);
-    }
-    
-    public void setUp() {
-       deleteAll(DFGTest.class);
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        EntityTransaction t= pm.getTransaction();
-        t.begin();
-        DFGTest a = new DFGTest();
-        pm.persist(a);
-        a.setNonDFGField(2);
-        t.commit();
-        
-        // modify a field so that if we're examining sql we can see
-        // how much is flushed.
-        t.begin();
-        a.setDFGField(1);
-        t.commit();
-        
-        oid = pm.getObjectId(a);
-        pm.close();
-    }
-    
-    public void testDFG() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        
-        DFGTest a = (DFGTest) pm.getObjectId(oid);
-        
-        // check the non-dfg fields
-        
-        OpenJPAStateManager sm = getStateManager(a,pm);
-        FieldMetaData fmd = sm.getMetaData().getField("nonDFGField");
-        assertTrue("nonDFGField should not be loaded",
-                !sm.getLoaded().get(fmd.getIndex()));
-        
-        fmd = sm.getMetaData().getField("dfgField");
-        assertTrue("dfgField should be loaded",
-                sm.getLoaded().get(fmd.getIndex()));
-        
-        int val = a.getNonDFGField();
-        assertTrue("nonDFGField should be loaded",
-                sm.getLoaded().get(fmd.getIndex()));
-        assertEquals(2, val);
-        
-        pm.close();
-    }
-    
-    // it'd be nice if we could actually automate this test. As it
-    // stands, this is just here so that there's an easy place to look
-    // at the SQL.
-    public void testDFGWrites() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        
-        
-        DFGTest a = (DFGTest) pm.getObjectId(oid);
-        a.setDFGField(3);
-        endTx(pm);
-        
-        pm.close();
-    }
-    
-}
+/*
+ * TestDFG.java
+ *
+ * Created on October 2, 2006, 5:55 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import javax.persistence.EntityTransaction;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.FieldMetaData;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+
+public class TestDFG extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    private Object oid;
+    /** Creates a new instance of TestDFG */
+    public TestDFG(String name)
+    {
+    	super(name);
+    }
+    
+    public void setUp() {
+       deleteAll(DFGTest.class);
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        EntityTransaction t= pm.getTransaction();
+        t.begin();
+        DFGTest a = new DFGTest();
+        pm.persist(a);
+        a.setNonDFGField(2);
+        t.commit();
+        
+        // modify a field so that if we're examining sql we can see
+        // how much is flushed.
+        t.begin();
+        a.setDFGField(1);
+        t.commit();
+        
+        oid = pm.getObjectId(a);
+        pm.close();
+    }
+    
+    public void testDFG() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        
+        DFGTest a = (DFGTest) pm.getObjectId(oid);
+        
+        // check the non-dfg fields
+        
+        OpenJPAStateManager sm = getStateManager(a,pm);
+        FieldMetaData fmd = sm.getMetaData().getField("nonDFGField");
+        assertTrue("nonDFGField should not be loaded",
+                !sm.getLoaded().get(fmd.getIndex()));
+        
+        fmd = sm.getMetaData().getField("dfgField");
+        assertTrue("dfgField should be loaded",
+                sm.getLoaded().get(fmd.getIndex()));
+        
+        int val = a.getNonDFGField();
+        assertTrue("nonDFGField should be loaded",
+                sm.getLoaded().get(fmd.getIndex()));
+        assertEquals(2, val);
+        
+        pm.close();
+    }
+    
+    // it'd be nice if we could actually automate this test. As it
+    // stands, this is just here so that there's an easy place to look
+    // at the SQL.
+    public void testDFGWrites() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        
+        
+        DFGTest a = (DFGTest) pm.getObjectId(oid);
+        a.setDFGField(3);
+        endTx(pm);
+        
+        pm.close();
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBByteArray.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBByteArray.java
index 3947e3b..3b4f1ab 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBByteArray.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBByteArray.java
@@ -1,140 +1,140 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.kernel.common.apps.*;
-
-import junit.framework.*;
-
-public class TestEJBByteArray extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	private int _null;
-	private int _empty;
-	private int _small;
-	private int _large;
-
-
-	public TestEJBByteArray(String name)
-	{
-		super(name);
-	}
-
-	public void setUp() throws Exception
-	{
-		deleteAll(ByteArray.class);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-
-		ByteArray pc = new ByteArray ("Null", 1);
-		pm.persist (pc);
-		_null = 1;
-
-		pc = new ByteArray ("Empty", 2);
-		pc.setBytes (new byte[0]);
-		pm.persist (pc);
-		_empty = 2;
-
-		pc = new ByteArray ("Small", 3);
-		pc.setBytes (pc.getString ().getBytes ());
-		pm.persist (pc);
-		_small = 3;
-
-		byte[] bytes = new byte [10000];
-		for (int i = 0; i < bytes.length; i++)
-			bytes[i] = (byte) (i % 8);
-
-		pc = new ByteArray ("Large", 4);
-		pc.setBytes (bytes);
-		pm.persist (pc);
-		_large = 4;
-
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testNull ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-
-		ByteArray pc = pm.find(ByteArray.class, _null);
-		assertNull (pc.getBytes ());
-
-
-		pc.setBytes ("Not Null".getBytes ());
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ByteArray.class, _null);
-
-		assertEquals ("Not Null", new String (pc.getBytes ()));
-
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testEmpty ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-
-		ByteArray pc = pm.find(ByteArray.class, _empty);
-		byte [] bytes = pc.getBytes ();
-		assertNotNull (bytes);
-		assertEquals (0, bytes.length);
-
-		pc.setBytes ("Not Empty".getBytes ());
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ByteArray.class, _empty);
-		assertEquals ("Not Empty", new String (pc.getBytes ()));
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testLarge ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		ByteArray pc = pm.find(ByteArray.class, _large);
-		byte [] bytes = pc.getBytes ();
-		assertNotNull (bytes);
-		assertEquals (10000, bytes.length);
-		for (int i = 0; i < bytes.length; i++)
-			assertEquals (bytes[i], (byte) (i % 8));
-		endTx(pm);
-		endEm(pm);
-	}
-
-
-
-
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.kernel.common.apps.*;
+
+import junit.framework.*;
+
+public class TestEJBByteArray extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	private int _null;
+	private int _empty;
+	private int _small;
+	private int _large;
+
+
+	public TestEJBByteArray(String name)
+	{
+		super(name);
+	}
+
+	public void setUp() throws Exception
+	{
+		deleteAll(ByteArray.class);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+
+		ByteArray pc = new ByteArray ("Null", 1);
+		pm.persist (pc);
+		_null = 1;
+
+		pc = new ByteArray ("Empty", 2);
+		pc.setBytes (new byte[0]);
+		pm.persist (pc);
+		_empty = 2;
+
+		pc = new ByteArray ("Small", 3);
+		pc.setBytes (pc.getString ().getBytes ());
+		pm.persist (pc);
+		_small = 3;
+
+		byte[] bytes = new byte [10000];
+		for (int i = 0; i < bytes.length; i++)
+			bytes[i] = (byte) (i % 8);
+
+		pc = new ByteArray ("Large", 4);
+		pc.setBytes (bytes);
+		pm.persist (pc);
+		_large = 4;
+
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testNull ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+
+		ByteArray pc = pm.find(ByteArray.class, _null);
+		assertNull (pc.getBytes ());
+
+
+		pc.setBytes ("Not Null".getBytes ());
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ByteArray.class, _null);
+
+		assertEquals ("Not Null", new String (pc.getBytes ()));
+
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testEmpty ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+
+		ByteArray pc = pm.find(ByteArray.class, _empty);
+		byte [] bytes = pc.getBytes ();
+		assertNotNull (bytes);
+		assertEquals (0, bytes.length);
+
+		pc.setBytes ("Not Empty".getBytes ());
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ByteArray.class, _empty);
+		assertEquals ("Not Empty", new String (pc.getBytes ()));
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testLarge ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		ByteArray pc = pm.find(ByteArray.class, _large);
+		byte [] bytes = pc.getBytes ();
+		assertNotNull (bytes);
+		assertEquals (10000, bytes.length);
+		for (int i = 0; i < bytes.length; i++)
+			assertEquals (bytes[i], (byte) (i % 8));
+		endTx(pm);
+		endEm(pm);
+	}
+
+
+
+
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBColumnIOMappings.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBColumnIOMappings.java
index 899ba10..0ba31f8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBColumnIOMappings.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBColumnIOMappings.java
@@ -1,165 +1,165 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.kernel.common.apps.*;
-import junit.framework.*;
-
-public class TestEJBColumnIOMappings extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	public TestEJBColumnIOMappings(String name)
-	{
-		super(name);
-	}
-
-	public void setUp()
-	{
-		deleteAll(ColumnIOPC.class);
-	}
-
-	public void testIgnoreInsert ()
-	{
-		ColumnIOPC pc = new ColumnIOPC (2);
-		pc.setName ("pc");
-		pc.setIgnoreInsert (10);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc);
-		assertEquals (10, pc.getIgnoreInsert ());
-		endTx(pm);
-
-		startTx(pm);
-		assertEquals (10, pc.getIgnoreInsert ());
-		int oid = pc.getId();
-        endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ColumnIOPC.class, oid);
-		assertNotNull (pc);
-		assertEquals (10, pc.getIgnoreInsert ());
-		pc.setIgnoreInsert (10);
-		endTx(pm);
-		startTx(pm);
-		assertEquals (10, pc.getIgnoreInsert ());
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ColumnIOPC.class, oid);
-		assertNotNull (pc);
-		assertEquals (10, pc.getIgnoreInsert ());
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testIgnoreUpdate ()
-	{
-		ColumnIOPC pc = new ColumnIOPC (3);
-		pc.setName ("pc");
-		pc.setIgnoreUpdate (10);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc);
-		assertEquals (10, pc.getIgnoreUpdate ());
-		endTx(pm);
-
-		Object oid = pc.getId();
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ColumnIOPC.class, oid);
-		assertNotNull (pc);
-		assertEquals (10, pc.getIgnoreUpdate ());
-		endTx(pm);
-
-		startTx(pm);
-		pc.setIgnoreUpdate (100);
-		assertEquals (100, pc.getIgnoreUpdate ());
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ColumnIOPC.class, oid);
-		assertNotNull (pc);
-		assertEquals (10, pc.getIgnoreUpdate ());
-		endTx(pm);
-		endEm(pm);
-	}
-
-
-	public void testPrimitiveMappedToFieldOfForeignKey ()
-	{
-		// have to make rel persistent before setting ident field b/c not
-		// insertable
-		ColumnIOPC rel = new ColumnIOPC (1);
-		rel.setName ("rel");
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(rel);
-		endTx(pm);
-
-		startTx(pm);
-		ColumnIOPC pc = new ColumnIOPC (2);
-		pc.setName ("pc");
-		rel = pm.find(ColumnIOPC.class, 1);
-		pc.setRel (rel);
-		rel.setIdent (10);
-		pm.persist(pc);
-		endTx(pm);
-
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ColumnIOPC.class, 2);
-		assertNotNull (pc);
-		assertEquals (0, pc.getIdent ());
-		assertNotNull (pc.getRel ());
-		assertEquals ("rel", pc.getRel ().getName ());
-
-		pc.setIdent (50);
-		pc.setRel (new ColumnIOPC (3));
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(ColumnIOPC.class, 2);
-		assertNotNull (pc);
-		assertEquals (50, pc.getIdent());
-		assertNotNull (pc.getRel());
-		endTx(pm);
-		endEm(pm);
-	}
-
-
-
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.kernel.common.apps.*;
+import junit.framework.*;
+
+public class TestEJBColumnIOMappings extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	public TestEJBColumnIOMappings(String name)
+	{
+		super(name);
+	}
+
+	public void setUp()
+	{
+		deleteAll(ColumnIOPC.class);
+	}
+
+	public void testIgnoreInsert ()
+	{
+		ColumnIOPC pc = new ColumnIOPC (2);
+		pc.setName ("pc");
+		pc.setIgnoreInsert (10);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc);
+		assertEquals (10, pc.getIgnoreInsert ());
+		endTx(pm);
+
+		startTx(pm);
+		assertEquals (10, pc.getIgnoreInsert ());
+		int oid = pc.getId();
+        endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ColumnIOPC.class, oid);
+		assertNotNull (pc);
+		assertEquals (10, pc.getIgnoreInsert ());
+		pc.setIgnoreInsert (10);
+		endTx(pm);
+		startTx(pm);
+		assertEquals (10, pc.getIgnoreInsert ());
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ColumnIOPC.class, oid);
+		assertNotNull (pc);
+		assertEquals (10, pc.getIgnoreInsert ());
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testIgnoreUpdate ()
+	{
+		ColumnIOPC pc = new ColumnIOPC (3);
+		pc.setName ("pc");
+		pc.setIgnoreUpdate (10);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc);
+		assertEquals (10, pc.getIgnoreUpdate ());
+		endTx(pm);
+
+		Object oid = pc.getId();
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ColumnIOPC.class, oid);
+		assertNotNull (pc);
+		assertEquals (10, pc.getIgnoreUpdate ());
+		endTx(pm);
+
+		startTx(pm);
+		pc.setIgnoreUpdate (100);
+		assertEquals (100, pc.getIgnoreUpdate ());
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ColumnIOPC.class, oid);
+		assertNotNull (pc);
+		assertEquals (10, pc.getIgnoreUpdate ());
+		endTx(pm);
+		endEm(pm);
+	}
+
+
+	public void testPrimitiveMappedToFieldOfForeignKey ()
+	{
+		// have to make rel persistent before setting ident field b/c not
+		// insertable
+		ColumnIOPC rel = new ColumnIOPC (1);
+		rel.setName ("rel");
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(rel);
+		endTx(pm);
+
+		startTx(pm);
+		ColumnIOPC pc = new ColumnIOPC (2);
+		pc.setName ("pc");
+		rel = pm.find(ColumnIOPC.class, 1);
+		pc.setRel (rel);
+		rel.setIdent (10);
+		pm.persist(pc);
+		endTx(pm);
+
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ColumnIOPC.class, 2);
+		assertNotNull (pc);
+		assertEquals (0, pc.getIdent ());
+		assertNotNull (pc.getRel ());
+		assertEquals ("rel", pc.getRel ().getName ());
+
+		pc.setIdent (50);
+		pc.setRel (new ColumnIOPC (3));
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(ColumnIOPC.class, 2);
+		assertNotNull (pc);
+		assertEquals (50, pc.getIdent());
+		assertNotNull (pc.getRel());
+		endTx(pm);
+		endEm(pm);
+	}
+
+
+
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBConstantJoinOnSameRefTable.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBConstantJoinOnSameRefTable.java
index 19562e6..4f7d9ab 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBConstantJoinOnSameRefTable.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBConstantJoinOnSameRefTable.java
@@ -1,110 +1,110 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.Iterator;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC4;
-import org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC5;
-
-import junit.framework.*;
-
-public class TestEJBConstantJoinOnSameRefTable extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	private int oid;
-	
-	public TestEJBConstantJoinOnSameRefTable(String name)
-	{
-		super(name);
-	}
-
-	@SuppressWarnings("unchecked")
-	public void setUp ()
-	{
-		deleteAll(ConstantJoinPC4.class);
-		deleteAll(ConstantJoinPC5.class);
-
-		ConstantJoinPC4 pc4 = new ConstantJoinPC4 ("pc4-1", 1);
-		pc4.setOneToOne1 (new ConstantJoinPC5 ("pc5-one-to-one-1"));
-		//### see note in testConstantOneToOne2
-		//### pc4.setOneToOne2 (new ConstantJoinPC5 ("pc5-one-to-one-2"));
-		pc4.getManyToMany ().add (new ConstantJoinPC5 ("pc5-many-to-many-1"));
-		pc4.getManyToMany ().add (new ConstantJoinPC5 ("pc5-many-to-many-2"));
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc4);
-		endTx(pm);
-		oid = pc4.getId();
-		endEm(pm);
-	}
-
-	public void testConstantManyToMany ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		ConstantJoinPC4 pc4 = pm.find(ConstantJoinPC4.class, oid);
-		assertEquals (2, pc4.getManyToMany ().size ());
-		Iterator iter = pc4.getManyToMany ().iterator ();
-		ConstantJoinPC5 pc5_1 = (ConstantJoinPC5) iter.next ();
-		ConstantJoinPC5 pc5_2 = (ConstantJoinPC5) iter.next ();
-		if ("pc5-many-to-many-2".equals (pc5_1.getName ()))
-		{
-			ConstantJoinPC5 other = pc5_1;
-			pc5_1 = pc5_2;
-			pc5_2 = other;
-		}
-		assertEquals ("pc5-many-to-many-1", pc5_1.getName ());
-		assertEquals ("pc5-many-to-many-2", pc5_2.getName ());
-		endTx(pm);
-		endEm(pm);
-	}
-
-
-	public void testConstantOneToOne1 ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		ConstantJoinPC4 pc4 =  pm.find(ConstantJoinPC4.class, oid);
-		assertEquals (2, pc4.getManyToMany ().size ());
-		assertEquals ("pc5-one-to-one-1", pc4.getOneToOne1 ().getName ());
-
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testSharedJoinTableModifications ()
-	{
-		EntityManager pm = currentEntityManager();
-		ConstantJoinPC4 pc4 = pm.find(ConstantJoinPC4.class, oid);
-		startTx(pm);
-		pc4.getManyToMany ().clear ();
-		endTx(pm);
-
-		EntityManager pm2 = currentEntityManager();
-		pc4 = pm2.find(ConstantJoinPC4.class, oid);
-		assertNotNull (pc4.getOneToOne1 ());
-		assertEquals (0, pc4.getManyToMany ().size ());
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.Iterator;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC4;
+import org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC5;
+
+import junit.framework.*;
+
+public class TestEJBConstantJoinOnSameRefTable extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	private int oid;
+	
+	public TestEJBConstantJoinOnSameRefTable(String name)
+	{
+		super(name);
+	}
+
+	@SuppressWarnings("unchecked")
+	public void setUp ()
+	{
+		deleteAll(ConstantJoinPC4.class);
+		deleteAll(ConstantJoinPC5.class);
+
+		ConstantJoinPC4 pc4 = new ConstantJoinPC4 ("pc4-1", 1);
+		pc4.setOneToOne1 (new ConstantJoinPC5 ("pc5-one-to-one-1"));
+		//### see note in testConstantOneToOne2
+		//### pc4.setOneToOne2 (new ConstantJoinPC5 ("pc5-one-to-one-2"));
+		pc4.getManyToMany ().add (new ConstantJoinPC5 ("pc5-many-to-many-1"));
+		pc4.getManyToMany ().add (new ConstantJoinPC5 ("pc5-many-to-many-2"));
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc4);
+		endTx(pm);
+		oid = pc4.getId();
+		endEm(pm);
+	}
+
+	public void testConstantManyToMany ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		ConstantJoinPC4 pc4 = pm.find(ConstantJoinPC4.class, oid);
+		assertEquals (2, pc4.getManyToMany ().size ());
+		Iterator iter = pc4.getManyToMany ().iterator ();
+		ConstantJoinPC5 pc5_1 = (ConstantJoinPC5) iter.next ();
+		ConstantJoinPC5 pc5_2 = (ConstantJoinPC5) iter.next ();
+		if ("pc5-many-to-many-2".equals (pc5_1.getName ()))
+		{
+			ConstantJoinPC5 other = pc5_1;
+			pc5_1 = pc5_2;
+			pc5_2 = other;
+		}
+		assertEquals ("pc5-many-to-many-1", pc5_1.getName ());
+		assertEquals ("pc5-many-to-many-2", pc5_2.getName ());
+		endTx(pm);
+		endEm(pm);
+	}
+
+
+	public void testConstantOneToOne1 ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		ConstantJoinPC4 pc4 =  pm.find(ConstantJoinPC4.class, oid);
+		assertEquals (2, pc4.getManyToMany ().size ());
+		assertEquals ("pc5-one-to-one-1", pc4.getOneToOne1 ().getName ());
+
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testSharedJoinTableModifications ()
+	{
+		EntityManager pm = currentEntityManager();
+		ConstantJoinPC4 pc4 = pm.find(ConstantJoinPC4.class, oid);
+		startTx(pm);
+		pc4.getManyToMany ().clear ();
+		endTx(pm);
+
+		EntityManager pm2 = currentEntityManager();
+		pc4 = pm2.find(ConstantJoinPC4.class, oid);
+		assertNotNull (pc4.getOneToOne1 ());
+		assertEquals (0, pc4.getManyToMany ().size ());
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBCustomMapping.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBCustomMapping.java
index e839994..dd199aa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBCustomMapping.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBCustomMapping.java
@@ -1,85 +1,85 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.CustomMappingPC;
-import junit.framework.*;
-
-
-public class TestEJBCustomMapping extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	private int _oid;
-
-	public TestEJBCustomMapping(String name)
-	{
-		super(name);
-	}
-
-	public void setUp ()
-	{
-		deleteAll(CustomMappingPC.class);
-
-		CustomMappingPC pc = new CustomMappingPC (2);
-		pc.setName ("name");
-		pc.setFemale (true);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc);
-		endTx(pm);
-		_oid = pc.getId();
-		endEm(pm);
-	}
-
-	public void testInsert ()
-	{
-		EntityManager pm = currentEntityManager();
-		CustomMappingPC pc = pm.find(CustomMappingPC.class, _oid);
-		assertNotNull (pc);
-
-		assertEquals ("name", pc.getName ());
-		assertEquals (true, pc.isFemale ());
-		endEm(pm);
-	}
-
-	public void testUpdate ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		CustomMappingPC pc = pm.find(CustomMappingPC.class, _oid);
-
-		pc.setName ("name2");
-		pc.setFemale (false);
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(CustomMappingPC.class, _oid);
-		assertEquals ("name2", pc.getName ());
-		assertTrue (!pc.isFemale ());
-		endTx(pm);
-		endEm(pm);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.CustomMappingPC;
+import junit.framework.*;
+
+
+public class TestEJBCustomMapping extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	private int _oid;
+
+	public TestEJBCustomMapping(String name)
+	{
+		super(name);
+	}
+
+	public void setUp ()
+	{
+		deleteAll(CustomMappingPC.class);
+
+		CustomMappingPC pc = new CustomMappingPC (2);
+		pc.setName ("name");
+		pc.setFemale (true);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc);
+		endTx(pm);
+		_oid = pc.getId();
+		endEm(pm);
+	}
+
+	public void testInsert ()
+	{
+		EntityManager pm = currentEntityManager();
+		CustomMappingPC pc = pm.find(CustomMappingPC.class, _oid);
+		assertNotNull (pc);
+
+		assertEquals ("name", pc.getName ());
+		assertEquals (true, pc.isFemale ());
+		endEm(pm);
+	}
+
+	public void testUpdate ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		CustomMappingPC pc = pm.find(CustomMappingPC.class, _oid);
+
+		pc.setName ("name2");
+		pc.setFemale (false);
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(CustomMappingPC.class, _oid);
+		assertEquals ("name2", pc.getName ());
+		assertTrue (!pc.isFemale ());
+		endTx(pm);
+		endEm(pm);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBDateVersion.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBDateVersion.java
index 973f12d..48ff482 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBDateVersion.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBDateVersion.java
@@ -1,119 +1,119 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.kernel.common.apps.DateVersion;
-import junit.framework.*;
-
-public class TestEJBDateVersion extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	private int oid;
-
-	public TestEJBDateVersion(String name)
-	{
-		super(name);
-	}
-
-	public void setUp() throws Exception
-	{
-		deleteAll(DateVersion.class);
-
-		DateVersion pc = new DateVersion ("pc1", 1);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc);
-
-		oid = pc.getId();
-
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testOptLock ()	throws InterruptedException
-{
-	EntityManager pm1 = currentEntityManager();
-	EntityManager pm2 = currentEntityManager();
-
-
-	startTx(pm1);
-	startTx(pm2);
-	DateVersion pc1 = (DateVersion) pm1.find(DateVersion.class, oid);
-	DateVersion pc2 = (DateVersion) pm2.find(DateVersion.class, oid);
-
-	pc1.setString ("pc-2-1");
-	pc2.setString ("pc-2-2");
-
-	// some DBs do not distinguish dates unless there is 1 sec diff
-	Thread.currentThread ().sleep (1 * 1000);
-	endTx(pm1);
-	try
-	{
-		Thread.currentThread ().sleep (1 * 1000);
-		endTx(pm2);
-		fail ("Should have caused OL exception.");
-	}
-	catch (Exception jfe)
-	{
-		startTx(pm2);
-		pm2.refresh (pc2);
-		pc2.setString ("pc-3-2");
-		endTx(pm2);
-	}
-
-	// make sure the next transaction works too
-	startTx(pm2);
-	pc2.setString ("pc-string-4-2");
-	endTx(pm2);
-
-	startTx(pm1);
-	pm1.refresh (pc1);
-	pc1.setString ("pc-string-3-1");
-
-	startTx(pm2);
-	pc2.setString ("pc-string-5-2");
-
-	Thread.currentThread ().sleep (1 * 1000);
-	endTx(pm1);
-	try
-	{
-		Thread.currentThread ().sleep (1 * 1000);
-		endTx(pm2);
-		fail ("Should have caused OL exception2.");
-	}
-	catch (Exception jfe)
-	{
-		startTx(pm2);
-		pm2.refresh (pc2);
-		pc2.setString ("pc-string-6-2");
-		endTx(pm2);
-	}
-	endEm(pm1);
-	endEm(pm2);
-
-	EntityManager pm = currentEntityManager();
-	DateVersion pc = pm.find(DateVersion.class, oid);
-	assertEquals ("pc-string-6-2", pc.toString ());
-	endEm(pm);
-  }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.kernel.common.apps.DateVersion;
+import junit.framework.*;
+
+public class TestEJBDateVersion extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	private int oid;
+
+	public TestEJBDateVersion(String name)
+	{
+		super(name);
+	}
+
+	public void setUp() throws Exception
+	{
+		deleteAll(DateVersion.class);
+
+		DateVersion pc = new DateVersion ("pc1", 1);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc);
+
+		oid = pc.getId();
+
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testOptLock ()	throws InterruptedException
+{
+	EntityManager pm1 = currentEntityManager();
+	EntityManager pm2 = currentEntityManager();
+
+
+	startTx(pm1);
+	startTx(pm2);
+	DateVersion pc1 = (DateVersion) pm1.find(DateVersion.class, oid);
+	DateVersion pc2 = (DateVersion) pm2.find(DateVersion.class, oid);
+
+	pc1.setString ("pc-2-1");
+	pc2.setString ("pc-2-2");
+
+	// some DBs do not distinguish dates unless there is 1 sec diff
+	Thread.currentThread ().sleep (1 * 1000);
+	endTx(pm1);
+	try
+	{
+		Thread.currentThread ().sleep (1 * 1000);
+		endTx(pm2);
+		fail ("Should have caused OL exception.");
+	}
+	catch (Exception jfe)
+	{
+		startTx(pm2);
+		pm2.refresh (pc2);
+		pc2.setString ("pc-3-2");
+		endTx(pm2);
+	}
+
+	// make sure the next transaction works too
+	startTx(pm2);
+	pc2.setString ("pc-string-4-2");
+	endTx(pm2);
+
+	startTx(pm1);
+	pm1.refresh (pc1);
+	pc1.setString ("pc-string-3-1");
+
+	startTx(pm2);
+	pc2.setString ("pc-string-5-2");
+
+	Thread.currentThread ().sleep (1 * 1000);
+	endTx(pm1);
+	try
+	{
+		Thread.currentThread ().sleep (1 * 1000);
+		endTx(pm2);
+		fail ("Should have caused OL exception2.");
+	}
+	catch (Exception jfe)
+	{
+		startTx(pm2);
+		pm2.refresh (pc2);
+		pc2.setString ("pc-string-6-2");
+		endTx(pm2);
+	}
+	endEm(pm1);
+	endEm(pm2);
+
+	EntityManager pm = currentEntityManager();
+	DateVersion pc = pm.find(DateVersion.class, oid);
+	assertEquals ("pc-string-6-2", pc.toString ());
+	endEm(pm);
+  }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBEager.java
index 61360fd..6af5dbc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBEager.java
@@ -1,153 +1,153 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import junit.framework.*;
-
-public class TestEJBEager extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	private int _oid;
-
-	public TestEJBEager(String name)
-	{
-		super(name);
-	}
-
-	@SuppressWarnings("unchecked")
-	public void setUp()
-	{
-		deleteAll(EagerPCSub.class);
-		deleteAll(EagerPC.class);
-		deleteAll(HelperPC.class);
-		deleteAll(HelperPC2.class);
-		deleteAll(HelperPC4.class);
-		deleteAll(HelperPC3.class);
-
-		EagerPCSub pc = new EagerPCSub (1);
-		pc.setStringField ("string1");
-		EagerPCSub pc2 = new EagerPCSub (2);
-		pc2.setStringField ("string2");
-
-		HelperPC helper1 = new HelperPC (4);
-		helper1.setStringField ("helper1");
-		pc.setHelper (helper1);
-
-		HelperPC2 helperCollection1 = new HelperPC2 ();
-		helperCollection1.setStringField ("helperCollection1");
-		helperCollection1.getHelperCollection ().add (new HelperPC (5));
-		HelperPC2 helperCollection2 = new HelperPC2 (6);
-		helperCollection2.setStringField ("helperCollection2");
-		pc.getHelperCollection ().add (helperCollection1);
-		pc.getHelperCollection ().add (helperCollection2);
-
-		HelperPC eager = new HelperPC (7);
-		eager.setStringField ("eager");
-		pc.setEager (eager);
-
-		HelperPC4 eagerSub = new HelperPC4 ();
-		eagerSub.setStringField ("eagerSub");
-		eagerSub.setIntField (1);
-		pc.setEagerSub (eagerSub);
-
-		HelperPC eagerCollection1 = new HelperPC (8);
-		eagerCollection1.setStringField ("eagerCollection1");
-		HelperPC eagerCollection2 = new HelperPC (9);
-		eagerCollection2.setStringField ("eagerCollection2");
-		pc.getEagerCollection ().add (eagerCollection1);
-		pc.getEagerCollection ().add (eagerCollection2);
-		eagerCollection1.setEager (pc);
-		eagerCollection2.setEager (pc);
-		pc.getEagerCollection2 ().add (eagerCollection1);
-		pc.getEagerCollection2 ().add (eagerCollection2);
-
-		HelperPC eagerCollection3 = new HelperPC (10);
-		eagerCollection3.setStringField ("eagerCollection3");
-		pc2.getEagerCollection ().add (eagerCollection3);
-
-		HelperPC2 recurse = new HelperPC2 (11);
-		recurse.setStringField ("recurse");
-		HelperPC3 helper3 = new HelperPC3 (12);
-		helper3.setStringField ("helper3");
-		recurse.setHelper (helper3);
-		eager.setHelper (helper1);
-		pc.setRecurse (recurse);
-
-		HelperPC2 recurseCollection1 = new HelperPC2 (13);
-		recurseCollection1.setStringField ("recurseCollection1");
-		HelperPC2 recurseCollection2 = new HelperPC2 (14);
-		recurseCollection2.setStringField ("recurseCollection2");
-		pc.getRecurseCollection ().add (recurseCollection1);
-		pc.getRecurseCollection ().add (recurseCollection2);
-		recurseCollection1.getHelperCollection ().add (helper1);
-		HelperPC helper2 = new HelperPC (15);
-		helper2.setStringField ("helper2");
-		recurseCollection1.getHelperCollection ().add (helper2);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc);
-		pm.persist(pc2);
-		endTx(pm);
-		_oid = pc.getId();
-		endEm(pm);
-	}
-
-	public void testOuterJoin ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		EagerPCSub pc = pm.find(EagerPCSub.class, _oid);
-		pc.setEager (null);
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		pc = pm.find(EagerPCSub.class, _oid);
-		assertNull (pc.getEager());
-		assertNotNull (pc.getRecurse ());
-		assertEquals ("helper3", pc.getRecurse ().getHelper ().
-			getStringField ());
-		endEm(pm);
-	}
-
-	public void testOuterJoinToSubclass ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		EagerPCSub pc = pm.find(EagerPCSub.class, _oid);
-		pc.setEagerSub (null);
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		pc = pm.find(EagerPCSub.class, _oid);
-		assertNull (pc.getEagerSub ());
-		assertNotNull (pc.getRecurse ());
-		assertEquals ("helper3", pc.getRecurse ().getHelper ().getStringField ());
-		endTx(pm);
-		endEm(pm);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import junit.framework.*;
+
+public class TestEJBEager extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	private int _oid;
+
+	public TestEJBEager(String name)
+	{
+		super(name);
+	}
+
+	@SuppressWarnings("unchecked")
+	public void setUp()
+	{
+		deleteAll(EagerPCSub.class);
+		deleteAll(EagerPC.class);
+		deleteAll(HelperPC.class);
+		deleteAll(HelperPC2.class);
+		deleteAll(HelperPC4.class);
+		deleteAll(HelperPC3.class);
+
+		EagerPCSub pc = new EagerPCSub (1);
+		pc.setStringField ("string1");
+		EagerPCSub pc2 = new EagerPCSub (2);
+		pc2.setStringField ("string2");
+
+		HelperPC helper1 = new HelperPC (4);
+		helper1.setStringField ("helper1");
+		pc.setHelper (helper1);
+
+		HelperPC2 helperCollection1 = new HelperPC2 ();
+		helperCollection1.setStringField ("helperCollection1");
+		helperCollection1.getHelperCollection ().add (new HelperPC (5));
+		HelperPC2 helperCollection2 = new HelperPC2 (6);
+		helperCollection2.setStringField ("helperCollection2");
+		pc.getHelperCollection ().add (helperCollection1);
+		pc.getHelperCollection ().add (helperCollection2);
+
+		HelperPC eager = new HelperPC (7);
+		eager.setStringField ("eager");
+		pc.setEager (eager);
+
+		HelperPC4 eagerSub = new HelperPC4 ();
+		eagerSub.setStringField ("eagerSub");
+		eagerSub.setIntField (1);
+		pc.setEagerSub (eagerSub);
+
+		HelperPC eagerCollection1 = new HelperPC (8);
+		eagerCollection1.setStringField ("eagerCollection1");
+		HelperPC eagerCollection2 = new HelperPC (9);
+		eagerCollection2.setStringField ("eagerCollection2");
+		pc.getEagerCollection ().add (eagerCollection1);
+		pc.getEagerCollection ().add (eagerCollection2);
+		eagerCollection1.setEager (pc);
+		eagerCollection2.setEager (pc);
+		pc.getEagerCollection2 ().add (eagerCollection1);
+		pc.getEagerCollection2 ().add (eagerCollection2);
+
+		HelperPC eagerCollection3 = new HelperPC (10);
+		eagerCollection3.setStringField ("eagerCollection3");
+		pc2.getEagerCollection ().add (eagerCollection3);
+
+		HelperPC2 recurse = new HelperPC2 (11);
+		recurse.setStringField ("recurse");
+		HelperPC3 helper3 = new HelperPC3 (12);
+		helper3.setStringField ("helper3");
+		recurse.setHelper (helper3);
+		eager.setHelper (helper1);
+		pc.setRecurse (recurse);
+
+		HelperPC2 recurseCollection1 = new HelperPC2 (13);
+		recurseCollection1.setStringField ("recurseCollection1");
+		HelperPC2 recurseCollection2 = new HelperPC2 (14);
+		recurseCollection2.setStringField ("recurseCollection2");
+		pc.getRecurseCollection ().add (recurseCollection1);
+		pc.getRecurseCollection ().add (recurseCollection2);
+		recurseCollection1.getHelperCollection ().add (helper1);
+		HelperPC helper2 = new HelperPC (15);
+		helper2.setStringField ("helper2");
+		recurseCollection1.getHelperCollection ().add (helper2);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc);
+		pm.persist(pc2);
+		endTx(pm);
+		_oid = pc.getId();
+		endEm(pm);
+	}
+
+	public void testOuterJoin ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		EagerPCSub pc = pm.find(EagerPCSub.class, _oid);
+		pc.setEager (null);
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		pc = pm.find(EagerPCSub.class, _oid);
+		assertNull (pc.getEager());
+		assertNotNull (pc.getRecurse ());
+		assertEquals ("helper3", pc.getRecurse ().getHelper ().
+			getStringField ());
+		endEm(pm);
+	}
+
+	public void testOuterJoinToSubclass ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		EagerPCSub pc = pm.find(EagerPCSub.class, _oid);
+		pc.setEagerSub (null);
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		pc = pm.find(EagerPCSub.class, _oid);
+		assertNull (pc.getEagerSub ());
+		assertNotNull (pc.getRecurse ());
+		assertEquals ("helper3", pc.getRecurse ().getHelper ().getStringField ());
+		endTx(pm);
+		endEm(pm);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBInverseOneToOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBInverseOneToOne.java
index 76e3f82..edf5682 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBInverseOneToOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBInverseOneToOne.java
@@ -1,83 +1,83 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.InvertA;
-import org.apache.openjpa.persistence.jdbc.common.apps.InvertB;
-import junit.framework.*;
-
-public class TestEJBInverseOneToOne extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	public TestEJBInverseOneToOne(String name)
-	{
-		super(name);
-	}
-
-	public void setUp ()
-	{
-		deleteAll(InvertA.class);
-		deleteAll(InvertB.class);
-	}
-
-
-	private static Object insertData (EntityManager pm)
-	{
-		InvertA a;
-		InvertB b;
-		a = new InvertA (1);
-		b = new InvertB (2);
-		a.setTest ("testA");
-		b.setTest ("testB");
-		b.setInvertA (a);
-
-		EntityTransaction t = pm.getTransaction ();
-		t.begin ();
-		pm.persist(b);
-		//pm.makeTransactional (b);
-
-		return (pm.find(InvertB.class, 2));
-	}
-
-
-	public void testLoad ()
-	{
-		InvertA a;
-		InvertB b;
-		Object aId;
-		Object bId;
-
-		EntityManager pm = currentEntityManager();
-		aId = insertData (pm);
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		startTx(pm);
-		b = (InvertB) aId;
-
-		assertNotNull(b.getInvertA().getTest());
-		assertEquals (b.getInvertA().getTest (), "testA");
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.InvertA;
+import org.apache.openjpa.persistence.jdbc.common.apps.InvertB;
+import junit.framework.*;
+
+public class TestEJBInverseOneToOne extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	public TestEJBInverseOneToOne(String name)
+	{
+		super(name);
+	}
+
+	public void setUp ()
+	{
+		deleteAll(InvertA.class);
+		deleteAll(InvertB.class);
+	}
+
+
+	private static Object insertData (EntityManager pm)
+	{
+		InvertA a;
+		InvertB b;
+		a = new InvertA (1);
+		b = new InvertB (2);
+		a.setTest ("testA");
+		b.setTest ("testB");
+		b.setInvertA (a);
+
+		EntityTransaction t = pm.getTransaction ();
+		t.begin ();
+		pm.persist(b);
+		//pm.makeTransactional (b);
+
+		return (pm.find(InvertB.class, 2));
+	}
+
+
+	public void testLoad ()
+	{
+		InvertA a;
+		InvertB b;
+		Object aId;
+		Object bId;
+
+		EntityManager pm = currentEntityManager();
+		aId = insertData (pm);
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		startTx(pm);
+		b = (InvertB) aId;
+
+		assertNotNull(b.getInvertA().getTest());
+		assertEquals (b.getInvertA().getTest (), "testA");
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBOuterJoinValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBOuterJoinValues.java
index 0dfc484..68b872f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBOuterJoinValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEJBOuterJoinValues.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.kernel.common.apps.OuterJoinValuePC;
-import junit.framework.*;
-
-public class TestEJBOuterJoinValues extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	public int oid = 0;
-
-	public TestEJBOuterJoinValues(String name)
-	{
-		super(name);
-	}
-
-	public void setUp()
-	{
-		deleteAll(OuterJoinValuePC.class);
-
-		OuterJoinValuePC pc = new OuterJoinValuePC (10);
-		pc.setStringField ("pc");
-		pc.setValue1 (1);
-		pc.setValue2 (2);
-
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		pm.persist(pc);
-		endTx(pm);
-
-		oid = pc.getId();
-		endEm(pm);
-	}
-
-	public void testNull ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		OuterJoinValuePC pc = pm.find(OuterJoinValuePC.class, oid);
-
-		pc.setValue1 (0);
-		pc.setValue2 (0);
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		pc = pm.find(OuterJoinValuePC.class, oid);
-		assertEquals (0, pc.getValue1 ());
-		assertEquals (0, pc.getValue2 ());
-		endEm(pm);
-	}
-
-	public void testUpdate ()
-	{
-		EntityManager pm = currentEntityManager();
-		startTx(pm);
-		OuterJoinValuePC pc = pm.find(OuterJoinValuePC.class, oid);
-		pc.setValue1 (3);
-		pc.setValue2 (0);
-		endTx(pm);
-		endEm(pm);
-
-		pm = currentEntityManager();
-		pc = pm.find(OuterJoinValuePC.class, oid);
-		assertEquals (3, pc.getValue1 ());
-		assertEquals (0, pc.getValue2 ());
-		endEm(pm);
-	}
-
-	public void testInsert ()
-	{
-		// just tests the values inserted in the setup method
-		EntityManager pm = currentEntityManager();
-		OuterJoinValuePC pc = pm.find(OuterJoinValuePC.class, oid);
-		assertEquals ("pc", pc.getStringField ());
-		assertEquals (1, pc.getValue1 ());
-		assertEquals (2, pc.getValue2 ());
-		endEm(pm);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.kernel.common.apps.OuterJoinValuePC;
+import junit.framework.*;
+
+public class TestEJBOuterJoinValues extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	public int oid = 0;
+
+	public TestEJBOuterJoinValues(String name)
+	{
+		super(name);
+	}
+
+	public void setUp()
+	{
+		deleteAll(OuterJoinValuePC.class);
+
+		OuterJoinValuePC pc = new OuterJoinValuePC (10);
+		pc.setStringField ("pc");
+		pc.setValue1 (1);
+		pc.setValue2 (2);
+
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		pm.persist(pc);
+		endTx(pm);
+
+		oid = pc.getId();
+		endEm(pm);
+	}
+
+	public void testNull ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		OuterJoinValuePC pc = pm.find(OuterJoinValuePC.class, oid);
+
+		pc.setValue1 (0);
+		pc.setValue2 (0);
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		pc = pm.find(OuterJoinValuePC.class, oid);
+		assertEquals (0, pc.getValue1 ());
+		assertEquals (0, pc.getValue2 ());
+		endEm(pm);
+	}
+
+	public void testUpdate ()
+	{
+		EntityManager pm = currentEntityManager();
+		startTx(pm);
+		OuterJoinValuePC pc = pm.find(OuterJoinValuePC.class, oid);
+		pc.setValue1 (3);
+		pc.setValue2 (0);
+		endTx(pm);
+		endEm(pm);
+
+		pm = currentEntityManager();
+		pc = pm.find(OuterJoinValuePC.class, oid);
+		assertEquals (3, pc.getValue1 ());
+		assertEquals (0, pc.getValue2 ());
+		endEm(pm);
+	}
+
+	public void testInsert ()
+	{
+		// just tests the values inserted in the setup method
+		EntityManager pm = currentEntityManager();
+		OuterJoinValuePC pc = pm.find(OuterJoinValuePC.class, oid);
+		assertEquals ("pc", pc.getStringField ());
+		assertEquals (1, pc.getValue1 ());
+		assertEquals (2, pc.getValue2 ());
+		endEm(pm);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerDistinct.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerDistinct.java
index 05405fd..53d79e4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerDistinct.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerDistinct.java
@@ -1,242 +1,242 @@
-/*
- * TestEagerDistinct.java
- *
- * Created on October 4, 2006, 4:27 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.Join;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestEagerDistinct extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase 
-{
-        
-    /** Creates a new instance of TestEagerDistinct */
-    public TestEagerDistinct(String name) 
-    {
-    	super(name);
-    }
-    
-    public boolean skipTest() {
-        return ((JDBCConfiguration) getConfiguration()).
-                getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
-    }
-    
-    public void setUpTestCase() {
-       deleteAll(EagerPC.class);
-       deleteAll(HelperPC.class);
-       deleteAll(HelperPC2.class);
-        
-        HelperPC shared = new HelperPC();
-        shared.setStringField("shared");
-        
-        HelperPC2 pc1 = new HelperPC2();
-        pc1.setStringField("pc1");
-        pc1.getHelperCollection().add(shared);
-        pc1.getHelperCollection().add(new HelperPC());
-        
-        HelperPC2 pc2 = new HelperPC2();
-        pc2.setStringField("pc2");
-        pc2.getHelperCollection().add(shared);
-        pc2.getHelperCollection().add(new HelperPC());
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);
-        
-        // to make sure subclasses are selected, etc
-        //FIXME jthomas
-        //pm.createNativeQuery("",HelperPC.class).execute();
-        //pm.newQuery(HelperPC2.class).execute();
-        pm.close();
-    }
-    
-    public OpenJPAEntityManager getPM() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().setMaxFetchDepth(-1);
-        return pm;
-    }
-    
-    public void testEagerParallelWithNonDistinctQuery()
-    throws Exception {
-        eagerParallelWithNonDistinctQuery(-1);
-    }
-    
-    public void testPagingEagerParallelWithNonDistinctQuery()
-    throws Exception {
-        eagerParallelWithNonDistinctQuery(0);
-    }
-    
-    private void eagerParallelWithNonDistinctQuery(int fetchSize)
-    throws Exception {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createNativeQuery("stringField.startsWith ('pc')",HelperPC2.class);
-        //FIXME jthomas
-        //q.setOrdering("stringField ascending");
-        q.getFetchPlan().setFetchBatchSize(fetchSize);
-        List res = (List) q.getResultList();
-        
-        if (fetchSize == -1)
-            assertEquals(2, sql.size());
-        
-        assertEquals(2, res.size());
-        assertHelperPC2("pc1", (HelperPC2) res.get(0));
-        assertHelperPC2("pc2", (HelperPC2) res.get(1));
-        
-        assertNotSQL("DISTINCT");
-        pm.close();
-    }
-    
-    private void assertHelperPC2(String stringField, HelperPC2 pc) {
-        assertEquals(stringField, pc.getStringField());
-        assertEquals(2, pc.getHelperCollection().size());
-        assertEquals("shared", ((HelperPC) pc.getHelperCollection().get(0)).
-                getStringField());
-        assertNull(((HelperPC) pc.getHelperCollection().get(1)).
-                getStringField());
-    }
-    
-    public void testEagerParallelWithDistinctQuery()
-    throws Exception {
-        eagerParallelWithDistinctQuery(-1);
-    }
-    
-    public void testPagingEagerParallelWithDistinctQuery()
-    throws Exception {
-        eagerParallelWithDistinctQuery(0);
-    }
-    
-    private void eagerParallelWithDistinctQuery(int fetchSize)
-    throws Exception {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q =  pm.createNativeQuery("helperCollection.contains (h) && h.stringField == 'shared'",HelperPC2.class);
-        //FIXME  jthomas
-        //q.setOrdering("stringField ascending");
-        q.getFetchPlan().setFetchBatchSize(fetchSize);
-        List res = (List) q.getResultList();
-        
-        if (fetchSize == -1) {
-            sql.remove(0);    // orig sel
-            assertSQL("DISTINCT");
-        }
-        
-        assertEquals(2, res.size());
-        assertHelperPC2("pc1", (HelperPC2) res.get(0));
-        assertHelperPC2("pc2", (HelperPC2) res.get(1));
-        pm.close();
-    }
-    
-    public void testNestedEagerParallel()
-    throws Exception {
-        nestedEagerParallel(-1);
-    }
-    
-    public void testPagingNestedEagerParallel()
-    throws Exception {
-        nestedEagerParallel(0);
-    }
-    
-    private void nestedEagerParallel(int fetchSize)
-    throws Exception {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createNativeQuery("",HelperPC2.class);
-        //FIXME jthomas
-        //q.setOrdering("stringField ascending");
-        List helpers = (List) q.getResultList();
-        
-        EagerPC eager1 = new EagerPC();
-        eager1.setStringField("eager1");
-        eager1.getRecurseCollection().addAll(helpers);
-        
-        EagerPC eager2 = new EagerPC();
-        eager2.setStringField("eager2");
-        eager2.getRecurseCollection().addAll(helpers);
-        HelperPC2 pc3 = new HelperPC2();
-        pc3.setStringField("pc3");
-        pc3.getHelperCollection().add(new HelperPC());
-        pc3.getHelperCollection().add(new HelperPC());
-        pc3.getHelperCollection().add(new HelperPC());
-        eager2.getRecurseCollection().add(pc3);
-        
-        startTx(pm);;
-        pm.persist(eager1);
-        pm.persist(eager2);
-        endTx(pm);;
-        // make sure subclasses selected, etc
-        //FIXME jthomas
-        pm.createNativeQuery("",EagerPC.class).getResultList();
-        pm.close();
-        sql.clear();
-        
-        pm = getPM();
-        q = pm.createNativeQuery("stringField.startsWith ('eager')",EagerPC.class);
-        //FIXME jthomas
-        //q.setOrdering("stringField ascending");
-        q.getFetchPlan().setFetchBatchSize(fetchSize);
-        List res = (List) q.getResultList();
-        
-        if (fetchSize == -1) {
-            sql.remove(0); // orig sel
-            assertSQL("DISTINCT");
-        }
-        
-        assertEquals(2, res.size());
-        eager1 = (EagerPC) res.get(0);
-        assertEquals("eager1", eager1.getStringField());
-        assertEquals(2, eager1.getRecurseCollection().size());
-        assertHelperPC2("pc1", (HelperPC2) eager1.getRecurseCollection().
-                get(0));
-        assertHelperPC2("pc2", (HelperPC2) eager1.getRecurseCollection().
-                get(1));
-        
-        eager2 = (EagerPC) res.get(1);
-        assertEquals("eager2", eager2.getStringField());
-        assertEquals(3, eager2.getRecurseCollection().size());
-        assertHelperPC2("pc1", (HelperPC2) eager2.getRecurseCollection().
-                get(0));
-        assertHelperPC2("pc2", (HelperPC2) eager2.getRecurseCollection().
-                get(1));
-        pc3 = (HelperPC2) eager2.getRecurseCollection().get(2);
-        assertEquals("pc3", pc3.getStringField());
-        assertEquals(3, pc3.getHelperCollection().size());
-        pm.close();
-    }
-    
-}
+/*
+ * TestEagerDistinct.java
+ *
+ * Created on October 4, 2006, 4:27 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.Join;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestEagerDistinct extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase 
+{
+        
+    /** Creates a new instance of TestEagerDistinct */
+    public TestEagerDistinct(String name) 
+    {
+    	super(name);
+    }
+    
+    public boolean skipTest() {
+        return ((JDBCConfiguration) getConfiguration()).
+                getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
+    }
+    
+    public void setUpTestCase() {
+       deleteAll(EagerPC.class);
+       deleteAll(HelperPC.class);
+       deleteAll(HelperPC2.class);
+        
+        HelperPC shared = new HelperPC();
+        shared.setStringField("shared");
+        
+        HelperPC2 pc1 = new HelperPC2();
+        pc1.setStringField("pc1");
+        pc1.getHelperCollection().add(shared);
+        pc1.getHelperCollection().add(new HelperPC());
+        
+        HelperPC2 pc2 = new HelperPC2();
+        pc2.setStringField("pc2");
+        pc2.getHelperCollection().add(shared);
+        pc2.getHelperCollection().add(new HelperPC());
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);
+        
+        // to make sure subclasses are selected, etc
+        //FIXME jthomas
+        //pm.createNativeQuery("",HelperPC.class).execute();
+        //pm.newQuery(HelperPC2.class).execute();
+        pm.close();
+    }
+    
+    public OpenJPAEntityManager getPM() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().setMaxFetchDepth(-1);
+        return pm;
+    }
+    
+    public void testEagerParallelWithNonDistinctQuery()
+    throws Exception {
+        eagerParallelWithNonDistinctQuery(-1);
+    }
+    
+    public void testPagingEagerParallelWithNonDistinctQuery()
+    throws Exception {
+        eagerParallelWithNonDistinctQuery(0);
+    }
+    
+    private void eagerParallelWithNonDistinctQuery(int fetchSize)
+    throws Exception {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createNativeQuery("stringField.startsWith ('pc')",HelperPC2.class);
+        //FIXME jthomas
+        //q.setOrdering("stringField ascending");
+        q.getFetchPlan().setFetchBatchSize(fetchSize);
+        List res = (List) q.getResultList();
+        
+        if (fetchSize == -1)
+            assertEquals(2, sql.size());
+        
+        assertEquals(2, res.size());
+        assertHelperPC2("pc1", (HelperPC2) res.get(0));
+        assertHelperPC2("pc2", (HelperPC2) res.get(1));
+        
+        assertNotSQL("DISTINCT");
+        pm.close();
+    }
+    
+    private void assertHelperPC2(String stringField, HelperPC2 pc) {
+        assertEquals(stringField, pc.getStringField());
+        assertEquals(2, pc.getHelperCollection().size());
+        assertEquals("shared", ((HelperPC) pc.getHelperCollection().get(0)).
+                getStringField());
+        assertNull(((HelperPC) pc.getHelperCollection().get(1)).
+                getStringField());
+    }
+    
+    public void testEagerParallelWithDistinctQuery()
+    throws Exception {
+        eagerParallelWithDistinctQuery(-1);
+    }
+    
+    public void testPagingEagerParallelWithDistinctQuery()
+    throws Exception {
+        eagerParallelWithDistinctQuery(0);
+    }
+    
+    private void eagerParallelWithDistinctQuery(int fetchSize)
+    throws Exception {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q =  pm.createNativeQuery("helperCollection.contains (h) && h.stringField == 'shared'",HelperPC2.class);
+        //FIXME  jthomas
+        //q.setOrdering("stringField ascending");
+        q.getFetchPlan().setFetchBatchSize(fetchSize);
+        List res = (List) q.getResultList();
+        
+        if (fetchSize == -1) {
+            sql.remove(0);    // orig sel
+            assertSQL("DISTINCT");
+        }
+        
+        assertEquals(2, res.size());
+        assertHelperPC2("pc1", (HelperPC2) res.get(0));
+        assertHelperPC2("pc2", (HelperPC2) res.get(1));
+        pm.close();
+    }
+    
+    public void testNestedEagerParallel()
+    throws Exception {
+        nestedEagerParallel(-1);
+    }
+    
+    public void testPagingNestedEagerParallel()
+    throws Exception {
+        nestedEagerParallel(0);
+    }
+    
+    private void nestedEagerParallel(int fetchSize)
+    throws Exception {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createNativeQuery("",HelperPC2.class);
+        //FIXME jthomas
+        //q.setOrdering("stringField ascending");
+        List helpers = (List) q.getResultList();
+        
+        EagerPC eager1 = new EagerPC();
+        eager1.setStringField("eager1");
+        eager1.getRecurseCollection().addAll(helpers);
+        
+        EagerPC eager2 = new EagerPC();
+        eager2.setStringField("eager2");
+        eager2.getRecurseCollection().addAll(helpers);
+        HelperPC2 pc3 = new HelperPC2();
+        pc3.setStringField("pc3");
+        pc3.getHelperCollection().add(new HelperPC());
+        pc3.getHelperCollection().add(new HelperPC());
+        pc3.getHelperCollection().add(new HelperPC());
+        eager2.getRecurseCollection().add(pc3);
+        
+        startTx(pm);;
+        pm.persist(eager1);
+        pm.persist(eager2);
+        endTx(pm);;
+        // make sure subclasses selected, etc
+        //FIXME jthomas
+        pm.createNativeQuery("",EagerPC.class).getResultList();
+        pm.close();
+        sql.clear();
+        
+        pm = getPM();
+        q = pm.createNativeQuery("stringField.startsWith ('eager')",EagerPC.class);
+        //FIXME jthomas
+        //q.setOrdering("stringField ascending");
+        q.getFetchPlan().setFetchBatchSize(fetchSize);
+        List res = (List) q.getResultList();
+        
+        if (fetchSize == -1) {
+            sql.remove(0); // orig sel
+            assertSQL("DISTINCT");
+        }
+        
+        assertEquals(2, res.size());
+        eager1 = (EagerPC) res.get(0);
+        assertEquals("eager1", eager1.getStringField());
+        assertEquals(2, eager1.getRecurseCollection().size());
+        assertHelperPC2("pc1", (HelperPC2) eager1.getRecurseCollection().
+                get(0));
+        assertHelperPC2("pc2", (HelperPC2) eager1.getRecurseCollection().
+                get(1));
+        
+        eager2 = (EagerPC) res.get(1);
+        assertEquals("eager2", eager2.getStringField());
+        assertEquals(3, eager2.getRecurseCollection().size());
+        assertHelperPC2("pc1", (HelperPC2) eager2.getRecurseCollection().
+                get(0));
+        assertHelperPC2("pc2", (HelperPC2) eager2.getRecurseCollection().
+                get(1));
+        pc3 = (HelperPC2) eager2.getRecurseCollection().get(2);
+        assertEquals("pc3", pc3.getStringField());
+        assertEquals(3, pc3.getHelperCollection().size());
+        pm.close();
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerOuterToManyJoins.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerOuterToManyJoins.java
index b94ad7e..89814d7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerOuterToManyJoins.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestEagerOuterToManyJoins.java
@@ -1,874 +1,874 @@
-/*
- * TestEagerOuterToManyJoins.java
- *
- * Created on October 3, 2006, 10:53 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.persistence.FetchPlan;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.jdbc.common.apps.EagerOuterJoinPC;
-
-
-public class TestEagerOuterToManyJoins extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    /** Creates a new instance of TestEagerOuterToManyJoins */
-    public TestEagerOuterToManyJoins(String name) {
-    	super(name);
-    }
-    
-    public boolean skipTest() {
-        DBDictionary dict = ((JDBCConfiguration) getConfiguration()).
-                getDBDictionaryInstance();
-        return !dict.supportsSubselect;
-    }
-    
-    public void setUp() {
-        
-       deleteAll(HelperPC.class);
-       deleteAll(EagerOuterJoinPC2.class);
-       deleteAll(EagerOuterJoinPC.class);
-    }
-    
-    
-    public void testStringCollectionById() {
-        stringCollectionByIdTest(false);
-    }
-    
-    public void testEmptyStringCollectionById() {
-        stringCollectionByIdTest(true);
-    }
-    
-    private void stringCollectionByIdTest(boolean empty) {
-        Object oid = insertStringCollection((empty) ? 1 : 0);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
-        assertEquals("1", pc.getName());
-        if (empty)
-            assertEquals(pc.getStringCollection().toString(),
-                    0, pc.getStringCollection().size());
-        else {
-            assertEquals(pc.getStringCollection().toString(),
-                    2, pc.getStringCollection().size());
-            assertTrue(pc.getStringCollection().contains("1.1"));
-            assertTrue(pc.getStringCollection().contains("1.2"));
-        }
-        pm.close();
-    }
-    
-    public void testStringCollectionByQuery() {
-        stringCollectionByQueryTest(0);
-    }
-    
-    public void testEmptyStringCollectionByQuery1() {
-        stringCollectionByQueryTest(1);
-    }
-    
-    public void testEmptyStringCollectionByQuery2() {
-        stringCollectionByQueryTest(2);
-    }
-    
-    public void testEmptyStringCollectionByQuery3() {
-        stringCollectionByQueryTest(3);
-    }
-    
-    private void stringCollectionByQueryTest(int empty) {
-        insertStringCollection(empty);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
-        fetch.setFetchBatchSize(-1);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        
-        assertEquals(2, results.size());
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("1", pc.getName());
-        if ((empty & 1) > 0)
-            assertEquals(pc.getStringCollection().toString(),
-                    0, pc.getStringCollection().size());
-        else {
-            assertEquals(pc.getStringCollection().toString(),
-                    2, pc.getStringCollection().size());
-            assertTrue(pc.getStringCollection().contains("1.1"));
-            assertTrue(pc.getStringCollection().contains("1.2"));
-        }
-        
-        pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("2", pc.getName());
-        if ((empty & 2) > 0)
-            assertEquals(pc.getStringCollection().toString(),
-                    0, pc.getStringCollection().size());
-        else {
-            assertEquals(pc.getStringCollection().toString(),
-                    2, pc.getStringCollection().size());
-            assertTrue(pc.getStringCollection().contains("2.1"));
-            assertTrue(pc.getStringCollection().contains("2.2"));
-        }
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertStringCollection(int empty) {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        if ((empty & 1) == 0) {
-            pc1.getStringCollection().add("1.1");
-            pc1.getStringCollection().add("1.2");
-        }
-        
-        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
-        pc2.setName("2");
-        if ((empty & 2) == 0) {
-            pc2.getStringCollection().add("2.1");
-            pc2.getStringCollection().add("2.2");
-        }
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        
-        startTx(pm);;
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);;
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    public void testStringListById() {
-        Object oid = insertStringList();
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        
-        
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringList");
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getStringList().size());
-        assertEquals("1.1", pc.getStringList().get(0));
-        assertEquals("1.2", pc.getStringList().get(1));
-        pm.close();
-    }
-    
-    public void testStringListByQuery() {
-        insertStringList();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringList");
-        fetch.setFetchBatchSize(-1);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        
-        assertEquals(2, results.size());
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getStringList().size());
-        assertEquals("1.1", pc.getStringList().get(0));
-        assertEquals("1.2", pc.getStringList().get(1));
-        pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("2", pc.getName());
-        assertEquals(2, pc.getStringList().size());
-        assertEquals("2.1", pc.getStringList().get(0));
-        assertEquals("2.2", pc.getStringList().get(1));
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertStringList() {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        pc1.getStringList().add("1.1");
-        pc1.getStringList().add("1.2");
-        
-        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
-        pc2.setName("2");
-        pc2.getStringList().add("2.1");
-        pc2.getStringList().add("2.2");
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);;
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    public void testOneManyCollectionById() {
-        oneManyCollectionByIdTest(false);
-    }
-    
-    public void testEmptyOneManyCollectionById() {
-        oneManyCollectionByIdTest(true);
-    }
-    
-    private void oneManyCollectionByIdTest(boolean empty) {
-        Object oid = insertOneManyCollection((empty) ? 1 : 0);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "oneManyCollection");
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
-        assertEquals("1", pc.getName());
-        if (empty)
-            assertEquals(0, pc.getOneManyCollection().size());
-        else
-            assertEquals(2, pc.getOneManyCollection().size());
-        pm.close();
-    }
-    
-    public void testOneManyCollectionByQuery() {
-        oneManyCollectionByQueryTest(0);
-    }
-    
-    public void testEmptyOneManyCollectionByQuery1() {
-        oneManyCollectionByQueryTest(1);
-    }
-    
-    public void testEmptyOneManyCollectionByQuery2() {
-        oneManyCollectionByQueryTest(2);
-    }
-    
-    public void testEmptyOneManyCollectionByQuery3() {
-        oneManyCollectionByQueryTest(3);
-    }
-    
-    private void oneManyCollectionByQueryTest(int empty) {
-        insertOneManyCollection(empty);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "oneManyCollection");
-        fetch.setFetchBatchSize(-1);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        
-        assertEquals(2, results.size());
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("1", pc.getName());
-        if ((empty & 1) > 0)
-            assertEquals(0, pc.getOneManyCollection().size());
-        else
-            assertEquals(2, pc.getOneManyCollection().size());
-        
-        pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("2", pc.getName());
-        if ((empty & 2) > 0)
-            assertEquals(0, pc.getOneManyCollection().size());
-        else
-            assertEquals(2, pc.getOneManyCollection().size());
-        
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertOneManyCollection(int empty) {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        EagerOuterJoinPC2 hpc;
-        if ((empty & 1) == 0) {
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("1.1");
-            hpc.setRef(pc1);
-            pc1.getOneManyCollection().add(hpc);
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("1.2");
-            hpc.setRef(pc1);
-            pc1.getOneManyCollection().add(hpc);
-        }
-        
-        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
-        pc2.setName("2");
-        if ((empty & 2) == 0) {
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("2.1");
-            hpc.setRef(pc2);
-            pc2.getOneManyCollection().add(hpc);
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("2.2");
-            hpc.setRef(pc2);
-            pc2.getOneManyCollection().add(hpc);
-        }
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    public void testManyManyCollectionById() {
-        Object oid = insertManyManyCollection();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "manyManyCollection");
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getManyManyCollection().size());
-        pm.close();
-    }
-    
-    public void testManyManyCollectionByQuery() {
-        insertManyManyCollection();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "manyManyCollection");
-        fetch.setFetchBatchSize(-1);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        
-        assertEquals(2, results.size());
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getManyManyCollection().size());
-        pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("2", pc.getName());
-        assertEquals(2, pc.getManyManyCollection().size());
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertManyManyCollection() {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        EagerOuterJoinPC2 hpc = new EagerOuterJoinPC2();
-        hpc.setName("1.1");
-        pc1.getManyManyCollection().add(hpc);
-        hpc = new EagerOuterJoinPC2();
-        hpc.setName("1.2");
-        pc1.getManyManyCollection().add(hpc);
-        
-        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
-        pc2.setName("2");
-        hpc = new EagerOuterJoinPC2();
-        hpc.setName("2.1");
-        pc2.getManyManyCollection().add(hpc);
-        hpc = new EagerOuterJoinPC2();
-        hpc.setName("2.2");
-        pc2.getManyManyCollection().add(hpc);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);;
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    public void testManyManyListById() {
-        manyManyListByIdTest(false);
-    }
-    
-    public void testEmptyManyManyListById() {
-        manyManyListByIdTest(true);
-    }
-    
-    private void manyManyListByIdTest(boolean empty) {
-        Object oid = insertManyManyList((empty) ? 1 : 0);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
-        assertEquals("1", pc.getName());
-        if (empty)
-            assertEquals(0, pc.getManyManyList().size());
-        else {
-            assertEquals(2, pc.getManyManyList().size());
-            EagerOuterJoinPC2 hpc = (EagerOuterJoinPC2)
-            pc.getManyManyList().get(0);
-            assertEquals("1.1", hpc.getName());
-            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-            assertEquals("1.2", hpc.getName());
-        }
-        pm.close();
-    }
-    
-    public void testManyManyListByQuery() {
-        manyManyListByQueryTest(0);
-    }
-    
-    public void testEmptyManyManyListByQuery1() {
-        manyManyListByQueryTest(1);
-    }
-    
-    public void testEmptyManyManyListByQuery2() {
-        manyManyListByQueryTest(2);
-    }
-    
-    public void testEmptyManyManyListByQuery3() {
-        manyManyListByQueryTest(3);
-    }
-    
-    private void manyManyListByQueryTest(int empty) {
-        insertManyManyList(empty);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
-        fetch.setFetchBatchSize(-1);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        
-        assertEquals(2, results.size());
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("1", pc.getName());
-        EagerOuterJoinPC2 hpc;
-        if ((empty & 1) > 0)
-            assertEquals(0, pc.getManyManyList().size());
-        else {
-            assertEquals(2, pc.getManyManyList().size());
-            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(0);
-            assertEquals("1.1", hpc.getName());
-            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-            assertEquals("1.2", hpc.getName());
-        }
-        
-        pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("2", pc.getName());
-        if ((empty & 2) > 0)
-            assertEquals(0, pc.getManyManyList().size());
-        else {
-            assertEquals(2, pc.getManyManyList().size());
-            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(0);
-            assertEquals("2.1", hpc.getName());
-            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-            assertEquals("2.2", hpc.getName());
-        }
-        
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertManyManyList(int empty) {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        EagerOuterJoinPC2 hpc;
-        if ((empty & 1) == 0) {
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("1.1");
-            pc1.getManyManyList().add(hpc);
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("1.2");
-            pc1.getManyManyList().add(hpc);
-        }
-        
-        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
-        pc2.setName("2");
-        if ((empty & 2) == 0) {
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("2.1");
-            pc2.getManyManyList().add(hpc);
-            hpc = new EagerOuterJoinPC2();
-            hpc.setName("2.2");
-            pc2.getManyManyList().add(hpc);
-        }
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);;
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    public void testTwoCollectionsInFetchGroupsById() {
-        Object oid = insertTwoCollections();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
-        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getStringCollection().size());
-        assertTrue(pc.getStringCollection().contains("1.1"));
-        assertTrue(pc.getStringCollection().contains("1.2"));
-        assertEquals(2, pc.getManyManyList().size());
-        EagerOuterJoinPC2 hpc = (EagerOuterJoinPC2)
-        pc.getManyManyList().get(0);
-        assertEquals("1.1", hpc.getName());
-        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-        assertEquals("1.2", hpc.getName());
-        pm.close();
-    }
-    
-    public void testTwoCollectionsInFetchGroupsByQuery() {
-        insertTwoCollections();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
-        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
-        fetch.setFetchBatchSize(-1);
-        
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        
-        assertEquals(2, results.size());
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getStringCollection().size());
-        assertTrue(pc.getStringCollection().contains("1.1"));
-        assertTrue(pc.getStringCollection().contains("1.2"));
-        assertEquals(2, pc.getManyManyList().size());
-        EagerOuterJoinPC2 hpc = (EagerOuterJoinPC2)
-        pc.getManyManyList().get(0);
-        assertEquals("1.1", hpc.getName());
-        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-        assertEquals("1.2", hpc.getName());
-        
-        pc = (EagerOuterJoinPC) itr.next();
-        assertEquals("2", pc.getName());
-        assertEquals(2, pc.getStringCollection().size());
-        assertTrue(pc.getStringCollection().contains("2.1"));
-        assertTrue(pc.getStringCollection().contains("2.2"));
-        assertEquals(2, pc.getManyManyList().size());
-        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(0);
-        assertEquals("2.1", hpc.getName());
-        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-        assertEquals("2.2", hpc.getName());
-        
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertTwoCollections() {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        pc1.getStringCollection().add("1.1");
-        pc1.getStringCollection().add("1.2");
-        EagerOuterJoinPC2 hpc = new EagerOuterJoinPC2();
-        hpc.setName("1.1");
-        pc1.getManyManyList().add(hpc);
-        hpc = new EagerOuterJoinPC2();
-        hpc.setName("1.2");
-        pc1.getManyManyList().add(hpc);
-        
-        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
-        pc2.setName("2");
-        pc2.getStringCollection().add("2.1");
-        pc2.getStringCollection().add("2.2");
-        hpc = new EagerOuterJoinPC2();
-        hpc.setName("2.1");
-        pc2.getManyManyList().add(hpc);
-        hpc = new EagerOuterJoinPC2();
-        hpc.setName("2.2");
-        pc2.getManyManyList().add(hpc);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(pc1);
-        pm.persist(pc2);
-        endTx(pm);;
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    public void testQueryRandomAccess() {
-        insertManyStringList();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringList");
-        fetch.setFetchBatchSize(3);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        List results = (List) q.getResultList();
-        assertEquals(10, results.size());
-        
-        for (int i = 5; i < results.size(); i++) {
-            EagerOuterJoinPC pc = (EagerOuterJoinPC) results.get(i);
-            assertEquals(String.valueOf(i), pc.getName());
-            assertEquals(2, pc.getStringList().size());
-            assertEquals(i + ".1", pc.getStringList().get(0));
-            assertEquals(i + ".2", pc.getStringList().get(1));
-        }
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testQueryRange() {
-        insertManyStringList();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "stringList");
-        fetch.setFetchBatchSize(3);
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        //q.setRange(5, 20);
-        
-        List results = (List) q.getResultList();
-        assertEquals(5, results.size());
-        
-        for (int i = 0; i < results.size(); i++) {
-            EagerOuterJoinPC pc = (EagerOuterJoinPC) results.get(i);
-            assertEquals(String.valueOf(i + 5), pc.getName());
-            assertEquals(2, pc.getStringList().size());
-            assertEquals((i + 5) + ".1", pc.getStringList().get(0));
-            assertEquals((i + 5) + ".2", pc.getStringList().get(1));
-        }
-        q.closeAll();
-        pm.close();
-    }
-    
-    private void insertManyStringList() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        for (int i = 0; i < 10; i++) {
-            EagerOuterJoinPC pc = new EagerOuterJoinPC();
-            pc.setName(String.valueOf(i));
-            pc.getStringList().add(i + ".1");
-            pc.getStringList().add(i + ".2");
-            pm.persist(pc);
-        }
-        endTx(pm);;
-        pm.close();
-    }
-    
-    public void testEagerToOneThenEagerToMany() {
-        insertEagers();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC2.class, "ref");
-        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC2.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        assertEquals(new ArrayList(results).toString(), 2, results.size());
-        
-        Iterator itr = results.iterator();
-        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2) itr.next();
-        assertEquals("r1", ref.getName());
-        EagerOuterJoinPC pc = ref.getRef();
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getStringCollection().size());
-        assertTrue(pc.getStringCollection().contains("1.1"));
-        assertTrue(pc.getStringCollection().contains("1.2"));
-        
-        ref = (EagerOuterJoinPC2) itr.next();
-        assertEquals("r2", ref.getName());
-        assertTrue(pc == ref.getRef());
-        
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    public void testEagerToManyThenEagerToOne() {
-        insertEagers();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
-        fetch.addField(EagerOuterJoinPC2.class, "helper");
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        assertEquals(1, results.size());
-        
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) results.iterator().next();
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getManyManyList().size());
-        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2)
-        pc.getManyManyList().get(0);
-        assertEquals("r1", ref.getName());
-        assertEquals("h1", ref.getHelper().getStringField());
-        ref = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-        assertEquals("r2", ref.getName());
-        assertEquals("h2", ref.getHelper().getStringField());
-        
-        pm.close();
-    }
-    
-    public void testEagerToManyThenEagerToMany() {
-        insertEagers();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
-        fetch.addField(EagerOuterJoinPC2.class, "stringCollection");
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        assertEquals(1, results.size());
-        
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) results.iterator().next();
-        assertEquals("1", pc.getName());
-        assertEquals(2, pc.getManyManyList().size());
-        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2)
-        pc.getManyManyList().get(0);
-        assertEquals("r1", ref.getName());
-        assertEquals(2, ref.getStringCollection().size());
-        assertTrue(ref.getStringCollection().contains("r1.1"));
-        assertTrue(ref.getStringCollection().contains("r1.2"));
-        
-        ref = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
-        assertEquals("r2", ref.getName());
-        assertEquals(2, ref.getStringCollection().size());
-        assertTrue(ref.getStringCollection().contains("r2.1"));
-        assertTrue(ref.getStringCollection().contains("r2.2"));
-        
-        pm.close();
-    }
-    
-    public void testEagerToOneAndToManyThenEagerToOne() {
-        Object oid = insertEagers();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        fetch.addField(EagerOuterJoinPC.class, "oneManyCollection");
-        fetch.addField(EagerOuterJoinPC.class, "helper");
-        fetch.addField(EagerOuterJoinPC2.class, "helper");
-        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
-        //FIXME jthomas
-        //q.setOrdering("name ascending");
-        Collection results = (Collection) q.getResultList();
-        assertEquals(1, results.size());
-        
-        EagerOuterJoinPC pc = (EagerOuterJoinPC) results.iterator().next();
-        assertEquals("1", pc.getName());
-        assertEquals("h3", pc.getHelper().getStringField());
-        assertEquals(2, pc.getOneManyCollection().size());
-        Iterator itr = pc.getOneManyCollection().iterator();
-        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2) itr.next();
-        if ("r1".equals(ref.getName())) {
-            assertEquals("h1", ref.getHelper().getStringField());
-            ref = (EagerOuterJoinPC2) itr.next();
-            assertEquals("r2", ref.getName());
-            assertEquals("h2", ref.getHelper().getStringField());
-        } else {
-            assertEquals("r2", ref.getName());
-            assertEquals("h2", ref.getHelper().getStringField());
-            ref = (EagerOuterJoinPC2) itr.next();
-            assertEquals("r1", ref.getName());
-            assertEquals("h1", ref.getHelper().getStringField());
-        }
-        assertTrue(!itr.hasNext());
-        pm.close();
-    }
-    
-    private Object insertEagers() {
-        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
-        pc1.setName("1");
-        pc1.getStringCollection().add("1.1");
-        pc1.getStringCollection().add("1.2");
-        
-        EagerOuterJoinPC2 ref1 = new EagerOuterJoinPC2();
-        ref1.setName("r1");
-        ref1.getStringCollection().add("r1.1");
-        ref1.getStringCollection().add("r1.2");
-        
-        EagerOuterJoinPC2 ref2 = new EagerOuterJoinPC2();
-        ref2.setName("r2");
-        ref2.getStringCollection().add("r2.1");
-        ref2.getStringCollection().add("r2.2");
-        
-        HelperPC hpc1 = new HelperPC();
-        hpc1.setStringField("h1");
-        
-        HelperPC hpc2 = new HelperPC();
-        hpc2.setStringField("h2");
-        
-        HelperPC hpc3 = new HelperPC();
-        hpc3.setStringField("h3");
-        
-        pc1.getManyManyList().add(ref1);
-        pc1.getOneManyCollection().add(ref1);
-        ref1.setRef(pc1);
-        pc1.getManyManyList().add(ref2);
-        pc1.getOneManyCollection().add(ref2);
-        ref2.setRef(pc1);
-        
-        ref1.setHelper(hpc1);
-        ref2.setHelper(hpc2);
-        pc1.setHelper(hpc3);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(pc1);
-        endTx(pm);;
-        Object oid = pm.getObjectId(pc1);
-        pm.close();
-        return oid;
-    }
-    
-    
-}
+/*
+ * TestEagerOuterToManyJoins.java
+ *
+ * Created on October 3, 2006, 10:53 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.persistence.FetchPlan;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.jdbc.common.apps.EagerOuterJoinPC;
+
+
+public class TestEagerOuterToManyJoins extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    /** Creates a new instance of TestEagerOuterToManyJoins */
+    public TestEagerOuterToManyJoins(String name) {
+    	super(name);
+    }
+    
+    public boolean skipTest() {
+        DBDictionary dict = ((JDBCConfiguration) getConfiguration()).
+                getDBDictionaryInstance();
+        return !dict.supportsSubselect;
+    }
+    
+    public void setUp() {
+        
+       deleteAll(HelperPC.class);
+       deleteAll(EagerOuterJoinPC2.class);
+       deleteAll(EagerOuterJoinPC.class);
+    }
+    
+    
+    public void testStringCollectionById() {
+        stringCollectionByIdTest(false);
+    }
+    
+    public void testEmptyStringCollectionById() {
+        stringCollectionByIdTest(true);
+    }
+    
+    private void stringCollectionByIdTest(boolean empty) {
+        Object oid = insertStringCollection((empty) ? 1 : 0);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
+        assertEquals("1", pc.getName());
+        if (empty)
+            assertEquals(pc.getStringCollection().toString(),
+                    0, pc.getStringCollection().size());
+        else {
+            assertEquals(pc.getStringCollection().toString(),
+                    2, pc.getStringCollection().size());
+            assertTrue(pc.getStringCollection().contains("1.1"));
+            assertTrue(pc.getStringCollection().contains("1.2"));
+        }
+        pm.close();
+    }
+    
+    public void testStringCollectionByQuery() {
+        stringCollectionByQueryTest(0);
+    }
+    
+    public void testEmptyStringCollectionByQuery1() {
+        stringCollectionByQueryTest(1);
+    }
+    
+    public void testEmptyStringCollectionByQuery2() {
+        stringCollectionByQueryTest(2);
+    }
+    
+    public void testEmptyStringCollectionByQuery3() {
+        stringCollectionByQueryTest(3);
+    }
+    
+    private void stringCollectionByQueryTest(int empty) {
+        insertStringCollection(empty);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
+        fetch.setFetchBatchSize(-1);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        
+        assertEquals(2, results.size());
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("1", pc.getName());
+        if ((empty & 1) > 0)
+            assertEquals(pc.getStringCollection().toString(),
+                    0, pc.getStringCollection().size());
+        else {
+            assertEquals(pc.getStringCollection().toString(),
+                    2, pc.getStringCollection().size());
+            assertTrue(pc.getStringCollection().contains("1.1"));
+            assertTrue(pc.getStringCollection().contains("1.2"));
+        }
+        
+        pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("2", pc.getName());
+        if ((empty & 2) > 0)
+            assertEquals(pc.getStringCollection().toString(),
+                    0, pc.getStringCollection().size());
+        else {
+            assertEquals(pc.getStringCollection().toString(),
+                    2, pc.getStringCollection().size());
+            assertTrue(pc.getStringCollection().contains("2.1"));
+            assertTrue(pc.getStringCollection().contains("2.2"));
+        }
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertStringCollection(int empty) {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        if ((empty & 1) == 0) {
+            pc1.getStringCollection().add("1.1");
+            pc1.getStringCollection().add("1.2");
+        }
+        
+        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
+        pc2.setName("2");
+        if ((empty & 2) == 0) {
+            pc2.getStringCollection().add("2.1");
+            pc2.getStringCollection().add("2.2");
+        }
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        
+        startTx(pm);;
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);;
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    public void testStringListById() {
+        Object oid = insertStringList();
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        
+        
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringList");
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getStringList().size());
+        assertEquals("1.1", pc.getStringList().get(0));
+        assertEquals("1.2", pc.getStringList().get(1));
+        pm.close();
+    }
+    
+    public void testStringListByQuery() {
+        insertStringList();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringList");
+        fetch.setFetchBatchSize(-1);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        
+        assertEquals(2, results.size());
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getStringList().size());
+        assertEquals("1.1", pc.getStringList().get(0));
+        assertEquals("1.2", pc.getStringList().get(1));
+        pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("2", pc.getName());
+        assertEquals(2, pc.getStringList().size());
+        assertEquals("2.1", pc.getStringList().get(0));
+        assertEquals("2.2", pc.getStringList().get(1));
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertStringList() {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        pc1.getStringList().add("1.1");
+        pc1.getStringList().add("1.2");
+        
+        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
+        pc2.setName("2");
+        pc2.getStringList().add("2.1");
+        pc2.getStringList().add("2.2");
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);;
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    public void testOneManyCollectionById() {
+        oneManyCollectionByIdTest(false);
+    }
+    
+    public void testEmptyOneManyCollectionById() {
+        oneManyCollectionByIdTest(true);
+    }
+    
+    private void oneManyCollectionByIdTest(boolean empty) {
+        Object oid = insertOneManyCollection((empty) ? 1 : 0);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "oneManyCollection");
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
+        assertEquals("1", pc.getName());
+        if (empty)
+            assertEquals(0, pc.getOneManyCollection().size());
+        else
+            assertEquals(2, pc.getOneManyCollection().size());
+        pm.close();
+    }
+    
+    public void testOneManyCollectionByQuery() {
+        oneManyCollectionByQueryTest(0);
+    }
+    
+    public void testEmptyOneManyCollectionByQuery1() {
+        oneManyCollectionByQueryTest(1);
+    }
+    
+    public void testEmptyOneManyCollectionByQuery2() {
+        oneManyCollectionByQueryTest(2);
+    }
+    
+    public void testEmptyOneManyCollectionByQuery3() {
+        oneManyCollectionByQueryTest(3);
+    }
+    
+    private void oneManyCollectionByQueryTest(int empty) {
+        insertOneManyCollection(empty);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "oneManyCollection");
+        fetch.setFetchBatchSize(-1);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        
+        assertEquals(2, results.size());
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("1", pc.getName());
+        if ((empty & 1) > 0)
+            assertEquals(0, pc.getOneManyCollection().size());
+        else
+            assertEquals(2, pc.getOneManyCollection().size());
+        
+        pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("2", pc.getName());
+        if ((empty & 2) > 0)
+            assertEquals(0, pc.getOneManyCollection().size());
+        else
+            assertEquals(2, pc.getOneManyCollection().size());
+        
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertOneManyCollection(int empty) {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        EagerOuterJoinPC2 hpc;
+        if ((empty & 1) == 0) {
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("1.1");
+            hpc.setRef(pc1);
+            pc1.getOneManyCollection().add(hpc);
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("1.2");
+            hpc.setRef(pc1);
+            pc1.getOneManyCollection().add(hpc);
+        }
+        
+        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
+        pc2.setName("2");
+        if ((empty & 2) == 0) {
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("2.1");
+            hpc.setRef(pc2);
+            pc2.getOneManyCollection().add(hpc);
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("2.2");
+            hpc.setRef(pc2);
+            pc2.getOneManyCollection().add(hpc);
+        }
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    public void testManyManyCollectionById() {
+        Object oid = insertManyManyCollection();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "manyManyCollection");
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getManyManyCollection().size());
+        pm.close();
+    }
+    
+    public void testManyManyCollectionByQuery() {
+        insertManyManyCollection();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "manyManyCollection");
+        fetch.setFetchBatchSize(-1);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        
+        assertEquals(2, results.size());
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getManyManyCollection().size());
+        pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("2", pc.getName());
+        assertEquals(2, pc.getManyManyCollection().size());
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertManyManyCollection() {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        EagerOuterJoinPC2 hpc = new EagerOuterJoinPC2();
+        hpc.setName("1.1");
+        pc1.getManyManyCollection().add(hpc);
+        hpc = new EagerOuterJoinPC2();
+        hpc.setName("1.2");
+        pc1.getManyManyCollection().add(hpc);
+        
+        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
+        pc2.setName("2");
+        hpc = new EagerOuterJoinPC2();
+        hpc.setName("2.1");
+        pc2.getManyManyCollection().add(hpc);
+        hpc = new EagerOuterJoinPC2();
+        hpc.setName("2.2");
+        pc2.getManyManyCollection().add(hpc);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);;
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    public void testManyManyListById() {
+        manyManyListByIdTest(false);
+    }
+    
+    public void testEmptyManyManyListById() {
+        manyManyListByIdTest(true);
+    }
+    
+    private void manyManyListByIdTest(boolean empty) {
+        Object oid = insertManyManyList((empty) ? 1 : 0);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
+        assertEquals("1", pc.getName());
+        if (empty)
+            assertEquals(0, pc.getManyManyList().size());
+        else {
+            assertEquals(2, pc.getManyManyList().size());
+            EagerOuterJoinPC2 hpc = (EagerOuterJoinPC2)
+            pc.getManyManyList().get(0);
+            assertEquals("1.1", hpc.getName());
+            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+            assertEquals("1.2", hpc.getName());
+        }
+        pm.close();
+    }
+    
+    public void testManyManyListByQuery() {
+        manyManyListByQueryTest(0);
+    }
+    
+    public void testEmptyManyManyListByQuery1() {
+        manyManyListByQueryTest(1);
+    }
+    
+    public void testEmptyManyManyListByQuery2() {
+        manyManyListByQueryTest(2);
+    }
+    
+    public void testEmptyManyManyListByQuery3() {
+        manyManyListByQueryTest(3);
+    }
+    
+    private void manyManyListByQueryTest(int empty) {
+        insertManyManyList(empty);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
+        fetch.setFetchBatchSize(-1);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        
+        assertEquals(2, results.size());
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("1", pc.getName());
+        EagerOuterJoinPC2 hpc;
+        if ((empty & 1) > 0)
+            assertEquals(0, pc.getManyManyList().size());
+        else {
+            assertEquals(2, pc.getManyManyList().size());
+            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(0);
+            assertEquals("1.1", hpc.getName());
+            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+            assertEquals("1.2", hpc.getName());
+        }
+        
+        pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("2", pc.getName());
+        if ((empty & 2) > 0)
+            assertEquals(0, pc.getManyManyList().size());
+        else {
+            assertEquals(2, pc.getManyManyList().size());
+            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(0);
+            assertEquals("2.1", hpc.getName());
+            hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+            assertEquals("2.2", hpc.getName());
+        }
+        
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertManyManyList(int empty) {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        EagerOuterJoinPC2 hpc;
+        if ((empty & 1) == 0) {
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("1.1");
+            pc1.getManyManyList().add(hpc);
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("1.2");
+            pc1.getManyManyList().add(hpc);
+        }
+        
+        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
+        pc2.setName("2");
+        if ((empty & 2) == 0) {
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("2.1");
+            pc2.getManyManyList().add(hpc);
+            hpc = new EagerOuterJoinPC2();
+            hpc.setName("2.2");
+            pc2.getManyManyList().add(hpc);
+        }
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);;
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    public void testTwoCollectionsInFetchGroupsById() {
+        Object oid = insertTwoCollections();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
+        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) pm.getObjectId(oid);
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getStringCollection().size());
+        assertTrue(pc.getStringCollection().contains("1.1"));
+        assertTrue(pc.getStringCollection().contains("1.2"));
+        assertEquals(2, pc.getManyManyList().size());
+        EagerOuterJoinPC2 hpc = (EagerOuterJoinPC2)
+        pc.getManyManyList().get(0);
+        assertEquals("1.1", hpc.getName());
+        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+        assertEquals("1.2", hpc.getName());
+        pm.close();
+    }
+    
+    public void testTwoCollectionsInFetchGroupsByQuery() {
+        insertTwoCollections();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
+        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
+        fetch.setFetchBatchSize(-1);
+        
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        
+        assertEquals(2, results.size());
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getStringCollection().size());
+        assertTrue(pc.getStringCollection().contains("1.1"));
+        assertTrue(pc.getStringCollection().contains("1.2"));
+        assertEquals(2, pc.getManyManyList().size());
+        EagerOuterJoinPC2 hpc = (EagerOuterJoinPC2)
+        pc.getManyManyList().get(0);
+        assertEquals("1.1", hpc.getName());
+        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+        assertEquals("1.2", hpc.getName());
+        
+        pc = (EagerOuterJoinPC) itr.next();
+        assertEquals("2", pc.getName());
+        assertEquals(2, pc.getStringCollection().size());
+        assertTrue(pc.getStringCollection().contains("2.1"));
+        assertTrue(pc.getStringCollection().contains("2.2"));
+        assertEquals(2, pc.getManyManyList().size());
+        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(0);
+        assertEquals("2.1", hpc.getName());
+        hpc = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+        assertEquals("2.2", hpc.getName());
+        
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertTwoCollections() {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        pc1.getStringCollection().add("1.1");
+        pc1.getStringCollection().add("1.2");
+        EagerOuterJoinPC2 hpc = new EagerOuterJoinPC2();
+        hpc.setName("1.1");
+        pc1.getManyManyList().add(hpc);
+        hpc = new EagerOuterJoinPC2();
+        hpc.setName("1.2");
+        pc1.getManyManyList().add(hpc);
+        
+        EagerOuterJoinPC pc2 = new EagerOuterJoinPC();
+        pc2.setName("2");
+        pc2.getStringCollection().add("2.1");
+        pc2.getStringCollection().add("2.2");
+        hpc = new EagerOuterJoinPC2();
+        hpc.setName("2.1");
+        pc2.getManyManyList().add(hpc);
+        hpc = new EagerOuterJoinPC2();
+        hpc.setName("2.2");
+        pc2.getManyManyList().add(hpc);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(pc1);
+        pm.persist(pc2);
+        endTx(pm);;
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    public void testQueryRandomAccess() {
+        insertManyStringList();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringList");
+        fetch.setFetchBatchSize(3);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        List results = (List) q.getResultList();
+        assertEquals(10, results.size());
+        
+        for (int i = 5; i < results.size(); i++) {
+            EagerOuterJoinPC pc = (EagerOuterJoinPC) results.get(i);
+            assertEquals(String.valueOf(i), pc.getName());
+            assertEquals(2, pc.getStringList().size());
+            assertEquals(i + ".1", pc.getStringList().get(0));
+            assertEquals(i + ".2", pc.getStringList().get(1));
+        }
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testQueryRange() {
+        insertManyStringList();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "stringList");
+        fetch.setFetchBatchSize(3);
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        //q.setRange(5, 20);
+        
+        List results = (List) q.getResultList();
+        assertEquals(5, results.size());
+        
+        for (int i = 0; i < results.size(); i++) {
+            EagerOuterJoinPC pc = (EagerOuterJoinPC) results.get(i);
+            assertEquals(String.valueOf(i + 5), pc.getName());
+            assertEquals(2, pc.getStringList().size());
+            assertEquals((i + 5) + ".1", pc.getStringList().get(0));
+            assertEquals((i + 5) + ".2", pc.getStringList().get(1));
+        }
+        q.closeAll();
+        pm.close();
+    }
+    
+    private void insertManyStringList() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        for (int i = 0; i < 10; i++) {
+            EagerOuterJoinPC pc = new EagerOuterJoinPC();
+            pc.setName(String.valueOf(i));
+            pc.getStringList().add(i + ".1");
+            pc.getStringList().add(i + ".2");
+            pm.persist(pc);
+        }
+        endTx(pm);;
+        pm.close();
+    }
+    
+    public void testEagerToOneThenEagerToMany() {
+        insertEagers();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC2.class, "ref");
+        fetch.addField(EagerOuterJoinPC.class, "stringCollection");
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC2.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        assertEquals(new ArrayList(results).toString(), 2, results.size());
+        
+        Iterator itr = results.iterator();
+        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2) itr.next();
+        assertEquals("r1", ref.getName());
+        EagerOuterJoinPC pc = ref.getRef();
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getStringCollection().size());
+        assertTrue(pc.getStringCollection().contains("1.1"));
+        assertTrue(pc.getStringCollection().contains("1.2"));
+        
+        ref = (EagerOuterJoinPC2) itr.next();
+        assertEquals("r2", ref.getName());
+        assertTrue(pc == ref.getRef());
+        
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    public void testEagerToManyThenEagerToOne() {
+        insertEagers();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
+        fetch.addField(EagerOuterJoinPC2.class, "helper");
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        assertEquals(1, results.size());
+        
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) results.iterator().next();
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getManyManyList().size());
+        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2)
+        pc.getManyManyList().get(0);
+        assertEquals("r1", ref.getName());
+        assertEquals("h1", ref.getHelper().getStringField());
+        ref = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+        assertEquals("r2", ref.getName());
+        assertEquals("h2", ref.getHelper().getStringField());
+        
+        pm.close();
+    }
+    
+    public void testEagerToManyThenEagerToMany() {
+        insertEagers();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "manyManyList");
+        fetch.addField(EagerOuterJoinPC2.class, "stringCollection");
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        assertEquals(1, results.size());
+        
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) results.iterator().next();
+        assertEquals("1", pc.getName());
+        assertEquals(2, pc.getManyManyList().size());
+        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2)
+        pc.getManyManyList().get(0);
+        assertEquals("r1", ref.getName());
+        assertEquals(2, ref.getStringCollection().size());
+        assertTrue(ref.getStringCollection().contains("r1.1"));
+        assertTrue(ref.getStringCollection().contains("r1.2"));
+        
+        ref = (EagerOuterJoinPC2) pc.getManyManyList().get(1);
+        assertEquals("r2", ref.getName());
+        assertEquals(2, ref.getStringCollection().size());
+        assertTrue(ref.getStringCollection().contains("r2.1"));
+        assertTrue(ref.getStringCollection().contains("r2.2"));
+        
+        pm.close();
+    }
+    
+    public void testEagerToOneAndToManyThenEagerToOne() {
+        Object oid = insertEagers();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        fetch.addField(EagerOuterJoinPC.class, "oneManyCollection");
+        fetch.addField(EagerOuterJoinPC.class, "helper");
+        fetch.addField(EagerOuterJoinPC2.class, "helper");
+        OpenJPAQuery q = pm.createNativeQuery("",EagerOuterJoinPC.class);
+        //FIXME jthomas
+        //q.setOrdering("name ascending");
+        Collection results = (Collection) q.getResultList();
+        assertEquals(1, results.size());
+        
+        EagerOuterJoinPC pc = (EagerOuterJoinPC) results.iterator().next();
+        assertEquals("1", pc.getName());
+        assertEquals("h3", pc.getHelper().getStringField());
+        assertEquals(2, pc.getOneManyCollection().size());
+        Iterator itr = pc.getOneManyCollection().iterator();
+        EagerOuterJoinPC2 ref = (EagerOuterJoinPC2) itr.next();
+        if ("r1".equals(ref.getName())) {
+            assertEquals("h1", ref.getHelper().getStringField());
+            ref = (EagerOuterJoinPC2) itr.next();
+            assertEquals("r2", ref.getName());
+            assertEquals("h2", ref.getHelper().getStringField());
+        } else {
+            assertEquals("r2", ref.getName());
+            assertEquals("h2", ref.getHelper().getStringField());
+            ref = (EagerOuterJoinPC2) itr.next();
+            assertEquals("r1", ref.getName());
+            assertEquals("h1", ref.getHelper().getStringField());
+        }
+        assertTrue(!itr.hasNext());
+        pm.close();
+    }
+    
+    private Object insertEagers() {
+        EagerOuterJoinPC pc1 = new EagerOuterJoinPC();
+        pc1.setName("1");
+        pc1.getStringCollection().add("1.1");
+        pc1.getStringCollection().add("1.2");
+        
+        EagerOuterJoinPC2 ref1 = new EagerOuterJoinPC2();
+        ref1.setName("r1");
+        ref1.getStringCollection().add("r1.1");
+        ref1.getStringCollection().add("r1.2");
+        
+        EagerOuterJoinPC2 ref2 = new EagerOuterJoinPC2();
+        ref2.setName("r2");
+        ref2.getStringCollection().add("r2.1");
+        ref2.getStringCollection().add("r2.2");
+        
+        HelperPC hpc1 = new HelperPC();
+        hpc1.setStringField("h1");
+        
+        HelperPC hpc2 = new HelperPC();
+        hpc2.setStringField("h2");
+        
+        HelperPC hpc3 = new HelperPC();
+        hpc3.setStringField("h3");
+        
+        pc1.getManyManyList().add(ref1);
+        pc1.getOneManyCollection().add(ref1);
+        ref1.setRef(pc1);
+        pc1.getManyManyList().add(ref2);
+        pc1.getOneManyCollection().add(ref2);
+        ref2.setRef(pc1);
+        
+        ref1.setHelper(hpc1);
+        ref2.setHelper(hpc2);
+        pc1.setHelper(hpc3);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(pc1);
+        endTx(pm);;
+        Object oid = pm.getObjectId(pc1);
+        pm.close();
+        return oid;
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIntermediate.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIntermediate.java
index 9e0b908..7cbc469 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIntermediate.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIntermediate.java
@@ -1,132 +1,132 @@
-/*
- * TestIntermediate.java
- *
- * Created on October 3, 2006, 12:01 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestIntermediate extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-    
-    private Object _pc;
-    private Object _rel;
-    
-    public TestIntermediate(String test) {
-        super(test);
-    }
-    
-    /** Creates a new instance of TestIntermediate */
-    public TestIntermediate() {
-    }
-    
-    public void setUp() {
-        RuntimeTest1 pc = new RuntimeTest1("pc", 1);
-        RuntimeTest1 rel = new RuntimeTest1("rel", 2);
-        pc.setSelfOneOne(rel);
-        
-        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-        Broker broker = JPAFacadeHelper.toBroker(em);
-        broker.begin();
-        broker.persist(pc, null);
-        broker.commit();
-        _pc = broker.getObjectId(pc);
-        _rel = broker.getObjectId(rel);
-        broker.close();
-        em.close();
-    }
-    
-    public void testOneOneSetsIntermediate() {
-        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
-        Broker broker = JPAFacadeHelper.toBroker(em);
-        try {
-            oneOneIntermediateTest(broker);
-        } finally {
-            broker.close();
-            em.close();
-        }
-    }
-    
-    public void testDataCacheOneOneSetsIntermediate() {
-        BrokerFactory factory = getBrokerFactory(new String[]{
-            "openjpa.DataCache", "true",
-            "openjpa.RemoteCommitProvider", "sjvm",
-        });
-        
-        // get obj into cache
-        Broker broker = factory.newBroker();
-        try {
-            broker.find(_pc, true, null);
-        } finally {
-            broker.close();
-        }
-        
-        // test from cache
-        broker = factory.newBroker();
-        try {
-            oneOneIntermediateTest(broker);
-        } finally {
-            broker.close();
-            try {
-                factory.close();
-            } catch (Exception e) {
-            }
-        }
-    }
-    
-    /**
-     * Helper method to see that the one to one uses an intermediate values.
-     */
-    private void oneOneIntermediateTest(Broker broker) {
-        RuntimeTest1 pc = (RuntimeTest1) broker.find(_pc, true, null);
-        OpenJPAStateManager sm = broker.getStateManager(pc);
-        assertNotNull(sm);
-        FieldMetaData fmd = sm.getMetaData().getField("selfOneOne");
-        assertNotNull(fmd);
-        assertEquals(_rel, sm.getIntermediate(fmd.getIndex()));
-        assertEquals(_rel, broker.getObjectId(pc.getSelfOneOne()));
-        assertNull(sm.getIntermediate(fmd.getIndex()));
-    }
-    
-    
-}
+/*
+ * TestIntermediate.java
+ *
+ * Created on October 3, 2006, 12:01 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestIntermediate extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+    
+    private Object _pc;
+    private Object _rel;
+    
+    public TestIntermediate(String test) {
+        super(test);
+    }
+    
+    /** Creates a new instance of TestIntermediate */
+    public TestIntermediate() {
+    }
+    
+    public void setUp() {
+        RuntimeTest1 pc = new RuntimeTest1("pc", 1);
+        RuntimeTest1 rel = new RuntimeTest1("rel", 2);
+        pc.setSelfOneOne(rel);
+        
+        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+        Broker broker = JPAFacadeHelper.toBroker(em);
+        broker.begin();
+        broker.persist(pc, null);
+        broker.commit();
+        _pc = broker.getObjectId(pc);
+        _rel = broker.getObjectId(rel);
+        broker.close();
+        em.close();
+    }
+    
+    public void testOneOneSetsIntermediate() {
+        OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
+        Broker broker = JPAFacadeHelper.toBroker(em);
+        try {
+            oneOneIntermediateTest(broker);
+        } finally {
+            broker.close();
+            em.close();
+        }
+    }
+    
+    public void testDataCacheOneOneSetsIntermediate() {
+        BrokerFactory factory = getBrokerFactory(new String[]{
+            "openjpa.DataCache", "true",
+            "openjpa.RemoteCommitProvider", "sjvm",
+        });
+        
+        // get obj into cache
+        Broker broker = factory.newBroker();
+        try {
+            broker.find(_pc, true, null);
+        } finally {
+            broker.close();
+        }
+        
+        // test from cache
+        broker = factory.newBroker();
+        try {
+            oneOneIntermediateTest(broker);
+        } finally {
+            broker.close();
+            try {
+                factory.close();
+            } catch (Exception e) {
+            }
+        }
+    }
+    
+    /**
+     * Helper method to see that the one to one uses an intermediate values.
+     */
+    private void oneOneIntermediateTest(Broker broker) {
+        RuntimeTest1 pc = (RuntimeTest1) broker.find(_pc, true, null);
+        OpenJPAStateManager sm = broker.getStateManager(pc);
+        assertNotNull(sm);
+        FieldMetaData fmd = sm.getMetaData().getField("selfOneOne");
+        assertNotNull(fmd);
+        assertEquals(_rel, sm.getIntermediate(fmd.getIndex()));
+        assertEquals(_rel, broker.getObjectId(pc.getSelfOneOne()));
+        assertNull(sm.getIntermediate(fmd.getIndex()));
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIrregularJoins.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIrregularJoins.java
index 36c8404..5c1a436 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIrregularJoins.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestIrregularJoins.java
@@ -1,363 +1,363 @@
-/*
- * TestIrregularJoins.java
- *
- * Created on October 3, 2006, 12:47 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.jdbc.common.apps.NonPKJoinPC2;
-
-
-
-public class TestIrregularJoins extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-
-    private Object _nonpk = null;
-    private Object _nonpk3 = null;
-    private Object _partial = null;
-    private Object _partial3 = null;
-    private Object _constant2 = null;
-    private Object _constant3 = null;
-
-    public TestIrregularJoins(String test) {
-        super(test);
-    }
-    
-    /** Creates a new instance of TestIrregularJoins */
-    public TestIrregularJoins() {
-    }
-
-    public void setUp()
-        throws Exception {
-        // make sure these classes are registered since we're using metadata
-        // values for the class indicator
-        new ConstantJoinPC();
-        new ConstantJoinPC2();
-        new ConstantJoinPC3();
-
-       deleteAll(PartialJoinPC.class);
-       deleteAll(NonPKJoinPC.class);
-       deleteAll(ConstantJoinPC.class);
-
-        PartialJoinPC partial = new PartialJoinPC();
-        partial.setPk1(1);
-        partial.setPk2(2);
-        PartialJoinPC2 partial2 = new PartialJoinPC2();
-        partial2.setPk1(2);
-        partial2.setPk2(3);
-        PartialJoinPC3 partial3 = new PartialJoinPC3();
-        partial3.setPk1(3);
-        partial3.setPk2(4);
-
-        NonPKJoinPC nonpk = new NonPKJoinPC();
-        nonpk.setId1(1);
-        nonpk.setId2(2);
-        NonPKJoinPC2 nonpk2 = new NonPKJoinPC2();
-        nonpk2.setId1(2);
-        nonpk2.setId2(3);
-        NonPKJoinPC3 nonpk3 = new NonPKJoinPC3();
-        nonpk3.setId1(3);
-        nonpk3.setId2(4);
-
-        partial.setNonPK(nonpk);
-        partial.getNonPKs().add(nonpk);
-        nonpk.setPartial(partial);
-        nonpk.getPartials().add(partial);
-
-        partial3.setNonPK(nonpk);
-        partial3.setNonPK3(nonpk3);
-        partial3.getNonPKs().add(nonpk);
-        partial3.getNonPK2s().add(nonpk2);
-        nonpk3.setPartial(partial);
-        nonpk3.setPartial3(partial3);
-        nonpk3.getPartials().add(partial);
-        nonpk3.getPartial2s().add(partial2);
-
-        ConstantJoinPC2 constant2 = new ConstantJoinPC2();
-        constant2.setPk1(1);
-        constant2.setPk2(2);
-        constant2.setNonPK(nonpk3);
-        constant2.setNonPK2(nonpk3);
-
-        // set the object's inverse on diff objects so we can be sure
-        // that its 1-many includes only the object with the right constant
-        nonpk.setConstant(constant2);
-        nonpk2.setConstant(constant2);
-        nonpk3.setConstant(constant2);
-
-        ConstantJoinPC3 constant3 = new ConstantJoinPC3();
-        constant3.setPk1(1);
-        constant3.setPk2(3);
-
-        OpenJPAEntityManager pm =(OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        
-        pm.persist(partial);
-        pm.persist(partial3);
-        pm.persist(constant2);
-        pm.persist(constant3);
-        endTx(pm);
-        _partial = pm.getObjectId(partial);
-        _partial3 = pm.getObjectId(partial3);
-        _nonpk = pm.getObjectId(nonpk);
-        _nonpk3 = pm.getObjectId(nonpk3);
-        _constant2 = pm.getObjectId(constant2);
-        _constant3 = pm.getObjectId(constant3);
-        pm.close();
-    }
-
-    public void testNonPKOneOne() {
-        
-        nonPKOneOne((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerNonPKOneOne() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nonPK");
-        nonPKOneOne(pm);
-    }
-
-    private void nonPKOneOne(OpenJPAEntityManager pm) {
-        PartialJoinPC partial = (PartialJoinPC) pm.getObjectId(_partial);
-        NonPKJoinPC nonpk = partial.getNonPK();
-        assertEquals(1, nonpk.getId1());
-        assertEquals(2, nonpk.getId2());
-        pm.close();
-    }
-
-    public void testPartialOneOne() {
-        partialOneOne((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerPartialOneOne() {
-        
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("partial");
-        partialOneOne(pm);
-    }
-
-    private void partialOneOne(OpenJPAEntityManager pm) {
-        NonPKJoinPC nonpk = (NonPKJoinPC) pm.getObjectId(_nonpk);
-        PartialJoinPC partial = nonpk.getPartial();
-        assertEquals(1, partial.getPk1());
-        assertEquals(2, partial.getPk2());
-        pm.close();
-    }
-
-    public void testVerticalNonPKOneOne() {
-        verticalNonPKOneOne((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerVerticalNonPKOneOne() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nonPK3");
-        verticalNonPKOneOne(pm);
-    }
-
-    private void verticalNonPKOneOne(OpenJPAEntityManager pm) {
-        PartialJoinPC3 partial3 = (PartialJoinPC3) pm.getObjectId(_partial3);
-        NonPKJoinPC nonpk = partial3.getNonPK();
-        assertEquals(1, nonpk.getId1());
-        assertEquals(2, nonpk.getId2());
-        NonPKJoinPC3 nonpk3 = partial3.getNonPK3();
-        assertEquals(3, nonpk3.getId1());
-        assertEquals(4, nonpk3.getId2());
-        pm.close();
-    }
-
-    public void testVerticalPartialOneOne() {
-        verticalPartialOneOne((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerVerticalPartialOneOne() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("partial3");
-        verticalPartialOneOne(pm);
-    }
-
-    private void verticalPartialOneOne(OpenJPAEntityManager pm) {
-        NonPKJoinPC3 nonpk3 = (NonPKJoinPC3) pm.getObjectId(_nonpk3);
-        PartialJoinPC partial = nonpk3.getPartial();
-        assertEquals(1, partial.getPk1());
-        assertEquals(2, partial.getPk2());
-        PartialJoinPC3 partial3 = nonpk3.getPartial3();
-        assertEquals(3, partial3.getPk1());
-        assertEquals(4, partial3.getPk2());
-        pm.close();
-    }
-
-    public void testNonPKManyMany() {
-        nonPKManyMany((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerNonPKManyMany() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nonPKs");
-        nonPKManyMany(pm);
-    }
-
-    private void nonPKManyMany(OpenJPAEntityManager pm) {
-        PartialJoinPC partial = (PartialJoinPC) pm.getObjectId(_partial);
-        Collection nonpks = partial.getNonPKs();
-        assertEquals(1, nonpks.size());
-        NonPKJoinPC nonpk = (NonPKJoinPC) nonpks.iterator().next();
-        assertEquals(1, nonpk.getId1());
-        assertEquals(2, nonpk.getId2());
-        pm.close();
-    }
-
-    public void testPartialManyMany() {
-        partialManyMany((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerPartialManyMany() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("partials");
-        partialManyMany(pm);
-    }
-
-    private void partialManyMany(OpenJPAEntityManager pm) {
-        NonPKJoinPC nonpk = (NonPKJoinPC) pm.getObjectId(_nonpk);
-        Collection partials = nonpk.getPartials();
-        assertEquals(1, partials.size());
-        PartialJoinPC partial = (PartialJoinPC) partials.iterator().next();
-        assertEquals(1, partial.getPk1());
-        assertEquals(2, partial.getPk2());
-        pm.close();
-    }
-
-    public void testVerticalNonPKManyMany() {
-        verticalNonPKManyMany((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerVerticalNonPKManyMany() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nonPK2s");
-        verticalNonPKManyMany(pm);
-    }
-
-    private void verticalNonPKManyMany(OpenJPAEntityManager pm) {
-        PartialJoinPC3 partial3 = (PartialJoinPC3) pm.getObjectId(_partial3);
-        Collection nonpks = partial3.getNonPKs();
-        assertEquals(1, nonpks.size());
-        NonPKJoinPC nonpk = (NonPKJoinPC) nonpks.iterator().next();
-        assertEquals(1, nonpk.getId1());
-        assertEquals(2, nonpk.getId2());
-        Collection nonpk2s = partial3.getNonPK2s();
-        assertEquals(1, nonpk2s.size());
-        NonPKJoinPC2 nonpk2 = (NonPKJoinPC2) nonpk2s.iterator().next();
-        assertEquals(2, nonpk2.getId1());
-        assertEquals(3, nonpk2.getId2());
-        pm.close();
-    }
-
-    public void testVerticalPartialManyMany() {
-        verticalPartialManyMany((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerVerticalPartialManyMany() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("partial2s");
-        verticalPartialManyMany(pm);
-    }
-
-    private void verticalPartialManyMany(OpenJPAEntityManager pm) {
-        NonPKJoinPC3 nonpk3 = (NonPKJoinPC3) pm.getObjectId(_nonpk3);
-        Collection partials = nonpk3.getPartials();
-        assertEquals(1, partials.size());
-        PartialJoinPC partial = (PartialJoinPC) partials.iterator().next();
-        assertEquals(1, partial.getPk1());
-        assertEquals(2, partial.getPk2());
-        Collection partial2s = nonpk3.getPartial2s();
-        assertEquals(1, partial2s.size());
-        PartialJoinPC2 partial2 = (PartialJoinPC2) partial2s.iterator().next();
-        assertEquals(2, partial2.getPk1());
-        assertEquals(3, partial2.getPk2());
-        pm.close();
-    }
-
-    public void testVerticalConstant() {
-        
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        ConstantJoinPC2 constant2 = (ConstantJoinPC2) pm.getObjectId(_constant2);
-        assertEquals(1, constant2.getPk1());
-        assertEquals(2, constant2.getPk2());
-        ConstantJoinPC3 constant3 = (ConstantJoinPC3) pm.getObjectId(_constant3);
-        assertEquals(1, constant3.getPk1());
-        assertEquals(3, constant3.getPk2());
-    }
-
-    public void testConstantOneOne() {
-        constantOneOne((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerConstantOneOne() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nonPK");
-        constantOneOne(pm);
-    }
-
-    private void constantOneOne(OpenJPAEntityManager pm) {
-        ConstantJoinPC2 constant2 = (ConstantJoinPC2) pm.getObjectId(_constant2);
-
-        assertEquals(_nonpk3, pm.getObjectId(constant2.getNonPK()));
-        assertEquals(_nonpk3, pm.getObjectId(constant2.getNonPK2()));
-        pm.close();
-    }
-
-    public void testConstantOneMany() {
-        constantOneMany((OpenJPAEntityManager)currentEntityManager());
-    }
-
-    public void testEagerConstantOneMany() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nonPKs");
-        constantOneMany(pm);
-    }
-
-    private void constantOneMany(OpenJPAEntityManager pm) {
-        ConstantJoinPC2 constant2 = (ConstantJoinPC2) pm.getObjectId(_constant2);
-
-        Collection nonpks = constant2.getNonPKs();
-        assertEquals(1, nonpks.size());
-        assertEquals(_nonpk, pm.getObjectId
-            (nonpks.iterator().next()));
-        pm.close();
-    }
-    
-    
-    
-}
+/*
+ * TestIrregularJoins.java
+ *
+ * Created on October 3, 2006, 12:47 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.jdbc.common.apps.NonPKJoinPC2;
+
+
+
+public class TestIrregularJoins extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+
+    private Object _nonpk = null;
+    private Object _nonpk3 = null;
+    private Object _partial = null;
+    private Object _partial3 = null;
+    private Object _constant2 = null;
+    private Object _constant3 = null;
+
+    public TestIrregularJoins(String test) {
+        super(test);
+    }
+    
+    /** Creates a new instance of TestIrregularJoins */
+    public TestIrregularJoins() {
+    }
+
+    public void setUp()
+        throws Exception {
+        // make sure these classes are registered since we're using metadata
+        // values for the class indicator
+        new ConstantJoinPC();
+        new ConstantJoinPC2();
+        new ConstantJoinPC3();
+
+       deleteAll(PartialJoinPC.class);
+       deleteAll(NonPKJoinPC.class);
+       deleteAll(ConstantJoinPC.class);
+
+        PartialJoinPC partial = new PartialJoinPC();
+        partial.setPk1(1);
+        partial.setPk2(2);
+        PartialJoinPC2 partial2 = new PartialJoinPC2();
+        partial2.setPk1(2);
+        partial2.setPk2(3);
+        PartialJoinPC3 partial3 = new PartialJoinPC3();
+        partial3.setPk1(3);
+        partial3.setPk2(4);
+
+        NonPKJoinPC nonpk = new NonPKJoinPC();
+        nonpk.setId1(1);
+        nonpk.setId2(2);
+        NonPKJoinPC2 nonpk2 = new NonPKJoinPC2();
+        nonpk2.setId1(2);
+        nonpk2.setId2(3);
+        NonPKJoinPC3 nonpk3 = new NonPKJoinPC3();
+        nonpk3.setId1(3);
+        nonpk3.setId2(4);
+
+        partial.setNonPK(nonpk);
+        partial.getNonPKs().add(nonpk);
+        nonpk.setPartial(partial);
+        nonpk.getPartials().add(partial);
+
+        partial3.setNonPK(nonpk);
+        partial3.setNonPK3(nonpk3);
+        partial3.getNonPKs().add(nonpk);
+        partial3.getNonPK2s().add(nonpk2);
+        nonpk3.setPartial(partial);
+        nonpk3.setPartial3(partial3);
+        nonpk3.getPartials().add(partial);
+        nonpk3.getPartial2s().add(partial2);
+
+        ConstantJoinPC2 constant2 = new ConstantJoinPC2();
+        constant2.setPk1(1);
+        constant2.setPk2(2);
+        constant2.setNonPK(nonpk3);
+        constant2.setNonPK2(nonpk3);
+
+        // set the object's inverse on diff objects so we can be sure
+        // that its 1-many includes only the object with the right constant
+        nonpk.setConstant(constant2);
+        nonpk2.setConstant(constant2);
+        nonpk3.setConstant(constant2);
+
+        ConstantJoinPC3 constant3 = new ConstantJoinPC3();
+        constant3.setPk1(1);
+        constant3.setPk2(3);
+
+        OpenJPAEntityManager pm =(OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        
+        pm.persist(partial);
+        pm.persist(partial3);
+        pm.persist(constant2);
+        pm.persist(constant3);
+        endTx(pm);
+        _partial = pm.getObjectId(partial);
+        _partial3 = pm.getObjectId(partial3);
+        _nonpk = pm.getObjectId(nonpk);
+        _nonpk3 = pm.getObjectId(nonpk3);
+        _constant2 = pm.getObjectId(constant2);
+        _constant3 = pm.getObjectId(constant3);
+        pm.close();
+    }
+
+    public void testNonPKOneOne() {
+        
+        nonPKOneOne((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerNonPKOneOne() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nonPK");
+        nonPKOneOne(pm);
+    }
+
+    private void nonPKOneOne(OpenJPAEntityManager pm) {
+        PartialJoinPC partial = (PartialJoinPC) pm.getObjectId(_partial);
+        NonPKJoinPC nonpk = partial.getNonPK();
+        assertEquals(1, nonpk.getId1());
+        assertEquals(2, nonpk.getId2());
+        pm.close();
+    }
+
+    public void testPartialOneOne() {
+        partialOneOne((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerPartialOneOne() {
+        
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("partial");
+        partialOneOne(pm);
+    }
+
+    private void partialOneOne(OpenJPAEntityManager pm) {
+        NonPKJoinPC nonpk = (NonPKJoinPC) pm.getObjectId(_nonpk);
+        PartialJoinPC partial = nonpk.getPartial();
+        assertEquals(1, partial.getPk1());
+        assertEquals(2, partial.getPk2());
+        pm.close();
+    }
+
+    public void testVerticalNonPKOneOne() {
+        verticalNonPKOneOne((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerVerticalNonPKOneOne() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nonPK3");
+        verticalNonPKOneOne(pm);
+    }
+
+    private void verticalNonPKOneOne(OpenJPAEntityManager pm) {
+        PartialJoinPC3 partial3 = (PartialJoinPC3) pm.getObjectId(_partial3);
+        NonPKJoinPC nonpk = partial3.getNonPK();
+        assertEquals(1, nonpk.getId1());
+        assertEquals(2, nonpk.getId2());
+        NonPKJoinPC3 nonpk3 = partial3.getNonPK3();
+        assertEquals(3, nonpk3.getId1());
+        assertEquals(4, nonpk3.getId2());
+        pm.close();
+    }
+
+    public void testVerticalPartialOneOne() {
+        verticalPartialOneOne((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerVerticalPartialOneOne() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("partial3");
+        verticalPartialOneOne(pm);
+    }
+
+    private void verticalPartialOneOne(OpenJPAEntityManager pm) {
+        NonPKJoinPC3 nonpk3 = (NonPKJoinPC3) pm.getObjectId(_nonpk3);
+        PartialJoinPC partial = nonpk3.getPartial();
+        assertEquals(1, partial.getPk1());
+        assertEquals(2, partial.getPk2());
+        PartialJoinPC3 partial3 = nonpk3.getPartial3();
+        assertEquals(3, partial3.getPk1());
+        assertEquals(4, partial3.getPk2());
+        pm.close();
+    }
+
+    public void testNonPKManyMany() {
+        nonPKManyMany((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerNonPKManyMany() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nonPKs");
+        nonPKManyMany(pm);
+    }
+
+    private void nonPKManyMany(OpenJPAEntityManager pm) {
+        PartialJoinPC partial = (PartialJoinPC) pm.getObjectId(_partial);
+        Collection nonpks = partial.getNonPKs();
+        assertEquals(1, nonpks.size());
+        NonPKJoinPC nonpk = (NonPKJoinPC) nonpks.iterator().next();
+        assertEquals(1, nonpk.getId1());
+        assertEquals(2, nonpk.getId2());
+        pm.close();
+    }
+
+    public void testPartialManyMany() {
+        partialManyMany((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerPartialManyMany() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("partials");
+        partialManyMany(pm);
+    }
+
+    private void partialManyMany(OpenJPAEntityManager pm) {
+        NonPKJoinPC nonpk = (NonPKJoinPC) pm.getObjectId(_nonpk);
+        Collection partials = nonpk.getPartials();
+        assertEquals(1, partials.size());
+        PartialJoinPC partial = (PartialJoinPC) partials.iterator().next();
+        assertEquals(1, partial.getPk1());
+        assertEquals(2, partial.getPk2());
+        pm.close();
+    }
+
+    public void testVerticalNonPKManyMany() {
+        verticalNonPKManyMany((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerVerticalNonPKManyMany() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nonPK2s");
+        verticalNonPKManyMany(pm);
+    }
+
+    private void verticalNonPKManyMany(OpenJPAEntityManager pm) {
+        PartialJoinPC3 partial3 = (PartialJoinPC3) pm.getObjectId(_partial3);
+        Collection nonpks = partial3.getNonPKs();
+        assertEquals(1, nonpks.size());
+        NonPKJoinPC nonpk = (NonPKJoinPC) nonpks.iterator().next();
+        assertEquals(1, nonpk.getId1());
+        assertEquals(2, nonpk.getId2());
+        Collection nonpk2s = partial3.getNonPK2s();
+        assertEquals(1, nonpk2s.size());
+        NonPKJoinPC2 nonpk2 = (NonPKJoinPC2) nonpk2s.iterator().next();
+        assertEquals(2, nonpk2.getId1());
+        assertEquals(3, nonpk2.getId2());
+        pm.close();
+    }
+
+    public void testVerticalPartialManyMany() {
+        verticalPartialManyMany((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerVerticalPartialManyMany() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("partial2s");
+        verticalPartialManyMany(pm);
+    }
+
+    private void verticalPartialManyMany(OpenJPAEntityManager pm) {
+        NonPKJoinPC3 nonpk3 = (NonPKJoinPC3) pm.getObjectId(_nonpk3);
+        Collection partials = nonpk3.getPartials();
+        assertEquals(1, partials.size());
+        PartialJoinPC partial = (PartialJoinPC) partials.iterator().next();
+        assertEquals(1, partial.getPk1());
+        assertEquals(2, partial.getPk2());
+        Collection partial2s = nonpk3.getPartial2s();
+        assertEquals(1, partial2s.size());
+        PartialJoinPC2 partial2 = (PartialJoinPC2) partial2s.iterator().next();
+        assertEquals(2, partial2.getPk1());
+        assertEquals(3, partial2.getPk2());
+        pm.close();
+    }
+
+    public void testVerticalConstant() {
+        
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        ConstantJoinPC2 constant2 = (ConstantJoinPC2) pm.getObjectId(_constant2);
+        assertEquals(1, constant2.getPk1());
+        assertEquals(2, constant2.getPk2());
+        ConstantJoinPC3 constant3 = (ConstantJoinPC3) pm.getObjectId(_constant3);
+        assertEquals(1, constant3.getPk1());
+        assertEquals(3, constant3.getPk2());
+    }
+
+    public void testConstantOneOne() {
+        constantOneOne((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerConstantOneOne() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nonPK");
+        constantOneOne(pm);
+    }
+
+    private void constantOneOne(OpenJPAEntityManager pm) {
+        ConstantJoinPC2 constant2 = (ConstantJoinPC2) pm.getObjectId(_constant2);
+
+        assertEquals(_nonpk3, pm.getObjectId(constant2.getNonPK()));
+        assertEquals(_nonpk3, pm.getObjectId(constant2.getNonPK2()));
+        pm.close();
+    }
+
+    public void testConstantOneMany() {
+        constantOneMany((OpenJPAEntityManager)currentEntityManager());
+    }
+
+    public void testEagerConstantOneMany() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nonPKs");
+        constantOneMany(pm);
+    }
+
+    private void constantOneMany(OpenJPAEntityManager pm) {
+        ConstantJoinPC2 constant2 = (ConstantJoinPC2) pm.getObjectId(_constant2);
+
+        Collection nonpks = constant2.getNonPKs();
+        assertEquals(1, nonpks.size());
+        assertEquals(_nonpk, pm.getObjectId
+            (nonpks.iterator().next()));
+        pm.close();
+    }
+    
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJDBCType.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJDBCType.java
index 9830b7f..6cb687a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJDBCType.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJDBCType.java
@@ -1,119 +1,119 @@
-/*
- * TestJDBCType.java
- *
- * Created on October 3, 2006, 4:11 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.meta.RefreshStrategyInstaller;
-import org.apache.openjpa.jdbc.meta.strats.BlobValueHandler;
-import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
-import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
-import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.SchemaGroup;
-import org.apache.openjpa.jdbc.schema.Table;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
-import org.apache.openjpa.jdbc.schema.Column;
-
-public class TestJDBCType extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	
-    /** Creates a new instance of TestJDBCType */
-    public TestJDBCType(String name) 
-    {
-    	super(name);
-    }
-    /**
-     * Tests that application identity classes are returned correctly.
-     */
-    public void testSchemaGeneration() {
-        JDBCConfiguration conf = new JDBCConfigurationImpl();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        MappingRepository repos = conf.getMappingRepositoryInstance();
-        repos.setStrategyInstaller(new RefreshStrategyInstaller(repos));
-        ClassMapping mapping = repos.getMapping(Column.class, null, true);
-
-        Class cls;
-        if (dict.getPreferredType(JavaSQLTypes.CLOB) ==  JavaSQLTypes.CLOB) {
-            if (dict.maxEmbeddedClobSize > 0) {
-                cls = mapping.getFieldMapping("toClob").getStrategy().
-                    getClass();
-                assertTrue(cls.getName(),
-                    MaxEmbeddedClobFieldStrategy.class.isAssignableFrom(cls));
-            } else {
-                cls = mapping.getFieldMapping("toClob").getHandler().
-                    getClass();
-                assertTrue(cls.getName(),
-                    ClobValueHandler.class.isAssignableFrom(cls));
-            }
-        } else
-            assertTrue(mapping.getFieldMapping("toClob").getStrategy()
-                instanceof StringFieldStrategy);
-
-        cls = mapping.getFieldMapping("toBlob").getHandler().getClass();
-        assertTrue(cls.getName(),
-            BlobValueHandler.class.isAssignableFrom(cls));
-
-        SchemaGroup schema = repos.getSchemaGroup();
-        Table table = schema.getSchemas()[0].getTables()[0];
-        Column[] cols = table.getColumns();
-        for (int i = 0; i < cols.length; i++) {
-            if (cols[i].getName().equalsIgnoreCase("id")
-                || cols[i].getName().equalsIgnoreCase("versn")
-                || cols[i].getName().equalsIgnoreCase("typ"))
-                continue;
-            if ("longToInt".equalsIgnoreCase(cols[i].getName()))
-                assertEquals(dict.getPreferredType(JavaSQLTypes.INT),
-                    cols[i].getType());
-            else if ("longToSQL".equalsIgnoreCase(cols[i].getName()))
-                assertEquals("varchar", cols[i].getTypeName());
-            else if ("toClob".equalsIgnoreCase(cols[i].getName()))
-                assertEquals(dict.getPreferredType(JavaSQLTypes.CLOB),
-                    cols[i].getType());
-            else if ("toBlob".equalsIgnoreCase(cols[i].getName()))
-                assertEquals(dict.getPreferredType(JavaSQLTypes.BLOB),
-                    cols[i].getType());
-            else
-                fail("Unknown column:" + cols[i].getName());
-        }
-    }    
-}
+/*
+ * TestJDBCType.java
+ *
+ * Created on October 3, 2006, 4:11 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.MappingRepository;
+import org.apache.openjpa.jdbc.meta.RefreshStrategyInstaller;
+import org.apache.openjpa.jdbc.meta.strats.BlobValueHandler;
+import org.apache.openjpa.jdbc.meta.strats.ClobValueHandler;
+import org.apache.openjpa.jdbc.meta.strats.MaxEmbeddedClobFieldStrategy;
+import org.apache.openjpa.jdbc.meta.strats.StringFieldStrategy;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.schema.Column;
+
+public class TestJDBCType extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	
+    /** Creates a new instance of TestJDBCType */
+    public TestJDBCType(String name) 
+    {
+    	super(name);
+    }
+    /**
+     * Tests that application identity classes are returned correctly.
+     */
+    public void testSchemaGeneration() {
+        JDBCConfiguration conf = new JDBCConfigurationImpl();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        MappingRepository repos = conf.getMappingRepositoryInstance();
+        repos.setStrategyInstaller(new RefreshStrategyInstaller(repos));
+        ClassMapping mapping = repos.getMapping(Column.class, null, true);
+
+        Class cls;
+        if (dict.getPreferredType(JavaSQLTypes.CLOB) ==  JavaSQLTypes.CLOB) {
+            if (dict.maxEmbeddedClobSize > 0) {
+                cls = mapping.getFieldMapping("toClob").getStrategy().
+                    getClass();
+                assertTrue(cls.getName(),
+                    MaxEmbeddedClobFieldStrategy.class.isAssignableFrom(cls));
+            } else {
+                cls = mapping.getFieldMapping("toClob").getHandler().
+                    getClass();
+                assertTrue(cls.getName(),
+                    ClobValueHandler.class.isAssignableFrom(cls));
+            }
+        } else
+            assertTrue(mapping.getFieldMapping("toClob").getStrategy()
+                instanceof StringFieldStrategy);
+
+        cls = mapping.getFieldMapping("toBlob").getHandler().getClass();
+        assertTrue(cls.getName(),
+            BlobValueHandler.class.isAssignableFrom(cls));
+
+        SchemaGroup schema = repos.getSchemaGroup();
+        Table table = schema.getSchemas()[0].getTables()[0];
+        Column[] cols = table.getColumns();
+        for (int i = 0; i < cols.length; i++) {
+            if (cols[i].getName().equalsIgnoreCase("id")
+                || cols[i].getName().equalsIgnoreCase("versn")
+                || cols[i].getName().equalsIgnoreCase("typ"))
+                continue;
+            if ("longToInt".equalsIgnoreCase(cols[i].getName()))
+                assertEquals(dict.getPreferredType(JavaSQLTypes.INT),
+                    cols[i].getType());
+            else if ("longToSQL".equalsIgnoreCase(cols[i].getName()))
+                assertEquals("varchar", cols[i].getTypeName());
+            else if ("toClob".equalsIgnoreCase(cols[i].getName()))
+                assertEquals(dict.getPreferredType(JavaSQLTypes.CLOB),
+                    cols[i].getType());
+            else if ("toBlob".equalsIgnoreCase(cols[i].getName()))
+                assertEquals(dict.getPreferredType(JavaSQLTypes.BLOB),
+                    cols[i].getType());
+            else
+                fail("Unknown column:" + cols[i].getName());
+        }
+    }    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJoinToBaseClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJoinToBaseClass.java
index 70d8090..1cdd160 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJoinToBaseClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestJoinToBaseClass.java
@@ -1,118 +1,118 @@
-/*
- * TestJoinToBaseClass.java
- *
- * Created on October 3, 2006, 4:19 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.ForeignKey;
-import org.apache.openjpa.jdbc.schema.Table;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestJoinToBaseClass extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    
-    
-    /** Creates a new instance of TestJoinToBaseClass */
-    public TestJoinToBaseClass(String name) 
-    {
-    	super(name);
-    }
-    
-    public void testMapping() {
-        ClassMapping mapping = ((JDBCConfiguration) getConfiguration()).
-            getMappingRepositoryInstance().
-            getMapping(MappingTest5.class, null, true);
-
-        Table supTable = mapping.getPCSuperclassMapping().getTable();
-        assertTrue(mapping.getTable() != supTable);
-        FieldMapping field = mapping.getFieldMapping("vertRel");
-        ForeignKey fk = field.getForeignKey();
-        assertEquals(mapping.getTable(), fk.getTable());
-        assertEquals(supTable, fk.getPrimaryKeyTable());
-        Column[] cols = field.getColumns();
-        assertEquals(2, cols.length);
-        assertEquals("V1", cols[0].getName());
-        assertEquals("V2", cols[1].getName());
-    }
-
-    public void testConstraintAnalysis() {
-        //FIXME jthomas
-        //PersistenceManagerFactory factory = getPMFactory(new String[]{
-          //  "openjpa.jdbc.SchemaFactory", "native(ForeignKeys=true)",
-        //});
-        OpenJPAEntityManagerFactory factory=null;
-        OpenJPAEntityManager pm = factory.createEntityManager();
-        startTx(pm);
-        
-       deleteAll( MappingTest1.class,pm);
-       deleteAll( MappingTest2.class,pm);
-        endTx(pm);
-        pm.close();
-
-        pm = factory.createEntityManager();
-        startTx(pm);
-        for (int i = 0; i < 10; i++) {
-            MappingTest5 pc1 = new MappingTest5();
-            pc1.setPk1(i);
-            pc1.setPk2(i + 1);
-            MappingTest5 pc2 = new MappingTest5();
-            pc2.setPk1(i + 10);
-            pc2.setPk2(i + 11);
-            pc1.setVertRel(pc2);
-            pc2.setVertRel(pc1);
-            pm.persist(pc1);
-        }
-        endTx(pm);
-        pm.close();
-
-        assertSizes(20, MappingTest5.class);
-
-        pm = factory.createEntityManager();
-        startTx(pm);
-        deleteAll(MappingTest2.class,pm);
-        endTx(pm);
-        pm.close();
-    }
-
-    private void assertSizes(int size, Class cls) {
-        assertSize(size, currentEntityManager().createExtent(cls, true).list());
-    }
-}
+/*
+ * TestJoinToBaseClass.java
+ *
+ * Created on October 3, 2006, 4:19 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Table;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestJoinToBaseClass extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    
+    
+    /** Creates a new instance of TestJoinToBaseClass */
+    public TestJoinToBaseClass(String name) 
+    {
+    	super(name);
+    }
+    
+    public void testMapping() {
+        ClassMapping mapping = ((JDBCConfiguration) getConfiguration()).
+            getMappingRepositoryInstance().
+            getMapping(MappingTest5.class, null, true);
+
+        Table supTable = mapping.getPCSuperclassMapping().getTable();
+        assertTrue(mapping.getTable() != supTable);
+        FieldMapping field = mapping.getFieldMapping("vertRel");
+        ForeignKey fk = field.getForeignKey();
+        assertEquals(mapping.getTable(), fk.getTable());
+        assertEquals(supTable, fk.getPrimaryKeyTable());
+        Column[] cols = field.getColumns();
+        assertEquals(2, cols.length);
+        assertEquals("V1", cols[0].getName());
+        assertEquals("V2", cols[1].getName());
+    }
+
+    public void testConstraintAnalysis() {
+        //FIXME jthomas
+        //PersistenceManagerFactory factory = getPMFactory(new String[]{
+          //  "openjpa.jdbc.SchemaFactory", "native(ForeignKeys=true)",
+        //});
+        OpenJPAEntityManagerFactory factory=null;
+        OpenJPAEntityManager pm = factory.createEntityManager();
+        startTx(pm);
+        
+       deleteAll( MappingTest1.class,pm);
+       deleteAll( MappingTest2.class,pm);
+        endTx(pm);
+        pm.close();
+
+        pm = factory.createEntityManager();
+        startTx(pm);
+        for (int i = 0; i < 10; i++) {
+            MappingTest5 pc1 = new MappingTest5();
+            pc1.setPk1(i);
+            pc1.setPk2(i + 1);
+            MappingTest5 pc2 = new MappingTest5();
+            pc2.setPk1(i + 10);
+            pc2.setPk2(i + 11);
+            pc1.setVertRel(pc2);
+            pc2.setVertRel(pc1);
+            pm.persist(pc1);
+        }
+        endTx(pm);
+        pm.close();
+
+        assertSizes(20, MappingTest5.class);
+
+        pm = factory.createEntityManager();
+        startTx(pm);
+        deleteAll(MappingTest2.class,pm);
+        endTx(pm);
+        pm.close();
+    }
+
+    private void assertSizes(int size, Class cls) {
+        assertSize(size, currentEntityManager().createExtent(cls, true).list());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLRSProxies.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLRSProxies.java
index fc10477..84f2e67 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLRSProxies.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLRSProxies.java
@@ -1,601 +1,601 @@
-/*
- * TestLRSProxies.java
- *
- * Created on October 3, 2006, 5:01 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.lib.jdbc.JDBCEvent;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestLRSProxies extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-   
-    private Object _oid = null;
-    private Object _coid = null;
-    
-    public TestLRSProxies(String casename) {
-        super(casename);
-    }
-    
-    
-    /** Creates a new instance of TestLRSProxies */
-    public TestLRSProxies() {
-    }
-    public void setUp() {
-       deleteAll(LRSPC.class);
-       deleteAll(LRSCompoundPC.class);
-        
-        LRSPC pc = new LRSPC("main");
-        
-        pc.getStringSet().add("val1");
-        pc.getStringSet().add("val2");
-        pc.getStringSet().add("val3");
-        
-        pc.getRelSet().add(new LRSPC("set1"));
-        pc.getRelSet().add(new LRSPC("set2"));
-        pc.getRelSet().add(new LRSPC("set3"));
-        
-        pc.getStringCollection().add("val1");
-        pc.getStringCollection().add("val2");
-        pc.getStringCollection().add("val3");
-        
-        pc.getRelCollection().add(new LRSPC("set1"));
-        pc.getRelCollection().add(new LRSPC("set2"));
-        pc.getRelCollection().add(new LRSPC("set3"));
-        
-        pc.getStringMap().put("key1", "1");
-        pc.getStringMap().put("key2", "2");
-        pc.getStringMap().put("key3", "3");
-        
-        pc.getRelMap().put("key1", new LRSPC("map1"));
-        pc.getRelMap().put("key2", new LRSPC("map2"));
-        pc.getRelMap().put("key3", new LRSPC("map3"));
-        
-        LRSCompoundPC cpc = new LRSCompoundPC("main");
-        
-        cpc.getStringSet().add("val1");
-        cpc.getStringSet().add("val2");
-        cpc.getStringSet().add("val3");
-        
-        cpc.getRelSet().add(new LRSCompoundPC("set1"));
-        cpc.getRelSet().add(new LRSCompoundPC("set2"));
-        cpc.getRelSet().add(new LRSCompoundPC("set3"));
-        
-        cpc.getStringCollection().add("val1");
-        cpc.getStringCollection().add("val2");
-        cpc.getStringCollection().add("val3");
-        
-        cpc.getRelCollection().add(new LRSCompoundPC("set1"));
-        cpc.getRelCollection().add(new LRSCompoundPC("set2"));
-        cpc.getRelCollection().add(new LRSCompoundPC("set3"));
-        
-        cpc.getStringMap().put("key1", "1");
-        cpc.getStringMap().put("key2", "2");
-        cpc.getStringMap().put("key3", "3");
-        
-        cpc.getRelMap().put("key1", new LRSCompoundPC("map1"));
-        cpc.getRelMap().put("key2", new LRSCompoundPC("map2"));
-        cpc.getRelMap().put("key3", new LRSCompoundPC("map3"));
-        
-        
-        
-        OpenJPAEntityManager pm = getEm(false, false);
-        
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(cpc);
-        endTx(pm);
-        _oid = pm.getObjectId(pc);
-        _coid = pm.getObjectId(cpc);
-        pm.close();
-    }
-    
-    public void testStringSet() {
-        stringCollectionTest(_oid, true, true);
-        stringCollectionTest(_coid, true, true);
-    }
-    
-    public void testStringSetRetain() {
-        stringCollectionTest(_oid, false, true);
-        stringCollectionTest(_coid, false, true);
-    }
-    
-    public void testStringCollection() {
-        stringCollectionTest(_oid, true, false);
-        stringCollectionTest(_coid, true, false);
-    }
-    
-    public void testStringCollectionRetain() {
-        stringCollectionTest(_oid, false, false);
-        stringCollectionTest(_coid, false, false);
-    }
-    
-    private void stringCollectionTest(Object oid, boolean close,
-            boolean isSet) {
-        //FIXME jthomas
-        //PersistenceManager pm = getPM(!close, !close);
-        OpenJPAEntityManager pm =null;
-        startTx(pm);
-        
-        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
-        
-        // check that orig values are correct
-        Collection set = isSet ? pc.getStringSet() : pc.getStringCollection();
-        assertEquals(3, set.size());
-        assertTrue(set.contains("val1"));
-        assertTrue(set.contains("val2"));
-        assertTrue(set.contains("val3"));
-        if (!isSet) {
-            Iterator itr = set.iterator();
-            assertEquals("val1", itr.next());
-            assertEquals("val2", itr.next());
-            assertEquals("val3", itr.next());
-            //FIXME jthomas
-            //KodoJDOHelper.close(itr);
-        }
-        
-        // do some mods to try to confuse the proxy
-        set.remove("val1");
-        set.remove("val1");
-        set.add("val4");
-        set.remove("val4");
-        set.add("val5");
-        set.add("val6");
-        assertStringCollectionChanged(set, isSet);
-        endTx(pm);
-        if (close) {
-            pm.close();
-            pm = getEm(false, false);
-        }
-        
-        // re-retrieve and check set
-        pc = (LRSPCIntf) pm.getObjectId(oid);
-        set = isSet ? pc.getStringSet() : pc.getStringCollection();
-        assertStringCollectionChanged(set, isSet);
-        pm.close();
-    }
-    
-    private void assertStringCollectionChanged(Collection set, boolean isSet) {
-        assertEquals(4, set.size());
-        assertTrue(!set.contains("val1"));
-        assertTrue(set.contains("val2"));
-        assertTrue(set.contains("val3"));
-        assertTrue(!set.contains("val4"));
-        assertTrue(set.contains("val5"));
-        assertTrue(set.contains("val6"));
-        if (!isSet) {
-            Iterator itr = set.iterator();
-            assertEquals("val2", itr.next());
-            assertEquals("val3", itr.next());
-            assertEquals("val5", itr.next());
-            assertEquals("val6", itr.next());
-            assertTrue(!itr.hasNext());
-            //FIXME jthomas
-            //KodoJDOHelper.close(itr);
-        }
-    }
-    
-    public void testStringMap() {
-        stringMapTest(_oid, true);
-        stringMapTest(_coid, true);
-    }
-    
-    public void testStringMapRetain() {
-        stringMapTest(_oid, false);
-        stringMapTest(_coid, false);
-    }
-    
-    private void stringMapTest(Object oid, boolean close) {
-        OpenJPAEntityManager pm = getEm(!close, !close);
-        startTx(pm);
-        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
-        
-        // check that orig values are correct
-        Map map = pc.getStringMap();
-        assertEquals(3, map.size());
-        assertEquals("1", map.get("key1"));
-        assertEquals("2", map.get("key2"));
-        assertEquals("3", map.get("key3"));
-        
-        // do some mods to try to confuse the proxy
-        map.put("key1", "1a");
-        map.put("key1", "1b");
-        map.put("key2", "4");
-        map.remove("key2");
-        map.remove("foo");
-        map.put("key5", "5");
-        assertStringMapChanged(map);
-        endTx(pm);
-        
-        if (close) {
-            pm.close();
-            pm = getEm(false, false);
-        }
-        
-        // re-retrieve and check map
-        pc = (LRSPCIntf) pm.getObjectId(oid);
-        map = pc.getStringMap();
-        assertStringMapChanged(map);
-        pm.close();
-    }
-    
-    private void assertStringMapChanged(Map map) {
-        assertEquals(3, map.size());
-        assertEquals("1b", map.get("key1"));
-        assertEquals("3", map.get("key3"));
-        assertEquals("5", map.get("key5"));
-        assertNull(map.get("key2"));
-        assertTrue(map.containsKey("key1"));
-        assertFalse(map.containsKey("key2"));
-        assertTrue(map.containsValue("5"));
-        assertFalse(map.containsValue("1"));
-        
-        Iterator itr = map.entrySet().iterator();
-        Map.Entry entry;
-        int count = 0;
-        for (; itr.hasNext(); count++) {
-            entry = (Map.Entry) itr.next();
-            if (entry.getKey().equals("key1"))
-                assertEquals("1b", entry.getValue());
-            else if (entry.getKey().equals("key3"))
-                assertEquals("3", entry.getValue());
-            else if (entry.getKey().equals("key5"))
-                assertEquals("5", entry.getValue());
-            else
-                fail("Bad key: " + entry.getKey());
-        }
-        assertEquals(3, count);
-        //FIXME
-        //KodoJDOHelper.close(itr);
-    }
-    
-    public void testRelSet() {
-        relCollectionTest(_oid, true, true);
-        relCollectionTest(_coid, true, true);
-    }
-    
-    public void testRelSetRetain() {
-        relCollectionTest(_oid, false, true);
-        relCollectionTest(_coid, false, true);
-    }
-    
-    public void testRelCollection() {
-        relCollectionTest(_oid, true, false);
-        relCollectionTest(_coid, true, false);
-    }
-    
-    public void testRelCollectionRetain() {
-        relCollectionTest(_oid, false, false);
-        relCollectionTest(_coid, false, false);
-    }
-    
-    private void relCollectionTest(Object oid, boolean close, boolean isSet) {
-        OpenJPAEntityManager pm = getEm(!close, !close);
-        startTx(pm);
-        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
-        
-        // check that orig values are correct
-        Collection set = isSet ? pc.getRelSet() : pc.getRelCollection();
-        assertEquals(3, set.size());
-        Collection ordered = new TreeSet();
-        Iterator itr = set.iterator();
-        ordered.add(itr.next());
-        ordered.add(itr.next());
-        ordered.add(itr.next());
-        assertTrue(!itr.hasNext());
-        //FIXME
-        //KodoJDOHelper.close(itr);
-        itr = ordered.iterator();
-        LRSPCIntf set1 = (LRSPCIntf) itr.next();
-        if (!isSet) {
-            LRSPCIntf set2 = (LRSPCIntf) itr.next();
-            LRSPCIntf set3 = (LRSPCIntf) itr.next();
-            assertEquals("set1", set1.getStringField());
-            assertEquals("set2", set2.getStringField());
-            assertEquals("set3", set3.getStringField());
-        }
-        assertTrue(set.contains(set1));
-        assertFalse(set.contains(pc));
-        
-        // do some mods to try to confuse the proxy
-        set.remove(set1);
-        set.remove(set1);
-        LRSPCIntf set4 = pc.newInstance("set4");
-        set.add(set4);
-        set.remove(set4);
-        LRSPCIntf set5 = pc.newInstance("set5");
-        set.add(set5);
-        assertRelCollectionChanged(pc, isSet);
-        endTx(pm);
-        
-        if (close) {
-            pm.close();
-            pm = getEm(false, false);
-        }
-        
-        // re-retrieve and check set
-        pc = (LRSPCIntf) pm.getObjectId(oid);
-        assertRelCollectionChanged(pc, isSet);
-        pm.close();
-    }
-    
-    private void assertRelCollectionChanged(LRSPCIntf pc, boolean isSet) {
-        Collection set = isSet ? pc.getRelSet() : pc.getRelCollection();
-        assertEquals(3, set.size());
-        Collection ordered = new TreeSet();
-        Iterator itr = set.iterator();
-        ordered.add(itr.next());
-        ordered.add(itr.next());
-        ordered.add(itr.next());
-        assertTrue(!itr.hasNext());
-        //FIXME
-        //KodoJDOHelper.close(itr);
-        itr = ordered.iterator();
-        LRSPCIntf set2 = (LRSPCIntf) itr.next();
-        if (!isSet) {
-            LRSPCIntf set3 = (LRSPCIntf) itr.next();
-            LRSPCIntf set5 = (LRSPCIntf) itr.next();
-            assertEquals("set2", set2.getStringField());
-            assertEquals("set3", set3.getStringField());
-            assertEquals("set5", set5.getStringField());
-        }
-        assertTrue(set.contains(set2));
-        assertFalse(set.contains(pc));
-    }
-    
-    public void testRelMap() {
-        relMapTest(_oid, true);
-        relMapTest(_coid, true);
-    }
-    
-    public void testRelMapRetain() {
-        relMapTest(_oid, false);
-        relMapTest(_coid, false);
-    }
-    
-    private void relMapTest(Object oid, boolean close) {
-        OpenJPAEntityManager pm = getEm(!close, !close);
-        startTx(pm);
-        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
-        
-        // check that orig values are correct
-        Map map = pc.getRelMap();
-        assertEquals(3, map.size());
-        LRSPCIntf map1 = (LRSPCIntf) map.get("key1");
-        LRSPCIntf map2 = (LRSPCIntf) map.get("key2");
-        LRSPCIntf map3 = (LRSPCIntf) map.get("key3");
-        assertEquals("map1", map1.getStringField());
-        assertEquals("map2", map2.getStringField());
-        assertEquals("map3", map3.getStringField());
-        assertTrue(map.containsKey("key1"));
-        assertFalse(map.containsKey("key4"));
-        assertTrue(map.containsValue(map1));
-        assertFalse(map.containsValue(pc));
-        
-        // do some mods to try to confuse the proxy
-        LRSPCIntf map1a = pc.newInstance("map1a");
-        map.put("key1", map1a);
-        LRSPCIntf map1b = pc.newInstance("map1b");
-        map.put("key1", map1b);
-        map.remove("key2");
-        map.put("key4", pc.newInstance("map4"));
-        map.remove("key4");
-        map.remove("foo");
-        map.put("key5", pc.newInstance("map5"));
-        assertRelMapChanged(pc);
-        endTx(pm);
-        
-        if (close) {
-            pm.close();
-            pm = getEm(false, false);
-        }
-        
-        // re-retrieve and check map
-        pc = (LRSPCIntf) pm.getObjectId(oid);
-        assertRelMapChanged(pc);
-        pm.close();
-    }
-    
-    private void assertRelMapChanged(LRSPCIntf pc) {
-        Map map = pc.getRelMap();
-        assertEquals(3, map.size());
-        LRSPCIntf map1b = (LRSPCIntf) map.get("key1");
-        LRSPCIntf map3 = (LRSPCIntf) map.get("key3");
-        LRSPCIntf map5 = (LRSPCIntf) map.get("key5");
-        assertEquals("map1b", map1b.getStringField());
-        assertEquals("map3", map3.getStringField());
-        assertEquals("map5", map5.getStringField());
-        assertTrue(map.containsKey("key1"));
-        assertFalse(map.containsKey("key2"));
-        assertTrue(map.containsValue(map1b));
-        assertFalse(map.containsValue(pc));
-        
-        Iterator itr = map.entrySet().iterator();
-        Map.Entry entry;
-        int count = 0;
-        for (; itr.hasNext(); count++) {
-            entry = (Map.Entry) itr.next();
-            if (entry.getKey().equals("key1"))
-                assertEquals(map1b, entry.getValue());
-            else if (entry.getKey().equals("key3"))
-                assertEquals(map3, entry.getValue());
-            else if (entry.getKey().equals("key5"))
-                assertEquals(map5, entry.getValue());
-            else
-                fail("Bad key: " + entry.getKey());
-        }
-        assertEquals(3, count);
-        //FIXME
-        //KodoJDOHelper.close(itr);
-    }
-    
-    public void testTransfer() {
-        // cannot transfer an lrs from one field to another
-        
-        OpenJPAEntityManager pm = getEm(true, true);
-        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
-        LRSPC map1 = (LRSPC) pc.getRelMap().get("key1");
-        assertNotNull(map1);
-        
-        startTx(pm);
-        Map map = pc.getRelMap();
-        pc.setRelMap(null);
-        map1.setRelMap(map);
-        
-        try {
-            endTx(pm);
-            fail("Allowed transfer of lrs field");
-        } catch (Exception jue) {
-        }
-        if (pm.getTransaction().isActive())
-            pm.getTransaction().rollback();
-        pm.close();
-    }
-    
-    public void testShare() {
-        OpenJPAEntityManager pm = getEm(true, true);
-        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
-        LRSPC map1 = (LRSPC) pc.getRelMap().get("key1");
-        assertNotNull(map1);
-        
-        startTx(pm);
-        Map map = pc.getRelMap();
-        map1.setRelMap(map);
-        endTx(pm);
-        assertTrue(pc.getRelMap() != map1.getRelMap());
-        assertEquals(3, map1.getRelMap().size());
-        assertTrue(map1.getRelMap().containsValue(map1));
-        pm.close();
-        
-        // make sure it sticks
-        pm = getEm(true, true);
-        pc = (LRSPC) pm.getObjectId(_oid);
-        map1 = (LRSPC) pc.getRelMap().get("key1");
-        assertEquals(map1, map1.getRelMap().get("key1"));
-        pm.close();
-    }
-    
-    public void testRollback() {
-        //FIXME
-        //PersistenceManagerFactory factory = getPMFactory(new String[]{
-        //    "openjpa.RestoreMutableValues", "true",
-        //});
-        OpenJPAEntityManagerFactory factory =null;
-        OpenJPAEntityManager pm = factory.createEntityManager();
-        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
-        startTx(pm);
-        pc.getStringCollection().remove("val2");
-        pc.getStringCollection().add("val4");
-        rollbackTx(pm);
-        assertTrue(pc.getStringCollection().contains("val2"));
-        assertFalse(pc.getStringCollection().contains("val4"));
-        pm.close();
-        factory.close();
-    }
-    
-    public void testReplace() {
-        OpenJPAEntityManager pm = getEm(false, false);
-        startTx(pm);
-        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
-        
-        // totally replace set
-        Collection set = new HashSet();
-        set.add("new");
-        pc.setStringCollection(set);
-        
-        endTx(pm);
-        pm.close();
-        
-        // re-retrieve and check set
-        pm = getEm(false, false);
-        pc = (LRSPC) pm.getObjectId(_oid);
-        
-        set = pc.getStringCollection();
-        assertEquals(1, set.size());
-        assertTrue(set.contains("new"));
-        pm.close();
-    }
-    
-    public void testAdd()
-    throws Exception {
-/*
-        //FIXME
-        //KodoPersistenceManagerFactory pmf = getPMFactory(new String []{
-        //    "openjpa.jdbc.JDBCListeners", Listener.class.getName(),
-        //});
-        OpenJPAEntityManagerFactory pmf =null;
-        JDBCConfiguration conf = (JDBCConfiguration) pmf.getConfiguration();
-        //FIXME need to fix inner class
-        //Listener l = (Listener) conf.getJDBCListenerInstances()[0];
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-        try {
-            startTx(pm);
-            LRSPC pc = (LRSPC) pm.getObjectId(_oid);
-            l.count = 0;
-            pc.getStringCollection().add("testAddStringValue");
-            endTx(pm);
-            assertEquals(3, l.count);
-        } catch (Exception e) {
-            if (pm.getTransaction().isActive())
-                pm.getTransaction().rollback();
-            throw e;
-        } finally {
-            pm.close();
-        }
- */
-    }
-    
-    private OpenJPAEntityManager getEm(boolean optimistic,boolean retainValues) {
-        OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-        em.setNontransactionalRead(true);
-        em.setRetainState(retainValues);
-        em.setOptimistic(optimistic);
-        return em;
-    }
-    
-    //FIXME - could not find AbstractJDBCListener because of package imports in source file
-/*
-    public static class Listener extends AbstractJDBCListener {
- 
-        public int count = 0;
- 
-        public void afterExecuteStatement(JDBCEvent ev) {
-            count++;
-        }
-    }
- */
-}
+/*
+ * TestLRSProxies.java
+ *
+ * Created on October 3, 2006, 5:01 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.lib.jdbc.JDBCEvent;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestLRSProxies extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+   
+    private Object _oid = null;
+    private Object _coid = null;
+    
+    public TestLRSProxies(String casename) {
+        super(casename);
+    }
+    
+    
+    /** Creates a new instance of TestLRSProxies */
+    public TestLRSProxies() {
+    }
+    public void setUp() {
+       deleteAll(LRSPC.class);
+       deleteAll(LRSCompoundPC.class);
+        
+        LRSPC pc = new LRSPC("main");
+        
+        pc.getStringSet().add("val1");
+        pc.getStringSet().add("val2");
+        pc.getStringSet().add("val3");
+        
+        pc.getRelSet().add(new LRSPC("set1"));
+        pc.getRelSet().add(new LRSPC("set2"));
+        pc.getRelSet().add(new LRSPC("set3"));
+        
+        pc.getStringCollection().add("val1");
+        pc.getStringCollection().add("val2");
+        pc.getStringCollection().add("val3");
+        
+        pc.getRelCollection().add(new LRSPC("set1"));
+        pc.getRelCollection().add(new LRSPC("set2"));
+        pc.getRelCollection().add(new LRSPC("set3"));
+        
+        pc.getStringMap().put("key1", "1");
+        pc.getStringMap().put("key2", "2");
+        pc.getStringMap().put("key3", "3");
+        
+        pc.getRelMap().put("key1", new LRSPC("map1"));
+        pc.getRelMap().put("key2", new LRSPC("map2"));
+        pc.getRelMap().put("key3", new LRSPC("map3"));
+        
+        LRSCompoundPC cpc = new LRSCompoundPC("main");
+        
+        cpc.getStringSet().add("val1");
+        cpc.getStringSet().add("val2");
+        cpc.getStringSet().add("val3");
+        
+        cpc.getRelSet().add(new LRSCompoundPC("set1"));
+        cpc.getRelSet().add(new LRSCompoundPC("set2"));
+        cpc.getRelSet().add(new LRSCompoundPC("set3"));
+        
+        cpc.getStringCollection().add("val1");
+        cpc.getStringCollection().add("val2");
+        cpc.getStringCollection().add("val3");
+        
+        cpc.getRelCollection().add(new LRSCompoundPC("set1"));
+        cpc.getRelCollection().add(new LRSCompoundPC("set2"));
+        cpc.getRelCollection().add(new LRSCompoundPC("set3"));
+        
+        cpc.getStringMap().put("key1", "1");
+        cpc.getStringMap().put("key2", "2");
+        cpc.getStringMap().put("key3", "3");
+        
+        cpc.getRelMap().put("key1", new LRSCompoundPC("map1"));
+        cpc.getRelMap().put("key2", new LRSCompoundPC("map2"));
+        cpc.getRelMap().put("key3", new LRSCompoundPC("map3"));
+        
+        
+        
+        OpenJPAEntityManager pm = getEm(false, false);
+        
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(cpc);
+        endTx(pm);
+        _oid = pm.getObjectId(pc);
+        _coid = pm.getObjectId(cpc);
+        pm.close();
+    }
+    
+    public void testStringSet() {
+        stringCollectionTest(_oid, true, true);
+        stringCollectionTest(_coid, true, true);
+    }
+    
+    public void testStringSetRetain() {
+        stringCollectionTest(_oid, false, true);
+        stringCollectionTest(_coid, false, true);
+    }
+    
+    public void testStringCollection() {
+        stringCollectionTest(_oid, true, false);
+        stringCollectionTest(_coid, true, false);
+    }
+    
+    public void testStringCollectionRetain() {
+        stringCollectionTest(_oid, false, false);
+        stringCollectionTest(_coid, false, false);
+    }
+    
+    private void stringCollectionTest(Object oid, boolean close,
+            boolean isSet) {
+        //FIXME jthomas
+        //PersistenceManager pm = getPM(!close, !close);
+        OpenJPAEntityManager pm =null;
+        startTx(pm);
+        
+        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
+        
+        // check that orig values are correct
+        Collection set = isSet ? pc.getStringSet() : pc.getStringCollection();
+        assertEquals(3, set.size());
+        assertTrue(set.contains("val1"));
+        assertTrue(set.contains("val2"));
+        assertTrue(set.contains("val3"));
+        if (!isSet) {
+            Iterator itr = set.iterator();
+            assertEquals("val1", itr.next());
+            assertEquals("val2", itr.next());
+            assertEquals("val3", itr.next());
+            //FIXME jthomas
+            //KodoJDOHelper.close(itr);
+        }
+        
+        // do some mods to try to confuse the proxy
+        set.remove("val1");
+        set.remove("val1");
+        set.add("val4");
+        set.remove("val4");
+        set.add("val5");
+        set.add("val6");
+        assertStringCollectionChanged(set, isSet);
+        endTx(pm);
+        if (close) {
+            pm.close();
+            pm = getEm(false, false);
+        }
+        
+        // re-retrieve and check set
+        pc = (LRSPCIntf) pm.getObjectId(oid);
+        set = isSet ? pc.getStringSet() : pc.getStringCollection();
+        assertStringCollectionChanged(set, isSet);
+        pm.close();
+    }
+    
+    private void assertStringCollectionChanged(Collection set, boolean isSet) {
+        assertEquals(4, set.size());
+        assertTrue(!set.contains("val1"));
+        assertTrue(set.contains("val2"));
+        assertTrue(set.contains("val3"));
+        assertTrue(!set.contains("val4"));
+        assertTrue(set.contains("val5"));
+        assertTrue(set.contains("val6"));
+        if (!isSet) {
+            Iterator itr = set.iterator();
+            assertEquals("val2", itr.next());
+            assertEquals("val3", itr.next());
+            assertEquals("val5", itr.next());
+            assertEquals("val6", itr.next());
+            assertTrue(!itr.hasNext());
+            //FIXME jthomas
+            //KodoJDOHelper.close(itr);
+        }
+    }
+    
+    public void testStringMap() {
+        stringMapTest(_oid, true);
+        stringMapTest(_coid, true);
+    }
+    
+    public void testStringMapRetain() {
+        stringMapTest(_oid, false);
+        stringMapTest(_coid, false);
+    }
+    
+    private void stringMapTest(Object oid, boolean close) {
+        OpenJPAEntityManager pm = getEm(!close, !close);
+        startTx(pm);
+        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
+        
+        // check that orig values are correct
+        Map map = pc.getStringMap();
+        assertEquals(3, map.size());
+        assertEquals("1", map.get("key1"));
+        assertEquals("2", map.get("key2"));
+        assertEquals("3", map.get("key3"));
+        
+        // do some mods to try to confuse the proxy
+        map.put("key1", "1a");
+        map.put("key1", "1b");
+        map.put("key2", "4");
+        map.remove("key2");
+        map.remove("foo");
+        map.put("key5", "5");
+        assertStringMapChanged(map);
+        endTx(pm);
+        
+        if (close) {
+            pm.close();
+            pm = getEm(false, false);
+        }
+        
+        // re-retrieve and check map
+        pc = (LRSPCIntf) pm.getObjectId(oid);
+        map = pc.getStringMap();
+        assertStringMapChanged(map);
+        pm.close();
+    }
+    
+    private void assertStringMapChanged(Map map) {
+        assertEquals(3, map.size());
+        assertEquals("1b", map.get("key1"));
+        assertEquals("3", map.get("key3"));
+        assertEquals("5", map.get("key5"));
+        assertNull(map.get("key2"));
+        assertTrue(map.containsKey("key1"));
+        assertFalse(map.containsKey("key2"));
+        assertTrue(map.containsValue("5"));
+        assertFalse(map.containsValue("1"));
+        
+        Iterator itr = map.entrySet().iterator();
+        Map.Entry entry;
+        int count = 0;
+        for (; itr.hasNext(); count++) {
+            entry = (Map.Entry) itr.next();
+            if (entry.getKey().equals("key1"))
+                assertEquals("1b", entry.getValue());
+            else if (entry.getKey().equals("key3"))
+                assertEquals("3", entry.getValue());
+            else if (entry.getKey().equals("key5"))
+                assertEquals("5", entry.getValue());
+            else
+                fail("Bad key: " + entry.getKey());
+        }
+        assertEquals(3, count);
+        //FIXME
+        //KodoJDOHelper.close(itr);
+    }
+    
+    public void testRelSet() {
+        relCollectionTest(_oid, true, true);
+        relCollectionTest(_coid, true, true);
+    }
+    
+    public void testRelSetRetain() {
+        relCollectionTest(_oid, false, true);
+        relCollectionTest(_coid, false, true);
+    }
+    
+    public void testRelCollection() {
+        relCollectionTest(_oid, true, false);
+        relCollectionTest(_coid, true, false);
+    }
+    
+    public void testRelCollectionRetain() {
+        relCollectionTest(_oid, false, false);
+        relCollectionTest(_coid, false, false);
+    }
+    
+    private void relCollectionTest(Object oid, boolean close, boolean isSet) {
+        OpenJPAEntityManager pm = getEm(!close, !close);
+        startTx(pm);
+        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
+        
+        // check that orig values are correct
+        Collection set = isSet ? pc.getRelSet() : pc.getRelCollection();
+        assertEquals(3, set.size());
+        Collection ordered = new TreeSet();
+        Iterator itr = set.iterator();
+        ordered.add(itr.next());
+        ordered.add(itr.next());
+        ordered.add(itr.next());
+        assertTrue(!itr.hasNext());
+        //FIXME
+        //KodoJDOHelper.close(itr);
+        itr = ordered.iterator();
+        LRSPCIntf set1 = (LRSPCIntf) itr.next();
+        if (!isSet) {
+            LRSPCIntf set2 = (LRSPCIntf) itr.next();
+            LRSPCIntf set3 = (LRSPCIntf) itr.next();
+            assertEquals("set1", set1.getStringField());
+            assertEquals("set2", set2.getStringField());
+            assertEquals("set3", set3.getStringField());
+        }
+        assertTrue(set.contains(set1));
+        assertFalse(set.contains(pc));
+        
+        // do some mods to try to confuse the proxy
+        set.remove(set1);
+        set.remove(set1);
+        LRSPCIntf set4 = pc.newInstance("set4");
+        set.add(set4);
+        set.remove(set4);
+        LRSPCIntf set5 = pc.newInstance("set5");
+        set.add(set5);
+        assertRelCollectionChanged(pc, isSet);
+        endTx(pm);
+        
+        if (close) {
+            pm.close();
+            pm = getEm(false, false);
+        }
+        
+        // re-retrieve and check set
+        pc = (LRSPCIntf) pm.getObjectId(oid);
+        assertRelCollectionChanged(pc, isSet);
+        pm.close();
+    }
+    
+    private void assertRelCollectionChanged(LRSPCIntf pc, boolean isSet) {
+        Collection set = isSet ? pc.getRelSet() : pc.getRelCollection();
+        assertEquals(3, set.size());
+        Collection ordered = new TreeSet();
+        Iterator itr = set.iterator();
+        ordered.add(itr.next());
+        ordered.add(itr.next());
+        ordered.add(itr.next());
+        assertTrue(!itr.hasNext());
+        //FIXME
+        //KodoJDOHelper.close(itr);
+        itr = ordered.iterator();
+        LRSPCIntf set2 = (LRSPCIntf) itr.next();
+        if (!isSet) {
+            LRSPCIntf set3 = (LRSPCIntf) itr.next();
+            LRSPCIntf set5 = (LRSPCIntf) itr.next();
+            assertEquals("set2", set2.getStringField());
+            assertEquals("set3", set3.getStringField());
+            assertEquals("set5", set5.getStringField());
+        }
+        assertTrue(set.contains(set2));
+        assertFalse(set.contains(pc));
+    }
+    
+    public void testRelMap() {
+        relMapTest(_oid, true);
+        relMapTest(_coid, true);
+    }
+    
+    public void testRelMapRetain() {
+        relMapTest(_oid, false);
+        relMapTest(_coid, false);
+    }
+    
+    private void relMapTest(Object oid, boolean close) {
+        OpenJPAEntityManager pm = getEm(!close, !close);
+        startTx(pm);
+        LRSPCIntf pc = (LRSPCIntf) pm.getObjectId(oid);
+        
+        // check that orig values are correct
+        Map map = pc.getRelMap();
+        assertEquals(3, map.size());
+        LRSPCIntf map1 = (LRSPCIntf) map.get("key1");
+        LRSPCIntf map2 = (LRSPCIntf) map.get("key2");
+        LRSPCIntf map3 = (LRSPCIntf) map.get("key3");
+        assertEquals("map1", map1.getStringField());
+        assertEquals("map2", map2.getStringField());
+        assertEquals("map3", map3.getStringField());
+        assertTrue(map.containsKey("key1"));
+        assertFalse(map.containsKey("key4"));
+        assertTrue(map.containsValue(map1));
+        assertFalse(map.containsValue(pc));
+        
+        // do some mods to try to confuse the proxy
+        LRSPCIntf map1a = pc.newInstance("map1a");
+        map.put("key1", map1a);
+        LRSPCIntf map1b = pc.newInstance("map1b");
+        map.put("key1", map1b);
+        map.remove("key2");
+        map.put("key4", pc.newInstance("map4"));
+        map.remove("key4");
+        map.remove("foo");
+        map.put("key5", pc.newInstance("map5"));
+        assertRelMapChanged(pc);
+        endTx(pm);
+        
+        if (close) {
+            pm.close();
+            pm = getEm(false, false);
+        }
+        
+        // re-retrieve and check map
+        pc = (LRSPCIntf) pm.getObjectId(oid);
+        assertRelMapChanged(pc);
+        pm.close();
+    }
+    
+    private void assertRelMapChanged(LRSPCIntf pc) {
+        Map map = pc.getRelMap();
+        assertEquals(3, map.size());
+        LRSPCIntf map1b = (LRSPCIntf) map.get("key1");
+        LRSPCIntf map3 = (LRSPCIntf) map.get("key3");
+        LRSPCIntf map5 = (LRSPCIntf) map.get("key5");
+        assertEquals("map1b", map1b.getStringField());
+        assertEquals("map3", map3.getStringField());
+        assertEquals("map5", map5.getStringField());
+        assertTrue(map.containsKey("key1"));
+        assertFalse(map.containsKey("key2"));
+        assertTrue(map.containsValue(map1b));
+        assertFalse(map.containsValue(pc));
+        
+        Iterator itr = map.entrySet().iterator();
+        Map.Entry entry;
+        int count = 0;
+        for (; itr.hasNext(); count++) {
+            entry = (Map.Entry) itr.next();
+            if (entry.getKey().equals("key1"))
+                assertEquals(map1b, entry.getValue());
+            else if (entry.getKey().equals("key3"))
+                assertEquals(map3, entry.getValue());
+            else if (entry.getKey().equals("key5"))
+                assertEquals(map5, entry.getValue());
+            else
+                fail("Bad key: " + entry.getKey());
+        }
+        assertEquals(3, count);
+        //FIXME
+        //KodoJDOHelper.close(itr);
+    }
+    
+    public void testTransfer() {
+        // cannot transfer an lrs from one field to another
+        
+        OpenJPAEntityManager pm = getEm(true, true);
+        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
+        LRSPC map1 = (LRSPC) pc.getRelMap().get("key1");
+        assertNotNull(map1);
+        
+        startTx(pm);
+        Map map = pc.getRelMap();
+        pc.setRelMap(null);
+        map1.setRelMap(map);
+        
+        try {
+            endTx(pm);
+            fail("Allowed transfer of lrs field");
+        } catch (Exception jue) {
+        }
+        if (pm.getTransaction().isActive())
+            pm.getTransaction().rollback();
+        pm.close();
+    }
+    
+    public void testShare() {
+        OpenJPAEntityManager pm = getEm(true, true);
+        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
+        LRSPC map1 = (LRSPC) pc.getRelMap().get("key1");
+        assertNotNull(map1);
+        
+        startTx(pm);
+        Map map = pc.getRelMap();
+        map1.setRelMap(map);
+        endTx(pm);
+        assertTrue(pc.getRelMap() != map1.getRelMap());
+        assertEquals(3, map1.getRelMap().size());
+        assertTrue(map1.getRelMap().containsValue(map1));
+        pm.close();
+        
+        // make sure it sticks
+        pm = getEm(true, true);
+        pc = (LRSPC) pm.getObjectId(_oid);
+        map1 = (LRSPC) pc.getRelMap().get("key1");
+        assertEquals(map1, map1.getRelMap().get("key1"));
+        pm.close();
+    }
+    
+    public void testRollback() {
+        //FIXME
+        //PersistenceManagerFactory factory = getPMFactory(new String[]{
+        //    "openjpa.RestoreMutableValues", "true",
+        //});
+        OpenJPAEntityManagerFactory factory =null;
+        OpenJPAEntityManager pm = factory.createEntityManager();
+        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
+        startTx(pm);
+        pc.getStringCollection().remove("val2");
+        pc.getStringCollection().add("val4");
+        rollbackTx(pm);
+        assertTrue(pc.getStringCollection().contains("val2"));
+        assertFalse(pc.getStringCollection().contains("val4"));
+        pm.close();
+        factory.close();
+    }
+    
+    public void testReplace() {
+        OpenJPAEntityManager pm = getEm(false, false);
+        startTx(pm);
+        LRSPC pc = (LRSPC) pm.getObjectId(_oid);
+        
+        // totally replace set
+        Collection set = new HashSet();
+        set.add("new");
+        pc.setStringCollection(set);
+        
+        endTx(pm);
+        pm.close();
+        
+        // re-retrieve and check set
+        pm = getEm(false, false);
+        pc = (LRSPC) pm.getObjectId(_oid);
+        
+        set = pc.getStringCollection();
+        assertEquals(1, set.size());
+        assertTrue(set.contains("new"));
+        pm.close();
+    }
+    
+    public void testAdd()
+    throws Exception {
+/*
+        //FIXME
+        //KodoPersistenceManagerFactory pmf = getPMFactory(new String []{
+        //    "openjpa.jdbc.JDBCListeners", Listener.class.getName(),
+        //});
+        OpenJPAEntityManagerFactory pmf =null;
+        JDBCConfiguration conf = (JDBCConfiguration) pmf.getConfiguration();
+        //FIXME need to fix inner class
+        //Listener l = (Listener) conf.getJDBCListenerInstances()[0];
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+        try {
+            startTx(pm);
+            LRSPC pc = (LRSPC) pm.getObjectId(_oid);
+            l.count = 0;
+            pc.getStringCollection().add("testAddStringValue");
+            endTx(pm);
+            assertEquals(3, l.count);
+        } catch (Exception e) {
+            if (pm.getTransaction().isActive())
+                pm.getTransaction().rollback();
+            throw e;
+        } finally {
+            pm.close();
+        }
+ */
+    }
+    
+    private OpenJPAEntityManager getEm(boolean optimistic,boolean retainValues) {
+        OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+        em.setNontransactionalRead(true);
+        em.setRetainState(retainValues);
+        em.setOptimistic(optimistic);
+        return em;
+    }
+    
+    //FIXME - could not find AbstractJDBCListener because of package imports in source file
+/*
+    public static class Listener extends AbstractJDBCListener {
+ 
+        public int count = 0;
+ 
+        public void afterExecuteStatement(JDBCEvent ev) {
+            count++;
+        }
+    }
+ */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLocators.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLocators.java
index 1b8eedc..69daf02 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLocators.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestLocators.java
@@ -1,229 +1,229 @@
-/*
- * TestLocators.java
- *
- * Created on October 3, 2006, 4:37 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.OracleDictionary;
-import org.apache.openjpa.persistence.Extent;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-
-public class TestLocators extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    private OpenJPAEntityManagerFactory pmf;
-
-    public TestLocators(String name) {
-        super(name);
-    }    
-    
-    /** Creates a new instance of TestLocators */
-    public TestLocators() {
-    }
-    public void setUp() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        
-        Extent e = pm.createExtent(LocatorTestObject.class, true);
-        for (Iterator i = e.iterator(); i.hasNext();) {
-            pm.remove(i.next());
-            
-        }
-        endTx(pm);
-        pm.close();
-    }
-
-    public void tearDown()
-        throws Exception {
-        super.tearDown();
-
-       deleteAll(LocatorTestObject.class);
-    }
-
-    public void testBLOBs() {
-        doBlobTest(50000);
-    }
-
-    public void testSmallBLOBs() {
-        doBlobTest(50);
-
-        if (getCurrentPlatform() == AbstractTestCase.Platform.ORACLE) {
-            OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-            JDBCConfiguration conf = (JDBCConfiguration)
-                ((OpenJPAEntityManagerSPI) pm).getConfiguration();
-            OracleDictionary dict = (OracleDictionary)
-                conf.getDBDictionaryInstance();
-
-            int t = dict.maxEmbeddedBlobSize;
-            doBlobTest(t - 1);
-            doBlobTest(t);
-            doBlobTest(t + 1);
-        }
-    }
-
-    public void doBlobTest(int size) {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        LocatorTestObject o = new LocatorTestObject();
-        byte[] bytes = new byte[size];
-        Arrays.fill(bytes, (byte) 'b');
-        o.setBytes(bytes);
-        pm.persist(o);
-        Object oid = pm.getObjectId(o);
-        endTx(pm);
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        o = (LocatorTestObject) pm.getObjectId(oid);
-        byte[] newbytes = o.getBytes();
-        assertNotNull(newbytes);
-        assertEquals(bytes.length, newbytes.length);
-        for (int i = 0; i < bytes.length; i++) {
-            assertEquals(bytes[i], newbytes[i]);
-        }
-    }
-
-    public void testShrinkBLOB() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        LocatorTestObject o = new LocatorTestObject();
-        byte[] bytes = new byte[50000];
-        Arrays.fill(bytes, (byte) 'b');
-        o.setBytes(bytes);
-        pm.persist(o);
-        Object oid = pm.getObjectId(o);
-        endTx(pm);
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        o = (LocatorTestObject) pm.getObjectId(oid);
-
-        startTx(pm);
-        bytes = new byte[40000];
-        Arrays.fill(bytes, (byte) 'c');
-        o.setBytes(bytes);
-        endTx(pm);
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        o = (LocatorTestObject) pm.getObjectId(oid);
-        byte[] newbytes = o.getBytes();
-        assertEquals(bytes.length, newbytes.length);
-        for (int i = 0; i < bytes.length; i++) {
-            assertEquals(bytes[i], newbytes[i]);
-        }
-    }
-
-    public void testCLOBs() {
-        doClobTest(50000);
-    }
-
-    public void testSmallCLOBs() {
-        doClobTest(50);
-
-        if (getCurrentPlatform() == AbstractTestCase.Platform.ORACLE) {
-            OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-            JDBCConfiguration conf = (JDBCConfiguration)
-                ((OpenJPAEntityManagerSPI) pm).getConfiguration();
-            OracleDictionary dict = (OracleDictionary)
-                conf.getDBDictionaryInstance();
-
-            int t = dict.maxEmbeddedClobSize;
-            doClobTest(t - 1);
-            doClobTest(t);
-            doClobTest(t + 1);
-        }
-    }
-
-    public void doClobTest(int size) {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        LocatorTestObject o = new LocatorTestObject();
-        char[] chars = new char[size];
-        Arrays.fill(chars, (char) 'c');
-        o.setClobString(new String(chars));
-        pm.persist(o);
-        Object oid = pm.getObjectId(o);
-        endTx(pm);
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        o = (LocatorTestObject) pm.getObjectId(oid);
-        char[] newchars = o.getClobString().toCharArray();
-
-        assertNotNull(newchars);
-        assertEquals(chars.length, newchars.length);
-        for (int i = 0; i < chars.length; i++) {
-            assertEquals(chars[i], newchars[i]);
-        }
-    }
-
-    public void testShrinkCLOB() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);
-        LocatorTestObject o = new LocatorTestObject();
-        char[] chars = new char[50000];
-        Arrays.fill(chars, (char) 'c');
-        o.setClobString(new String(chars));
-        pm.persist(o);
-        Object oid = pm.getObjectId(o);
-        endTx(pm);
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        o = (LocatorTestObject) pm.getObjectId(oid);
-
-        startTx(pm);
-        chars = new char[40000];
-        Arrays.fill(chars, (char) 'd');
-        o.setClobString(new String(chars));
-        endTx(pm);
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        o = (LocatorTestObject) pm.getObjectId(oid);
-        char[] newchars = o.getClobString().toCharArray();
-        assertEquals(chars.length, newchars.length);
-        for (int i = 0; i < chars.length; i++) {
-            assertEquals(chars[i], newchars[i]);
-        }
-    }
-    
-}
+/*
+ * TestLocators.java
+ *
+ * Created on October 3, 2006, 4:37 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.OracleDictionary;
+import org.apache.openjpa.persistence.Extent;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+
+public class TestLocators extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    private OpenJPAEntityManagerFactory pmf;
+
+    public TestLocators(String name) {
+        super(name);
+    }    
+    
+    /** Creates a new instance of TestLocators */
+    public TestLocators() {
+    }
+    public void setUp() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        
+        Extent e = pm.createExtent(LocatorTestObject.class, true);
+        for (Iterator i = e.iterator(); i.hasNext();) {
+            pm.remove(i.next());
+            
+        }
+        endTx(pm);
+        pm.close();
+    }
+
+    public void tearDown()
+        throws Exception {
+        super.tearDown();
+
+       deleteAll(LocatorTestObject.class);
+    }
+
+    public void testBLOBs() {
+        doBlobTest(50000);
+    }
+
+    public void testSmallBLOBs() {
+        doBlobTest(50);
+
+        if (getCurrentPlatform() == AbstractTestCase.Platform.ORACLE) {
+            OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+            JDBCConfiguration conf = (JDBCConfiguration)
+                ((OpenJPAEntityManagerSPI) pm).getConfiguration();
+            OracleDictionary dict = (OracleDictionary)
+                conf.getDBDictionaryInstance();
+
+            int t = dict.maxEmbeddedBlobSize;
+            doBlobTest(t - 1);
+            doBlobTest(t);
+            doBlobTest(t + 1);
+        }
+    }
+
+    public void doBlobTest(int size) {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        LocatorTestObject o = new LocatorTestObject();
+        byte[] bytes = new byte[size];
+        Arrays.fill(bytes, (byte) 'b');
+        o.setBytes(bytes);
+        pm.persist(o);
+        Object oid = pm.getObjectId(o);
+        endTx(pm);
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        o = (LocatorTestObject) pm.getObjectId(oid);
+        byte[] newbytes = o.getBytes();
+        assertNotNull(newbytes);
+        assertEquals(bytes.length, newbytes.length);
+        for (int i = 0; i < bytes.length; i++) {
+            assertEquals(bytes[i], newbytes[i]);
+        }
+    }
+
+    public void testShrinkBLOB() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        LocatorTestObject o = new LocatorTestObject();
+        byte[] bytes = new byte[50000];
+        Arrays.fill(bytes, (byte) 'b');
+        o.setBytes(bytes);
+        pm.persist(o);
+        Object oid = pm.getObjectId(o);
+        endTx(pm);
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        o = (LocatorTestObject) pm.getObjectId(oid);
+
+        startTx(pm);
+        bytes = new byte[40000];
+        Arrays.fill(bytes, (byte) 'c');
+        o.setBytes(bytes);
+        endTx(pm);
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        o = (LocatorTestObject) pm.getObjectId(oid);
+        byte[] newbytes = o.getBytes();
+        assertEquals(bytes.length, newbytes.length);
+        for (int i = 0; i < bytes.length; i++) {
+            assertEquals(bytes[i], newbytes[i]);
+        }
+    }
+
+    public void testCLOBs() {
+        doClobTest(50000);
+    }
+
+    public void testSmallCLOBs() {
+        doClobTest(50);
+
+        if (getCurrentPlatform() == AbstractTestCase.Platform.ORACLE) {
+            OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+            JDBCConfiguration conf = (JDBCConfiguration)
+                ((OpenJPAEntityManagerSPI) pm).getConfiguration();
+            OracleDictionary dict = (OracleDictionary)
+                conf.getDBDictionaryInstance();
+
+            int t = dict.maxEmbeddedClobSize;
+            doClobTest(t - 1);
+            doClobTest(t);
+            doClobTest(t + 1);
+        }
+    }
+
+    public void doClobTest(int size) {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        LocatorTestObject o = new LocatorTestObject();
+        char[] chars = new char[size];
+        Arrays.fill(chars, (char) 'c');
+        o.setClobString(new String(chars));
+        pm.persist(o);
+        Object oid = pm.getObjectId(o);
+        endTx(pm);
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        o = (LocatorTestObject) pm.getObjectId(oid);
+        char[] newchars = o.getClobString().toCharArray();
+
+        assertNotNull(newchars);
+        assertEquals(chars.length, newchars.length);
+        for (int i = 0; i < chars.length; i++) {
+            assertEquals(chars[i], newchars[i]);
+        }
+    }
+
+    public void testShrinkCLOB() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);
+        LocatorTestObject o = new LocatorTestObject();
+        char[] chars = new char[50000];
+        Arrays.fill(chars, (char) 'c');
+        o.setClobString(new String(chars));
+        pm.persist(o);
+        Object oid = pm.getObjectId(o);
+        endTx(pm);
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        o = (LocatorTestObject) pm.getObjectId(oid);
+
+        startTx(pm);
+        chars = new char[40000];
+        Arrays.fill(chars, (char) 'd');
+        o.setClobString(new String(chars));
+        endTx(pm);
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        o = (LocatorTestObject) pm.getObjectId(oid);
+        char[] newchars = o.getClobString().toCharArray();
+        assertEquals(chars.length, newchars.length);
+        for (int i = 0; i < chars.length; i++) {
+            assertEquals(chars[i], newchars[i]);
+        }
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMappedByKeyMaps.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMappedByKeyMaps.java
index eca0fb4..3acd04b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMappedByKeyMaps.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMappedByKeyMaps.java
@@ -1,268 +1,268 @@
-/*
- * TestMappedByKeyMaps.java
- *
- * Created on October 4, 2006, 9:26 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.RelationMapInverseKeyFieldStrategy;
-import org.apache.openjpa.jdbc.meta.strats.RelationMapTableFieldStrategy;
-import org.apache.openjpa.util.AbstractLRSProxyMap;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-
-public class TestMappedByKeyMaps extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-    
-    /** Creates a new instance of TestMappedByKeyMaps */
-    public TestMappedByKeyMaps(String name) 
-    {
-    	super(name);
-    }
-    
-    public void testInverseKeyMapMapping() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        ClassMapping pc = conf.getMappingRepositoryInstance().getMapping
-                (InverseKeyMapPC.class, null, true);
-        FieldMapping map = pc.getFieldMapping("helpers");
-        
-        ClassMapping helper = conf.getMappingRepositoryInstance().getMapping
-                (HelperPC.class, null, true);
-        FieldMapping str = helper.getFieldMapping("stringField");
-        
-        assertEquals("stringField", map.getKey().getValueMappedBy());
-        assertEquals(str, map.getKey().getValueMappedByMetaData());
-        assertTrue(map.getStrategy() instanceof
-                RelationMapInverseKeyFieldStrategy);
-        assertEquals(1, map.getKeyMapping().getColumns().length);
-        assertEquals(map.getKeyMapping().getColumns()[0],
-                str.getColumns()[0]);
-    }
-    
-    public void testJoinTableMapMapping() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        ClassMapping pc = conf.getMappingRepositoryInstance().getMapping
-                (JoinTableMapPC.class, null, true);
-        FieldMapping map = pc.getFieldMapping("helpers");
-        
-        ClassMapping helper = conf.getMappingRepositoryInstance().getMapping
-                (HelperPC.class, null, true);
-        FieldMapping str = helper.getFieldMapping("stringField");
-        
-        assertEquals("stringField", map.getKey().getValueMappedBy());
-        assertEquals(str, map.getKey().getValueMappedByMetaData());
-        assertTrue(map.getStrategy() instanceof RelationMapTableFieldStrategy);
-        assertEquals(1, map.getKeyMapping().getColumns().length);
-        assertEquals(map.getKeyMapping().getColumns()[0],
-                str.getColumns()[0]);
-    }
-    
-    public void testInverseKeyMap() {
-        mappedByMap(new InverseKeyMapPC(), false);
-        queryMap(new InverseKeyMapPC());
-    }
-    
-    public void testInverseKeyLRSMap() {
-        mappedByMap(new InverseKeyMapPC(), true);
-    }
-    
-    public void testJoinTableMap() {
-        mappedByMap(new JoinTableMapPC(), false);
-        queryMap(new JoinTableMapPC());
-    }
-    
-    public void testJoinTableLRSMap() {
-        mappedByMap(new JoinTableMapPC(), true);
-    }
-    
-    private void mappedByMap(MappedByMapPC pc, boolean lrs) {
-       deleteAll(HelperPC.class);
-       deleteAll(pc.getClass());
-        
-        HelperPC h1 = new HelperPC();
-        h1.setStringField("h1");
-        pc.getHelpers().put(h1.getStringField(), h1);
-        HelperPC h2 = new HelperPC();
-        h2.setStringField("h2");
-        pc.getHelpers().put(h2.getStringField(), h2);
-        HelperPC h3 = new HelperPC();
-        h3.setStringField("h3");
-        pc.getHelpers().put(h3.getStringField(), h3);
-        
-        setLRS(pc.getClass(), lrs);
-        try {
-            OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-            startTx(pm);;
-            pm.persist(pc);
-            endTx(pm);;
-            Object oid = pm.getObjectId(pc);
-            
-            assertFalse(pc.getHelpers().containsKey("foo"));
-            assertNull(pc.getHelpers().get("foo"));
-            assertEquals(3, pc.getHelpers().size());
-            assertEquals(h1, pc.getHelpers().get("h1"));
-            assertEquals(h2, pc.getHelpers().get("h2"));
-            pm.close();
-            
-            pm = (OpenJPAEntityManager)currentEntityManager();;
-            pc = (MappedByMapPC) pm.getObjectId(oid);
-            if (lrs)
-                assertTrue(pc.getHelpers() instanceof AbstractLRSProxyMap);
-            assertEquals(3, pc.getHelpers().size());
-            assertFalse(pc.getHelpers().containsKey("foo"));
-            assertNull(pc.getHelpers().get("foo"));
-            assertEquals("h1", ((HelperPC) pc.getHelpers().get("h1")).
-                    getStringField());
-            assertEquals("h2", ((HelperPC) pc.getHelpers().get("h2")).
-                    getStringField());
-            
-            pm.begin();
-            pc.getHelpers().remove("h1");
-            assertEquals(2, pc.getHelpers().size());
-            assertFalse(pc.getHelpers().containsKey("h1"));
-            assertNull(pc.getHelpers().get("h1"));
-            HelperPC h4 = new HelperPC();
-            h4.setStringField("h4");
-            pc.getHelpers().put("h4", h4);
-            assertTrue(pc.getHelpers().containsKey("h4"));
-            assertEquals(h4, pc.getHelpers().get("h4"));
-            assertEquals(3, pc.getHelpers().size());
-            pm.commit();
-            assertEquals(3, pc.getHelpers().size());
-            assertFalse(pc.getHelpers().containsKey("h1"));
-            assertNull(pc.getHelpers().get("h1"));
-            assertEquals("h2", ((HelperPC) pc.getHelpers().get("h2")).
-                    getStringField());
-            assertEquals("h4", ((HelperPC) pc.getHelpers().get("h4")).
-                    getStringField());
-            pm.close();
-            
-            pm = (OpenJPAEntityManager)currentEntityManager();;
-            pc = (MappedByMapPC) pm.getObjectId(oid);
-            assertEquals(3, pc.getHelpers().size());
-            assertFalse(pc.getHelpers().containsKey("h1"));
-            assertNull(pc.getHelpers().get("h1"));
-            assertEquals("h2", ((HelperPC) pc.getHelpers().get("h2")).
-                    getStringField());
-            assertEquals("h4", ((HelperPC) pc.getHelpers().get("h4")).
-                    getStringField());
-            
-            // to test lrs functions
-            assertTrue(pc.getHelpers().containsValue
-                    (pc.getHelpers().get("h2")));
-            
-            Set keySet = pc.getHelpers().keySet();
-            Set ordered = new TreeSet();
-            assertEquals(3, keySet.size());
-            Iterator itr = keySet.iterator();
-            while (itr.hasNext())
-                ordered.add(itr.next());
-            //FIXME jthomas
-            //KodoJDOHelper.close(itr);
-            assertEquals(3, ordered.size());
-            assertTrue(ordered.contains("h2"));
-            assertTrue(ordered.contains("h3"));
-            assertTrue(ordered.contains("h4"));
-            ordered.clear();
-            
-            Collection values = pc.getHelpers().values();
-            assertEquals(3, values.size());
-            itr = values.iterator();
-            while (itr.hasNext()) {
-                Object next = itr.next();
-                assertTrue(next instanceof HelperPC);
-                ordered.add(((HelperPC) next).getStringField());
-            }
-            //FIXME jthomas
-            //KodoJDOHelper.close(itr);
-            assertEquals(3, ordered.size());
-            assertTrue(ordered.contains("h2"));
-            assertTrue(ordered.contains("h3"));
-            assertTrue(ordered.contains("h4"));
-            pm.close();
-        } finally {
-            unsetLRS(pc.getClass());
-        }
-    }
-    
-    private void queryMap(MappedByMapPC pc) {
-        HelperPC h5 = new HelperPC();
-        h5.setStringField("h5");
-        pc.getHelpers().put("h5", h5);
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.begin();
-        pm.persist(pc);
-        pm.commit();
-        pm.close();
-        
-        pm = (OpenJPAEntityManager)currentEntityManager();;
-        OpenJPAQuery q = pm.createNativeQuery("stringField == 'h2'",HelperPC.class);
-        //FIXME jthomas
-        //q.setUnique(true);
-        HelperPC h2 = (HelperPC) q.getSingleResult();
-        
-        q = pm.createNativeQuery("helpers.containsKey ('h2')",pc.getClass());
-        //FIXME jthomas
-        //q.setUnique(true);
-        pc = (MappedByMapPC) q.getSingleResult();
-        assertEquals(3, pc.getHelpers().size());
-        assertEquals(h2, pc.getHelpers().get("h2"));
-        
-        q = pm.createNativeQuery("helpers.containsValue (:h2)",pc.getClass());
-        //FIXME  jthomas
-        //q.setUnique(true);
-        pc = (MappedByMapPC) q.getSingleResult();
-        assertEquals(3, pc.getHelpers().size());
-        assertEquals(h2, pc.getHelpers().get("h2"));
-        pm.close();
-    }
-    
-    private void setLRS(Class cls, boolean lrs) {
-        ClassMapping cm = ((JDBCConfiguration) getConfiguration()).
-                getMappingRepositoryInstance().getMapping(cls, null, true);
-        cm.getFieldMapping("helpers").setLRS(lrs);
-    }
-    
-    private void unsetLRS(Class cls) {
-        ClassMapping cm = ((JDBCConfiguration) getConfiguration()).
-                getMappingRepositoryInstance().getMapping(cls, null, true);
-        cm.getFieldMapping("helpers").setLRS(false);
-    }
-    
-}
+/*
+ * TestMappedByKeyMaps.java
+ *
+ * Created on October 4, 2006, 9:26 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.RelationMapInverseKeyFieldStrategy;
+import org.apache.openjpa.jdbc.meta.strats.RelationMapTableFieldStrategy;
+import org.apache.openjpa.util.AbstractLRSProxyMap;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+
+public class TestMappedByKeyMaps extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+    
+    /** Creates a new instance of TestMappedByKeyMaps */
+    public TestMappedByKeyMaps(String name) 
+    {
+    	super(name);
+    }
+    
+    public void testInverseKeyMapMapping() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        ClassMapping pc = conf.getMappingRepositoryInstance().getMapping
+                (InverseKeyMapPC.class, null, true);
+        FieldMapping map = pc.getFieldMapping("helpers");
+        
+        ClassMapping helper = conf.getMappingRepositoryInstance().getMapping
+                (HelperPC.class, null, true);
+        FieldMapping str = helper.getFieldMapping("stringField");
+        
+        assertEquals("stringField", map.getKey().getValueMappedBy());
+        assertEquals(str, map.getKey().getValueMappedByMetaData());
+        assertTrue(map.getStrategy() instanceof
+                RelationMapInverseKeyFieldStrategy);
+        assertEquals(1, map.getKeyMapping().getColumns().length);
+        assertEquals(map.getKeyMapping().getColumns()[0],
+                str.getColumns()[0]);
+    }
+    
+    public void testJoinTableMapMapping() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        ClassMapping pc = conf.getMappingRepositoryInstance().getMapping
+                (JoinTableMapPC.class, null, true);
+        FieldMapping map = pc.getFieldMapping("helpers");
+        
+        ClassMapping helper = conf.getMappingRepositoryInstance().getMapping
+                (HelperPC.class, null, true);
+        FieldMapping str = helper.getFieldMapping("stringField");
+        
+        assertEquals("stringField", map.getKey().getValueMappedBy());
+        assertEquals(str, map.getKey().getValueMappedByMetaData());
+        assertTrue(map.getStrategy() instanceof RelationMapTableFieldStrategy);
+        assertEquals(1, map.getKeyMapping().getColumns().length);
+        assertEquals(map.getKeyMapping().getColumns()[0],
+                str.getColumns()[0]);
+    }
+    
+    public void testInverseKeyMap() {
+        mappedByMap(new InverseKeyMapPC(), false);
+        queryMap(new InverseKeyMapPC());
+    }
+    
+    public void testInverseKeyLRSMap() {
+        mappedByMap(new InverseKeyMapPC(), true);
+    }
+    
+    public void testJoinTableMap() {
+        mappedByMap(new JoinTableMapPC(), false);
+        queryMap(new JoinTableMapPC());
+    }
+    
+    public void testJoinTableLRSMap() {
+        mappedByMap(new JoinTableMapPC(), true);
+    }
+    
+    private void mappedByMap(MappedByMapPC pc, boolean lrs) {
+       deleteAll(HelperPC.class);
+       deleteAll(pc.getClass());
+        
+        HelperPC h1 = new HelperPC();
+        h1.setStringField("h1");
+        pc.getHelpers().put(h1.getStringField(), h1);
+        HelperPC h2 = new HelperPC();
+        h2.setStringField("h2");
+        pc.getHelpers().put(h2.getStringField(), h2);
+        HelperPC h3 = new HelperPC();
+        h3.setStringField("h3");
+        pc.getHelpers().put(h3.getStringField(), h3);
+        
+        setLRS(pc.getClass(), lrs);
+        try {
+            OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+            startTx(pm);;
+            pm.persist(pc);
+            endTx(pm);;
+            Object oid = pm.getObjectId(pc);
+            
+            assertFalse(pc.getHelpers().containsKey("foo"));
+            assertNull(pc.getHelpers().get("foo"));
+            assertEquals(3, pc.getHelpers().size());
+            assertEquals(h1, pc.getHelpers().get("h1"));
+            assertEquals(h2, pc.getHelpers().get("h2"));
+            pm.close();
+            
+            pm = (OpenJPAEntityManager)currentEntityManager();;
+            pc = (MappedByMapPC) pm.getObjectId(oid);
+            if (lrs)
+                assertTrue(pc.getHelpers() instanceof AbstractLRSProxyMap);
+            assertEquals(3, pc.getHelpers().size());
+            assertFalse(pc.getHelpers().containsKey("foo"));
+            assertNull(pc.getHelpers().get("foo"));
+            assertEquals("h1", ((HelperPC) pc.getHelpers().get("h1")).
+                    getStringField());
+            assertEquals("h2", ((HelperPC) pc.getHelpers().get("h2")).
+                    getStringField());
+            
+            pm.begin();
+            pc.getHelpers().remove("h1");
+            assertEquals(2, pc.getHelpers().size());
+            assertFalse(pc.getHelpers().containsKey("h1"));
+            assertNull(pc.getHelpers().get("h1"));
+            HelperPC h4 = new HelperPC();
+            h4.setStringField("h4");
+            pc.getHelpers().put("h4", h4);
+            assertTrue(pc.getHelpers().containsKey("h4"));
+            assertEquals(h4, pc.getHelpers().get("h4"));
+            assertEquals(3, pc.getHelpers().size());
+            pm.commit();
+            assertEquals(3, pc.getHelpers().size());
+            assertFalse(pc.getHelpers().containsKey("h1"));
+            assertNull(pc.getHelpers().get("h1"));
+            assertEquals("h2", ((HelperPC) pc.getHelpers().get("h2")).
+                    getStringField());
+            assertEquals("h4", ((HelperPC) pc.getHelpers().get("h4")).
+                    getStringField());
+            pm.close();
+            
+            pm = (OpenJPAEntityManager)currentEntityManager();;
+            pc = (MappedByMapPC) pm.getObjectId(oid);
+            assertEquals(3, pc.getHelpers().size());
+            assertFalse(pc.getHelpers().containsKey("h1"));
+            assertNull(pc.getHelpers().get("h1"));
+            assertEquals("h2", ((HelperPC) pc.getHelpers().get("h2")).
+                    getStringField());
+            assertEquals("h4", ((HelperPC) pc.getHelpers().get("h4")).
+                    getStringField());
+            
+            // to test lrs functions
+            assertTrue(pc.getHelpers().containsValue
+                    (pc.getHelpers().get("h2")));
+            
+            Set keySet = pc.getHelpers().keySet();
+            Set ordered = new TreeSet();
+            assertEquals(3, keySet.size());
+            Iterator itr = keySet.iterator();
+            while (itr.hasNext())
+                ordered.add(itr.next());
+            //FIXME jthomas
+            //KodoJDOHelper.close(itr);
+            assertEquals(3, ordered.size());
+            assertTrue(ordered.contains("h2"));
+            assertTrue(ordered.contains("h3"));
+            assertTrue(ordered.contains("h4"));
+            ordered.clear();
+            
+            Collection values = pc.getHelpers().values();
+            assertEquals(3, values.size());
+            itr = values.iterator();
+            while (itr.hasNext()) {
+                Object next = itr.next();
+                assertTrue(next instanceof HelperPC);
+                ordered.add(((HelperPC) next).getStringField());
+            }
+            //FIXME jthomas
+            //KodoJDOHelper.close(itr);
+            assertEquals(3, ordered.size());
+            assertTrue(ordered.contains("h2"));
+            assertTrue(ordered.contains("h3"));
+            assertTrue(ordered.contains("h4"));
+            pm.close();
+        } finally {
+            unsetLRS(pc.getClass());
+        }
+    }
+    
+    private void queryMap(MappedByMapPC pc) {
+        HelperPC h5 = new HelperPC();
+        h5.setStringField("h5");
+        pc.getHelpers().put("h5", h5);
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.begin();
+        pm.persist(pc);
+        pm.commit();
+        pm.close();
+        
+        pm = (OpenJPAEntityManager)currentEntityManager();;
+        OpenJPAQuery q = pm.createNativeQuery("stringField == 'h2'",HelperPC.class);
+        //FIXME jthomas
+        //q.setUnique(true);
+        HelperPC h2 = (HelperPC) q.getSingleResult();
+        
+        q = pm.createNativeQuery("helpers.containsKey ('h2')",pc.getClass());
+        //FIXME jthomas
+        //q.setUnique(true);
+        pc = (MappedByMapPC) q.getSingleResult();
+        assertEquals(3, pc.getHelpers().size());
+        assertEquals(h2, pc.getHelpers().get("h2"));
+        
+        q = pm.createNativeQuery("helpers.containsValue (:h2)",pc.getClass());
+        //FIXME  jthomas
+        //q.setUnique(true);
+        pc = (MappedByMapPC) q.getSingleResult();
+        assertEquals(3, pc.getHelpers().size());
+        assertEquals(h2, pc.getHelpers().get("h2"));
+        pm.close();
+    }
+    
+    private void setLRS(Class cls, boolean lrs) {
+        ClassMapping cm = ((JDBCConfiguration) getConfiguration()).
+                getMappingRepositoryInstance().getMapping(cls, null, true);
+        cm.getFieldMapping("helpers").setLRS(lrs);
+    }
+    
+    private void unsetLRS(Class cls) {
+        ClassMapping cm = ((JDBCConfiguration) getConfiguration()).
+                getMappingRepositoryInstance().getMapping(cls, null, true);
+        cm.getFieldMapping("helpers").setLRS(false);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMetaDataValueIndicator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMetaDataValueIndicator.java
index a1b7db1..987d44b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMetaDataValueIndicator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMetaDataValueIndicator.java
@@ -1,141 +1,141 @@
-/*
- * TestMetaDataValueIndicator.java
- *
- * Created on October 4, 2006, 1:35 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
-import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
-import org.apache.openjpa.persistence.Extent;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.*;
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-
-public class TestMetaDataValueIndicator extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{    
-    private OpenJPAEntityManager pm;
-    
-    private ClassMapping eMapping;
-    private ClassMapping fMapping;
-    
-    public TestMetaDataValueIndicator(String str) {
-        super(str);
-    }
-    
-    /** Creates a new instance of TestMetaDataValueIndicator */
-    public TestMetaDataValueIndicator() {
-    }
-    
-    public void setUp() {
-        // ### I hate that we have to do this
-        Class c = MultiE.class;
-        c = MultiF.class;
-        
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        
-        eMapping = (ClassMapping) ((OpenJPAEntityManagerSPI) pm).getConfiguration().
-                getMetaDataRepositoryInstance().getMetaData(MultiE.class,
-                pm.getClassLoader(), true);
-        fMapping = (ClassMapping) ((OpenJPAEntityManagerSPI) pm).getConfiguration().
-                getMetaDataRepositoryInstance().getMetaData(MultiF.class,
-                pm.getClassLoader(), true);
-    }
-    
-    public void tearDown()
-    throws Exception {
-        if (pm.getTransaction().isActive())
-            pm.getTransaction().rollback();
-        pm.close();
-        super.tearDown();
-    }
-    
-    public void testMetaData() {
-        assertEquals(ValueMapDiscriminatorStrategy.class,
-                eMapping.getDiscriminator().getStrategy().getClass());
-        assertEquals(SuperclassDiscriminatorStrategy.class,
-                fMapping.getDiscriminator().getStrategy().getClass());
-    }
-    
-    public void testOperations() {
-       deleteAll(MultiE.class);
-        
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-        
-        MultiE e = new MultiE();
-        e.setString0("foo");
-        pm.persist(e);
-        
-        MultiF f = new MultiF();
-        f.setString0("bar");
-        pm.persist(f);
-        
-        pm.getTransaction().commit();
-        
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        //FIXME jthomas
-        /* Cant find equivalent of getExtent()
-        assertEquals(2, countExtent(pm.getExtent(MultiE.class, true)));
-        assertEquals(1, countExtent(pm.getExtent(MultiE.class, false)));
-        assertEquals(1, countExtent(pm.getExtent(MultiF.class, true)));
-        assertEquals(1, countExtent(pm.getExtent(MultiF.class, false)));
-         
-        Object oid = pm.getObjectId
-            (pm.getExtent(MultiE.class, true).iterator().next());
-         */
-        //FIXME remove the next line once the above block is fixed
-        Object oid =null;
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        assertNotNull(pm.getObjectId(oid));
-        pm.close();
-        
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        assertNotNull(pm.getObjectId(oid));
-    }
-    
-    private int countExtent(Extent e) {
-        int count = 0;
-        for (Iterator iter = e.iterator(); iter.hasNext();) {
-            iter.next();
-            count++;
-        }
-        return count;
-    }
-    
-    
-}
+/*
+ * TestMetaDataValueIndicator.java
+ *
+ * Created on October 4, 2006, 1:35 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
+import org.apache.openjpa.persistence.Extent;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.*;
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+
+public class TestMetaDataValueIndicator extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{    
+    private OpenJPAEntityManager pm;
+    
+    private ClassMapping eMapping;
+    private ClassMapping fMapping;
+    
+    public TestMetaDataValueIndicator(String str) {
+        super(str);
+    }
+    
+    /** Creates a new instance of TestMetaDataValueIndicator */
+    public TestMetaDataValueIndicator() {
+    }
+    
+    public void setUp() {
+        // ### I hate that we have to do this
+        Class c = MultiE.class;
+        c = MultiF.class;
+        
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        
+        eMapping = (ClassMapping) ((OpenJPAEntityManagerSPI) pm).getConfiguration().
+                getMetaDataRepositoryInstance().getMetaData(MultiE.class,
+                pm.getClassLoader(), true);
+        fMapping = (ClassMapping) ((OpenJPAEntityManagerSPI) pm).getConfiguration().
+                getMetaDataRepositoryInstance().getMetaData(MultiF.class,
+                pm.getClassLoader(), true);
+    }
+    
+    public void tearDown()
+    throws Exception {
+        if (pm.getTransaction().isActive())
+            pm.getTransaction().rollback();
+        pm.close();
+        super.tearDown();
+    }
+    
+    public void testMetaData() {
+        assertEquals(ValueMapDiscriminatorStrategy.class,
+                eMapping.getDiscriminator().getStrategy().getClass());
+        assertEquals(SuperclassDiscriminatorStrategy.class,
+                fMapping.getDiscriminator().getStrategy().getClass());
+    }
+    
+    public void testOperations() {
+       deleteAll(MultiE.class);
+        
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+        
+        MultiE e = new MultiE();
+        e.setString0("foo");
+        pm.persist(e);
+        
+        MultiF f = new MultiF();
+        f.setString0("bar");
+        pm.persist(f);
+        
+        pm.getTransaction().commit();
+        
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        //FIXME jthomas
+        /* Cant find equivalent of getExtent()
+        assertEquals(2, countExtent(pm.getExtent(MultiE.class, true)));
+        assertEquals(1, countExtent(pm.getExtent(MultiE.class, false)));
+        assertEquals(1, countExtent(pm.getExtent(MultiF.class, true)));
+        assertEquals(1, countExtent(pm.getExtent(MultiF.class, false)));
+         
+        Object oid = pm.getObjectId
+            (pm.getExtent(MultiE.class, true).iterator().next());
+         */
+        //FIXME remove the next line once the above block is fixed
+        Object oid =null;
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        assertNotNull(pm.getObjectId(oid));
+        pm.close();
+        
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        assertNotNull(pm.getObjectId(oid));
+    }
+    
+    private int countExtent(Extent e) {
+        int count = 0;
+        for (Iterator iter = e.iterator(); iter.hasNext();) {
+            iter.next();
+            count++;
+        }
+        return count;
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiDFG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiDFG.java
index 480533c..cb4557b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiDFG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiDFG.java
@@ -1,99 +1,99 @@
-/*
- * TestMultiDFG.java
- *
- * Created on October 4, 2006, 1:50 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import javax.persistence.EntityTransaction;
-import javax.transaction.Transaction;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.FieldMetaData;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestMultiDFG extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{    
-    private Object boid;
-    
-    public TestMultiDFG(String name) {
-        super(name);
-    }
-    
-    
-    /** Creates a new instance of TestMultiDFG */
-    public TestMultiDFG() {
-    }
-    
-    public void setUp() {
-        
-       deleteAll(MultiB.class);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        EntityTransaction t = pm.getTransaction();
-        t.begin();
-        MultiB b = new MultiB();
-        pm.persist(b);
-        t.commit();
-        boid = pm.getObjectId(b);
-        pm.close();
-    }
-    
-    public void testDFG() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        MultiB b = (MultiB) pm.getObjectId(boid);
-        
-        // check the non-dfg fields
-        OpenJPAStateManager sm = getStateManager(b, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("bString");
-        assertTrue("bString should not be loaded",
-                !sm.getLoaded().get(fmd.getIndex()));
-        
-        fmd = sm.getMetaData().getField("bInt");
-        assertTrue("bInt should not be loaded",
-                !sm.getLoaded().get(fmd.getIndex()));
-        
-        System.out.println("### getting values");
-        b.getBString();
-        
-        System.out.println("### getting values again");
-        b.getString0();
-        b.getBString();
-        
-        pm.close();
-    }
-    
-    
-}
+/*
+ * TestMultiDFG.java
+ *
+ * Created on October 4, 2006, 1:50 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import javax.persistence.EntityTransaction;
+import javax.transaction.Transaction;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.FieldMetaData;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestMultiDFG extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{    
+    private Object boid;
+    
+    public TestMultiDFG(String name) {
+        super(name);
+    }
+    
+    
+    /** Creates a new instance of TestMultiDFG */
+    public TestMultiDFG() {
+    }
+    
+    public void setUp() {
+        
+       deleteAll(MultiB.class);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        EntityTransaction t = pm.getTransaction();
+        t.begin();
+        MultiB b = new MultiB();
+        pm.persist(b);
+        t.commit();
+        boid = pm.getObjectId(b);
+        pm.close();
+    }
+    
+    public void testDFG() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        MultiB b = (MultiB) pm.getObjectId(boid);
+        
+        // check the non-dfg fields
+        OpenJPAStateManager sm = getStateManager(b, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("bString");
+        assertTrue("bString should not be loaded",
+                !sm.getLoaded().get(fmd.getIndex()));
+        
+        fmd = sm.getMetaData().getField("bInt");
+        assertTrue("bInt should not be loaded",
+                !sm.getLoaded().get(fmd.getIndex()));
+        
+        System.out.println("### getting values");
+        b.getBString();
+        
+        System.out.println("### getting values again");
+        b.getString0();
+        b.getBString();
+        
+        pm.close();
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableMappings.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableMappings.java
index 11b30d4..8b3980d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableMappings.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableMappings.java
@@ -1,237 +1,237 @@
-/*
- * TestMultiTableMappings.java
- *
- * Created on October 4, 2006, 4:09 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import javax.persistence.EntityTransaction;
-import javax.transaction.Transaction;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestMultiTableMappings extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase {
-    
-
-    private Object aoid;
-    private Object boid;
-    private Object coid;
-    private Object doid;
-    
-    public TestMultiTableMappings(String name) {
-        super(name);
-    }
-    
-    /** Creates a new instance of TestMultiTableMappings */
-    public TestMultiTableMappings() {
-    }
-    
-    public void setUpTestCase() {
-       deleteAll(MultiA.class);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Collection os = new ArrayList();
-        MultiA a = new MultiA();
-        MultiB b = new MultiB();
-        MultiC c = new MultiC();
-        MultiD d = new MultiD();
-        os.add(a);
-        os.add(b);
-        os.add(c);
-        os.add(d);
-        d.setA(new MultiA());
-        os.add(new MultiD());
-        d.setDString1("d string 1");
-        
-        EntityTransaction t = pm.getTransaction();
-        t.begin();
-        pm.persistAll(os);
-        t.commit();
-        aoid = pm.getObjectId(a);
-        boid = pm.getObjectId(b);
-        coid = pm.getObjectId(c);
-        doid = pm.getObjectId(d);
-        pm.close();
-    }
-    
-    public void XXXtestUpdates() {
-        //TEST DISABLED ... not converted
-        /*
-        PersistenceManager pm = getPM();
-        Transaction t = pm.currentTransaction();
-        try {
-            for (int i = 0; i < 2; i++) {
-                t.begin();
-                changeA((MultiA) pm.getObjectById(aoid, i == 0));
-                changeB((MultiB) pm.getObjectById(boid, i == 0));
-                changeC((MultiC) pm.getObjectById(coid, i == 0));
-                changeD((MultiD) pm.getObjectById(doid, i == 0));
-                t.commit();
-            }
-        } finally {
-            if (t.isActive()) {
-                t.rollback();
-            }
-            pm.close();
-        }
-         */
-    }
-    
-    public void XXXtestInserts() {
-        //TEST DISABLED ... not converted
-        /*
-        PersistenceManager pm = getPM();
-        assertEquals(2,
-                ((Collection) pm.newQuery
-                (pm.getExtent(MultiA.class, false)).execute()).size());
-         
-        assertEquals(4,
-                ((Collection) pm.newQuery
-                (pm.getExtent(MultiB.class, true)).execute()).size());
-         
-        assertEquals(1,
-                ((Collection) pm.newQuery
-                (pm.getExtent(MultiB.class, false)).execute()).size());
-         
-        assertEquals(1,
-                ((Collection) pm.newQuery
-                (pm.getExtent(MultiC.class, false)).execute()).size());
-         
-        assertEquals(2,
-                ((Collection) pm.newQuery
-                (pm.getExtent(MultiD.class, false)).execute()).size());
-         
-        assertEquals(6,
-                ((Collection) pm.newQuery
-                (pm.getExtent(MultiA.class, true)).execute()).size());
-         
-        pm.close();
-         */
-    }
-    
-    public void XXXtestOneToOne() {
-        //TEST DISABLED ... not converted
-        /*
-        PersistenceManager pm = getPM();
-        MultiD d = (MultiD) pm.getObjectById(doid, true);
-        assertNotNull(d.getA());
-        pm.close();
-         */
-    }
-    
-    public void XXXtestQueries() {
-        //TEST DISABLED ... not converted
-        /*
-        PersistenceManager pm = getPM();
-        Query q = pm.newQuery(pm.getExtent(MultiD.class, false),
-                "dString1 == \"d string 1\"");
-        //### this behaves like '""': "d string 1");
-        Collection c = (Collection) q.execute();
-        assertEquals(1, c.size());
-        pm.close();
-         */
-    }
-    
-    // ### more tests:
-    // ### - horizontal with extent with subclass=false
-    // ### - aggregates with horizontal, interface, this stuff,
-    // ### - base A, vertical B extends A, virtual C extends B,
-    // ###   vertical D extends C, vertical E extends C, flat F extends C
-    
-    public void testVerticalQueryModeQueries() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createNativeQuery("",MultiA.class);
-        ((JDBCFetchPlan) q.getFetchPlan()).
-                setSubclassFetchMode(JDBCFetchPlan.EAGER_PARALLEL);
-        // we need ordering; otherwise kodo is smart enough to only run first
-        // select until its results are exhausted
-        
-        //FIXME jthomas
-        //q.setOrdering("string0 ascending");
-        sql.clear();
-        assertEquals(sql.toString(), 0, sql.size());
-        
-        Collection c = (Collection) q.getCandidateCollection();
-        
-        // account for the select distinct
-        if (((String) sql.get(0)).startsWith("SELECT DISTINCT"))
-            assertEquals(sql.toString(), 5, sql.size());
-        else
-            assertEquals(sql.toString(), 4, sql.size());
-        sql.clear();
-        
-        assertEquals(6, c.size());
-        
-        // only check for counts sql if any was executed (some databases
-        // might eagerly instantiate all the rows, such as pointbase)
-        if (sql.size() != 0)
-            assertEquals(sql.toString(), 4, sql.size()); // select counts
-        sql.clear();
-        
-        // walk through the results. This will cause individual
-        // objects to be loaded, and therefore the dfgs to be loaded,
-        // and therefore any additional SQL to be executed.
-        for (Iterator iter = c.iterator(); iter.hasNext();)
-            iter.next();
-        
-        assertEquals(sql.toString(), 0, sql.size());
-        
-        pm.close();
-    }
-    
-    private void changeA(MultiA a) {
-        a.setString0(a.getString0() + " changed");
-        a.setInt0(a.getInt0() + 1);
-    }
-    
-    private void changeB(MultiB b) {
-        changeA(b);
-        b.setBString(b.getBString() + " changed");
-    }
-    
-    private void changeC(MultiC c) {
-        changeB(c);
-        c.setCString0(c.getCString0() + " changed");
-    }
-    
-    private void changeD(MultiD d) {
-        changeB(d);
-        d.setDString0(d.getDString0() + " changed");
-    }
-    
-    
-}
+/*
+ * TestMultiTableMappings.java
+ *
+ * Created on October 4, 2006, 4:09 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import javax.persistence.EntityTransaction;
+import javax.transaction.Transaction;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestMultiTableMappings extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase {
+    
+
+    private Object aoid;
+    private Object boid;
+    private Object coid;
+    private Object doid;
+    
+    public TestMultiTableMappings(String name) {
+        super(name);
+    }
+    
+    /** Creates a new instance of TestMultiTableMappings */
+    public TestMultiTableMappings() {
+    }
+    
+    public void setUpTestCase() {
+       deleteAll(MultiA.class);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Collection os = new ArrayList();
+        MultiA a = new MultiA();
+        MultiB b = new MultiB();
+        MultiC c = new MultiC();
+        MultiD d = new MultiD();
+        os.add(a);
+        os.add(b);
+        os.add(c);
+        os.add(d);
+        d.setA(new MultiA());
+        os.add(new MultiD());
+        d.setDString1("d string 1");
+        
+        EntityTransaction t = pm.getTransaction();
+        t.begin();
+        pm.persistAll(os);
+        t.commit();
+        aoid = pm.getObjectId(a);
+        boid = pm.getObjectId(b);
+        coid = pm.getObjectId(c);
+        doid = pm.getObjectId(d);
+        pm.close();
+    }
+    
+    public void XXXtestUpdates() {
+        //TEST DISABLED ... not converted
+        /*
+        PersistenceManager pm = getPM();
+        Transaction t = pm.currentTransaction();
+        try {
+            for (int i = 0; i < 2; i++) {
+                t.begin();
+                changeA((MultiA) pm.getObjectById(aoid, i == 0));
+                changeB((MultiB) pm.getObjectById(boid, i == 0));
+                changeC((MultiC) pm.getObjectById(coid, i == 0));
+                changeD((MultiD) pm.getObjectById(doid, i == 0));
+                t.commit();
+            }
+        } finally {
+            if (t.isActive()) {
+                t.rollback();
+            }
+            pm.close();
+        }
+         */
+    }
+    
+    public void XXXtestInserts() {
+        //TEST DISABLED ... not converted
+        /*
+        PersistenceManager pm = getPM();
+        assertEquals(2,
+                ((Collection) pm.newQuery
+                (pm.getExtent(MultiA.class, false)).execute()).size());
+         
+        assertEquals(4,
+                ((Collection) pm.newQuery
+                (pm.getExtent(MultiB.class, true)).execute()).size());
+         
+        assertEquals(1,
+                ((Collection) pm.newQuery
+                (pm.getExtent(MultiB.class, false)).execute()).size());
+         
+        assertEquals(1,
+                ((Collection) pm.newQuery
+                (pm.getExtent(MultiC.class, false)).execute()).size());
+         
+        assertEquals(2,
+                ((Collection) pm.newQuery
+                (pm.getExtent(MultiD.class, false)).execute()).size());
+         
+        assertEquals(6,
+                ((Collection) pm.newQuery
+                (pm.getExtent(MultiA.class, true)).execute()).size());
+         
+        pm.close();
+         */
+    }
+    
+    public void XXXtestOneToOne() {
+        //TEST DISABLED ... not converted
+        /*
+        PersistenceManager pm = getPM();
+        MultiD d = (MultiD) pm.getObjectById(doid, true);
+        assertNotNull(d.getA());
+        pm.close();
+         */
+    }
+    
+    public void XXXtestQueries() {
+        //TEST DISABLED ... not converted
+        /*
+        PersistenceManager pm = getPM();
+        Query q = pm.newQuery(pm.getExtent(MultiD.class, false),
+                "dString1 == \"d string 1\"");
+        //### this behaves like '""': "d string 1");
+        Collection c = (Collection) q.execute();
+        assertEquals(1, c.size());
+        pm.close();
+         */
+    }
+    
+    // ### more tests:
+    // ### - horizontal with extent with subclass=false
+    // ### - aggregates with horizontal, interface, this stuff,
+    // ### - base A, vertical B extends A, virtual C extends B,
+    // ###   vertical D extends C, vertical E extends C, flat F extends C
+    
+    public void testVerticalQueryModeQueries() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createNativeQuery("",MultiA.class);
+        ((JDBCFetchPlan) q.getFetchPlan()).
+                setSubclassFetchMode(JDBCFetchPlan.EAGER_PARALLEL);
+        // we need ordering; otherwise kodo is smart enough to only run first
+        // select until its results are exhausted
+        
+        //FIXME jthomas
+        //q.setOrdering("string0 ascending");
+        sql.clear();
+        assertEquals(sql.toString(), 0, sql.size());
+        
+        Collection c = (Collection) q.getCandidateCollection();
+        
+        // account for the select distinct
+        if (((String) sql.get(0)).startsWith("SELECT DISTINCT"))
+            assertEquals(sql.toString(), 5, sql.size());
+        else
+            assertEquals(sql.toString(), 4, sql.size());
+        sql.clear();
+        
+        assertEquals(6, c.size());
+        
+        // only check for counts sql if any was executed (some databases
+        // might eagerly instantiate all the rows, such as pointbase)
+        if (sql.size() != 0)
+            assertEquals(sql.toString(), 4, sql.size()); // select counts
+        sql.clear();
+        
+        // walk through the results. This will cause individual
+        // objects to be loaded, and therefore the dfgs to be loaded,
+        // and therefore any additional SQL to be executed.
+        for (Iterator iter = c.iterator(); iter.hasNext();)
+            iter.next();
+        
+        assertEquals(sql.toString(), 0, sql.size());
+        
+        pm.close();
+    }
+    
+    private void changeA(MultiA a) {
+        a.setString0(a.getString0() + " changed");
+        a.setInt0(a.getInt0() + 1);
+    }
+    
+    private void changeB(MultiB b) {
+        changeA(b);
+        b.setBString(b.getBString() + " changed");
+    }
+    
+    private void changeC(MultiC c) {
+        changeB(c);
+        c.setCString0(c.getCString0() + " changed");
+    }
+    
+    private void changeD(MultiD d) {
+        changeB(d);
+        d.setDString0(d.getDString0() + " changed");
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableSelfCollection.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableSelfCollection.java
index 428f9f7..5750afd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableSelfCollection.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestMultiTableSelfCollection.java
@@ -1,209 +1,209 @@
-/*
- * TestMultiTableSelfCollection.java
- *
- * Created on October 4, 2006, 2:35 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestMultiTableSelfCollection extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{    
-    private Object a1oid;
-    private Object a2oid;
-    private Object a3oid;
-    private Object a4oid;
-    
-    private Object c1oid;
-    private Object c2oid;
-    private Object c3oid;
-    private Object c4oid;
-    
-    public TestMultiTableSelfCollection(String name) {
-        super(name);
-    }
-    
-    /** Creates a new instance of TestMultiTableSelfCollection */
-    public TestMultiTableSelfCollection() {
-    }
-    
-    public void setUp() {
-       deleteAll(MultiA.class);
-        
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-        
-        Collection os = new ArrayList();
-        MultiA a1 = new MultiA();
-        MultiA a2 = new MultiA();
-        MultiA a3 = new MultiA();
-        MultiA a4 = new MultiA();
-        MultiC c1 = new MultiC();
-        MultiC c2 = new MultiC();
-        MultiC c3 = new MultiC();
-        MultiC c4 = new MultiC();
-        os.add(a1);
-        os.add(a2);
-        os.add(a3);
-        os.add(a4);
-        os.add(c1);
-        os.add(c2);
-        os.add(c3);
-        os.add(c4);
-        
-        c1.getMultiAs().add(a1);
-        c1.getMultiAs().add(a2);
-        a1.getMultiCs().add(c1);
-        a2.getMultiCs().add(c1);
-        
-        c2.getMultiAs().add(a1);
-        c2.getMultiAs().add(a2);
-        a1.getMultiCs().add(c2);
-        a2.getMultiCs().add(c2);
-        
-        c3.getMultiAs().add(a3);
-        c3.getMultiAs().add(a4);
-        a3.getMultiCs().add(c3);
-        a4.getMultiCs().add(c3);
-        
-        c4.getMultiAs().add(a3);
-        c4.getMultiAs().add(a4);
-        a3.getMultiCs().add(c4);
-        a4.getMultiCs().add(c4);
-        
-        pm.persistAll(os);
-        pm.getTransaction().commit();
-        
-        a1oid = pm.getObjectId(a1);
-        a2oid = pm.getObjectId(a2);
-        a3oid = pm.getObjectId(a3);
-        a4oid = pm.getObjectId(a4);
-        
-        c1oid = pm.getObjectId(c1);
-        c2oid = pm.getObjectId(c2);
-        c3oid = pm.getObjectId(c3);
-        c4oid = pm.getObjectId(c4);
-        
-        pm.close();
-    }
-    
-    public void testSelfCollections() {
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
-        
-        // check that all the sets are the right size, and equal where
-        // they should be.
-        
-        MultiA a1 = (MultiA) pm.getObjectId(a1oid);
-        assertEquals(2, a1.getMultiCs().size());
-        
-        MultiA a2 = (MultiA) pm.getObjectId(a2oid);
-        assertEquals(2, a2.getMultiCs().size());
-        
-        assertEquals(a1.getMultiCs(), a2.getMultiCs());
-        
-        MultiA a3 = (MultiA) pm.getObjectId(a3oid);
-        assertEquals(2, a3.getMultiCs().size());
-        
-        MultiA a4 = (MultiA) pm.getObjectId(a4oid);
-        assertEquals(2, a4.getMultiCs().size());
-        
-        assertEquals(a3.getMultiCs(), a4.getMultiCs());
-        
-        MultiC c1 = (MultiC) pm.getObjectId(c1oid);
-        assertEquals(2, c1.getMultiAs().size());
-        
-        MultiC c2 = (MultiC) pm.getObjectId(c2oid);
-        assertEquals(2, c2.getMultiAs().size());
-        
-        assertEquals(c1.getMultiAs(), c2.getMultiAs());
-        
-        MultiC c3 = (MultiC) pm.getObjectId(c3oid);
-        assertEquals(2, c3.getMultiAs().size());
-        
-        MultiC c4 = (MultiC) pm.getObjectId(c4oid);
-        assertEquals(2, c4.getMultiAs().size());
-        
-        assertEquals(c3.getMultiAs(), c4.getMultiAs());
-        
-        // check that all the sets contain the correct values, and
-        // don't contain the wrong values. Probably don't need to do
-        // the above check as well.
-        
-        assertTrue(a1.getMultiCs().contains(c1));
-        assertTrue(a1.getMultiCs().contains(c2));
-        assertTrue(!a1.getMultiCs().contains(c3));
-        assertTrue(!a1.getMultiCs().contains(c4));
-        
-        assertTrue(a2.getMultiCs().contains(c1));
-        assertTrue(a2.getMultiCs().contains(c2));
-        assertTrue(!a2.getMultiCs().contains(c3));
-        assertTrue(!a2.getMultiCs().contains(c4));
-        
-        assertTrue(!a3.getMultiCs().contains(c1));
-        assertTrue(!a3.getMultiCs().contains(c2));
-        assertTrue(a3.getMultiCs().contains(c3));
-        assertTrue(a3.getMultiCs().contains(c4));
-        
-        assertTrue(!a4.getMultiCs().contains(c1));
-        assertTrue(!a4.getMultiCs().contains(c2));
-        assertTrue(a4.getMultiCs().contains(c3));
-        assertTrue(a4.getMultiCs().contains(c4));
-        
-        assertTrue(c1.getMultiAs().contains(a1));
-        assertTrue(c1.getMultiAs().contains(a2));
-        assertTrue(!c1.getMultiAs().contains(a3));
-        assertTrue(!c1.getMultiAs().contains(a4));
-        
-        assertTrue(c2.getMultiAs().contains(a1));
-        assertTrue(c2.getMultiAs().contains(a2));
-        assertTrue(!c2.getMultiAs().contains(a3));
-        assertTrue(!c2.getMultiAs().contains(a4));
-        
-        assertTrue(!c3.getMultiAs().contains(a1));
-        assertTrue(!c3.getMultiAs().contains(a2));
-        assertTrue(c3.getMultiAs().contains(a3));
-        assertTrue(c3.getMultiAs().contains(a4));
-        
-        assertTrue(!c4.getMultiAs().contains(a1));
-        assertTrue(!c4.getMultiAs().contains(a2));
-        assertTrue(c4.getMultiAs().contains(a3));
-        assertTrue(c4.getMultiAs().contains(a4));
-        
-        pm.close();
-    }
-    
-    
-}
+/*
+ * TestMultiTableSelfCollection.java
+ *
+ * Created on October 4, 2006, 2:35 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestMultiTableSelfCollection extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{    
+    private Object a1oid;
+    private Object a2oid;
+    private Object a3oid;
+    private Object a4oid;
+    
+    private Object c1oid;
+    private Object c2oid;
+    private Object c3oid;
+    private Object c4oid;
+    
+    public TestMultiTableSelfCollection(String name) {
+        super(name);
+    }
+    
+    /** Creates a new instance of TestMultiTableSelfCollection */
+    public TestMultiTableSelfCollection() {
+    }
+    
+    public void setUp() {
+       deleteAll(MultiA.class);
+        
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+        
+        Collection os = new ArrayList();
+        MultiA a1 = new MultiA();
+        MultiA a2 = new MultiA();
+        MultiA a3 = new MultiA();
+        MultiA a4 = new MultiA();
+        MultiC c1 = new MultiC();
+        MultiC c2 = new MultiC();
+        MultiC c3 = new MultiC();
+        MultiC c4 = new MultiC();
+        os.add(a1);
+        os.add(a2);
+        os.add(a3);
+        os.add(a4);
+        os.add(c1);
+        os.add(c2);
+        os.add(c3);
+        os.add(c4);
+        
+        c1.getMultiAs().add(a1);
+        c1.getMultiAs().add(a2);
+        a1.getMultiCs().add(c1);
+        a2.getMultiCs().add(c1);
+        
+        c2.getMultiAs().add(a1);
+        c2.getMultiAs().add(a2);
+        a1.getMultiCs().add(c2);
+        a2.getMultiCs().add(c2);
+        
+        c3.getMultiAs().add(a3);
+        c3.getMultiAs().add(a4);
+        a3.getMultiCs().add(c3);
+        a4.getMultiCs().add(c3);
+        
+        c4.getMultiAs().add(a3);
+        c4.getMultiAs().add(a4);
+        a3.getMultiCs().add(c4);
+        a4.getMultiCs().add(c4);
+        
+        pm.persistAll(os);
+        pm.getTransaction().commit();
+        
+        a1oid = pm.getObjectId(a1);
+        a2oid = pm.getObjectId(a2);
+        a3oid = pm.getObjectId(a3);
+        a4oid = pm.getObjectId(a4);
+        
+        c1oid = pm.getObjectId(c1);
+        c2oid = pm.getObjectId(c2);
+        c3oid = pm.getObjectId(c3);
+        c4oid = pm.getObjectId(c4);
+        
+        pm.close();
+    }
+    
+    public void testSelfCollections() {
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)currentEntityManager();
+        
+        // check that all the sets are the right size, and equal where
+        // they should be.
+        
+        MultiA a1 = (MultiA) pm.getObjectId(a1oid);
+        assertEquals(2, a1.getMultiCs().size());
+        
+        MultiA a2 = (MultiA) pm.getObjectId(a2oid);
+        assertEquals(2, a2.getMultiCs().size());
+        
+        assertEquals(a1.getMultiCs(), a2.getMultiCs());
+        
+        MultiA a3 = (MultiA) pm.getObjectId(a3oid);
+        assertEquals(2, a3.getMultiCs().size());
+        
+        MultiA a4 = (MultiA) pm.getObjectId(a4oid);
+        assertEquals(2, a4.getMultiCs().size());
+        
+        assertEquals(a3.getMultiCs(), a4.getMultiCs());
+        
+        MultiC c1 = (MultiC) pm.getObjectId(c1oid);
+        assertEquals(2, c1.getMultiAs().size());
+        
+        MultiC c2 = (MultiC) pm.getObjectId(c2oid);
+        assertEquals(2, c2.getMultiAs().size());
+        
+        assertEquals(c1.getMultiAs(), c2.getMultiAs());
+        
+        MultiC c3 = (MultiC) pm.getObjectId(c3oid);
+        assertEquals(2, c3.getMultiAs().size());
+        
+        MultiC c4 = (MultiC) pm.getObjectId(c4oid);
+        assertEquals(2, c4.getMultiAs().size());
+        
+        assertEquals(c3.getMultiAs(), c4.getMultiAs());
+        
+        // check that all the sets contain the correct values, and
+        // don't contain the wrong values. Probably don't need to do
+        // the above check as well.
+        
+        assertTrue(a1.getMultiCs().contains(c1));
+        assertTrue(a1.getMultiCs().contains(c2));
+        assertTrue(!a1.getMultiCs().contains(c3));
+        assertTrue(!a1.getMultiCs().contains(c4));
+        
+        assertTrue(a2.getMultiCs().contains(c1));
+        assertTrue(a2.getMultiCs().contains(c2));
+        assertTrue(!a2.getMultiCs().contains(c3));
+        assertTrue(!a2.getMultiCs().contains(c4));
+        
+        assertTrue(!a3.getMultiCs().contains(c1));
+        assertTrue(!a3.getMultiCs().contains(c2));
+        assertTrue(a3.getMultiCs().contains(c3));
+        assertTrue(a3.getMultiCs().contains(c4));
+        
+        assertTrue(!a4.getMultiCs().contains(c1));
+        assertTrue(!a4.getMultiCs().contains(c2));
+        assertTrue(a4.getMultiCs().contains(c3));
+        assertTrue(a4.getMultiCs().contains(c4));
+        
+        assertTrue(c1.getMultiAs().contains(a1));
+        assertTrue(c1.getMultiAs().contains(a2));
+        assertTrue(!c1.getMultiAs().contains(a3));
+        assertTrue(!c1.getMultiAs().contains(a4));
+        
+        assertTrue(c2.getMultiAs().contains(a1));
+        assertTrue(c2.getMultiAs().contains(a2));
+        assertTrue(!c2.getMultiAs().contains(a3));
+        assertTrue(!c2.getMultiAs().contains(a4));
+        
+        assertTrue(!c3.getMultiAs().contains(a1));
+        assertTrue(!c3.getMultiAs().contains(a2));
+        assertTrue(c3.getMultiAs().contains(a3));
+        assertTrue(c3.getMultiAs().contains(a4));
+        
+        assertTrue(!c4.getMultiAs().contains(a1));
+        assertTrue(!c4.getMultiAs().contains(a2));
+        assertTrue(c4.getMultiAs().contains(a3));
+        assertTrue(c4.getMultiAs().contains(a4));
+        
+        pm.close();
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestNoClassColumn.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestNoClassColumn.java
index 14b412d..d403233 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestNoClassColumn.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestNoClassColumn.java
@@ -1,68 +1,68 @@
-/*
- * TestNoClassColumn.java
- *
- * Created on October 4, 2006, 2:44 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestNoClassColumn extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-        
-    /** Creates a new instance of TestNoClassColumn */
-    public TestNoClassColumn() {
-    }
-
-    public TestNoClassColumn(String test) {
-        super(test);
-    }
-
-    public void testQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createNativeQuery("",NoClassColumn.class);
-        //FIXME jthomas
-        //q.declareParameters("java.lang.String input");
-        //q.setFilter("test==input");
-        Map params = new HashMap();
-        params.put("input", "blah");
-        //FIXME jthomas
-        //Collection c = (Collection) q.executeWithMap(params);
-        pm.close();
-    }    
-    
-}
+/*
+ * TestNoClassColumn.java
+ *
+ * Created on October 4, 2006, 2:44 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestNoClassColumn extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+        
+    /** Creates a new instance of TestNoClassColumn */
+    public TestNoClassColumn() {
+    }
+
+    public TestNoClassColumn(String test) {
+        super(test);
+    }
+
+    public void testQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createNativeQuery("",NoClassColumn.class);
+        //FIXME jthomas
+        //q.declareParameters("java.lang.String input");
+        //q.setFilter("test==input");
+        Map params = new HashMap();
+        params.put("input", "blah");
+        //FIXME jthomas
+        //Collection c = (Collection) q.executeWithMap(params);
+        pm.close();
+    }    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestRawField.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestRawField.java
index bfc6a7d..45e8316 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestRawField.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestRawField.java
@@ -1,75 +1,75 @@
-/*
- * TestRawField.java
- *
- * Created on October 4, 2006, 2:57 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestRawField extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    /** Creates a new instance of TestRawField */
-    public TestRawField(String name) 
-    {
-    	super(name);
-    }
-    
-    public void setUp() {
-       deleteAll(RawField.class);
-    }
-
-    public void testRaw() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-        RawField pc = new RawField();
-        pc.setString("BAR");
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-
-        // batching?
-        pc = new RawField();
-        pc.setString("GOO");
-        pm.persist(pc);
-        pm.getTransaction().commit();
-        pm.close();
-
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (RawField) pm.getObjectId(oid);
-        assertEquals(pc.getString(), "BARFOO", pc.getString());
-        pm.close();
-    }    
-}
+/*
+ * TestRawField.java
+ *
+ * Created on October 4, 2006, 2:57 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestRawField extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    /** Creates a new instance of TestRawField */
+    public TestRawField(String name) 
+    {
+    	super(name);
+    }
+    
+    public void setUp() {
+       deleteAll(RawField.class);
+    }
+
+    public void testRaw() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+        RawField pc = new RawField();
+        pc.setString("BAR");
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+
+        // batching?
+        pc = new RawField();
+        pc.setString("GOO");
+        pm.persist(pc);
+        pm.getTransaction().commit();
+        pm.close();
+
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (RawField) pm.getObjectId(oid);
+        assertEquals(pc.getString(), "BARFOO", pc.getString());
+        pm.close();
+    }    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestStateImage.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestStateImage.java
index 3e3a0e3..c00a0c9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestStateImage.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/TestStateImage.java
@@ -1,241 +1,241 @@
-/*
- * TestStateImage.java
- *
- * Created on October 4, 2006, 3:09 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta;
-
-import java.util.*;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestStateImage extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase {
-    private Object _oid = null;
-    
-    /** Creates a new instance of TestStateImage */
-    public TestStateImage() {
-    }
-    public TestStateImage(String test) {
-        super(test);
-    }
-    
-    
-    public void setUpTestCase() {
-       deleteAll(StateImagePC2.class);
-       deleteAll(StateImagePC3.class);
-        
-        StateImagePC2 pc = new StateImagePC2();
-        pc.setStringField("string1");
-        pc.setIntField(1);
-        StateImagePC2 pc2 = new StateImagePC2();
-        pc2.setStringField("string2");
-        pc2.setIntField(2);
-        pc.setStateImage(pc2);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-        pm.persist(pc);
-        _oid = pm.getObjectId(pc);
-        pm.getTransaction().commit();
-        pm.close();
-    }
-    
-    public void testOptLock() {
-        OpenJPAEntityManager pm1 = getEm(true, true);
-        OpenJPAEntityManager pm2 = getEm(true, true);
-        
-        pm1.getTransaction().begin();
-        pm2.getTransaction().begin();
-        StateImagePC2 pc1 = (StateImagePC2) pm1.getObjectId(_oid);
-        StateImagePC2 pc2 = (StateImagePC2) pm2.getObjectId(_oid);
-        
-        pc1.setIntField(3);
-        pc1.setStateImage(null);
-        
-        pc2.setIntField(4);
-        
-        pm1.getTransaction().commit();
-        try {
-            pm2.getTransaction().commit();
-            fail("Should have caused OL exception.");
-        } catch (Exception jfe) {
-            pm2.getTransaction().begin();
-            pm2.refresh(pc2);
-            pc2.setIntField(4);
-            pm2.getTransaction().commit();
-        }
-        
-        // make sure the next transaction works too
-        pm2.getTransaction().begin();
-        pc2.setIntField(5);
-        pm2.getTransaction().commit();
-        
-        pm1.getTransaction().begin();
-        pm1.refresh(pc1);
-        pc1.setIntField(6);
-        
-        pm2.getTransaction().begin();
-        pc2.setIntField(7);
-        
-        pm1.getTransaction().commit();
-        try {
-            pm2.getTransaction().commit();
-            fail("Should have caused OL exception.");
-        } catch (Exception jfe) {
-            pm2.getTransaction().begin();
-            pm2.refresh(pc2);
-            pc2.setIntField(7);
-            pm2.getTransaction().commit();
-        }
-        pm1.close();
-        pm2.close();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        StateImagePC2 pc = (StateImagePC2) pm.getObjectId(_oid);
-        assertNull(pc.getStateImage());
-        assertEquals(7, pc.getIntField());
-        pm.close();
-    }
-    
-    /**
-     * This currently isn't working: state-image locking will not
-     * detect when someone else updated the row before deleting.
-     */
-    public void NOTWORKINGtestOptLockWithDelete() {
-        OpenJPAEntityManager pm1 = getEm(true, true);
-        StateImagePC2 pc1 = (StateImagePC2) pm1.getObjectId(_oid);
-        
-        OpenJPAEntityManager pm2 = getEm(true, true);
-        StateImagePC2 pc2 = (StateImagePC2) pm2.getObjectId(_oid);
-        
-        pm1.getTransaction().begin();
-        pc1.setIntField(3);
-        
-        pm2.getTransaction().begin();
-        pm2.remove(pc2);
-        
-        pm1.getTransaction().commit();
-        try {
-            pm2.getTransaction().commit();
-            fail("Should have caused OL exception.");
-        } catch (Exception jfe) {
-            pm2.getTransaction().begin();
-            pm2.refresh(pc2);
-            pm2.remove(pc2);
-            pm2.getTransaction().commit();
-        }
-    }
-    
-    public void testOptLockOnVerticalClass() {
-        OpenJPAEntityManager pm1 = getEm(true, true);
-        OpenJPAEntityManager pm2 = getEm(true, true);
-        
-        // have to load via query or extent where we're selecting the vertical
-        // field in the initial SELECT
-        OpenJPAQuery q1 = pm1.createNativeQuery("",StateImagePC2.class);
-        //FIXME  jthomas
-        //q1.setOrdering("intField ascending");
-        StateImagePC2 pc1 = (StateImagePC2) ((Collection) q1.getCandidateCollection()).
-                iterator().next();
-        q1.closeAll();
-        
-        OpenJPAQuery q2 = pm2.createNativeQuery("",StateImagePC2.class);
-        //FIXME jthomas
-        //q2.setOrdering("intField ascending");
-        StateImagePC2 pc2 = (StateImagePC2) ((Collection) q2.getCandidateCollection()).
-                iterator().next();
-        q2.closeAll();
-        
-        pm1.getTransaction().begin();
-        pc1.setStringField("changed1");
-        pc1.setStateImage(null);
-        
-        pm2.getTransaction().begin();
-        pc2.setStringField("changed2");
-        
-        pm1.getTransaction().commit();
-        
-        try {
-            pm2.getTransaction().commit();
-            fail("Should have caused OL exception.");
-        } catch (Exception jfe) {
-            pm2.getTransaction().begin();
-            pm2.refresh(pc2);
-            pc2.setStringField("changed2");
-            pm2.getTransaction().commit();
-        }
-        pm1.close();
-        pm2.close();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        StateImagePC2 pc = (StateImagePC2) pm.getObjectId(_oid);
-        assertNull(pc.getStateImage());
-        assertEquals("changed2", pc.getStringField());
-        pm.close();
-    }
-    
-    public void testLockGroup()
-    throws Exception {
-        OpenJPAEntityManager pm = getEm(true, true);
-        pm.getTransaction().begin();
-        StateImagePC3 pc = new StateImagePC3();
-        pc.setLockField(4);
-        pc.setNoLockField(6);
-        pm.persist(pc);
-        pm.getTransaction().commit();
-        
-        pm.getTransaction().begin();
-        pc.setLockField(6);
-        sql.clear();
-        pm.getTransaction().commit();
-        assertNotSQL("* WHERE * NOLOCK*");
-        
-        pm.close();
-    }
-    
-    public static void main(String[] args) {
-        
-        //FIXME
-        //main(TestStateImage.class);
-    }
-    private OpenJPAEntityManager getEm(boolean optimistic,boolean retainValues){
-        OpenJPAEntityManager em = currentEntityManager();
-        em.setNontransactionalRead(true);
-        em.setRetainState(retainValues);
-        em.setOptimistic(optimistic);
-        return em;
-    }
-}
+/*
+ * TestStateImage.java
+ *
+ * Created on October 4, 2006, 3:09 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta;
+
+import java.util.*;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestStateImage extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase {
+    private Object _oid = null;
+    
+    /** Creates a new instance of TestStateImage */
+    public TestStateImage() {
+    }
+    public TestStateImage(String test) {
+        super(test);
+    }
+    
+    
+    public void setUpTestCase() {
+       deleteAll(StateImagePC2.class);
+       deleteAll(StateImagePC3.class);
+        
+        StateImagePC2 pc = new StateImagePC2();
+        pc.setStringField("string1");
+        pc.setIntField(1);
+        StateImagePC2 pc2 = new StateImagePC2();
+        pc2.setStringField("string2");
+        pc2.setIntField(2);
+        pc.setStateImage(pc2);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+        pm.persist(pc);
+        _oid = pm.getObjectId(pc);
+        pm.getTransaction().commit();
+        pm.close();
+    }
+    
+    public void testOptLock() {
+        OpenJPAEntityManager pm1 = getEm(true, true);
+        OpenJPAEntityManager pm2 = getEm(true, true);
+        
+        pm1.getTransaction().begin();
+        pm2.getTransaction().begin();
+        StateImagePC2 pc1 = (StateImagePC2) pm1.getObjectId(_oid);
+        StateImagePC2 pc2 = (StateImagePC2) pm2.getObjectId(_oid);
+        
+        pc1.setIntField(3);
+        pc1.setStateImage(null);
+        
+        pc2.setIntField(4);
+        
+        pm1.getTransaction().commit();
+        try {
+            pm2.getTransaction().commit();
+            fail("Should have caused OL exception.");
+        } catch (Exception jfe) {
+            pm2.getTransaction().begin();
+            pm2.refresh(pc2);
+            pc2.setIntField(4);
+            pm2.getTransaction().commit();
+        }
+        
+        // make sure the next transaction works too
+        pm2.getTransaction().begin();
+        pc2.setIntField(5);
+        pm2.getTransaction().commit();
+        
+        pm1.getTransaction().begin();
+        pm1.refresh(pc1);
+        pc1.setIntField(6);
+        
+        pm2.getTransaction().begin();
+        pc2.setIntField(7);
+        
+        pm1.getTransaction().commit();
+        try {
+            pm2.getTransaction().commit();
+            fail("Should have caused OL exception.");
+        } catch (Exception jfe) {
+            pm2.getTransaction().begin();
+            pm2.refresh(pc2);
+            pc2.setIntField(7);
+            pm2.getTransaction().commit();
+        }
+        pm1.close();
+        pm2.close();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        StateImagePC2 pc = (StateImagePC2) pm.getObjectId(_oid);
+        assertNull(pc.getStateImage());
+        assertEquals(7, pc.getIntField());
+        pm.close();
+    }
+    
+    /**
+     * This currently isn't working: state-image locking will not
+     * detect when someone else updated the row before deleting.
+     */
+    public void NOTWORKINGtestOptLockWithDelete() {
+        OpenJPAEntityManager pm1 = getEm(true, true);
+        StateImagePC2 pc1 = (StateImagePC2) pm1.getObjectId(_oid);
+        
+        OpenJPAEntityManager pm2 = getEm(true, true);
+        StateImagePC2 pc2 = (StateImagePC2) pm2.getObjectId(_oid);
+        
+        pm1.getTransaction().begin();
+        pc1.setIntField(3);
+        
+        pm2.getTransaction().begin();
+        pm2.remove(pc2);
+        
+        pm1.getTransaction().commit();
+        try {
+            pm2.getTransaction().commit();
+            fail("Should have caused OL exception.");
+        } catch (Exception jfe) {
+            pm2.getTransaction().begin();
+            pm2.refresh(pc2);
+            pm2.remove(pc2);
+            pm2.getTransaction().commit();
+        }
+    }
+    
+    public void testOptLockOnVerticalClass() {
+        OpenJPAEntityManager pm1 = getEm(true, true);
+        OpenJPAEntityManager pm2 = getEm(true, true);
+        
+        // have to load via query or extent where we're selecting the vertical
+        // field in the initial SELECT
+        OpenJPAQuery q1 = pm1.createNativeQuery("",StateImagePC2.class);
+        //FIXME  jthomas
+        //q1.setOrdering("intField ascending");
+        StateImagePC2 pc1 = (StateImagePC2) ((Collection) q1.getCandidateCollection()).
+                iterator().next();
+        q1.closeAll();
+        
+        OpenJPAQuery q2 = pm2.createNativeQuery("",StateImagePC2.class);
+        //FIXME jthomas
+        //q2.setOrdering("intField ascending");
+        StateImagePC2 pc2 = (StateImagePC2) ((Collection) q2.getCandidateCollection()).
+                iterator().next();
+        q2.closeAll();
+        
+        pm1.getTransaction().begin();
+        pc1.setStringField("changed1");
+        pc1.setStateImage(null);
+        
+        pm2.getTransaction().begin();
+        pc2.setStringField("changed2");
+        
+        pm1.getTransaction().commit();
+        
+        try {
+            pm2.getTransaction().commit();
+            fail("Should have caused OL exception.");
+        } catch (Exception jfe) {
+            pm2.getTransaction().begin();
+            pm2.refresh(pc2);
+            pc2.setStringField("changed2");
+            pm2.getTransaction().commit();
+        }
+        pm1.close();
+        pm2.close();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        StateImagePC2 pc = (StateImagePC2) pm.getObjectId(_oid);
+        assertNull(pc.getStateImage());
+        assertEquals("changed2", pc.getStringField());
+        pm.close();
+    }
+    
+    public void testLockGroup()
+    throws Exception {
+        OpenJPAEntityManager pm = getEm(true, true);
+        pm.getTransaction().begin();
+        StateImagePC3 pc = new StateImagePC3();
+        pc.setLockField(4);
+        pc.setNoLockField(6);
+        pm.persist(pc);
+        pm.getTransaction().commit();
+        
+        pm.getTransaction().begin();
+        pc.setLockField(6);
+        sql.clear();
+        pm.getTransaction().commit();
+        assertNotSQL("* WHERE * NOLOCK*");
+        
+        pm.close();
+    }
+    
+    public static void main(String[] args) {
+        
+        //FIXME
+        //main(TestStateImage.class);
+    }
+    private OpenJPAEntityManager getEm(boolean optimistic,boolean retainValues){
+        OpenJPAEntityManager em = currentEntityManager();
+        em.setNontransactionalRead(true);
+        em.setRetainState(retainValues);
+        em.setOptimistic(optimistic);
+        return em;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestLockGroupsWithHorizontalBaseType.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestLockGroupsWithHorizontalBaseType.java
index fd19552..86ce1e0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestLockGroupsWithHorizontalBaseType.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestLockGroupsWithHorizontalBaseType.java
@@ -1,85 +1,85 @@
-/*
- * TestLockGroupsWithHorizontalBaseType.java
- *
- * Created on October 4, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.horizontal;
-
-
-import java.util.*;
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.*;
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestLockGroupsWithHorizontalBaseType extends AbstractTestCase
-{   
-    /** Creates a new instance of TestLockGroupsWithHorizontalBaseType */
-    public TestLockGroupsWithHorizontalBaseType(String name) 
-    {
-    	super(name, "jdbccactusapp");
-    }
-
-
-    public void setUp() {
-       deleteAll(LockGroupSubclass.class);
-    }
-
-    public void testHorizontalLockGroup() {
-        LockGroupSubclass pc = new LockGroupSubclass();
-        pc.setDefaultLockGroupField("foo");
-        pc.setNonDefaultLockGroupField("bar");
-        OpenJPAEntityManager pm = getEm(true, true);
-        pm.getTransaction().begin();
-        pm.persist(pc);
-        pm.getTransaction().commit();
-        pm.getTransaction().begin();
-
-        Object oid = pm.getObjectId(pc);
-
-        OpenJPAEntityManager  pm2 = getEm(true, true);
-        LockGroupSubclass pc2 = (LockGroupSubclass) pm2.getObjectId(oid);
-        pm2.getTransaction().begin();
-        pc2.setNonDefaultLockGroupField("baz");
-        pm2.getTransaction().commit();
-
-        pc.setDefaultLockGroupField("wookie");
-        pm.getTransaction().commit();
-    }    
-    
-   private OpenJPAEntityManager getEm(boolean optimistic,boolean retainValues) {
-        OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
-        em.setNontransactionalRead(true);
-        em.setRetainState(retainValues);
-        em.setOptimistic(optimistic);
-        return em;
-    }    
-    
-}
+/*
+ * TestLockGroupsWithHorizontalBaseType.java
+ *
+ * Created on October 4, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.horizontal;
+
+
+import java.util.*;
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.*;
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestLockGroupsWithHorizontalBaseType extends AbstractTestCase
+{   
+    /** Creates a new instance of TestLockGroupsWithHorizontalBaseType */
+    public TestLockGroupsWithHorizontalBaseType(String name) 
+    {
+    	super(name, "jdbccactusapp");
+    }
+
+
+    public void setUp() {
+       deleteAll(LockGroupSubclass.class);
+    }
+
+    public void testHorizontalLockGroup() {
+        LockGroupSubclass pc = new LockGroupSubclass();
+        pc.setDefaultLockGroupField("foo");
+        pc.setNonDefaultLockGroupField("bar");
+        OpenJPAEntityManager pm = getEm(true, true);
+        pm.getTransaction().begin();
+        pm.persist(pc);
+        pm.getTransaction().commit();
+        pm.getTransaction().begin();
+
+        Object oid = pm.getObjectId(pc);
+
+        OpenJPAEntityManager  pm2 = getEm(true, true);
+        LockGroupSubclass pc2 = (LockGroupSubclass) pm2.getObjectId(oid);
+        pm2.getTransaction().begin();
+        pc2.setNonDefaultLockGroupField("baz");
+        pm2.getTransaction().commit();
+
+        pc.setDefaultLockGroupField("wookie");
+        pm.getTransaction().commit();
+    }    
+    
+   private OpenJPAEntityManager getEm(boolean optimistic,boolean retainValues) {
+        OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+        em.setNontransactionalRead(true);
+        em.setRetainState(retainValues);
+        em.setOptimistic(optimistic);
+        return em;
+    }    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestQueryAgainstEntireMappedHierarchy.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestQueryAgainstEntireMappedHierarchy.java
index 40ec5d3..f8be2ea 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestQueryAgainstEntireMappedHierarchy.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/horizontal/TestQueryAgainstEntireMappedHierarchy.java
@@ -1,91 +1,91 @@
-/*
- * TestQueryAgainstEntireMappedHierarchy.java
- *
- * Created on October 5, 2006, 10:46 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.horizontal;
-
-import java.util.*;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestQueryAgainstEntireMappedHierarchy extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase
-{
-	
-    /** Creates a new instance of TestQueryAgainstEntireMappedHierarchy */
-    public TestQueryAgainstEntireMappedHierarchy(String name) 
-    {
-    	super(name);
-    }
-    
-    public void setUpTestCase() 
-    {        
-        // this test depends on this fact
-        assertTrue(HorizJ.class.getSuperclass() == HorizD.class);
-        assertTrue(HorizK.class.getSuperclass() == HorizJ.class);
-
-       deleteAll(HorizD.class);
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-
-        HorizD d = new HorizD();
-        d.setStringA("stringa-d");
-        d.setStringC("stringc-d");
-        pm.persist(d);
-
-        HorizJ j = new HorizJ();
-        j.setStringA("stringa-j");
-        j.setStringC("stringc-j");
-        pm.persist(j);
-
-        HorizK k = new HorizK();
-        k.setStringA("stringa-k");
-        k.setStringC("stringc-k");
-        pm.persist(k);
-
-        pm.getTransaction().commit();
-        pm.close();
-    }
-
-    public void testQueryAgainstEntireMappedHierarchy() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        sql.clear();
-        //FIXME jthomas
-        //pm.newQuery(HorizD.class).execute();
-        String lastStatement = (String) sql.get(sql.size() - 1);
-        assertTrue(lastStatement.toLowerCase().indexOf("in (") == -1);
-        pm.close();
-    }
-    
-}
+/*
+ * TestQueryAgainstEntireMappedHierarchy.java
+ *
+ * Created on October 5, 2006, 10:46 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.horizontal;
+
+import java.util.*;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestQueryAgainstEntireMappedHierarchy extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase
+{
+	
+    /** Creates a new instance of TestQueryAgainstEntireMappedHierarchy */
+    public TestQueryAgainstEntireMappedHierarchy(String name) 
+    {
+    	super(name);
+    }
+    
+    public void setUpTestCase() 
+    {        
+        // this test depends on this fact
+        assertTrue(HorizJ.class.getSuperclass() == HorizD.class);
+        assertTrue(HorizK.class.getSuperclass() == HorizJ.class);
+
+       deleteAll(HorizD.class);
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+
+        HorizD d = new HorizD();
+        d.setStringA("stringa-d");
+        d.setStringC("stringc-d");
+        pm.persist(d);
+
+        HorizJ j = new HorizJ();
+        j.setStringA("stringa-j");
+        j.setStringC("stringc-j");
+        pm.persist(j);
+
+        HorizK k = new HorizK();
+        k.setStringA("stringa-k");
+        k.setStringC("stringc-k");
+        pm.persist(k);
+
+        pm.getTransaction().commit();
+        pm.close();
+    }
+
+    public void testQueryAgainstEntireMappedHierarchy() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        sql.clear();
+        //FIXME jthomas
+        //pm.newQuery(HorizD.class).execute();
+        String lastStatement = (String) sql.get(sql.size() - 1);
+        assertTrue(lastStatement.toLowerCase().indexOf("in (") == -1);
+        pm.close();
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/tableperclass/TestUnionPlaceholderTypes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/tableperclass/TestUnionPlaceholderTypes.java
index fe547e0..cdcbc47 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/tableperclass/TestUnionPlaceholderTypes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/tableperclass/TestUnionPlaceholderTypes.java
@@ -1,123 +1,123 @@
-/*
- * TestUnionPlaceholderTypes.java
- *
- * Created on October 5, 2006, 2:04 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.tableperclass;
-
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.SQLFactory;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.util.Id;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestUnionPlaceholderTypes extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase {
-    
-    
-    /** Creates a new instance of TestUnionPlaceholderTypes */
-    public TestUnionPlaceholderTypes(String name) 
-    {
-    	super(name);
-    }
-
-    private boolean _union = false;
-
-    public void setUpTestCase() {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        //FIXME jthomas
-        //_union = ((SQLFactory) conf.getSQLFactoryInstance()).getAdvancedSQL().getSupportsUnion();
-    }
-
-    public void testUnion()
-        throws Exception {
-       deleteAll(PlaceholderTypesA.class);
-
-        PlaceholderTypesA pta = new PlaceholderTypesA();
-        pta.setIntA(1);
-        PlaceholderTypesB ptb = new PlaceholderTypesB();
-        ptb.setIntA(2);
-        ptb.setIntB(3);
-        ptb.setBooleanB(true);
-        ptb.setByteB((byte) 64);
-        ptb.setCharB('a');
-        ptb.setFloatB(99.9F);
-        ptb.setStringB("stringB");
-        ptb.setClobB("clobB");
-        ptb.setBlobB("blobB");
-
-        Broker broker = getBrokerFactory().newBroker();
-        broker.begin();
-        broker.persist(pta, null);
-        broker.persist(ptb, null);
-        broker.commit();
-        Object oida = broker.getObjectId(pta);
-        long idb = ((Id) broker.getObjectId(ptb)).getId();
-        broker.close();
-
-        broker = getBrokerFactory().newBroker();
-        broker.begin();
-        sql.clear();
-        pta = (PlaceholderTypesA) broker.find(oida, true, null);
-        assertEquals(1, pta.getIntA());
-        if (_union)
-            assertEquals(1, sql.size());
-        else
-            assertNotSQL("UNION");
-        broker.close();
-
-        broker = getBrokerFactory().newBroker();
-        broker.begin();
-        sql.clear();
-        ptb = (PlaceholderTypesB) broker.find(broker.newObjectId
-            (PlaceholderTypesB.class, new Long(idb)), true, null);
-        assertEquals(2, ptb.getIntA());
-        assertEquals(3, ptb.getIntB());
-        assertTrue(ptb.getBooleanB());
-        assertEquals(64, ptb.getByteB());
-        assertEquals('a', ptb.getCharB());
-        assertEquals(99.9F, ptb.getFloatB(), .001);
-        assertEquals("stringB", ptb.getStringB());
-        assertEquals("clobB", ptb.getClobB());
-        assertEquals("blobB", ptb.getBlobB());
-        if (_union)
-            assertEquals(1, sql.size());
-        else
-            assertNotSQL("UNION");
-        broker.close();
-    }
-    
-}
+/*
+ * TestUnionPlaceholderTypes.java
+ *
+ * Created on October 5, 2006, 2:04 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.tableperclass;
+
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.SQLFactory;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.util.Id;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestUnionPlaceholderTypes extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase {
+    
+    
+    /** Creates a new instance of TestUnionPlaceholderTypes */
+    public TestUnionPlaceholderTypes(String name) 
+    {
+    	super(name);
+    }
+
+    private boolean _union = false;
+
+    public void setUpTestCase() {
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        //FIXME jthomas
+        //_union = ((SQLFactory) conf.getSQLFactoryInstance()).getAdvancedSQL().getSupportsUnion();
+    }
+
+    public void testUnion()
+        throws Exception {
+       deleteAll(PlaceholderTypesA.class);
+
+        PlaceholderTypesA pta = new PlaceholderTypesA();
+        pta.setIntA(1);
+        PlaceholderTypesB ptb = new PlaceholderTypesB();
+        ptb.setIntA(2);
+        ptb.setIntB(3);
+        ptb.setBooleanB(true);
+        ptb.setByteB((byte) 64);
+        ptb.setCharB('a');
+        ptb.setFloatB(99.9F);
+        ptb.setStringB("stringB");
+        ptb.setClobB("clobB");
+        ptb.setBlobB("blobB");
+
+        Broker broker = getBrokerFactory().newBroker();
+        broker.begin();
+        broker.persist(pta, null);
+        broker.persist(ptb, null);
+        broker.commit();
+        Object oida = broker.getObjectId(pta);
+        long idb = ((Id) broker.getObjectId(ptb)).getId();
+        broker.close();
+
+        broker = getBrokerFactory().newBroker();
+        broker.begin();
+        sql.clear();
+        pta = (PlaceholderTypesA) broker.find(oida, true, null);
+        assertEquals(1, pta.getIntA());
+        if (_union)
+            assertEquals(1, sql.size());
+        else
+            assertNotSQL("UNION");
+        broker.close();
+
+        broker = getBrokerFactory().newBroker();
+        broker.begin();
+        sql.clear();
+        ptb = (PlaceholderTypesB) broker.find(broker.newObjectId
+            (PlaceholderTypesB.class, new Long(idb)), true, null);
+        assertEquals(2, ptb.getIntA());
+        assertEquals(3, ptb.getIntB());
+        assertTrue(ptb.getBooleanB());
+        assertEquals(64, ptb.getByteB());
+        assertEquals('a', ptb.getCharB());
+        assertEquals(99.9F, ptb.getFloatB(), .001);
+        assertEquals("stringB", ptb.getStringB());
+        assertEquals("clobB", ptb.getClobB());
+        assertEquals("blobB", ptb.getBlobB());
+        if (_union)
+            assertEquals(1, sql.size());
+        else
+            assertNotSQL("UNION");
+        broker.close();
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestJoinSubclasses.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestJoinSubclasses.java
index 02c4312..9ff8163 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestJoinSubclasses.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestJoinSubclasses.java
@@ -1,221 +1,221 @@
-/*
- * TestJoinSubclasses.java
- *
- * Created on October 5, 2006, 2:17 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.vertical;
-
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.Join;
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.util.Id;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestJoinSubclasses
-        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
-     
-    /** Creates a new instance of TestJoinSubclasses */
-    public TestJoinSubclasses(String name) 
-    {
-    	super(name);
-    }
-    
-    
-    private String _outer = "OUTER";
-    private Object _base = null;
-    private Object _baseSubFlat = null;
-    
-    public boolean skipTest() {
-        //FIXME
-        /*
-        return super.skipTest()
-            || ((JDBCConfiguration) getConfiguration()).
-            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
-         */
-        return false;
-    }
-    
-    public void setUpTestCase() {
-        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
-                joinSyntax == Join.SYNTAX_DATABASE)
-            _outer = "(+)";
-        
-       deleteAll(JoinSubclassBase.class);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        JoinSubclassBase base = new JoinSubclassBase();
-        base.setBaseField(1);
-        pm.persist(base);
-        
-        JoinSubclassBaseSubVert sub1 = new JoinSubclassBaseSubVert();
-        sub1.setBaseField(2);
-        sub1.setBaseSubVertField(3);
-        pm.persist(sub1);
-        
-        JoinSubclassBaseSubFlat sub2 = new JoinSubclassBaseSubFlat();
-        sub2.setBaseField(3);
-        sub2.setBaseSubVertField(4);
-        sub2.setBaseSubFlatField(5);
-        pm.persist(sub2);
-        
-        endTx(pm);;
-        _base = pm.getObjectId(base);
-        _baseSubFlat = pm.getObjectId(sub2);
-        pm.close();
-    }
-    
-    public void testBaseExtentNoSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(JoinSubclassBase.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        JoinSubclassBase pc = (JoinSubclassBase) itr.next();
-        assertEquals(1, pc.getBaseField());
-        assertEquals(JoinSubclassBase.class, pc.getClass());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertNotSQL(_outer);
-    }
-    
-    public void testBaseExtentWithSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(JoinSubclassBase.class, true);
-        Collection pcs = new TreeSet(((Extent) extent).list());
-        assertEquals(3, pcs.size());
-        Iterator itr = pcs.iterator();
-        for (int i = 0; i < 2; i++) {
-            JoinSubclassBase pc = (JoinSubclassBase) itr.next();
-            assertEquals(i + 1, pc.getBaseField());
-            switch (i) {
-                case 0:
-                    assertEquals(JoinSubclassBase.class, pc.getClass());
-                    break;
-                case 1:
-                    assertEquals(JoinSubclassBaseSubVert.class, pc.getClass());
-                    assertEquals(i + 2, ((JoinSubclassBaseSubVert) pc).
-                            getBaseSubVertField());
-                    break;
-                case 2:
-                    assertEquals(JoinSubclassBaseSubFlat.class, pc.getClass());
-                    assertEquals(i + 2, ((JoinSubclassBaseSubFlat) pc).
-                            getBaseSubVertField());
-                    assertEquals(i + 3, ((JoinSubclassBaseSubFlat) pc).
-                            getBaseSubFlatField());
-                    break;
-            }
-        }
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testLeafExtent()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(JoinSubclassBaseSubFlat.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        JoinSubclassBaseSubFlat pc = (JoinSubclassBaseSubFlat) itr.next();
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSubVertField());
-        assertEquals(5, pc.getBaseSubFlatField());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertNotSQL(_outer);
-    }
-    
-    public void testBaseGetById()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        JoinSubclassBase pc = (JoinSubclassBase) pm.getObjectId(_base);
-        assertEquals(1, pc.getBaseField());
-        assertEquals(JoinSubclassBase.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-        
-        // should outer join with non-exact id
-        Id oid = new Id(JoinSubclassBase.class, ((Id) _base).getId());
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (JoinSubclassBase) pm.getObjectId(oid);
-        assertEquals(1, pc.getBaseField());
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testLeafGetById()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        JoinSubclassBaseSubFlat pc = (JoinSubclassBaseSubFlat)
-        pm.getObjectId(_baseSubFlat);
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSubVertField());
-        assertEquals(5, pc.getBaseSubFlatField());
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-        
-        // should outer join with non-exact id
-        Id oid = new Id(JoinSubclassBase.class, ((Id) _baseSubFlat).getId());
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (JoinSubclassBaseSubFlat) pm.getObjectId(oid);
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSubVertField());
-        assertEquals(5, pc.getBaseSubFlatField());
-        pm.close();
-        
-        assertEquals(sql.toString(), 1, sql.size());
-        assertSQL(_outer);
-    }
-    
-}
+/*
+ * TestJoinSubclasses.java
+ *
+ * Created on October 5, 2006, 2:17 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.vertical;
+
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.Join;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.util.Id;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestJoinSubclasses
+        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
+     
+    /** Creates a new instance of TestJoinSubclasses */
+    public TestJoinSubclasses(String name) 
+    {
+    	super(name);
+    }
+    
+    
+    private String _outer = "OUTER";
+    private Object _base = null;
+    private Object _baseSubFlat = null;
+    
+    public boolean skipTest() {
+        //FIXME
+        /*
+        return super.skipTest()
+            || ((JDBCConfiguration) getConfiguration()).
+            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
+         */
+        return false;
+    }
+    
+    public void setUpTestCase() {
+        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
+                joinSyntax == Join.SYNTAX_DATABASE)
+            _outer = "(+)";
+        
+       deleteAll(JoinSubclassBase.class);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        JoinSubclassBase base = new JoinSubclassBase();
+        base.setBaseField(1);
+        pm.persist(base);
+        
+        JoinSubclassBaseSubVert sub1 = new JoinSubclassBaseSubVert();
+        sub1.setBaseField(2);
+        sub1.setBaseSubVertField(3);
+        pm.persist(sub1);
+        
+        JoinSubclassBaseSubFlat sub2 = new JoinSubclassBaseSubFlat();
+        sub2.setBaseField(3);
+        sub2.setBaseSubVertField(4);
+        sub2.setBaseSubFlatField(5);
+        pm.persist(sub2);
+        
+        endTx(pm);;
+        _base = pm.getObjectId(base);
+        _baseSubFlat = pm.getObjectId(sub2);
+        pm.close();
+    }
+    
+    public void testBaseExtentNoSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(JoinSubclassBase.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        JoinSubclassBase pc = (JoinSubclassBase) itr.next();
+        assertEquals(1, pc.getBaseField());
+        assertEquals(JoinSubclassBase.class, pc.getClass());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertNotSQL(_outer);
+    }
+    
+    public void testBaseExtentWithSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(JoinSubclassBase.class, true);
+        Collection pcs = new TreeSet(((Extent) extent).list());
+        assertEquals(3, pcs.size());
+        Iterator itr = pcs.iterator();
+        for (int i = 0; i < 2; i++) {
+            JoinSubclassBase pc = (JoinSubclassBase) itr.next();
+            assertEquals(i + 1, pc.getBaseField());
+            switch (i) {
+                case 0:
+                    assertEquals(JoinSubclassBase.class, pc.getClass());
+                    break;
+                case 1:
+                    assertEquals(JoinSubclassBaseSubVert.class, pc.getClass());
+                    assertEquals(i + 2, ((JoinSubclassBaseSubVert) pc).
+                            getBaseSubVertField());
+                    break;
+                case 2:
+                    assertEquals(JoinSubclassBaseSubFlat.class, pc.getClass());
+                    assertEquals(i + 2, ((JoinSubclassBaseSubFlat) pc).
+                            getBaseSubVertField());
+                    assertEquals(i + 3, ((JoinSubclassBaseSubFlat) pc).
+                            getBaseSubFlatField());
+                    break;
+            }
+        }
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testLeafExtent()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(JoinSubclassBaseSubFlat.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        JoinSubclassBaseSubFlat pc = (JoinSubclassBaseSubFlat) itr.next();
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSubVertField());
+        assertEquals(5, pc.getBaseSubFlatField());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertNotSQL(_outer);
+    }
+    
+    public void testBaseGetById()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        JoinSubclassBase pc = (JoinSubclassBase) pm.getObjectId(_base);
+        assertEquals(1, pc.getBaseField());
+        assertEquals(JoinSubclassBase.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+        
+        // should outer join with non-exact id
+        Id oid = new Id(JoinSubclassBase.class, ((Id) _base).getId());
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (JoinSubclassBase) pm.getObjectId(oid);
+        assertEquals(1, pc.getBaseField());
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testLeafGetById()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        JoinSubclassBaseSubFlat pc = (JoinSubclassBaseSubFlat)
+        pm.getObjectId(_baseSubFlat);
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSubVertField());
+        assertEquals(5, pc.getBaseSubFlatField());
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+        
+        // should outer join with non-exact id
+        Id oid = new Id(JoinSubclassBase.class, ((Id) _baseSubFlat).getId());
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (JoinSubclassBaseSubFlat) pm.getObjectId(oid);
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSubVertField());
+        assertEquals(5, pc.getBaseSubFlatField());
+        pm.close();
+        
+        assertEquals(sql.toString(), 1, sql.size());
+        assertSQL(_outer);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinExtent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinExtent.java
index efb25ce..a1a133e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinExtent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinExtent.java
@@ -1,287 +1,287 @@
-/*
- * TestSubclassJoinExtent.java
- *
- * Created on October 5, 2006, 3:41 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.vertical;
-
-import java.util.*;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.Join;
-import org.apache.openjpa.persistence.Extent;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestSubclassJoinExtent
-        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
-   
-    private String _outer = "OUTER";
-    
-    /** Creates a new instance of TestSubclassJoinExtent */
-    public TestSubclassJoinExtent(String name) 
-    {
-    	super(name);
-    }
-    
-    public boolean skipTest() {
-        //FIXME
-        /*
-        return super.skipTest()
-            || ((JDBCConfiguration) getConfiguration()).
-            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
-         */
-        return false;
-    }
-    
-    public void setUpTestCase() {
-        // make sure all classes are registered
-        Class[] reg = new Class[]{
-            Base.class, BaseSub1.class, BaseSub2.class,
-            BaseSub1Sub1.class, BaseSub1Sub2.class,
-        };
-        
-        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
-                joinSyntax == Join.SYNTAX_DATABASE)
-            _outer = "(+)";
-        
-       deleteAll(Base.class);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        Base base = new Base();
-        base.setBaseField(1);
-        pm.persist(base);
-        
-        BaseSub1 sub1 = new BaseSub1();
-        sub1.setBaseField(2);
-        sub1.setBaseSub1Field(3);
-        pm.persist(sub1);
-        
-        BaseSub2 sub2 = new BaseSub2();
-        sub2.setBaseField(3);
-        sub2.setBaseSub2Field(4);
-        pm.persist(sub2);
-        
-        BaseSub1Sub2 sub1sub2 = new BaseSub1Sub2();
-        sub1sub2.setBaseField(4);
-        sub1sub2.setBaseSub1Field(5);
-        sub1sub2.setBaseSub1Sub2Field(6);
-        pm.persist(sub1sub2);
-        
-        endTx(pm);;
-        pm.close();
-    }
-    
-    public void testBaseNoSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(Base.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        Base pc = (Base) itr.next();
-        assertEquals(1, pc.getBaseField());
-        assertEquals(Base.class, pc.getClass());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testBaseWithSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(Base.class, true);
-        Collection pcs = new TreeSet(((Extent) extent).list());
-        assertEquals(4, pcs.size());
-        Iterator itr = pcs.iterator();
-        for (int i = 0; i < 4; i++) {
-            Base pc = (Base) itr.next();
-            assertEquals(i + 1, pc.getBaseField());
-            switch (i) {
-                case 0:
-                    assertEquals(Base.class, pc.getClass());
-                    break;
-                case 1:
-                    assertEquals(BaseSub1.class, pc.getClass());
-                    break;
-                case 2:
-                    assertEquals(BaseSub2.class, pc.getClass());
-                    break;
-                case 3:
-                    assertEquals(BaseSub1Sub2.class, pc.getClass());
-                    break;
-            }
-        }
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testEmptyNoSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub1Sub1.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        assertNotSQL(_outer);
-    }
-    
-    public void testEmptyWithSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub1Sub1.class, true);
-        Iterator itr = extent.iterator();
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        assertNotSQL(_outer);
-    }
-    
-    public void testLeafNoSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub1Sub2.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        BaseSub1Sub2 pc = (BaseSub1Sub2) itr.next();
-        assertEquals(4, pc.getBaseField());
-        assertEquals(5, pc.getBaseSub1Field());
-        assertEquals(6, pc.getBaseSub1Sub2Field());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-    }
-    
-    public void testLeafWithSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub1Sub2.class, true);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        BaseSub1Sub2 pc = (BaseSub1Sub2) itr.next();
-        assertEquals(4, pc.getBaseField());
-        assertEquals(5, pc.getBaseSub1Field());
-        assertEquals(6, pc.getBaseSub1Sub2Field());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-    }
-    
-    public void testLeafNoSubs2()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub2.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        BaseSub2 pc = (BaseSub2) itr.next();
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSub2Field());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-    }
-    
-    public void testLeafWithSubs2()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub2.class, true);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        BaseSub2 pc = (BaseSub2) itr.next();
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSub2Field());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-    }
-    
-    public void testMidNoSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub1.class, false);
-        Iterator itr = extent.iterator();
-        assertTrue(itr.hasNext());
-        BaseSub1 pc = (BaseSub1) itr.next();
-        assertEquals(2, pc.getBaseField());
-        assertEquals(3, pc.getBaseSub1Field());
-        assertEquals(BaseSub1.class, pc.getClass());
-        assertTrue(!itr.hasNext());
-        extent.closeAll();
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testMidWithSubs()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Extent extent = pm.createExtent(BaseSub1.class, true);
-        Collection pcs = new TreeSet(((Extent) extent).list());
-        assertEquals(2, pcs.size());
-        Iterator itr = pcs.iterator();
-        BaseSub1 pc = (BaseSub1) itr.next();
-        assertEquals(2, pc.getBaseField());
-        assertEquals(3, pc.getBaseSub1Field());
-        assertEquals(BaseSub1.class, pc.getClass());
-        pc = (BaseSub1) itr.next();
-        assertEquals(4, pc.getBaseField());
-        assertEquals(5, pc.getBaseSub1Field());
-        assertEquals(BaseSub1Sub2.class, pc.getClass());
-        assertEquals(6, ((BaseSub1Sub2) pc).getBaseSub1Sub2Field());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-}
+/*
+ * TestSubclassJoinExtent.java
+ *
+ * Created on October 5, 2006, 3:41 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.vertical;
+
+import java.util.*;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.Join;
+import org.apache.openjpa.persistence.Extent;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestSubclassJoinExtent
+        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
+   
+    private String _outer = "OUTER";
+    
+    /** Creates a new instance of TestSubclassJoinExtent */
+    public TestSubclassJoinExtent(String name) 
+    {
+    	super(name);
+    }
+    
+    public boolean skipTest() {
+        //FIXME
+        /*
+        return super.skipTest()
+            || ((JDBCConfiguration) getConfiguration()).
+            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
+         */
+        return false;
+    }
+    
+    public void setUpTestCase() {
+        // make sure all classes are registered
+        Class[] reg = new Class[]{
+            Base.class, BaseSub1.class, BaseSub2.class,
+            BaseSub1Sub1.class, BaseSub1Sub2.class,
+        };
+        
+        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
+                joinSyntax == Join.SYNTAX_DATABASE)
+            _outer = "(+)";
+        
+       deleteAll(Base.class);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        Base base = new Base();
+        base.setBaseField(1);
+        pm.persist(base);
+        
+        BaseSub1 sub1 = new BaseSub1();
+        sub1.setBaseField(2);
+        sub1.setBaseSub1Field(3);
+        pm.persist(sub1);
+        
+        BaseSub2 sub2 = new BaseSub2();
+        sub2.setBaseField(3);
+        sub2.setBaseSub2Field(4);
+        pm.persist(sub2);
+        
+        BaseSub1Sub2 sub1sub2 = new BaseSub1Sub2();
+        sub1sub2.setBaseField(4);
+        sub1sub2.setBaseSub1Field(5);
+        sub1sub2.setBaseSub1Sub2Field(6);
+        pm.persist(sub1sub2);
+        
+        endTx(pm);;
+        pm.close();
+    }
+    
+    public void testBaseNoSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(Base.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        Base pc = (Base) itr.next();
+        assertEquals(1, pc.getBaseField());
+        assertEquals(Base.class, pc.getClass());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testBaseWithSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(Base.class, true);
+        Collection pcs = new TreeSet(((Extent) extent).list());
+        assertEquals(4, pcs.size());
+        Iterator itr = pcs.iterator();
+        for (int i = 0; i < 4; i++) {
+            Base pc = (Base) itr.next();
+            assertEquals(i + 1, pc.getBaseField());
+            switch (i) {
+                case 0:
+                    assertEquals(Base.class, pc.getClass());
+                    break;
+                case 1:
+                    assertEquals(BaseSub1.class, pc.getClass());
+                    break;
+                case 2:
+                    assertEquals(BaseSub2.class, pc.getClass());
+                    break;
+                case 3:
+                    assertEquals(BaseSub1Sub2.class, pc.getClass());
+                    break;
+            }
+        }
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testEmptyNoSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub1Sub1.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        assertNotSQL(_outer);
+    }
+    
+    public void testEmptyWithSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub1Sub1.class, true);
+        Iterator itr = extent.iterator();
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        assertNotSQL(_outer);
+    }
+    
+    public void testLeafNoSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub1Sub2.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        BaseSub1Sub2 pc = (BaseSub1Sub2) itr.next();
+        assertEquals(4, pc.getBaseField());
+        assertEquals(5, pc.getBaseSub1Field());
+        assertEquals(6, pc.getBaseSub1Sub2Field());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+    }
+    
+    public void testLeafWithSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub1Sub2.class, true);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        BaseSub1Sub2 pc = (BaseSub1Sub2) itr.next();
+        assertEquals(4, pc.getBaseField());
+        assertEquals(5, pc.getBaseSub1Field());
+        assertEquals(6, pc.getBaseSub1Sub2Field());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+    }
+    
+    public void testLeafNoSubs2()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub2.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        BaseSub2 pc = (BaseSub2) itr.next();
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSub2Field());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+    }
+    
+    public void testLeafWithSubs2()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub2.class, true);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        BaseSub2 pc = (BaseSub2) itr.next();
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSub2Field());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+    }
+    
+    public void testMidNoSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub1.class, false);
+        Iterator itr = extent.iterator();
+        assertTrue(itr.hasNext());
+        BaseSub1 pc = (BaseSub1) itr.next();
+        assertEquals(2, pc.getBaseField());
+        assertEquals(3, pc.getBaseSub1Field());
+        assertEquals(BaseSub1.class, pc.getClass());
+        assertTrue(!itr.hasNext());
+        extent.closeAll();
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testMidWithSubs()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Extent extent = pm.createExtent(BaseSub1.class, true);
+        Collection pcs = new TreeSet(((Extent) extent).list());
+        assertEquals(2, pcs.size());
+        Iterator itr = pcs.iterator();
+        BaseSub1 pc = (BaseSub1) itr.next();
+        assertEquals(2, pc.getBaseField());
+        assertEquals(3, pc.getBaseSub1Field());
+        assertEquals(BaseSub1.class, pc.getClass());
+        pc = (BaseSub1) itr.next();
+        assertEquals(4, pc.getBaseField());
+        assertEquals(5, pc.getBaseSub1Field());
+        assertEquals(BaseSub1Sub2.class, pc.getClass());
+        assertEquals(6, ((BaseSub1Sub2) pc).getBaseSub1Sub2Field());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinGetObjectById.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinGetObjectById.java
index bdd2973..c22d1f9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinGetObjectById.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinGetObjectById.java
@@ -1,229 +1,229 @@
-/*
- * TestSubclassJoinGetObjectById.java
- *
- * Created on October 5, 2006, 3:55 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.vertical;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.Join;
-import org.apache.openjpa.util.Id;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestSubclassJoinGetObjectById
-        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
-    
-
-    private String _outer = "OUTER";
-    
-    /** Creates a new instance of TestSubclassJoinGetObjectById */
-    public TestSubclassJoinGetObjectById(String name) 
-    {
-    	super(name);
-    }
-    
-    
-    public boolean skipTest() {
-        //FIXME
-        /*
-        return super.skipTest()
-            || ((JDBCConfiguration) getConfiguration()).
-            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
-         */
-        return false;
-    }
-    
-    public void setUpTestCase() {
-        // make sure all classes are registered
-        Class[] reg = new Class[]{
-            Base.class, BaseSub1.class, BaseSub2.class,
-            BaseSub1Sub1.class, BaseSub1Sub2.class,
-        };
-        
-        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
-                joinSyntax == Join.SYNTAX_DATABASE)
-            _outer = "(+)";
-        
-       deleteAll(Base.class);
-    }
-    
-    public void testBase()
-    throws Exception {
-        Base pc = new Base();
-        pc.setBaseField(1);
-        Object oid = persist(pc);
-        sql.clear();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        
-        pc = (Base) pm.getObjectId(oid);
-        assertEquals(1, pc.getBaseField());
-        assertEquals(Base.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-        
-        // should outer join with non-exact oid
-        oid = new Id(Base.class, ((Id) oid).getId());
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (Base) pm.getObjectId(oid);
-        assertEquals(1, pc.getBaseField());
-        assertEquals(Base.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testBadId()
-    throws Exception {
-        Base pc = new Base();
-        pc.setBaseField(1);
-        Object oid = persist(pc);
-        sql.clear();
-        
-        Id id = new Id(Base.class, -1);
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        try {
-            pm.getObjectId(id);
-            fail("No exception on bad id.");
-        } catch (Exception jonfe) {
-        }
-        pm.close();
-    }
-    
-    public void testLeaf()
-    throws Exception {
-        BaseSub1Sub2 pc = new BaseSub1Sub2();
-        pc.setBaseField(4);
-        pc.setBaseSub1Field(5);
-        pc.setBaseSub1Sub2Field(6);
-        Object oid = persist(pc);
-        sql.clear();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pc = (BaseSub1Sub2) pm.getObjectId(oid);
-        assertEquals(4, pc.getBaseField());
-        assertEquals(5, pc.getBaseSub1Field());
-        assertEquals(6, pc.getBaseSub1Sub2Field());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-        
-        // should outer join with inexact oid
-        oid = new Id(Base.class, ((Id) oid).getId());
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (BaseSub1Sub2) pm.getObjectId(oid);
-        assertEquals(4, pc.getBaseField());
-        assertEquals(5, pc.getBaseSub1Field());
-        assertEquals(6, pc.getBaseSub1Sub2Field());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testLeaf2()
-    throws Exception {
-        BaseSub2 pc = new BaseSub2();
-        pc.setBaseField(3);
-        pc.setBaseSub2Field(4);
-        Object oid = persist(pc);
-        sql.clear();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pc = (BaseSub2) pm.getObjectId(oid);
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSub2Field());
-        assertEquals(BaseSub2.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-        
-        // should outer join with inexact oid
-        oid = new Id(Base.class, ((Id) oid).getId());
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (BaseSub2) pm.getObjectId(oid);
-        assertEquals(3, pc.getBaseField());
-        assertEquals(4, pc.getBaseSub2Field());
-        assertEquals(BaseSub2.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    public void testMid()
-    throws Exception {
-        BaseSub1 pc = new BaseSub1();
-        pc.setBaseField(2);
-        pc.setBaseSub1Field(3);
-        Object oid = persist(pc);
-        sql.clear();
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pc = (BaseSub1) pm.getObjectId(oid);
-        assertEquals(2, pc.getBaseField());
-        assertEquals(3, pc.getBaseSub1Field());
-        assertEquals(BaseSub1.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-        
-        // should outer join with inexact oid
-        oid = new Id(Base.class, ((Id) oid).getId());
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        pc = (BaseSub1) pm.getObjectId(oid);
-        assertEquals(2, pc.getBaseField());
-        assertEquals(3, pc.getBaseSub1Field());
-        assertEquals(BaseSub1.class, pc.getClass());
-        pm.close();
-        
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-    
-    
-    
-}
+/*
+ * TestSubclassJoinGetObjectById.java
+ *
+ * Created on October 5, 2006, 3:55 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.vertical;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.Join;
+import org.apache.openjpa.util.Id;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestSubclassJoinGetObjectById
+        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
+    
+
+    private String _outer = "OUTER";
+    
+    /** Creates a new instance of TestSubclassJoinGetObjectById */
+    public TestSubclassJoinGetObjectById(String name) 
+    {
+    	super(name);
+    }
+    
+    
+    public boolean skipTest() {
+        //FIXME
+        /*
+        return super.skipTest()
+            || ((JDBCConfiguration) getConfiguration()).
+            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
+         */
+        return false;
+    }
+    
+    public void setUpTestCase() {
+        // make sure all classes are registered
+        Class[] reg = new Class[]{
+            Base.class, BaseSub1.class, BaseSub2.class,
+            BaseSub1Sub1.class, BaseSub1Sub2.class,
+        };
+        
+        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
+                joinSyntax == Join.SYNTAX_DATABASE)
+            _outer = "(+)";
+        
+       deleteAll(Base.class);
+    }
+    
+    public void testBase()
+    throws Exception {
+        Base pc = new Base();
+        pc.setBaseField(1);
+        Object oid = persist(pc);
+        sql.clear();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        
+        pc = (Base) pm.getObjectId(oid);
+        assertEquals(1, pc.getBaseField());
+        assertEquals(Base.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+        
+        // should outer join with non-exact oid
+        oid = new Id(Base.class, ((Id) oid).getId());
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (Base) pm.getObjectId(oid);
+        assertEquals(1, pc.getBaseField());
+        assertEquals(Base.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testBadId()
+    throws Exception {
+        Base pc = new Base();
+        pc.setBaseField(1);
+        Object oid = persist(pc);
+        sql.clear();
+        
+        Id id = new Id(Base.class, -1);
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        try {
+            pm.getObjectId(id);
+            fail("No exception on bad id.");
+        } catch (Exception jonfe) {
+        }
+        pm.close();
+    }
+    
+    public void testLeaf()
+    throws Exception {
+        BaseSub1Sub2 pc = new BaseSub1Sub2();
+        pc.setBaseField(4);
+        pc.setBaseSub1Field(5);
+        pc.setBaseSub1Sub2Field(6);
+        Object oid = persist(pc);
+        sql.clear();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pc = (BaseSub1Sub2) pm.getObjectId(oid);
+        assertEquals(4, pc.getBaseField());
+        assertEquals(5, pc.getBaseSub1Field());
+        assertEquals(6, pc.getBaseSub1Sub2Field());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+        
+        // should outer join with inexact oid
+        oid = new Id(Base.class, ((Id) oid).getId());
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (BaseSub1Sub2) pm.getObjectId(oid);
+        assertEquals(4, pc.getBaseField());
+        assertEquals(5, pc.getBaseSub1Field());
+        assertEquals(6, pc.getBaseSub1Sub2Field());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testLeaf2()
+    throws Exception {
+        BaseSub2 pc = new BaseSub2();
+        pc.setBaseField(3);
+        pc.setBaseSub2Field(4);
+        Object oid = persist(pc);
+        sql.clear();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pc = (BaseSub2) pm.getObjectId(oid);
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSub2Field());
+        assertEquals(BaseSub2.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+        
+        // should outer join with inexact oid
+        oid = new Id(Base.class, ((Id) oid).getId());
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (BaseSub2) pm.getObjectId(oid);
+        assertEquals(3, pc.getBaseField());
+        assertEquals(4, pc.getBaseSub2Field());
+        assertEquals(BaseSub2.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    public void testMid()
+    throws Exception {
+        BaseSub1 pc = new BaseSub1();
+        pc.setBaseField(2);
+        pc.setBaseSub1Field(3);
+        Object oid = persist(pc);
+        sql.clear();
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pc = (BaseSub1) pm.getObjectId(oid);
+        assertEquals(2, pc.getBaseField());
+        assertEquals(3, pc.getBaseSub1Field());
+        assertEquals(BaseSub1.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+        
+        // should outer join with inexact oid
+        oid = new Id(Base.class, ((Id) oid).getId());
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        pc = (BaseSub1) pm.getObjectId(oid);
+        assertEquals(2, pc.getBaseField());
+        assertEquals(3, pc.getBaseSub1Field());
+        assertEquals(BaseSub1.class, pc.getClass());
+        pm.close();
+        
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+    
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinRelations.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinRelations.java
index cd9ca25..b2cc5e9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinRelations.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/meta/vertical/TestSubclassJoinRelations.java
@@ -1,466 +1,466 @@
-/*
- * TestSubclassJoinRelations.java
- *
- * Created on October 5, 2006, 4:28 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.meta.vertical;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.sql.Join;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestSubclassJoinRelations extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase 
-{
-    private String _outer = "OUTER";
-    private Object _oid = null;
-    
-    /** Creates a new instance of TestSubclassJoinRelations */
-    public TestSubclassJoinRelations(String name) 
-    {
-    	super(name);
-    }
-    
-    public boolean skipTest() {
-        //FIXME 
-        /*
-        return super.skipTest()
-            || ((JDBCConfiguration) getConfiguration()).
-            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
-         */
-        return false;
-    }
-
-    public void setUpTestCase() {
-        // make sure all classes are registered
-        Class[] reg = new Class[]{
-            Base.class, BaseSub1.class, BaseSub2.class,
-            BaseSub1Sub1.class, BaseSub1Sub2.class,
-        };
-
-        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
-            joinSyntax == Join.SYNTAX_DATABASE)
-            _outer = "(+)";
-
-       deleteAll(Relations.class);
-       deleteAll(Base.class);
-
-        Relations rel = new Relations();
-        BaseSub2 sub2 = new BaseSub2();
-        sub2.setBaseField(3);
-        sub2.setBaseSub2Field(4);
-        rel.setBase(sub2);
-
-        BaseSub1 sub1 = new BaseSub1();
-        sub1.setBaseField(2);
-        sub1.setBaseSub1Field(3);
-        rel.setBaseSub1(sub1);
-
-        BaseSub1Sub2 sub1sub2 = new BaseSub1Sub2();
-        sub1sub2.setBaseField(4);
-        sub1sub2.setBaseSub1Field(5);
-        sub1sub2.setBaseSub1Sub2Field(6);
-        rel.setBaseSub1Sub2(sub1sub2);
-
-        Base base = new Base();
-        base.setBaseField(1);
-        rel.getBaseList().add(base);
-        rel.getBaseList().add(sub2);
-
-        rel.getBaseSub1List().add(sub1);
-        rel.getBaseSub1List().add(sub1sub2);
-
-        rel.getBaseSub1Sub2List().add(sub1sub2);
-
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(rel);
-        endTx(pm);;
-        _oid = pm.getObjectId(rel);
-        pm.close();
-    }
-
-    public void testNullOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        assertNull(rel.getNullBase());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testEagerNullOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("nullBase");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        assertNull(rel.getNullBase());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testEmptyBaseList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        assertEquals(0, rel.getEmptyBaseList().size());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-
-    public void testEagerEmptyBaseList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("emptyBaseList");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        assertEquals(0, rel.getEmptyBaseList().size());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testBaseOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        BaseSub2 sub2 = (BaseSub2) rel.getBase();
-        assertEquals(3, sub2.getBaseField());
-        assertEquals(4, sub2.getBaseSub2Field());
-        assertEquals(BaseSub2.class, sub2.getClass());
-        pm.close();
-
-        assertEquals(sql.toString(), 1, sql.size());
-        assertSQL(_outer);
-    }
-
-    public void testEagerBaseOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("base");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        BaseSub2 sub2 = (BaseSub2) rel.getBase();
-        assertEquals(3, sub2.getBaseField());
-        assertEquals(4, sub2.getBaseSub2Field());
-        assertEquals(BaseSub2.class, sub2.getClass());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testLeafOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) rel.getBaseSub1Sub2();
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-    }
-
-    public void testEagerLeafOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("baseSub1Sub2");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) rel.getBaseSub1Sub2();
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testMidOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        BaseSub1 sub1 = (BaseSub1) rel.getBaseSub1();
-        assertEquals(2, sub1.getBaseField());
-        assertEquals(3, sub1.getBaseSub1Field());
-        assertEquals(BaseSub1.class, sub1.getClass());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-
-    public void testEagerMidOneOne()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("baseSub1");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        BaseSub1 sub1 = (BaseSub1) rel.getBaseSub1();
-        assertEquals(2, sub1.getBaseField());
-        assertEquals(3, sub1.getBaseSub1Field());
-        assertEquals(BaseSub1.class, sub1.getClass());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testBaseList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        List list = rel.getBaseList();
-        assertEquals(2, list.size());
-        Base base = (Base) list.get(0);
-        assertEquals(1, base.getBaseField());
-        assertEquals(Base.class, base.getClass());
-        BaseSub2 sub2 = (BaseSub2) list.get(1);
-        assertEquals(3, sub2.getBaseField());
-        assertEquals(4, sub2.getBaseSub2Field());
-        assertEquals(BaseSub2.class, sub2.getClass());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-
-    public void testEagerBaseList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("baseList");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        List list = rel.getBaseList();
-        assertEquals(2, list.size());
-        Base base = (Base) list.get(0);
-        assertEquals(1, base.getBaseField());
-        assertEquals(Base.class, base.getClass());
-        BaseSub2 sub2 = (BaseSub2) list.get(1);
-        assertEquals(3, sub2.getBaseField());
-        assertEquals(4, sub2.getBaseSub2Field());
-        assertEquals(BaseSub2.class, sub2.getClass());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testLeafList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        List list = rel.getBaseSub1Sub2List();
-        assertEquals(1, list.size());
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(0);
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-    }
-
-    public void testEagerLeafList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("baseSub1Sub2List");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(2, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        List list = rel.getBaseSub1Sub2List();
-        assertEquals(1, list.size());
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(0);
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testMidList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertNotSQL(_outer);
-        sql.clear();
-
-        List list = rel.getBaseSub1List();
-        assertEquals(2, list.size());
-        BaseSub1 sub1 = (BaseSub1) list.get(0);
-        assertEquals(2, sub1.getBaseField());
-        assertEquals(3, sub1.getBaseSub1Field());
-        assertEquals(BaseSub1.class, sub1.getClass());
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(1);
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }
-
-    public void testEagerMidList()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getFetchPlan().addFetchGroup("baseSub1List");
-        Relations rel = (Relations) pm.getObjectId(_oid);
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-        sql.clear();
-
-        List list = rel.getBaseSub1List();
-        assertEquals(2, list.size());
-        BaseSub1 sub1 = (BaseSub1) list.get(0);
-        assertEquals(2, sub1.getBaseField());
-        assertEquals(3, sub1.getBaseSub1Field());
-        assertEquals(BaseSub1.class, sub1.getClass());
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(1);
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(0, sql.size());
-    }
-
-    public void testProjections()
-        throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createNativeQuery("",Relations.class);
-        //FIXME jthomas
-        /*
-        q.setResult("base, baseSub1, baseSub1Sub2");
-        q.setUnique(true);
-        Object[] res = (Object[]) q.execute();
-         */
-        Object[] res=null;
-        assertNotNull(res);
-        assertEquals(3, res.length);
-
-        BaseSub2 sub2 = (BaseSub2) res[0];
-        assertEquals(3, sub2.getBaseField());
-        assertEquals(4, sub2.getBaseSub2Field());
-        assertEquals(BaseSub2.class, sub2.getClass());
-
-        BaseSub1 sub1 = (BaseSub1) res[1];
-        assertEquals(2, sub1.getBaseField());
-        assertEquals(3, sub1.getBaseSub1Field());
-        assertEquals(BaseSub1.class, sub1.getClass());
-
-        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) res[2];
-        assertEquals(4, sub1sub2.getBaseField());
-        assertEquals(5, sub1sub2.getBaseSub1Field());
-        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
-        pm.close();
-
-        assertEquals(1, sql.size());
-        assertSQL(_outer);
-    }    
-}
+/*
+ * TestSubclassJoinRelations.java
+ *
+ * Created on October 5, 2006, 4:28 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.meta.vertical;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.Join;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestSubclassJoinRelations extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase 
+{
+    private String _outer = "OUTER";
+    private Object _oid = null;
+    
+    /** Creates a new instance of TestSubclassJoinRelations */
+    public TestSubclassJoinRelations(String name) 
+    {
+    	super(name);
+    }
+    
+    public boolean skipTest() {
+        //FIXME 
+        /*
+        return super.skipTest()
+            || ((JDBCConfiguration) getConfiguration()).
+            getDBDictionaryInstance().joinSyntax == Join.SYNTAX_TRADITIONAL;
+         */
+        return false;
+    }
+
+    public void setUpTestCase() {
+        // make sure all classes are registered
+        Class[] reg = new Class[]{
+            Base.class, BaseSub1.class, BaseSub2.class,
+            BaseSub1Sub1.class, BaseSub1Sub2.class,
+        };
+
+        if (((JDBCConfiguration) getConfiguration()).getDBDictionaryInstance().
+            joinSyntax == Join.SYNTAX_DATABASE)
+            _outer = "(+)";
+
+       deleteAll(Relations.class);
+       deleteAll(Base.class);
+
+        Relations rel = new Relations();
+        BaseSub2 sub2 = new BaseSub2();
+        sub2.setBaseField(3);
+        sub2.setBaseSub2Field(4);
+        rel.setBase(sub2);
+
+        BaseSub1 sub1 = new BaseSub1();
+        sub1.setBaseField(2);
+        sub1.setBaseSub1Field(3);
+        rel.setBaseSub1(sub1);
+
+        BaseSub1Sub2 sub1sub2 = new BaseSub1Sub2();
+        sub1sub2.setBaseField(4);
+        sub1sub2.setBaseSub1Field(5);
+        sub1sub2.setBaseSub1Sub2Field(6);
+        rel.setBaseSub1Sub2(sub1sub2);
+
+        Base base = new Base();
+        base.setBaseField(1);
+        rel.getBaseList().add(base);
+        rel.getBaseList().add(sub2);
+
+        rel.getBaseSub1List().add(sub1);
+        rel.getBaseSub1List().add(sub1sub2);
+
+        rel.getBaseSub1Sub2List().add(sub1sub2);
+
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(rel);
+        endTx(pm);;
+        _oid = pm.getObjectId(rel);
+        pm.close();
+    }
+
+    public void testNullOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        assertNull(rel.getNullBase());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testEagerNullOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("nullBase");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        assertNull(rel.getNullBase());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testEmptyBaseList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        assertEquals(0, rel.getEmptyBaseList().size());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+
+    public void testEagerEmptyBaseList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("emptyBaseList");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        assertEquals(0, rel.getEmptyBaseList().size());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testBaseOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        BaseSub2 sub2 = (BaseSub2) rel.getBase();
+        assertEquals(3, sub2.getBaseField());
+        assertEquals(4, sub2.getBaseSub2Field());
+        assertEquals(BaseSub2.class, sub2.getClass());
+        pm.close();
+
+        assertEquals(sql.toString(), 1, sql.size());
+        assertSQL(_outer);
+    }
+
+    public void testEagerBaseOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("base");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        BaseSub2 sub2 = (BaseSub2) rel.getBase();
+        assertEquals(3, sub2.getBaseField());
+        assertEquals(4, sub2.getBaseSub2Field());
+        assertEquals(BaseSub2.class, sub2.getClass());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testLeafOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) rel.getBaseSub1Sub2();
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+    }
+
+    public void testEagerLeafOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("baseSub1Sub2");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) rel.getBaseSub1Sub2();
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testMidOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        BaseSub1 sub1 = (BaseSub1) rel.getBaseSub1();
+        assertEquals(2, sub1.getBaseField());
+        assertEquals(3, sub1.getBaseSub1Field());
+        assertEquals(BaseSub1.class, sub1.getClass());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+
+    public void testEagerMidOneOne()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("baseSub1");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        BaseSub1 sub1 = (BaseSub1) rel.getBaseSub1();
+        assertEquals(2, sub1.getBaseField());
+        assertEquals(3, sub1.getBaseSub1Field());
+        assertEquals(BaseSub1.class, sub1.getClass());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testBaseList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        List list = rel.getBaseList();
+        assertEquals(2, list.size());
+        Base base = (Base) list.get(0);
+        assertEquals(1, base.getBaseField());
+        assertEquals(Base.class, base.getClass());
+        BaseSub2 sub2 = (BaseSub2) list.get(1);
+        assertEquals(3, sub2.getBaseField());
+        assertEquals(4, sub2.getBaseSub2Field());
+        assertEquals(BaseSub2.class, sub2.getClass());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+
+    public void testEagerBaseList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("baseList");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        List list = rel.getBaseList();
+        assertEquals(2, list.size());
+        Base base = (Base) list.get(0);
+        assertEquals(1, base.getBaseField());
+        assertEquals(Base.class, base.getClass());
+        BaseSub2 sub2 = (BaseSub2) list.get(1);
+        assertEquals(3, sub2.getBaseField());
+        assertEquals(4, sub2.getBaseSub2Field());
+        assertEquals(BaseSub2.class, sub2.getClass());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testLeafList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        List list = rel.getBaseSub1Sub2List();
+        assertEquals(1, list.size());
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(0);
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+    }
+
+    public void testEagerLeafList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("baseSub1Sub2List");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(2, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        List list = rel.getBaseSub1Sub2List();
+        assertEquals(1, list.size());
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(0);
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testMidList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertNotSQL(_outer);
+        sql.clear();
+
+        List list = rel.getBaseSub1List();
+        assertEquals(2, list.size());
+        BaseSub1 sub1 = (BaseSub1) list.get(0);
+        assertEquals(2, sub1.getBaseField());
+        assertEquals(3, sub1.getBaseSub1Field());
+        assertEquals(BaseSub1.class, sub1.getClass());
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(1);
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }
+
+    public void testEagerMidList()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getFetchPlan().addFetchGroup("baseSub1List");
+        Relations rel = (Relations) pm.getObjectId(_oid);
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+        sql.clear();
+
+        List list = rel.getBaseSub1List();
+        assertEquals(2, list.size());
+        BaseSub1 sub1 = (BaseSub1) list.get(0);
+        assertEquals(2, sub1.getBaseField());
+        assertEquals(3, sub1.getBaseSub1Field());
+        assertEquals(BaseSub1.class, sub1.getClass());
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) list.get(1);
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(0, sql.size());
+    }
+
+    public void testProjections()
+        throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createNativeQuery("",Relations.class);
+        //FIXME jthomas
+        /*
+        q.setResult("base, baseSub1, baseSub1Sub2");
+        q.setUnique(true);
+        Object[] res = (Object[]) q.execute();
+         */
+        Object[] res=null;
+        assertNotNull(res);
+        assertEquals(3, res.length);
+
+        BaseSub2 sub2 = (BaseSub2) res[0];
+        assertEquals(3, sub2.getBaseField());
+        assertEquals(4, sub2.getBaseSub2Field());
+        assertEquals(BaseSub2.class, sub2.getClass());
+
+        BaseSub1 sub1 = (BaseSub1) res[1];
+        assertEquals(2, sub1.getBaseField());
+        assertEquals(3, sub1.getBaseSub1Field());
+        assertEquals(BaseSub1.class, sub1.getClass());
+
+        BaseSub1Sub2 sub1sub2 = (BaseSub1Sub2) res[2];
+        assertEquals(4, sub1sub2.getBaseField());
+        assertEquals(5, sub1sub2.getBaseSub1Field());
+        assertEquals(6, sub1sub2.getBaseSub1Sub2Field());
+        pm.close();
+
+        assertEquals(1, sql.size());
+        assertSQL(_outer);
+    }    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/JDBCTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/JDBCTestCase.java
index 897b10a..dab4bab 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/JDBCTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/JDBCTestCase.java
@@ -1,78 +1,78 @@
-/*
- * JDBCTestCase.java
- *
- * Created on October 6, 2006, 10:34 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.util.*;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public abstract class JDBCTestCase extends AbstractTestCase {
-    
-    /** Creates a new instance of JDBCTestCase */
-    public JDBCTestCase() {
-    }
-    
-    
-    public JDBCTestCase(String name) {
-        super(name);
-    }
-    
-    public Class getDefaultInheritanceStrategy() {
-        return getClassMapping(RuntimeTest2.class).getStrategy().getClass();
-    }
-    
-    public ClassMapping getClassMapping(Class c) {
-        OpenJPAConfiguration jdoConf = getConfiguration();
-        return ((JDBCConfiguration) jdoConf).getMappingRepositoryInstance().
-                getMapping(c, getClass().getClassLoader(), true);
-    }
-    
-    public FieldMapping getFieldMapping(Class c, String field) {
-        return getClassMapping(c).getFieldMapping(field);
-    }
-    
-    public boolean isInheritanceStrategyVertical() {
-        return VerticalClassStrategy.class.
-                isAssignableFrom(getDefaultInheritanceStrategy());
-    }
-    
-}
+/*
+ * JDBCTestCase.java
+ *
+ * Created on October 6, 2006, 10:34 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.*;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public abstract class JDBCTestCase extends AbstractTestCase {
+    
+    /** Creates a new instance of JDBCTestCase */
+    public JDBCTestCase() {
+    }
+    
+    
+    public JDBCTestCase(String name) {
+        super(name);
+    }
+    
+    public Class getDefaultInheritanceStrategy() {
+        return getClassMapping(RuntimeTest2.class).getStrategy().getClass();
+    }
+    
+    public ClassMapping getClassMapping(Class c) {
+        OpenJPAConfiguration jdoConf = getConfiguration();
+        return ((JDBCConfiguration) jdoConf).getMappingRepositoryInstance().
+                getMapping(c, getClass().getClassLoader(), true);
+    }
+    
+    public FieldMapping getFieldMapping(Class c, String field) {
+        return getClassMapping(c).getFieldMapping(field);
+    }
+    
+    public boolean isInheritanceStrategyVertical() {
+        return VerticalClassStrategy.class.
+                isAssignableFrom(getDefaultInheritanceStrategy());
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestEJBQLSelectNPlusOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestEJBQLSelectNPlusOne.java
index ba899ea..6769f17 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestEJBQLSelectNPlusOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestEJBQLSelectNPlusOne.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.*;
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import junit.framework.*;
-
-public class TestEJBQLSelectNPlusOne extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-	public TestEJBQLSelectNPlusOne(String name)
-	{
-		super(name);
-	}
-
-	public void setUp()
-	{
-		deleteAll (RuntimeTest1.class);
-		EntityManager pm = currentEntityManager();
-		pm.getTransaction ().begin ();
-		pm.persist(new RuntimeTest1("foo", 3));
-		endTx(pm);
-		endEm(pm);
-	}
-
-	public void testSimpleEJBQLQuery() throws Exception
-	{
-		EntityManager pm = currentEntityManager();
-		// run a JDOQL query first to take care of any class-loading issues
-		List l = pm.createQuery("select object(o) from " + RuntimeTest1.class.getSimpleName()+" o").getResultList();
-
-		// now run the actual test.
-		assertEquals(1, l.size());
-		endEm(pm);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.*;
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import junit.framework.*;
+
+public class TestEJBQLSelectNPlusOne extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+	public TestEJBQLSelectNPlusOne(String name)
+	{
+		super(name);
+	}
+
+	public void setUp()
+	{
+		deleteAll (RuntimeTest1.class);
+		EntityManager pm = currentEntityManager();
+		pm.getTransaction ().begin ();
+		pm.persist(new RuntimeTest1("foo", 3));
+		endTx(pm);
+		endEm(pm);
+	}
+
+	public void testSimpleEJBQLQuery() throws Exception
+	{
+		EntityManager pm = currentEntityManager();
+		// run a JDOQL query first to take care of any class-loading issues
+		List l = pm.createQuery("select object(o) from " + RuntimeTest1.class.getSimpleName()+" o").getResultList();
+
+		// now run the actual test.
+		assertEquals(1, l.size());
+		endEm(pm);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestGroupByQuery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestGroupByQuery.java
index 0af7321..825bc92 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestGroupByQuery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestGroupByQuery.java
@@ -1,84 +1,84 @@
-/*
- * TestLockGroupsWithHorizontalBaseType.java
- *
- * Created on October 4, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.jdbc.query.domain.IndoorGame;
-import org.apache.openjpa.persistence.jdbc.query.domain.Scrabble;
-import org.apache.openjpa.persistence.jdbc.query.domain.Chess;
-import org.apache.openjpa.persistence.jdbc.query.domain.Game;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests GROUP BY in sub query does not get parsed by owning query.
- * 
- * Further details can be found in <A
- * HREF="https://issues.apache.org/jira/browse/OPENJPA-28">OPENJPA-28</A>
- * 
- * @author Pinaki Poddar
- * 
- */
-public class TestGroupByQuery extends SingleEMFTestCase {
-	public void setUp() {
-		super.setUp(DROP_TABLES, Game.class, IndoorGame.class, Scrabble.class,
-				Chess.class);
-		try {
-			createData();
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	void createData() throws Exception {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		Class[] classes = { Game.class, IndoorGame.class, Scrabble.class,
-				Chess.class };
-		for (Class cls : classes) {
-			for (int i = 1; i <= 4; i++) {
-				Game p = (Game) cls.newInstance();
-				p.setName(cls.getSimpleName() + "-" + i);
-				em.persist(p);
-			}
-		}
-		em.getTransaction().commit();
-	}
-
-	public void testGroupBy() {
-		String jpql = "SELECT g.name, g.nTile FROM Scrabble g WHERE "
-				+ "(g.name = ANY(SELECT g1.name FROM Scrabble g1 "
-				+ "GROUP BY g1.name )) ORDER BY g.name";
-		EntityManager em = emf.createEntityManager();
-
-		List<IndoorGame> employees = em.createQuery(jpql).getResultList();
-
-	}
-}
+/*
+ * TestLockGroupsWithHorizontalBaseType.java
+ *
+ * Created on October 4, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.jdbc.query.domain.IndoorGame;
+import org.apache.openjpa.persistence.jdbc.query.domain.Scrabble;
+import org.apache.openjpa.persistence.jdbc.query.domain.Chess;
+import org.apache.openjpa.persistence.jdbc.query.domain.Game;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests GROUP BY in sub query does not get parsed by owning query.
+ * 
+ * Further details can be found in <A
+ * HREF="https://issues.apache.org/jira/browse/OPENJPA-28">OPENJPA-28</A>
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class TestGroupByQuery extends SingleEMFTestCase {
+	public void setUp() {
+		super.setUp(DROP_TABLES, Game.class, IndoorGame.class, Scrabble.class,
+				Chess.class);
+		try {
+			createData();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	void createData() throws Exception {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Class[] classes = { Game.class, IndoorGame.class, Scrabble.class,
+				Chess.class };
+		for (Class cls : classes) {
+			for (int i = 1; i <= 4; i++) {
+				Game p = (Game) cls.newInstance();
+				p.setName(cls.getSimpleName() + "-" + i);
+				em.persist(p);
+			}
+		}
+		em.getTransaction().commit();
+	}
+
+	public void testGroupBy() {
+		String jpql = "SELECT g.name, g.nTile FROM Scrabble g WHERE "
+				+ "(g.name = ANY(SELECT g1.name FROM Scrabble g1 "
+				+ "GROUP BY g1.name )) ORDER BY g.name";
+		EntityManager em = emf.createEntityManager();
+
+		List<IndoorGame> employees = em.createQuery(jpql).getResultList();
+
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestJDBCGrouping.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestJDBCGrouping.java
index 4d60de1..76943bd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestJDBCGrouping.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestJDBCGrouping.java
@@ -1,30 +1,30 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.query.GroupingTestCase;
-
-public class TestJDBCGrouping extends GroupingTestCase {
-
-    protected void prepareQuery(Query q) {
-        // nothing to do for JDBC case
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.query.GroupingTestCase;
+
+public class TestJDBCGrouping extends GroupingTestCase {
+
+    protected void prepareQuery(Query q) {
+        // nothing to do for JDBC case
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNamedSQLQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNamedSQLQueries.java
index 917f46c..67ad1da 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNamedSQLQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNamedSQLQueries.java
@@ -1,110 +1,110 @@
-/*
- * TestNamedSQLQueries.java
- *
- * Created on October 5, 2006, 5:26 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.util.*;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestNamedSQLQueries extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-     
-    
-    /** Creates a new instance of TestNamedSQLQueries */
-    public TestNamedSQLQueries() {
-    }
-    
-    public TestNamedSQLQueries(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-       deleteAll(NamedSQL.class);
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        NamedSQL pc;
-        for (int i = 0; i < 10; i++) {
-            pc = new NamedSQL();
-            if (i < 5)
-                pc.setNum(4);
-            else
-                pc.setNum(i + 10);
-            pm.persist(pc);
-        }
-        endTx(pm);;
-        pm.close();
-    }
-
-    public void testNamedQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createNativeQuery("cls",NamedSQL.class);
-
-        assertEquals("javax.jdo.query.SQL", ((OpenJPAQuery) q).getLanguage());
-        Collection results = (Collection) q.getCandidateCollection();
-        for (Iterator i = results.iterator(); i.hasNext();)
-            assertEquals(4, ((NamedSQL) i.next()).getNum());
-        assertEquals(5, results.size());
-        q.closeAll();
-        pm.close();
-    }
-
-    public void testSystem() {
-        // test top-level package.jdoquery
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        //FIXME jthomas
-        /*
-        OpenJPAQuery query = pm.newNamedQuery(null, "system2");
-        query.setUnique(true);
-        query.setResultClass(int.class);
-        Integer count = (Integer) query.execute();
-        assertEquals(20, count.intValue());
-        query.closeAll();
-
-        // test sql query in local package.jdoquery
-        query = pm.newNamedQuery(NamedSQL.class, "cls");
-        query.closeAll(); // force parsing of package query file
-        query = pm.newNamedQuery(null, "system");
-        query.setUnique(true);
-        query.setResultClass(int.class);
-        count = (Integer) query.execute();
-        assertEquals(20, count.intValue());
-        query.closeAll();
-        pm.close();
-         */
-    }
-    
-}
+/*
+ * TestNamedSQLQueries.java
+ *
+ * Created on October 5, 2006, 5:26 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.*;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestNamedSQLQueries extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+     
+    
+    /** Creates a new instance of TestNamedSQLQueries */
+    public TestNamedSQLQueries() {
+    }
+    
+    public TestNamedSQLQueries(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+       deleteAll(NamedSQL.class);
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        NamedSQL pc;
+        for (int i = 0; i < 10; i++) {
+            pc = new NamedSQL();
+            if (i < 5)
+                pc.setNum(4);
+            else
+                pc.setNum(i + 10);
+            pm.persist(pc);
+        }
+        endTx(pm);;
+        pm.close();
+    }
+
+    public void testNamedQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createNativeQuery("cls",NamedSQL.class);
+
+        assertEquals("javax.jdo.query.SQL", ((OpenJPAQuery) q).getLanguage());
+        Collection results = (Collection) q.getCandidateCollection();
+        for (Iterator i = results.iterator(); i.hasNext();)
+            assertEquals(4, ((NamedSQL) i.next()).getNum());
+        assertEquals(5, results.size());
+        q.closeAll();
+        pm.close();
+    }
+
+    public void testSystem() {
+        // test top-level package.jdoquery
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        //FIXME jthomas
+        /*
+        OpenJPAQuery query = pm.newNamedQuery(null, "system2");
+        query.setUnique(true);
+        query.setResultClass(int.class);
+        Integer count = (Integer) query.execute();
+        assertEquals(20, count.intValue());
+        query.closeAll();
+
+        // test sql query in local package.jdoquery
+        query = pm.newNamedQuery(NamedSQL.class, "cls");
+        query.closeAll(); // force parsing of package query file
+        query = pm.newNamedQuery(null, "system");
+        query.setUnique(true);
+        query.setResultClass(int.class);
+        count = (Integer) query.execute();
+        assertEquals(20, count.intValue());
+        query.closeAll();
+        pm.close();
+         */
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNativeQueryParameterBinding.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNativeQueryParameterBinding.java
index 10b7319..d848675 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNativeQueryParameterBinding.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestNativeQueryParameterBinding.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.jdbc.query.domain.Applicant;
-import org.apache.openjpa.persistence.jdbc.query.domain.Application;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests that Native queries use only 1-based positional parameters and 
- * disallows named parameters.
- * 
- * Originally reported in 
- * <A HRE="http://issues.apache.org/jira/browse/OPENJPA-112>OPENJPA-112</A>
- *  
- * @author Pinaki Poddar
- *
- */
-public class TestNativeQueryParameterBinding extends SingleEMFTestCase {
-	private static Class NO_ERROR = null;
-	
-	@Override
-	public void setUp() throws Exception {
-		super.setUp(CLEAR_TABLES);
-	}
-	
-	public void testNamedParameterInNativeQueryIsNotValid() {
-		String sql = "SELECT * FROM Application WHERE id=:id";
-		verifyParams(sql, IllegalArgumentException.class, "id", 10);
-	}
-	
-	public void testPositionalParameterInNativeQueryIsValid() {
-		String sql = "SELECT * FROM Application WHERE id=?1";
-		verifyParams(sql, NO_ERROR, 1, 10);
-	}
-	
-	public void testZeroPositionalParameterInNativeQueryIsNotValid() {
-		String sql = "SELECT * FROM Application WHERE id=?1";
-		verifyParams(sql, IllegalArgumentException.class, 0, 10);
-	}
-	
-	void verifyParams(String jpql, Class error, Object...params) {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		Query query = em.createNativeQuery(jpql);
-		for (int i=0; params != null && i<params.length; i=+2) {
-			try {
-				if (params[i] instanceof Number) {
-					query.setParameter(((Number)params[i]).intValue(), params[i+1]);
-				} else { 
-					query.setParameter(params[i].toString(), params[i+1]);
-				}
-				if (error != null)
-					fail("Expected " + error.getName());
-			} catch (Exception e) {
-				if (error.isAssignableFrom(e.getClass())) {
-					System.err.println(e.getMessage());
-				} else {
-					e.printStackTrace();
-					fail();
-				}
-			} 
-				
-		}
-		em.getTransaction().commit();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.jdbc.query.domain.Applicant;
+import org.apache.openjpa.persistence.jdbc.query.domain.Application;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests that Native queries use only 1-based positional parameters and 
+ * disallows named parameters.
+ * 
+ * Originally reported in 
+ * <A HRE="http://issues.apache.org/jira/browse/OPENJPA-112>OPENJPA-112</A>
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+public class TestNativeQueryParameterBinding extends SingleEMFTestCase {
+	private static Class NO_ERROR = null;
+	
+	@Override
+	public void setUp() throws Exception {
+		super.setUp(CLEAR_TABLES);
+	}
+	
+	public void testNamedParameterInNativeQueryIsNotValid() {
+		String sql = "SELECT * FROM Application WHERE id=:id";
+		verifyParams(sql, IllegalArgumentException.class, "id", 10);
+	}
+	
+	public void testPositionalParameterInNativeQueryIsValid() {
+		String sql = "SELECT * FROM Application WHERE id=?1";
+		verifyParams(sql, NO_ERROR, 1, 10);
+	}
+	
+	public void testZeroPositionalParameterInNativeQueryIsNotValid() {
+		String sql = "SELECT * FROM Application WHERE id=?1";
+		verifyParams(sql, IllegalArgumentException.class, 0, 10);
+	}
+	
+	void verifyParams(String jpql, Class error, Object...params) {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Query query = em.createNativeQuery(jpql);
+		for (int i=0; params != null && i<params.length; i=+2) {
+			try {
+				if (params[i] instanceof Number) {
+					query.setParameter(((Number)params[i]).intValue(), params[i+1]);
+				} else { 
+					query.setParameter(params[i].toString(), params[i+1]);
+				}
+				if (error != null)
+					fail("Expected " + error.getName());
+			} catch (Exception e) {
+				if (error.isAssignableFrom(e.getClass())) {
+					System.err.println(e.getMessage());
+				} else {
+					e.printStackTrace();
+					fail();
+				}
+			} 
+				
+		}
+		em.getTransaction().commit();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestSQLQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestSQLQueries.java
index 40fad83..25aa14d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestSQLQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestSQLQueries.java
@@ -1,464 +1,464 @@
-/*
- * TestSQLQueries.java
- *
- * Created on October 5, 2006, 4:59 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-
-public class TestSQLQueries extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-     
-    
-    /** Creates a new instance of TestSQLQueries */
-    public TestSQLQueries(String name) 
-    {
-    	super(name);
-    }
-    
-    public TestSQLQueries() 
-    {}
-    
-    private String _tableName = null;
-    private String _fullTableName = null;
-    private String _pkColName = null;
-    private String _intColName = null;
-    private String _stringColName = null;
-    private String _relColName = null;
-    
-    public void setUp() {
-       deleteAll(RuntimeTest1.class);
-        
-        RuntimeTest1 pc1 = new RuntimeTest1("1", 1);
-        RuntimeTest1 pc2 = new RuntimeTest1("2", 2);
-        pc1.setSelfOneOne(pc2);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(pc1);
-        endTx(pm);;
-        
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) pm).getConfiguration();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        MappingRepository repos = conf.getMappingRepositoryInstance();
-        ClassMapping mapping = repos.getMapping(RuntimeTest1.class,
-                pm.getClassLoader(), true);
-        
-        _tableName = mapping.getTable().getName();
-        _fullTableName = dict.getFullName(mapping.getTable(), false);
-        _pkColName = mapping.getTable().getPrimaryKey().
-                getColumns()[0].getName();
-        _intColName = mapping.getFieldMapping("intField").
-                getColumns()[0].getName();
-        _stringColName = mapping.getFieldMapping("stringField").
-                getColumns()[0].getName();
-        _relColName = mapping.getFieldMapping("selfOneOne").
-                getColumns()[0].getName();
-        
-        pm.close();
-    }
-    
-    public void testStarQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select * from " + _fullTableName + " order by " + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testCompiledQuery()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select * from " + _fullTableName + " order by " + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        
-        //FIXME jthomas
-        //q = pm.createQuery(roundtrips(q, false));
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testCompiledLanguageQuery()
-    throws Exception {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select * from " + _fullTableName + " order by " + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        
-        //FIXME jthomas
-        //q = pm.createQuery("javax.jdo.query.SQL", roundtrips(q, false));
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testTableStarQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select " + _tableName + ".* from " + _fullTableName + " order by "
-                + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testColumnQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select " + _pkColName + ", " + _intColName + ", " + _stringColName
-                + " from " + _fullTableName + " order by " + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testJoinQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select t0.* from " + _fullTableName + " t0, "
-                + _fullTableName + " t1 where t0." + _relColName + " = t1."
-                + _pkColName + " and t1." + _intColName + " = 2");
-        q.setResultClass(RuntimeTest1.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testParameters() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select * from " + _fullTableName + " where 'foo' = ? and "
-                + _intColName + " = ?");
-        q.setResultClass(RuntimeTest1.class);
-        //FIXME jthomas
-        /*Iterator itr = ((Collection) q.execute("foo", new Integer(2))).
-                iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-         */
-        q.closeAll();
-        
-        Map params = new HashMap();
-        params.put(new Integer(1), "foo");
-        params.put(new Integer(2), new Integer(2));
-        //FIXME jthomas
-        /*itr = ((Collection) q.executeWithMap(params)).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
-        assertFalse(itr.hasNext());
-         */
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testOnlySelectedFieldsLoaded() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select " + _pkColName + ", " + _intColName + ", " + _stringColName
-                + " from " + _fullTableName + " order by " + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        RuntimeTest1 pc = (RuntimeTest1) itr.next();
-        OpenJPAStateManager sm = getStateManager(pc, pm);
-        assertTrue(sm.getLoaded().get(sm.getMetaData().
-                getField("intField").getIndex()));
-        assertTrue(sm.getLoaded().get(sm.getMetaData().
-                getField("stringField").getIndex()));
-        assertFalse(sm.getLoaded().get(sm.getMetaData().
-                getField("longField").getIndex()));
-        assertEquals("1", pc.getStringField());
-        assertFalse(sm.getLoaded().get(sm.getMetaData().
-                getField("longField").getIndex()));
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testSingleColumnClasslessQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select " + _stringColName + " from " + _fullTableName
-                + " order by " + _stringColName);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        assertEquals("1", itr.next());
-        assertTrue(itr.hasNext());
-        assertEquals("2", itr.next());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        
-        q.setResultClass(Object[].class);
-        itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        Object[] vals = (Object[]) itr.next();
-        assertEquals(1, vals.length);
-        assertEquals("1", vals[0]);
-        assertTrue(itr.hasNext());
-        vals = (Object[]) itr.next();
-        assertEquals(1, vals.length);
-        assertEquals("2", vals[0]);
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        
-        pm.close();
-    }
-    
-    public void testMultiColumnClasslessQuery() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select " + _intColName + ", " + _stringColName + " from "
-                + _fullTableName + " order by " + _stringColName);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        Object[] vals = (Object[]) itr.next();
-        assertEquals(2, vals.length);
-        assertEquals(1, ((Number) vals[0]).intValue());
-        assertEquals("1", vals[1]);
-        assertTrue(itr.hasNext());
-        vals = (Object[]) itr.next();
-        assertEquals(2, vals.length);
-        assertEquals(2, ((Number) vals[0]).intValue());
-        assertEquals("2", vals[1]);
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testResultClass() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select * from " + _fullTableName + " order by " + _intColName);
-        q.setResultClass(RuntimeTest1.class);
-        q.setResultClass(Holder.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        Holder holder = (Holder) itr.next();
-        assertEquals(0, holder.I);
-        assertNull(holder.S);
-        assertNotNull(holder.pc);
-        assertEquals("1", holder.pc.getStringField());
-        assertTrue(itr.hasNext());
-        holder = (Holder) itr.next();
-        assertEquals(0, holder.I);
-        assertNull(holder.S);
-        assertNotNull(holder.pc);
-        assertEquals("2", holder.pc.getStringField());
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    public void testClasslessProjection() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select " + _intColName + " as I, " + _stringColName + " as S from "
-                + _fullTableName + " order by " + _intColName);
-        q.setResultClass(Holder.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        Holder holder = (Holder) itr.next();
-        assertNull(holder.pc);
-        assertEquals(1, holder.I);
-        assertEquals("1", holder.S);
-        assertTrue(itr.hasNext());
-        holder = (Holder) itr.next();
-        assertNull(holder.pc);
-        assertEquals(2, holder.I);
-        assertEquals("2", holder.S);
-        assertFalse(itr.hasNext());
-        q.closeAll();
-        pm.close();
-    }
-    
-    /**
-     * Manual test to see if a relation will be eagerly loaded when SQL
-     * containing enough information is run. This is not run as part of
-     * the unit tests since we don't know if this behavior should be
-     * really expected to work or not.
-     */
-    public void relationLoadedTest() {
-       deleteAll(AttachD.class);
-       deleteAll(AttachA.class);
-        
-        AttachD d = new AttachD();
-        AttachA a = new AttachA();
-        d.setA(a);
-        
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-        pm.persist(d);
-        pm.getTransaction().commit();
-        pm.close();
-        
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) pm).getConfiguration();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        MappingRepository repos = conf.getMappingRepositoryInstance();
-        
-        ClassMapping mappingA = repos.getMapping(AttachD.class,
-                pm.getClassLoader(), true);
-        String tableNameA = mappingA.getTable().getName();
-        String fullTableNameA = dict.getFullName(mappingA.getTable(), false);
-        String relColNameA = mappingA.getFieldMapping("a").
-                getColumns()[0].getName();
-        
-        ClassMapping mappingD = repos.getMapping(AttachA.class,
-                pm.getClassLoader(), true);
-        String tableNameD = mappingD.getTable().getName();
-        String fullTableNameD = dict.getFullName(mappingD.getTable(), false);
-        String pkColNameD = mappingD.getTable().getPrimaryKey().
-                getColumns()[0].getName();
-        
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
-                "select t0.*, t1.* from "
-                + fullTableNameA + " t0, "
-                + fullTableNameD + " t1 "
-                + "where t0." + relColNameA + " = t1." + pkColNameD);
-        
-        // even the exact same SQL that Kodo generates will not
-        // eagerly load the relation
-        /*
-          q = pm.newQuery ("javax.jdo.query.SQL",
-              "SELECT t1.ID, t1.TYP, t1.VERSN, t1.ADBL, t1.AINT, "
-              + "t1.ASTR, t1.BDBL, t1.BINT, t1.BSTR, t1.CDBL, t1.CINT, "
-              + "t1.CSTR, t0.DDBL, t0.DINT, t0.DSTR "
-              + "FROM ATTACHD t0 LEFT OUTER JOIN ATTACHA t1 ON t0.A = t1.ID");
-         */
-        
-        q.setResultClass(AttachD.class);
-        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
-        assertTrue(itr.hasNext());
-        
-        d = (AttachD) itr.next();
-        // d.getDstr ();
-        
-        OpenJPAStateManager sm = getStateManager(d, pm);
-        assertTrue(sm.getLoaded().
-                get(sm.getMetaData().getField("a").getIndex()));
-        assertNotNull(d.getA());
-        assertFalse(itr.hasNext());
-        
-        q.closeAll();
-        pm.close();
-    }
-    
-    public static class Holder {
-        
-        public RuntimeTest1 pc;
-        public int I;
-        public String S;
-        
-        public void setRuntimeTest1(RuntimeTest1 pc) {
-            this.pc = pc;
-        }
-    }
-    
-    public static void main(String[] args)
-    throws Exception {
-        // main ();
-        
-        new TestSQLQueries().relationLoadedTest();
-    }
-    
-    private static Object roundtrips(Object orig, boolean validateEquality)
-    throws IOException, ClassNotFoundException {
-        assertNotNull(orig);
-        
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(bout);
-        out.writeObject(orig);
-        ByteArrayInputStream bin = new ByteArrayInputStream(
-                bout.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bin);
-        Object result = in.readObject();
-        
-        if (validateEquality) {
-            assertEquals(orig.hashCode(), result.hashCode());
-            assertEquals(orig, result);
-        }
-        
-        return result;
-    }
-    
-}
+/*
+ * TestSQLQueries.java
+ *
+ * Created on October 5, 2006, 4:59 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.MappingRepository;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+
+public class TestSQLQueries extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+     
+    
+    /** Creates a new instance of TestSQLQueries */
+    public TestSQLQueries(String name) 
+    {
+    	super(name);
+    }
+    
+    public TestSQLQueries() 
+    {}
+    
+    private String _tableName = null;
+    private String _fullTableName = null;
+    private String _pkColName = null;
+    private String _intColName = null;
+    private String _stringColName = null;
+    private String _relColName = null;
+    
+    public void setUp() {
+       deleteAll(RuntimeTest1.class);
+        
+        RuntimeTest1 pc1 = new RuntimeTest1("1", 1);
+        RuntimeTest1 pc2 = new RuntimeTest1("2", 2);
+        pc1.setSelfOneOne(pc2);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(pc1);
+        endTx(pm);;
+        
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) pm).getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        MappingRepository repos = conf.getMappingRepositoryInstance();
+        ClassMapping mapping = repos.getMapping(RuntimeTest1.class,
+                pm.getClassLoader(), true);
+        
+        _tableName = mapping.getTable().getName();
+        _fullTableName = dict.getFullName(mapping.getTable(), false);
+        _pkColName = mapping.getTable().getPrimaryKey().
+                getColumns()[0].getName();
+        _intColName = mapping.getFieldMapping("intField").
+                getColumns()[0].getName();
+        _stringColName = mapping.getFieldMapping("stringField").
+                getColumns()[0].getName();
+        _relColName = mapping.getFieldMapping("selfOneOne").
+                getColumns()[0].getName();
+        
+        pm.close();
+    }
+    
+    public void testStarQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select * from " + _fullTableName + " order by " + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testCompiledQuery()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select * from " + _fullTableName + " order by " + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        
+        //FIXME jthomas
+        //q = pm.createQuery(roundtrips(q, false));
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testCompiledLanguageQuery()
+    throws Exception {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select * from " + _fullTableName + " order by " + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        
+        //FIXME jthomas
+        //q = pm.createQuery("javax.jdo.query.SQL", roundtrips(q, false));
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testTableStarQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select " + _tableName + ".* from " + _fullTableName + " order by "
+                + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testColumnQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select " + _pkColName + ", " + _intColName + ", " + _stringColName
+                + " from " + _fullTableName + " order by " + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testJoinQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select t0.* from " + _fullTableName + " t0, "
+                + _fullTableName + " t1 where t0." + _relColName + " = t1."
+                + _pkColName + " and t1." + _intColName + " = 2");
+        q.setResultClass(RuntimeTest1.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testParameters() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select * from " + _fullTableName + " where 'foo' = ? and "
+                + _intColName + " = ?");
+        q.setResultClass(RuntimeTest1.class);
+        //FIXME jthomas
+        /*Iterator itr = ((Collection) q.execute("foo", new Integer(2))).
+                iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+         */
+        q.closeAll();
+        
+        Map params = new HashMap();
+        params.put(new Integer(1), "foo");
+        params.put(new Integer(2), new Integer(2));
+        //FIXME jthomas
+        /*itr = ((Collection) q.executeWithMap(params)).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("2", ((RuntimeTest1) itr.next()).getStringField());
+        assertFalse(itr.hasNext());
+         */
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testOnlySelectedFieldsLoaded() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select " + _pkColName + ", " + _intColName + ", " + _stringColName
+                + " from " + _fullTableName + " order by " + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        RuntimeTest1 pc = (RuntimeTest1) itr.next();
+        OpenJPAStateManager sm = getStateManager(pc, pm);
+        assertTrue(sm.getLoaded().get(sm.getMetaData().
+                getField("intField").getIndex()));
+        assertTrue(sm.getLoaded().get(sm.getMetaData().
+                getField("stringField").getIndex()));
+        assertFalse(sm.getLoaded().get(sm.getMetaData().
+                getField("longField").getIndex()));
+        assertEquals("1", pc.getStringField());
+        assertFalse(sm.getLoaded().get(sm.getMetaData().
+                getField("longField").getIndex()));
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testSingleColumnClasslessQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select " + _stringColName + " from " + _fullTableName
+                + " order by " + _stringColName);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("1", itr.next());
+        assertTrue(itr.hasNext());
+        assertEquals("2", itr.next());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        
+        q.setResultClass(Object[].class);
+        itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        Object[] vals = (Object[]) itr.next();
+        assertEquals(1, vals.length);
+        assertEquals("1", vals[0]);
+        assertTrue(itr.hasNext());
+        vals = (Object[]) itr.next();
+        assertEquals(1, vals.length);
+        assertEquals("2", vals[0]);
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        
+        pm.close();
+    }
+    
+    public void testMultiColumnClasslessQuery() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select " + _intColName + ", " + _stringColName + " from "
+                + _fullTableName + " order by " + _stringColName);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        Object[] vals = (Object[]) itr.next();
+        assertEquals(2, vals.length);
+        assertEquals(1, ((Number) vals[0]).intValue());
+        assertEquals("1", vals[1]);
+        assertTrue(itr.hasNext());
+        vals = (Object[]) itr.next();
+        assertEquals(2, vals.length);
+        assertEquals(2, ((Number) vals[0]).intValue());
+        assertEquals("2", vals[1]);
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testResultClass() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select * from " + _fullTableName + " order by " + _intColName);
+        q.setResultClass(RuntimeTest1.class);
+        q.setResultClass(Holder.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        Holder holder = (Holder) itr.next();
+        assertEquals(0, holder.I);
+        assertNull(holder.S);
+        assertNotNull(holder.pc);
+        assertEquals("1", holder.pc.getStringField());
+        assertTrue(itr.hasNext());
+        holder = (Holder) itr.next();
+        assertEquals(0, holder.I);
+        assertNull(holder.S);
+        assertNotNull(holder.pc);
+        assertEquals("2", holder.pc.getStringField());
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    public void testClasslessProjection() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select " + _intColName + " as I, " + _stringColName + " as S from "
+                + _fullTableName + " order by " + _intColName);
+        q.setResultClass(Holder.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        Holder holder = (Holder) itr.next();
+        assertNull(holder.pc);
+        assertEquals(1, holder.I);
+        assertEquals("1", holder.S);
+        assertTrue(itr.hasNext());
+        holder = (Holder) itr.next();
+        assertNull(holder.pc);
+        assertEquals(2, holder.I);
+        assertEquals("2", holder.S);
+        assertFalse(itr.hasNext());
+        q.closeAll();
+        pm.close();
+    }
+    
+    /**
+     * Manual test to see if a relation will be eagerly loaded when SQL
+     * containing enough information is run. This is not run as part of
+     * the unit tests since we don't know if this behavior should be
+     * really expected to work or not.
+     */
+    public void relationLoadedTest() {
+       deleteAll(AttachD.class);
+       deleteAll(AttachA.class);
+        
+        AttachD d = new AttachD();
+        AttachA a = new AttachA();
+        d.setA(a);
+        
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+        pm.persist(d);
+        pm.getTransaction().commit();
+        pm.close();
+        
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) pm).getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        MappingRepository repos = conf.getMappingRepositoryInstance();
+        
+        ClassMapping mappingA = repos.getMapping(AttachD.class,
+                pm.getClassLoader(), true);
+        String tableNameA = mappingA.getTable().getName();
+        String fullTableNameA = dict.getFullName(mappingA.getTable(), false);
+        String relColNameA = mappingA.getFieldMapping("a").
+                getColumns()[0].getName();
+        
+        ClassMapping mappingD = repos.getMapping(AttachA.class,
+                pm.getClassLoader(), true);
+        String tableNameD = mappingD.getTable().getName();
+        String fullTableNameD = dict.getFullName(mappingD.getTable(), false);
+        String pkColNameD = mappingD.getTable().getPrimaryKey().
+                getColumns()[0].getName();
+        
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        OpenJPAQuery q = pm.createQuery("javax.jdo.query.SQL",
+                "select t0.*, t1.* from "
+                + fullTableNameA + " t0, "
+                + fullTableNameD + " t1 "
+                + "where t0." + relColNameA + " = t1." + pkColNameD);
+        
+        // even the exact same SQL that Kodo generates will not
+        // eagerly load the relation
+        /*
+          q = pm.newQuery ("javax.jdo.query.SQL",
+              "SELECT t1.ID, t1.TYP, t1.VERSN, t1.ADBL, t1.AINT, "
+              + "t1.ASTR, t1.BDBL, t1.BINT, t1.BSTR, t1.CDBL, t1.CINT, "
+              + "t1.CSTR, t0.DDBL, t0.DINT, t0.DSTR "
+              + "FROM ATTACHD t0 LEFT OUTER JOIN ATTACHA t1 ON t0.A = t1.ID");
+         */
+        
+        q.setResultClass(AttachD.class);
+        Iterator itr = ((Collection) q.getCandidateCollection()).iterator();
+        assertTrue(itr.hasNext());
+        
+        d = (AttachD) itr.next();
+        // d.getDstr ();
+        
+        OpenJPAStateManager sm = getStateManager(d, pm);
+        assertTrue(sm.getLoaded().
+                get(sm.getMetaData().getField("a").getIndex()));
+        assertNotNull(d.getA());
+        assertFalse(itr.hasNext());
+        
+        q.closeAll();
+        pm.close();
+    }
+    
+    public static class Holder {
+        
+        public RuntimeTest1 pc;
+        public int I;
+        public String S;
+        
+        public void setRuntimeTest1(RuntimeTest1 pc) {
+            this.pc = pc;
+        }
+    }
+    
+    public static void main(String[] args)
+    throws Exception {
+        // main ();
+        
+        new TestSQLQueries().relationLoadedTest();
+    }
+    
+    private static Object roundtrips(Object orig, boolean validateEquality)
+    throws IOException, ClassNotFoundException {
+        assertNotNull(orig);
+        
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.writeObject(orig);
+        ByteArrayInputStream bin = new ByteArrayInputStream(
+                bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bin);
+        Object result = in.readObject();
+        
+        if (validateEquality) {
+            assertEquals(orig.hashCode(), result.hashCode());
+            assertEquals(orig, result);
+        }
+        
+        return result;
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestStringFunctions.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestStringFunctions.java
index bef95c6..bea38ad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestStringFunctions.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestStringFunctions.java
@@ -1,125 +1,125 @@
-/*
- * TestStringFunctions.java
- *
- * Created on October 5, 2006, 5:20 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.util.*;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestStringFunctions extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
-{
-    private OpenJPAEntityManager _pm = null;
-    private QueryTest1 _match = null;
-    
-    /** Creates a new instance of TestStringFunctions */
-    public TestStringFunctions(String name) 
-    {
-    	super(name);
-    }
-    
-    public void setUp() {
-       deleteAll(QueryTest1.class);
-
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        pm.getTransaction().begin();
-        QueryTest1 match = new QueryTest1();
-        match.setString("foobarbiz");
-        pm.persist(match);
-        QueryTest1 fail = new QueryTest1();
-        fail.setString("barbizraz");
-        pm.persist(fail);
-        pm.getTransaction().commit();
-        Object oid = pm.getObjectId(match);
-        pm.close();
-
-        _pm = (OpenJPAEntityManager)currentEntityManager();
-        _match = (QueryTest1) _pm.getObjectId(oid);
-    }
-
-    public void tearDown()
-        throws Exception {
-        if (_pm != null)
-            _pm.close();
-
-        super.tearDown();
-    }
-
-    public void testSubstring() {
-        assertMatch("string.substring (3) == 'barbiz'");
-        assertMatch("string.substring (3, 6) == 'bar'");
-    }
-
-    public void testIndexOf() {
-        assertMatch("string.indexOf ('bar') == 3");
-        assertMatch("string.indexOf (\"b\", 4) == 6");
-        assertMatch("string.indexOf ('b', 4) == 6");
-    }
-
-    public void testToLowerCase() {
-        assertMatch("string.toLowerCase () == 'foobarbiz'");
-        assertMatch("'FOOBARBIZ'.toLowerCase () == string");
-    }
-
-    public void testToUpperCase() {
-        assertMatch("string.toUpperCase () == 'FOOBARBIZ'");
-    }
-
-    public void testStartsWith() {
-        assertMatch("string.startsWith ('foobar')");
-        assertMatch("'foobarbizbaz'.startsWith (string)");
-    }
-
-    public void testEndsWith() {
-        assertMatch("string.endsWith ('barbiz')");
-        assertMatch("'bazfoobarbiz'.endsWith (string)");
-    }
-
-    public void testMatches() {
-        assertMatch("string.matches ('.oobar.*')");
-        assertMatch("string.matches ('FOO.AR.IZ(?i)')");
-    }
-
-    private void assertMatch(String filter) {
-        OpenJPAQuery q = _pm.createNativeQuery(filter,QueryTest1.class);
-        Collection res = (Collection) q.getCandidateCollection();
-        assertEquals(1, res.size());
-        assertEquals(_match, res.iterator().next());
-        q.closeAll();
-    }
-    
-}
+/*
+ * TestStringFunctions.java
+ *
+ * Created on October 5, 2006, 5:20 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.*;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestStringFunctions extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest
+{
+    private OpenJPAEntityManager _pm = null;
+    private QueryTest1 _match = null;
+    
+    /** Creates a new instance of TestStringFunctions */
+    public TestStringFunctions(String name) 
+    {
+    	super(name);
+    }
+    
+    public void setUp() {
+       deleteAll(QueryTest1.class);
+
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        pm.getTransaction().begin();
+        QueryTest1 match = new QueryTest1();
+        match.setString("foobarbiz");
+        pm.persist(match);
+        QueryTest1 fail = new QueryTest1();
+        fail.setString("barbizraz");
+        pm.persist(fail);
+        pm.getTransaction().commit();
+        Object oid = pm.getObjectId(match);
+        pm.close();
+
+        _pm = (OpenJPAEntityManager)currentEntityManager();
+        _match = (QueryTest1) _pm.getObjectId(oid);
+    }
+
+    public void tearDown()
+        throws Exception {
+        if (_pm != null)
+            _pm.close();
+
+        super.tearDown();
+    }
+
+    public void testSubstring() {
+        assertMatch("string.substring (3) == 'barbiz'");
+        assertMatch("string.substring (3, 6) == 'bar'");
+    }
+
+    public void testIndexOf() {
+        assertMatch("string.indexOf ('bar') == 3");
+        assertMatch("string.indexOf (\"b\", 4) == 6");
+        assertMatch("string.indexOf ('b', 4) == 6");
+    }
+
+    public void testToLowerCase() {
+        assertMatch("string.toLowerCase () == 'foobarbiz'");
+        assertMatch("'FOOBARBIZ'.toLowerCase () == string");
+    }
+
+    public void testToUpperCase() {
+        assertMatch("string.toUpperCase () == 'FOOBARBIZ'");
+    }
+
+    public void testStartsWith() {
+        assertMatch("string.startsWith ('foobar')");
+        assertMatch("'foobarbizbaz'.startsWith (string)");
+    }
+
+    public void testEndsWith() {
+        assertMatch("string.endsWith ('barbiz')");
+        assertMatch("'bazfoobarbiz'.endsWith (string)");
+    }
+
+    public void testMatches() {
+        assertMatch("string.matches ('.oobar.*')");
+        assertMatch("string.matches ('FOO.AR.IZ(?i)')");
+    }
+
+    private void assertMatch(String filter) {
+        OpenJPAQuery q = _pm.createNativeQuery(filter,QueryTest1.class);
+        Collection res = (Collection) q.getCandidateCollection();
+        assertEquals(1, res.size());
+        assertEquals(_match, res.iterator().next());
+        q.closeAll();
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
index 2b7053a..d6bbd08 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestUpdateSingleValuedAssociation.java
@@ -1,137 +1,137 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.jdbc.query;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.jdbc.query.domain.Application;
-import org.apache.openjpa.persistence.jdbc.query.domain.Applicant;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests that update query can set single-valued association field to non-null
- * or null values.
- * 
- * Originally reported in 
- * <A HRE="http://issues.apache.org/jira/browse/OPENJPA-533>OPENJPA-533</A>
- *  
- * @author Pinaki Poddar
- *
- */
-public class TestUpdateSingleValuedAssociation extends SingleEMFTestCase {
-	private static boolean MUST_BE_NULL = true;
-	
-	@Override
-	public void setUp() throws Exception {
-		super.setUp(CLEAR_TABLES, Application.class, Applicant.class);
-	}
-	
-	public void testUpdateSingleValuedAssociationToNullViaParameter() {
-		createApplicationWithNonNullApplicant();
-		assertUserNullity(!MUST_BE_NULL);
-		
-		String jpql = "UPDATE Application a SET a.user = :user";
-		updateByQuery(jpql, "user", null);
-		
-		assertUserNullity(MUST_BE_NULL);
-	}
-	
-	public void testUpdateSingleValuedAssociationToNullViaLiteral() {
-		createApplicationWithNonNullApplicant();
-		assertUserNullity(!MUST_BE_NULL);
-		
-		String jpql = "UPDATE Application a SET a.user = NULL";
-		updateByQuery(jpql);
-		
-		assertUserNullity(MUST_BE_NULL);
-	}
-	
-	public void testUpdateSingleValuedAssociationToNonNullViaParameter() {
-		Application pc = createApplicationWithNullApplicant();
-		assertNull(pc.getUser());
-		
-		String jpql = "UPDATE Application a SET a.user = :user";
-		Applicant newUser = createApplicant();
-		updateByQuery(jpql, "user", newUser);
-		
-		assertUserNullity(!MUST_BE_NULL);
-	}
-	
-	void assertUserNullity(boolean shouldBeNull) {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		List<Application> result = 
-			em.createQuery("SELECT a FROM Application a").getResultList();
-		assertFalse(result.isEmpty());
-		for (Application pc : result) {
-			Applicant user = pc.getUser();
-			if (shouldBeNull)
-				assertNull(user);
-			else
-				assertNotNull(user);
-		}
-		em.getTransaction().rollback();
-	}
-	
-	Application createApplicationWithNonNullApplicant() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		Application app = new Application();
-		Applicant user = new Applicant();
-		user.setName("Non-Null User");
-		app.setUser(user);
-		em.persist(app);
-		em.persist(user);
-		em.getTransaction().commit();
-		return app;
-	}
-	
-	Application createApplicationWithNullApplicant() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		Application app = new Application();
-		em.persist(app);
-		em.getTransaction().commit();
-		return app;
-	}
-	
-	Applicant createApplicant() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		Applicant user = new Applicant();
-		user.setName("Non-Null User");
-		em.persist(user);
-		em.getTransaction().commit();
-		return user;
-	}
-	
-	public void updateByQuery(String jpql, Object...params) {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		Query query = em.createQuery(jpql);
-		for (int i=0; params != null && i<params.length; i=+2) {
-			query.setParameter(params[i].toString(), params[i+1]);
-		}
-		query.executeUpdate();
-		em.getTransaction().commit();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.jdbc.query.domain.Application;
+import org.apache.openjpa.persistence.jdbc.query.domain.Applicant;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests that update query can set single-valued association field to non-null
+ * or null values.
+ * 
+ * Originally reported in 
+ * <A HRE="http://issues.apache.org/jira/browse/OPENJPA-533>OPENJPA-533</A>
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+public class TestUpdateSingleValuedAssociation extends SingleEMFTestCase {
+	private static boolean MUST_BE_NULL = true;
+	
+	@Override
+	public void setUp() throws Exception {
+		super.setUp(CLEAR_TABLES, Application.class, Applicant.class);
+	}
+	
+	public void testUpdateSingleValuedAssociationToNullViaParameter() {
+		createApplicationWithNonNullApplicant();
+		assertUserNullity(!MUST_BE_NULL);
+		
+		String jpql = "UPDATE Application a SET a.user = :user";
+		updateByQuery(jpql, "user", null);
+		
+		assertUserNullity(MUST_BE_NULL);
+	}
+	
+	public void testUpdateSingleValuedAssociationToNullViaLiteral() {
+		createApplicationWithNonNullApplicant();
+		assertUserNullity(!MUST_BE_NULL);
+		
+		String jpql = "UPDATE Application a SET a.user = NULL";
+		updateByQuery(jpql);
+		
+		assertUserNullity(MUST_BE_NULL);
+	}
+	
+	public void testUpdateSingleValuedAssociationToNonNullViaParameter() {
+		Application pc = createApplicationWithNullApplicant();
+		assertNull(pc.getUser());
+		
+		String jpql = "UPDATE Application a SET a.user = :user";
+		Applicant newUser = createApplicant();
+		updateByQuery(jpql, "user", newUser);
+		
+		assertUserNullity(!MUST_BE_NULL);
+	}
+	
+	void assertUserNullity(boolean shouldBeNull) {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		List<Application> result = 
+			em.createQuery("SELECT a FROM Application a").getResultList();
+		assertFalse(result.isEmpty());
+		for (Application pc : result) {
+			Applicant user = pc.getUser();
+			if (shouldBeNull)
+				assertNull(user);
+			else
+				assertNotNull(user);
+		}
+		em.getTransaction().rollback();
+	}
+	
+	Application createApplicationWithNonNullApplicant() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Application app = new Application();
+		Applicant user = new Applicant();
+		user.setName("Non-Null User");
+		app.setUser(user);
+		em.persist(app);
+		em.persist(user);
+		em.getTransaction().commit();
+		return app;
+	}
+	
+	Application createApplicationWithNullApplicant() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Application app = new Application();
+		em.persist(app);
+		em.getTransaction().commit();
+		return app;
+	}
+	
+	Applicant createApplicant() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Applicant user = new Applicant();
+		user.setName("Non-Null User");
+		em.persist(user);
+		em.getTransaction().commit();
+		return user;
+	}
+	
+	public void updateByQuery(String jpql, Object...params) {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Query query = em.createQuery(jpql);
+		for (int i=0; params != null && i<params.length; i=+2) {
+			query.setParameter(params[i].toString(), params[i+1]);
+		}
+		query.executeUpdate();
+		em.getTransaction().commit();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Department.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Department.java
index 83100b5..32917de 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Department.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Department.java
@@ -1,83 +1,83 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.jdbc.ElementClassCriteria;
-
-/**
- * Persistent entity with collection whose element type belongs to inheritance
- * hierarchy mapped to a SINGLE_TABLE. Hence relationship loading will require
- * 
- */
-@Entity
-@Table(name = "DEPT")
-@IdClass(DepartmentId.class)
-public class Department {
-
-	@Id
-	private String name;
-
-	@OneToMany(mappedBy = "dept", cascade = CascadeType.PERSIST)
-	@ElementClassCriteria
-	private Collection<PartTimeEmployee> partTimeEmployees;
-
-	@OneToMany(mappedBy = "dept", cascade = CascadeType.PERSIST)
-	@ElementClassCriteria
-	private Collection<FullTimeEmployee> fullTimeEmployees;
-
-	public Collection<FullTimeEmployee> getFullTimeEmployees() {
-		return fullTimeEmployees;
-	}
-
-	public void addEmployee(FullTimeEmployee e) {
-		if (fullTimeEmployees == null)
-			fullTimeEmployees = new ArrayList<FullTimeEmployee>();
-		this.fullTimeEmployees.add(e);
-		e.setDept(this);
-	}
-
-	public Collection<PartTimeEmployee> getPartTimeEmployees() {
-		return partTimeEmployees;
-	}
-
-	public void addEmployee(PartTimeEmployee e) {
-		if (partTimeEmployees == null)
-			partTimeEmployees = new ArrayList<PartTimeEmployee>();
-		this.partTimeEmployees.add(e);
-		e.setDept(this);
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.jdbc.ElementClassCriteria;
+
+/**
+ * Persistent entity with collection whose element type belongs to inheritance
+ * hierarchy mapped to a SINGLE_TABLE. Hence relationship loading will require
+ * 
+ */
+@Entity
+@Table(name = "DEPT")
+@IdClass(DepartmentId.class)
+public class Department {
+
+	@Id
+	private String name;
+
+	@OneToMany(mappedBy = "dept", cascade = CascadeType.PERSIST)
+	@ElementClassCriteria
+	private Collection<PartTimeEmployee> partTimeEmployees;
+
+	@OneToMany(mappedBy = "dept", cascade = CascadeType.PERSIST)
+	@ElementClassCriteria
+	private Collection<FullTimeEmployee> fullTimeEmployees;
+
+	public Collection<FullTimeEmployee> getFullTimeEmployees() {
+		return fullTimeEmployees;
+	}
+
+	public void addEmployee(FullTimeEmployee e) {
+		if (fullTimeEmployees == null)
+			fullTimeEmployees = new ArrayList<FullTimeEmployee>();
+		this.fullTimeEmployees.add(e);
+		e.setDept(this);
+	}
+
+	public Collection<PartTimeEmployee> getPartTimeEmployees() {
+		return partTimeEmployees;
+	}
+
+	public void addEmployee(PartTimeEmployee e) {
+		if (partTimeEmployees == null)
+			partTimeEmployees = new ArrayList<PartTimeEmployee>();
+		this.partTimeEmployees.add(e);
+		e.setDept(this);
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/DepartmentId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/DepartmentId.java
index a31e366..05eba56 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/DepartmentId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/DepartmentId.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import java.io.Serializable;
-
-public class DepartmentId implements Serializable {
-	private String name;
-
-	public DepartmentId() {
-		this(null);
-	}
-
-	public DepartmentId(String name) {
-		this.name = name;
-	}
-
-	public int hashCode() {
-		return name.hashCode();
-	}
-
-	public boolean equals(Object obj) {
-		if (this == obj) {
-			return true;
-		}
-		if (!(obj instanceof DepartmentId)) {
-			return false;
-		}
-
-		DepartmentId other = (DepartmentId) obj;
-		if (name == null) {
-			if (other.name != null) {
-				return false;
-			}
-		} else if (!name.equals(other.name)) {
-			return false;
-		}
-		return true;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import java.io.Serializable;
+
+public class DepartmentId implements Serializable {
+	private String name;
+
+	public DepartmentId() {
+		this(null);
+	}
+
+	public DepartmentId(String name) {
+		this.name = name;
+	}
+
+	public int hashCode() {
+		return name.hashCode();
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (!(obj instanceof DepartmentId)) {
+			return false;
+		}
+
+		DepartmentId other = (DepartmentId) obj;
+		if (name == null) {
+			if (other.name != null) {
+				return false;
+			}
+		} else if (!name.equals(other.name)) {
+			return false;
+		}
+		return true;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Employee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Employee.java
index 0b78aee..28491f9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Employee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Employee.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "EMP")
-@IdClass(EmployeeId.class)
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name = "TYPE")
-public abstract class Employee {
-
-	@Id
-	private String ssn;
-
-	@ManyToOne
-	private Department dept;
-
-	public String getSsn() {
-		return ssn;
-	}
-
-	public void setSsn(String ssn) {
-		this.ssn = ssn;
-	}
-
-	public Department getDept() {
-		return dept;
-	}
-
-	public void setDept(Department dept) {
-		this.dept = dept;
-	}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "EMP")
+@IdClass(EmployeeId.class)
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYPE")
+public abstract class Employee {
+
+	@Id
+	private String ssn;
+
+	@ManyToOne
+	private Department dept;
+
+	public String getSsn() {
+		return ssn;
+	}
+
+	public void setSsn(String ssn) {
+		this.ssn = ssn;
+	}
+
+	public Department getDept() {
+		return dept;
+	}
+
+	public void setDept(Department dept) {
+		this.dept = dept;
+	}
+
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/EmployeeId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/EmployeeId.java
index 2dc5e2b..c6046e6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/EmployeeId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/EmployeeId.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import java.io.Serializable;
-
-public class EmployeeId implements Serializable {
-	
-	private String ssn;
-	
-	public EmployeeId(){
-	}
-	public EmployeeId(String ssn){
-		this.ssn = ssn;
-	}
-    public boolean equals (Object other)
-    {
-        if (other == this)
-            return true;
-        if (!(other instanceof EmployeeId))
-            return false;
-
-        EmployeeId obj = (EmployeeId) other;
-		if (ssn == null) {
-			if (obj.ssn != null) {
-				return false;
-			}
-		} else if (!ssn.equals(obj.ssn)) {
-			return false;
-		}
-		
-        return (true);
-    }
-     
-   
-    public int hashCode ()
-    {
-        return (ssn.hashCode());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import java.io.Serializable;
+
+public class EmployeeId implements Serializable {
+	
+	private String ssn;
+	
+	public EmployeeId(){
+	}
+	public EmployeeId(String ssn){
+		this.ssn = ssn;
+	}
+    public boolean equals (Object other)
+    {
+        if (other == this)
+            return true;
+        if (!(other instanceof EmployeeId))
+            return false;
+
+        EmployeeId obj = (EmployeeId) other;
+		if (ssn == null) {
+			if (obj.ssn != null) {
+				return false;
+			}
+		} else if (!ssn.equals(obj.ssn)) {
+			return false;
+		}
+		
+        return (true);
+    }
+     
+   
+    public int hashCode ()
+    {
+        return (ssn.hashCode());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/FullTimeEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/FullTimeEmployee.java
index df2fb39..56cde58 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/FullTimeEmployee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/FullTimeEmployee.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity
-@DiscriminatorValue("F")
-public class FullTimeEmployee extends Employee {
-	@Column(name = "salary")
-	private double salary;
-
-	public double getSalary() {
-		return salary;
-	}
-
-	public void setSalary(double salary) {
-		this.salary = salary;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("F")
+public class FullTimeEmployee extends Employee {
+	@Column(name = "salary")
+	private double salary;
+
+	public double getSalary() {
+		return salary;
+	}
+
+	public void setSalary(double salary) {
+		this.salary = salary;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartTimeEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartTimeEmployee.java
index 986a189..ba15670 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartTimeEmployee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartTimeEmployee.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity
-@DiscriminatorValue("P")
-public class PartTimeEmployee extends Employee {
-	@Column(name = "wage")
-	private double hourlyWage;
-
-	public double getHourlyWage() {
-		return hourlyWage;
-	}
-
-	public void setHourlyWage(double hourlyWage) {
-		this.hourlyWage = hourlyWage;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("P")
+public class PartTimeEmployee extends Employee {
+	@Column(name = "wage")
+	private double hourlyWage;
+
+	public double getHourlyWage() {
+		return hourlyWage;
+	}
+
+	public void setHourlyWage(double hourlyWage) {
+		this.hourlyWage = hourlyWage;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestNonPrimaryKeyQueryParameters.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestNonPrimaryKeyQueryParameters.java
index 3808a49..06174fd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestNonPrimaryKeyQueryParameters.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestNonPrimaryKeyQueryParameters.java
@@ -1,180 +1,180 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.cache;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-
-/**
- * Tests that find() queries that use non-primary keys can be cached.
- * 
- * SQL Query Cache caches SQL queries generated to select single entity.
- * However, single instance queries may also join to other relations. Hence,
- * primary key and foreign keys are normally the parameters to these queries
- * which cached query binds again when being reused.
- * 
- * The test verifies the case where non-primary keys are used as query
- * parameters. The test employs a inheritance hierarchy mapped to SINGLE_TABLE.
- * When derived instances are used in relationship, the discriminator values
- * must be used in to join to the target type.
- * 
- * For further details, refer <A
- * HREF="https://issues.apache.org/jira/browse/OPENJPA-660">OPENJPA-660</A>
- * 
- * 
- * @author Pinaki Poddar
- * @author Vikram Bhatia
- * @author David Blevins
- */
-public class TestNonPrimaryKeyQueryParameters extends SQLListenerTestCase {
-	private static final int FULLTIME_EMPLOYEE_COUNT = 3;
-	private static final int PARTTIME_EMPLOYEE_COUNT = 2;
-    private static final int LINEITEM_PER_INVOICE = 1;
-	private static final String DEPT_NAME = "ENGINEERING";
-
-	public void setUp() {
-		super.setUp(CLEAR_TABLES, Department.class, Employee.class,
-				FullTimeEmployee.class, PartTimeEmployee.class,
-				Invoice.class, LineItem.class,
-				"openjpa.jdbc.QuerySQLCache", "true");
-		createDepartment(DEPT_NAME);
-		createInvoice();
-		sql.clear();
-	}
-
-	public void testSelectQueryWithPrimaryKeyParameter() {
-		EntityManager em = emf.createEntityManager();
-
-		Query query = em
-				.createQuery("SELECT d from Department d where d.name=?1");
-		query.setParameter(1, DEPT_NAME);
-		Department dept = (Department) query.getSingleResult();
-
-		assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
-				.size());
-		assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
-				.size());
-		assertSQL(".* AND t0.TYPE = .*");
-		em.close();
-	}
-
-	public void testSelectQueryWithNoParameter() {
-		EntityManager em = emf.createEntityManager();
-
-		Query query = em.createQuery("SELECT d from Department d");
-		query.setParameter(1, DEPT_NAME);
-		Department dept = (Department) query.getSingleResult();
-
-		assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
-				.size());
-		assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
-				.size());
-
-		assertSQL(".* AND t0.TYPE = .*");
-		em.close();
-	}
-
-	public void testFind() {
-		EntityManager em = emf.createEntityManager();
-
-		Department dept = em.find(Department.class, DEPT_NAME);
-
-		assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
-				.size());
-		assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
-				.size());
-
-		assertSQL(".* AND t0.TYPE = .*");
-		
-        Invoice invoice = em.find(Invoice.class, new InvoiceKey(1, "Red"));
-        List<LineItem> list = invoice.getLineItems();
-        assertEquals(LINEITEM_PER_INVOICE, list.size());
-		em.close();
-	}
-
-	public void testSelectSubClass() {
-		EntityManager em = emf.createEntityManager();
-
-		Query query = em.createQuery("SELECT e from FullTimeEmployee e");
-		assertEquals(FULLTIME_EMPLOYEE_COUNT, query.getResultList().size());
-
-		query = em.createQuery("SELECT e from PartTimeEmployee e");
-		assertEquals(PARTTIME_EMPLOYEE_COUNT, query.getResultList().size());
-
-		assertSQL(".* WHERE t0.TYPE = .*");
-	}
-
-	public void testSelectBaseClass() {
-		EntityManager em = emf.createEntityManager();
-
-		Query query = em.createQuery("SELECT e from Employee e");
-		assertEquals(FULLTIME_EMPLOYEE_COUNT + PARTTIME_EMPLOYEE_COUNT, query
-				.getResultList().size());
-		assertNotSQL(".* WHERE t0.TYPE = .*");
-	}
-
-	private void createDepartment(String deptName) {
-		if (count(Department.class) > 0)
-			return;
-
-		Department dept = new Department();
-		dept.setName(deptName);
-
-		for (int i = 1; i <= FULLTIME_EMPLOYEE_COUNT; i++) {
-			FullTimeEmployee e = new FullTimeEmployee();
-			e.setSsn("888-PP-001" + i);
-			e.setSalary(100000);
-			dept.addEmployee(e);
-		}
-		for (int i = 1; i <= PARTTIME_EMPLOYEE_COUNT; i++) {
-			PartTimeEmployee e = new PartTimeEmployee();
-			e.setSsn("999-PP-001" + i);
-			e.setHourlyWage(20);
-			dept.addEmployee(e);
-		}
-
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		em.persist(dept);
-		em.getTransaction().commit();
-		em.close();
-
-	}
-	
-    private void createInvoice() {
-        EntityManager em = emf.createEntityManager();
-        EntityTransaction tran = em.getTransaction();
-        tran.begin();
-        Invoice invoice = new Invoice(1, "Red", 1.30);
-        for (int i = 1;  i <= LINEITEM_PER_INVOICE; i++) {
-            LineItem item = new LineItem(String.valueOf(i), 10);
-            item.setInvoice(invoice);
-            invoice.getLineItems().add(item);
-            em.persist(invoice);
-        }
-        em.flush();
-        tran.commit();
-        em.close();        
-    }	
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.cache;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * Tests that find() queries that use non-primary keys can be cached.
+ * 
+ * SQL Query Cache caches SQL queries generated to select single entity.
+ * However, single instance queries may also join to other relations. Hence,
+ * primary key and foreign keys are normally the parameters to these queries
+ * which cached query binds again when being reused.
+ * 
+ * The test verifies the case where non-primary keys are used as query
+ * parameters. The test employs a inheritance hierarchy mapped to SINGLE_TABLE.
+ * When derived instances are used in relationship, the discriminator values
+ * must be used in to join to the target type.
+ * 
+ * For further details, refer <A
+ * HREF="https://issues.apache.org/jira/browse/OPENJPA-660">OPENJPA-660</A>
+ * 
+ * 
+ * @author Pinaki Poddar
+ * @author Vikram Bhatia
+ * @author David Blevins
+ */
+public class TestNonPrimaryKeyQueryParameters extends SQLListenerTestCase {
+	private static final int FULLTIME_EMPLOYEE_COUNT = 3;
+	private static final int PARTTIME_EMPLOYEE_COUNT = 2;
+    private static final int LINEITEM_PER_INVOICE = 1;
+	private static final String DEPT_NAME = "ENGINEERING";
+
+	public void setUp() {
+		super.setUp(CLEAR_TABLES, Department.class, Employee.class,
+				FullTimeEmployee.class, PartTimeEmployee.class,
+				Invoice.class, LineItem.class,
+				"openjpa.jdbc.QuerySQLCache", "true");
+		createDepartment(DEPT_NAME);
+		createInvoice();
+		sql.clear();
+	}
+
+	public void testSelectQueryWithPrimaryKeyParameter() {
+		EntityManager em = emf.createEntityManager();
+
+		Query query = em
+				.createQuery("SELECT d from Department d where d.name=?1");
+		query.setParameter(1, DEPT_NAME);
+		Department dept = (Department) query.getSingleResult();
+
+		assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
+				.size());
+		assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
+				.size());
+		assertSQL(".* AND t0.TYPE = .*");
+		em.close();
+	}
+
+	public void testSelectQueryWithNoParameter() {
+		EntityManager em = emf.createEntityManager();
+
+		Query query = em.createQuery("SELECT d from Department d");
+		query.setParameter(1, DEPT_NAME);
+		Department dept = (Department) query.getSingleResult();
+
+		assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
+				.size());
+		assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
+				.size());
+
+		assertSQL(".* AND t0.TYPE = .*");
+		em.close();
+	}
+
+	public void testFind() {
+		EntityManager em = emf.createEntityManager();
+
+		Department dept = em.find(Department.class, DEPT_NAME);
+
+		assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
+				.size());
+		assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
+				.size());
+
+		assertSQL(".* AND t0.TYPE = .*");
+		
+        Invoice invoice = em.find(Invoice.class, new InvoiceKey(1, "Red"));
+        List<LineItem> list = invoice.getLineItems();
+        assertEquals(LINEITEM_PER_INVOICE, list.size());
+		em.close();
+	}
+
+	public void testSelectSubClass() {
+		EntityManager em = emf.createEntityManager();
+
+		Query query = em.createQuery("SELECT e from FullTimeEmployee e");
+		assertEquals(FULLTIME_EMPLOYEE_COUNT, query.getResultList().size());
+
+		query = em.createQuery("SELECT e from PartTimeEmployee e");
+		assertEquals(PARTTIME_EMPLOYEE_COUNT, query.getResultList().size());
+
+		assertSQL(".* WHERE t0.TYPE = .*");
+	}
+
+	public void testSelectBaseClass() {
+		EntityManager em = emf.createEntityManager();
+
+		Query query = em.createQuery("SELECT e from Employee e");
+		assertEquals(FULLTIME_EMPLOYEE_COUNT + PARTTIME_EMPLOYEE_COUNT, query
+				.getResultList().size());
+		assertNotSQL(".* WHERE t0.TYPE = .*");
+	}
+
+	private void createDepartment(String deptName) {
+		if (count(Department.class) > 0)
+			return;
+
+		Department dept = new Department();
+		dept.setName(deptName);
+
+		for (int i = 1; i <= FULLTIME_EMPLOYEE_COUNT; i++) {
+			FullTimeEmployee e = new FullTimeEmployee();
+			e.setSsn("888-PP-001" + i);
+			e.setSalary(100000);
+			dept.addEmployee(e);
+		}
+		for (int i = 1; i <= PARTTIME_EMPLOYEE_COUNT; i++) {
+			PartTimeEmployee e = new PartTimeEmployee();
+			e.setSsn("999-PP-001" + i);
+			e.setHourlyWage(20);
+			dept.addEmployee(e);
+		}
+
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		em.persist(dept);
+		em.getTransaction().commit();
+		em.close();
+
+	}
+	
+    private void createInvoice() {
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tran = em.getTransaction();
+        tran.begin();
+        Invoice invoice = new Invoice(1, "Red", 1.30);
+        for (int i = 1;  i <= LINEITEM_PER_INVOICE; i++) {
+            LineItem item = new LineItem(String.valueOf(i), 10);
+            item.setInvoice(invoice);
+            invoice.getLineItems().add(item);
+            em.persist(invoice);
+        }
+        em.flush();
+        tran.commit();
+        em.close();        
+    }	
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
index 24d379a..54d266f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Applicant.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.domain;
-
-import javax.persistence.*;
-
-/**
- * Simple persistent entity as a target of uni-directional one-to-one 
- * association.
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class Applicant {
-	@Id
-	@GeneratedValue
-	private long id;
-
-	private String name;
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public long getId() {
-		return id;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.*;
+
+/**
+ * Simple persistent entity as a target of uni-directional one-to-one 
+ * association.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class Applicant {
+	@Id
+	@GeneratedValue
+	private long id;
+
+	private String name;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
index cc0a103..f6e6313 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Application.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.domain;
-
-import javax.persistence.*;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
-
-/**
- * Simple persistent entity as a source of uni-directional one-to-one 
- * association.
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class Application {
-	@Id
-	@GeneratedValue
-	private long id;
-
-	@ManyToOne
-	@JoinColumn(nullable = true)
-	@ForeignKey(deleteAction = ForeignKeyAction.NULL)
-	private Applicant user;
-
-	public Applicant getUser() {
-		return user;
-	}
-
-	public void setUser(Applicant user) {
-		this.user = user;
-	}
-
-	public long getId() {
-		return id;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+
+/**
+ * Simple persistent entity as a source of uni-directional one-to-one 
+ * association.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class Application {
+	@Id
+	@GeneratedValue
+	private long id;
+
+	@ManyToOne
+	@JoinColumn(nullable = true)
+	@ForeignKey(deleteAction = ForeignKeyAction.NULL)
+	private Applicant user;
+
+	public Applicant getUser() {
+		return user;
+	}
+
+	public void setUser(Applicant user) {
+		this.user = user;
+	}
+
+	public long getId() {
+		return id;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Chess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Chess.java
index 4d7a5bd..853d1c8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Chess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Chess.java
@@ -1,43 +1,43 @@
-/*
- * TestLockGroupsWithHorizontalBaseType.java
- *
- * Created on October 4, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.domain;
-
-import javax.persistence.Entity;
-
-@Entity
-public class Chess extends IndoorGame {
-	private int nPiece;
-
-	public int getPiece() {
-		return nPiece;
-	}
-
-	public void setPiece(int n) {
-		this.nPiece = n;
-	}
-}
+/*
+ * TestLockGroupsWithHorizontalBaseType.java
+ *
+ * Created on October 4, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.Entity;
+
+@Entity
+public class Chess extends IndoorGame {
+	private int nPiece;
+
+	public int getPiece() {
+		return nPiece;
+	}
+
+	public void setPiece(int n) {
+		this.nPiece = n;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Game.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Game.java
index de133a0..85d3a95 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Game.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Game.java
@@ -1,65 +1,65 @@
-/*
- * TestLockGroupsWithHorizontalBaseType.java
- *
- * Created on October 4, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.domain;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-/**
- * Simple unrelated persistent entity used to test logically union queries. 
- * This class is root of an inheritance hierarchy using TABLE PER CLASS 
- * strategy. Polymorphic queries on this class needs to run logical union
- * of queries on all known subclasses. 
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
-public class Game {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	private String name;
-
-	public long getId() {
-		return id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-}
+/*
+ * TestLockGroupsWithHorizontalBaseType.java
+ *
+ * Created on October 4, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+/**
+ * Simple unrelated persistent entity used to test logically union queries. 
+ * This class is root of an inheritance hierarchy using TABLE PER CLASS 
+ * strategy. Polymorphic queries on this class needs to run logical union
+ * of queries on all known subclasses. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
+public class Game {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	private String name;
+
+	public long getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/IndoorGame.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/IndoorGame.java
index ffe7384..6bfbe30 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/IndoorGame.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/IndoorGame.java
@@ -1,43 +1,43 @@
-/*
- * TestLockGroupsWithHorizontalBaseType.java
- *
- * Created on October 4, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.domain;
-
-import javax.persistence.Entity;
-
-@Entity
-public class IndoorGame extends Game {
-	private int nPlayer;
-
-	public int getPlayer() {
-		return nPlayer;
-	}
-
-	public void setPlayer(int n) {
-		this.nPlayer = n;
-	}
-}
+/*
+ * TestLockGroupsWithHorizontalBaseType.java
+ *
+ * Created on October 4, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.Entity;
+
+@Entity
+public class IndoorGame extends Game {
+	private int nPlayer;
+
+	public int getPlayer() {
+		return nPlayer;
+	}
+
+	public void setPlayer(int n) {
+		this.nPlayer = n;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Scrabble.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Scrabble.java
index fd03563..3aeaf52 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Scrabble.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/domain/Scrabble.java
@@ -1,44 +1,44 @@
-/*
- * TestLockGroupsWithHorizontalBaseType.java
- *
- * Created on October 4, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.query.domain;
-
-import javax.persistence.Entity;
-
-@Entity
-public class Scrabble extends IndoorGame {
-	private int nTile;
-
-	public int getTile() {
-		return nTile;
-	}
-
-	public void setTile(int n) {
-		this.nTile = n;
-	}
-
-}
+/*
+ * TestLockGroupsWithHorizontalBaseType.java
+ *
+ * Created on October 4, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.query.domain;
+
+import javax.persistence.Entity;
+
+@Entity
+public class Scrabble extends IndoorGame {
+	private int nTile;
+
+	public int getTile() {
+		return nTile;
+	}
+
+	public void setTile(int n) {
+		this.nTile = n;
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassDBSequenceFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassDBSequenceFactory.java
index b1b19b2..c276117 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassDBSequenceFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassDBSequenceFactory.java
@@ -1,237 +1,237 @@
-/*
- * TestClassDBSequenceFactory.java
- *
- * Created on October 6, 2006, 11:29 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.schema.Sequence;
-import org.apache.openjpa.kernel.Broker;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestClassDBSequenceFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    
-    /** Creates a new instance of TestClassDBSequenceFactory */
-    public TestClassDBSequenceFactory() {
-    }
-    
-    public TestClassDBSequenceFactory(String test) {
-        super(test);
-    }
-    
-    public void setUp() {
-       deleteAll(SeqE.class);
-    }
-    
-    boolean supportsPessimisticLocking() {
-        OpenJPAConfiguration conf = getConfiguration();
-        return conf instanceof JDBCConfiguration
-                && ((JDBCConfiguration) conf).getDBDictionaryInstance().
-                supportsSelectForUpdate;
-    }
-    
-    public void testVirtualSuperclass() {
-        
-        OpenJPAEntityManagerFactory pmf =(OpenJPAEntityManagerFactory)
-                getEmf(getProps());
-        OpenJPAEntityManager pm = (OpenJPAEntityManager) pmf.createEntityManager();
-        //FIXME jthomas
-        //Sequence gen = pm.getIdentitySequence(SeqF.class);
-        Sequence gen=null;
-        long next = ((Number) gen.getIncrement()).longValue();
-        //FIXME jthomas
-        //gen = pm.getIdentitySequence(SeqG.class);
-        assertEquals(next + 1, ((Number) gen.getIncrement()).longValue());
-        pm.close();
-        pmf.close();
-    }
-    
-    public void testIgnoreVirtualSuperclass() {
-        
-        Map props=new HashMap();
-        props.put("TableName", "JDO_CLASS_SEQUENCE");
-        props.put("IgnoreVirtual", "true");
-        OpenJPAEntityManagerFactory pmf =(OpenJPAEntityManagerFactory)
-                getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-        //FIXME jthomas
-        //Sequence gen = pm.getIdentitySequence(SeqF.class);
-        Sequence gen =null;
-        long next = ((Number) gen.getIncrement()).longValue();
-        //FIXME jthomas
-        //Sequence gen2 = pm.getIdentitySequence(SeqG.class);
-        Sequence gen2 =null;
-        long next2 = ((Number) gen2.getIncrement()).longValue();
-        if (next2 != next + 1)
-            return; // valid.
-        assertTrue(((Number) gen.getIncrement()).longValue() != next2 + 1);
-        
-        pm.close();
-        pmf.close();
-    }
-    
-    /**
-     * Based on reported bug case.
-     */
-    public void testNoSequenceHolesOnAttach() {
-        PerClassTestObject3 pc = new PerClassTestObject3();
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(pc);
-        endTx(pm);;
-        long id1 = pc.getId();
-        
-        pc = new PerClassTestObject3();
-        startTx(pm);;
-        pm.persist(pc);
-        long id2 = pc.getId();
-        endTx(pm);;
-        pm.close();
-        
-        pc = new PerClassTestObject3();
-        pm = (OpenJPAEntityManager)currentEntityManager();
-        startTx(pm);;
-        pm.persist(pc);
-        endTx(pm);;
-        long id3 = pc.getId();
-        pm.close();
-        
-        assertEquals(id1 + 1, id2);
-        assertEquals(id2 + 1, id3);
-    }
-    
-    /**
-     * Tests that all sequence numbers are unique and in order.
-     * Will fail for dbs without pessimistic locking.
-     */
-    public void testSequence()
-    throws Exception {
-        if (!(supportsPessimisticLocking()))
-            return;
-        
-        Set set = new HashSet();
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        Broker broker = getBrokerFactory().newBroker();
-        
-        
-        UpdateThread t1 = new UpdateThread(set, broker);
-        UpdateThread t2 = new UpdateThread(set, broker);
-        
-        t1.start();
-        t2.start();
-        t1.join();
-        t2.join();
-        
-        if (t1.error != null)
-            throw t1.error;
-        if (t2.error != null)
-            throw t2.error;
-        
-        assertEquals(102, set.size());
-    }
-    
-    public void testSequenceGenerator() {
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        
-        // make sure the sequence generator creates separate
-        // instances.
-        for (int i = 0; i < 100; i++) {
-            //FIXME jthomas
-            /*assertEquals(((Number) pm.getIdentitySequence(SeqD.class).
-                    next()).longValue() + 1,
-                    ((Number) pm.getIdentitySequence(SeqD.class).
-                    getIncrement()).longValue());
-             
-             */
-        }
-        // make sure the sequence generate is not the same as is
-        // used elsewhere
-        
-        for (int j = 0; j < 100; j++) {
-            //FIXME
-            /*
-            assertNotEquals(new Long(((Number) pm.getIdentitySequence
-                    (SeqA.class).getIncrement()).longValue() + 1),
-                    pm.getIdentitySequence(SeqD.class).next());
-             */
-        }
-    }
-    
-    public static void main(String[] args) {
-        //main();
-    }
-    private Map getProps() {
-        Map props=new HashMap();
-        props.put("openjpa.Sequence", "db-class(TableName=JDO_CLASS_SEQUENCE");
-        return props;
-    }
-    
-    
-    
-    private static class UpdateThread
-            extends Thread {
-        
-        private Set _set = null;
-        private Broker _broker = null;
-        public Exception error = null;
-        
-        public UpdateThread(Set set, Broker broker) {
-            _set = set;
-            _broker = broker;
-        }
-        
-        public void run() {
-            try {
-                ClassMapping mapping =
-                        ((JDBCConfiguration) _broker.getConfiguration()).
-                        getMappingRepositoryInstance().
-                        getMapping(SeqD.class, null, true);
-                ClassTableJDBCSeq seq = (ClassTableJDBCSeq)
-                _broker.getIdentitySequence(mapping);
-                for (int i = 0; i < 51; i++)
-                    _set.add(seq.next(_broker, mapping));
-            } catch (Exception e) {
-                error = e;
-            }
-        }
-    }
-}
+/*
+ * TestClassDBSequenceFactory.java
+ *
+ * Created on October 6, 2006, 11:29 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.schema.Sequence;
+import org.apache.openjpa.kernel.Broker;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestClassDBSequenceFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    
+    /** Creates a new instance of TestClassDBSequenceFactory */
+    public TestClassDBSequenceFactory() {
+    }
+    
+    public TestClassDBSequenceFactory(String test) {
+        super(test);
+    }
+    
+    public void setUp() {
+       deleteAll(SeqE.class);
+    }
+    
+    boolean supportsPessimisticLocking() {
+        OpenJPAConfiguration conf = getConfiguration();
+        return conf instanceof JDBCConfiguration
+                && ((JDBCConfiguration) conf).getDBDictionaryInstance().
+                supportsSelectForUpdate;
+    }
+    
+    public void testVirtualSuperclass() {
+        
+        OpenJPAEntityManagerFactory pmf =(OpenJPAEntityManagerFactory)
+                getEmf(getProps());
+        OpenJPAEntityManager pm = (OpenJPAEntityManager) pmf.createEntityManager();
+        //FIXME jthomas
+        //Sequence gen = pm.getIdentitySequence(SeqF.class);
+        Sequence gen=null;
+        long next = ((Number) gen.getIncrement()).longValue();
+        //FIXME jthomas
+        //gen = pm.getIdentitySequence(SeqG.class);
+        assertEquals(next + 1, ((Number) gen.getIncrement()).longValue());
+        pm.close();
+        pmf.close();
+    }
+    
+    public void testIgnoreVirtualSuperclass() {
+        
+        Map props=new HashMap();
+        props.put("TableName", "JDO_CLASS_SEQUENCE");
+        props.put("IgnoreVirtual", "true");
+        OpenJPAEntityManagerFactory pmf =(OpenJPAEntityManagerFactory)
+                getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+        //FIXME jthomas
+        //Sequence gen = pm.getIdentitySequence(SeqF.class);
+        Sequence gen =null;
+        long next = ((Number) gen.getIncrement()).longValue();
+        //FIXME jthomas
+        //Sequence gen2 = pm.getIdentitySequence(SeqG.class);
+        Sequence gen2 =null;
+        long next2 = ((Number) gen2.getIncrement()).longValue();
+        if (next2 != next + 1)
+            return; // valid.
+        assertTrue(((Number) gen.getIncrement()).longValue() != next2 + 1);
+        
+        pm.close();
+        pmf.close();
+    }
+    
+    /**
+     * Based on reported bug case.
+     */
+    public void testNoSequenceHolesOnAttach() {
+        PerClassTestObject3 pc = new PerClassTestObject3();
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(pc);
+        endTx(pm);;
+        long id1 = pc.getId();
+        
+        pc = new PerClassTestObject3();
+        startTx(pm);;
+        pm.persist(pc);
+        long id2 = pc.getId();
+        endTx(pm);;
+        pm.close();
+        
+        pc = new PerClassTestObject3();
+        pm = (OpenJPAEntityManager)currentEntityManager();
+        startTx(pm);;
+        pm.persist(pc);
+        endTx(pm);;
+        long id3 = pc.getId();
+        pm.close();
+        
+        assertEquals(id1 + 1, id2);
+        assertEquals(id2 + 1, id3);
+    }
+    
+    /**
+     * Tests that all sequence numbers are unique and in order.
+     * Will fail for dbs without pessimistic locking.
+     */
+    public void testSequence()
+    throws Exception {
+        if (!(supportsPessimisticLocking()))
+            return;
+        
+        Set set = new HashSet();
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        Broker broker = getBrokerFactory().newBroker();
+        
+        
+        UpdateThread t1 = new UpdateThread(set, broker);
+        UpdateThread t2 = new UpdateThread(set, broker);
+        
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+        
+        if (t1.error != null)
+            throw t1.error;
+        if (t2.error != null)
+            throw t2.error;
+        
+        assertEquals(102, set.size());
+    }
+    
+    public void testSequenceGenerator() {
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        
+        // make sure the sequence generator creates separate
+        // instances.
+        for (int i = 0; i < 100; i++) {
+            //FIXME jthomas
+            /*assertEquals(((Number) pm.getIdentitySequence(SeqD.class).
+                    next()).longValue() + 1,
+                    ((Number) pm.getIdentitySequence(SeqD.class).
+                    getIncrement()).longValue());
+             
+             */
+        }
+        // make sure the sequence generate is not the same as is
+        // used elsewhere
+        
+        for (int j = 0; j < 100; j++) {
+            //FIXME
+            /*
+            assertNotEquals(new Long(((Number) pm.getIdentitySequence
+                    (SeqA.class).getIncrement()).longValue() + 1),
+                    pm.getIdentitySequence(SeqD.class).next());
+             */
+        }
+    }
+    
+    public static void main(String[] args) {
+        //main();
+    }
+    private Map getProps() {
+        Map props=new HashMap();
+        props.put("openjpa.Sequence", "db-class(TableName=JDO_CLASS_SEQUENCE");
+        return props;
+    }
+    
+    
+    
+    private static class UpdateThread
+            extends Thread {
+        
+        private Set _set = null;
+        private Broker _broker = null;
+        public Exception error = null;
+        
+        public UpdateThread(Set set, Broker broker) {
+            _set = set;
+            _broker = broker;
+        }
+        
+        public void run() {
+            try {
+                ClassMapping mapping =
+                        ((JDBCConfiguration) _broker.getConfiguration()).
+                        getMappingRepositoryInstance().
+                        getMapping(SeqD.class, null, true);
+                ClassTableJDBCSeq seq = (ClassTableJDBCSeq)
+                _broker.getIdentitySequence(mapping);
+                for (int i = 0; i < 51; i++)
+                    _set.add(seq.next(_broker, mapping));
+            } catch (Exception e) {
+                error = e;
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassSequenceFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassSequenceFactory.java
index dcb7262..38ab5a8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassSequenceFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestClassSequenceFactory.java
@@ -1,208 +1,208 @@
-/*
- * TestClassSequenceFactory.java
- *
- * Created on October 6, 2006, 12:21 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.*;
-import javax.sql.DataSource;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
-import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest;
-
-
-public class TestClassSequenceFactory extends BaseJDBCTest{
-    
-
-    private static Map _sysprops = new HashMap();
-    
-    Broker _broker;
-    
-    /** Creates a new instance of TestClassSequenceFactory */
-    public TestClassSequenceFactory() {
-    }
-    public TestClassSequenceFactory(String test) {
-        super(test);
-    }
-    
-    public void setUp()
-    throws Exception {
-        JDBCConfiguration conf = new JDBCConfigurationImpl();
-        conf.fromProperties(getProperties());
-        if (!adjustConfiguration(conf))
-            return;
-        
-        String driver = conf.getConnectionDriverName().toLowerCase();
-        String [] sql = null;
-        
-        if (driver.indexOf("oracle") >= 0) {
-            sql = new String []{
-                "create sequence seqa_seq",
-                "create sequence seqb_seq"
-            };
-        }
-        
-        if (sql == null)
-            return;
-        
-        DataSource ds = conf.getDataSource2(null);
-        Connection c = ds.getConnection();
-        Statement s = null;
-        try {
-            s = c.createStatement();
-            for (int i = 0; i < sql.length; i++) {
-                try {
-                    s.execute(sql[i]);
-                } catch (SQLException sqe) {
-                }
-            }
-        } finally {
-            if (s != null)
-                try {
-                    s.close();
-                } catch (Exception e) {
-                }
-        }
-        
-        _broker = getBrokerFactory().newBroker();
-    }
-    
-    /**
-     * Tests that all sequence numbers are unique and in order.
-     */
-    public void testSequence()
-    throws Exception {
-        Set set = new HashSet();
-        
-        JDBCConfiguration conf = new JDBCConfigurationImpl();
-        conf.fromProperties(getProperties());
-        if (!adjustConfiguration(conf))
-            return;
-        Thread t1 = new UpdateThread(set, conf);
-        Thread t2 = new UpdateThread(set, conf);
-        
-        t1.start();
-        t2.start();
-        t1.join();
-        t2.join();
-        
-        assertEquals(102, set.size());
-    }
-    
-    public void testExtensions()
-    throws Exception {
-        JDBCConfiguration conf = new JDBCConfigurationImpl();
-        conf.fromProperties(getProperties());
-        if (!adjustConfiguration(conf))
-            return;
-        
-        ClassMapping aMapping = conf.getMappingRepositoryInstance().
-                getMapping(SeqA.class, null, true);
-        ClassMapping bMapping = conf.getMappingRepositoryInstance().
-                getMapping(SeqB.class, null, true);
-        ClassMapping cMapping = conf.getMappingRepositoryInstance().
-                getMapping(SeqC.class, null, true);
-        DataSource ds = conf.getDataSource2(null);
-        
-        // hold a and c and start b
-        
-        Seq seq = conf.getSequenceInstance();
-        long aid = ((Long) seq.next(_broker, aMapping)).longValue();
-        for (int i = 0; i < 5; i++)
-            seq.next(_broker, bMapping);
-        
-        assertEquals(new Long(aid + 1), seq.next(_broker, aMapping));
-        assertEquals(new Long(aid + 2), seq.next(_broker, cMapping));
-    }
-    
-    /**
-     * Pass in a mutable configuration
-     * <p/>
-     * return true if useable.
-     */
-    private boolean adjustConfiguration(JDBCConfiguration conf) {
-        String driver = conf.getConnectionDriverName();
-        if (driver == null)
-            return false;
-        driver = driver.toLowerCase();
-        if (driver.indexOf("oracle") >= 0) {
-            conf.setSequence(ClassTableJDBCSeq.class.getName());
-            return true;
-        }
-        
-        return false;
-    }
-    
-    public static void main(String[] args) {
-//        main();
-    }
-    
-    
-    private class UpdateThread
-            extends Thread {
-        
-        private JDBCConfiguration _conf;
-        private Set _set = null;
-        
-        public UpdateThread(Set set, JDBCConfiguration conf) {
-            _set = set;
-            _conf = conf;
-        }
-        
-        public void run() {
-            DataSource ds = _conf.getDataSource2(null);
-            try {
-                Seq seq = _conf.getSequenceInstance();
-                ClassMapping mapping = _conf.getMappingRepositoryInstance().
-                        getMapping(SeqA.class, null, true);
-                for (int i = 0; i < 51; i++)
-                    _set.add(seq.next(_broker, mapping));
-            } catch (Exception e) {
-                throw new RuntimeException(e.getMessage());
-            }
-        }
-    }
-    
-}
+/*
+ * TestClassSequenceFactory.java
+ *
+ * Created on October 6, 2006, 12:21 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.*;
+import javax.sql.DataSource;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest;
+
+
+public class TestClassSequenceFactory extends BaseJDBCTest{
+    
+
+    private static Map _sysprops = new HashMap();
+    
+    Broker _broker;
+    
+    /** Creates a new instance of TestClassSequenceFactory */
+    public TestClassSequenceFactory() {
+    }
+    public TestClassSequenceFactory(String test) {
+        super(test);
+    }
+    
+    public void setUp()
+    throws Exception {
+        JDBCConfiguration conf = new JDBCConfigurationImpl();
+        conf.fromProperties(getProperties());
+        if (!adjustConfiguration(conf))
+            return;
+        
+        String driver = conf.getConnectionDriverName().toLowerCase();
+        String [] sql = null;
+        
+        if (driver.indexOf("oracle") >= 0) {
+            sql = new String []{
+                "create sequence seqa_seq",
+                "create sequence seqb_seq"
+            };
+        }
+        
+        if (sql == null)
+            return;
+        
+        DataSource ds = conf.getDataSource2(null);
+        Connection c = ds.getConnection();
+        Statement s = null;
+        try {
+            s = c.createStatement();
+            for (int i = 0; i < sql.length; i++) {
+                try {
+                    s.execute(sql[i]);
+                } catch (SQLException sqe) {
+                }
+            }
+        } finally {
+            if (s != null)
+                try {
+                    s.close();
+                } catch (Exception e) {
+                }
+        }
+        
+        _broker = getBrokerFactory().newBroker();
+    }
+    
+    /**
+     * Tests that all sequence numbers are unique and in order.
+     */
+    public void testSequence()
+    throws Exception {
+        Set set = new HashSet();
+        
+        JDBCConfiguration conf = new JDBCConfigurationImpl();
+        conf.fromProperties(getProperties());
+        if (!adjustConfiguration(conf))
+            return;
+        Thread t1 = new UpdateThread(set, conf);
+        Thread t2 = new UpdateThread(set, conf);
+        
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+        
+        assertEquals(102, set.size());
+    }
+    
+    public void testExtensions()
+    throws Exception {
+        JDBCConfiguration conf = new JDBCConfigurationImpl();
+        conf.fromProperties(getProperties());
+        if (!adjustConfiguration(conf))
+            return;
+        
+        ClassMapping aMapping = conf.getMappingRepositoryInstance().
+                getMapping(SeqA.class, null, true);
+        ClassMapping bMapping = conf.getMappingRepositoryInstance().
+                getMapping(SeqB.class, null, true);
+        ClassMapping cMapping = conf.getMappingRepositoryInstance().
+                getMapping(SeqC.class, null, true);
+        DataSource ds = conf.getDataSource2(null);
+        
+        // hold a and c and start b
+        
+        Seq seq = conf.getSequenceInstance();
+        long aid = ((Long) seq.next(_broker, aMapping)).longValue();
+        for (int i = 0; i < 5; i++)
+            seq.next(_broker, bMapping);
+        
+        assertEquals(new Long(aid + 1), seq.next(_broker, aMapping));
+        assertEquals(new Long(aid + 2), seq.next(_broker, cMapping));
+    }
+    
+    /**
+     * Pass in a mutable configuration
+     * <p/>
+     * return true if useable.
+     */
+    private boolean adjustConfiguration(JDBCConfiguration conf) {
+        String driver = conf.getConnectionDriverName();
+        if (driver == null)
+            return false;
+        driver = driver.toLowerCase();
+        if (driver.indexOf("oracle") >= 0) {
+            conf.setSequence(ClassTableJDBCSeq.class.getName());
+            return true;
+        }
+        
+        return false;
+    }
+    
+    public static void main(String[] args) {
+//        main();
+    }
+    
+    
+    private class UpdateThread
+            extends Thread {
+        
+        private JDBCConfiguration _conf;
+        private Set _set = null;
+        
+        public UpdateThread(Set set, JDBCConfiguration conf) {
+            _set = set;
+            _conf = conf;
+        }
+        
+        public void run() {
+            DataSource ds = _conf.getDataSource2(null);
+            try {
+                Seq seq = _conf.getSequenceInstance();
+                ClassMapping mapping = _conf.getMappingRepositoryInstance().
+                        getMapping(SeqA.class, null, true);
+                for (int i = 0; i < 51; i++)
+                    _set.add(seq.next(_broker, mapping));
+            } catch (Exception e) {
+                throw new RuntimeException(e.getMessage());
+            }
+        }
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDBSequenceFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDBSequenceFactory.java
index 96fbeab..71de87a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDBSequenceFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDBSequenceFactory.java
@@ -1,114 +1,114 @@
-/*
- * TestDBSequenceFactory.java
- *
- * Created on October 6, 2006, 1:24 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import javax.sql.DataSource;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
-import org.apache.openjpa.jdbc.kernel.TableJDBCSeq;
-import org.apache.openjpa.kernel.Broker;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestDBSequenceFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-        
-    private Broker _broker;
-    
-    /** Creates a new instance of TestDBSequenceFactory */
-    public TestDBSequenceFactory() {
-    }
-
-    public TestDBSequenceFactory(String test) {
-        super(test);
-    }
-
-    /**
-     * Tests that all sequence numbers are unique and in order.
-     * Will fail for dbs without pessimistic locking.
-     */
-    public void testSequence()
-        throws Exception {
-        _broker = getBrokerFactory().newBroker();
-
-        Set set = Collections.synchronizedSet(new HashSet());
-        Thread t1 = new UpdateThread(set);
-        Thread t2 = new UpdateThread(set);
-
-        t1.start();
-        t2.start();
-        t1.join(5 * 60 * 1000);
-        t2.join(5 * 60 * 1000);
-
-        assertFalse(t1.isAlive());
-        assertFalse(t2.isAlive());
-
-        assertEquals(102, set.size());
-    }
-
-    public static void main(String[] args) {
-        //main();
-    }
-
-    private class UpdateThread
-        extends Thread {
-
-        private Set _set = null;
-
-        public UpdateThread(Set set) {
-            _set = set;
-        }
-
-        public void run() {
-            try {
-                JDBCConfiguration conf = new JDBCConfigurationImpl();
-                TableJDBCSeq seq = new TableJDBCSeq();
-                seq.setConfiguration(conf);
-                seq.startConfiguration();
-                seq.endConfiguration();
-                DataSource ds = conf.getDataSource2(null);
-                for (int i = 0; i < 51; i++)
-                    _set.add(seq.next(_broker, 
-                        conf.getMetaDataRepositoryInstance().
-                        getMetaData(RuntimeTest1.class, null, true)));
-            } catch (Exception e) {
-                throw new RuntimeException(e.getMessage());
-            }
-        }
-    }
-    
-}
+/*
+ * TestDBSequenceFactory.java
+ *
+ * Created on October 6, 2006, 1:24 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import javax.sql.DataSource;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.kernel.TableJDBCSeq;
+import org.apache.openjpa.kernel.Broker;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestDBSequenceFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+        
+    private Broker _broker;
+    
+    /** Creates a new instance of TestDBSequenceFactory */
+    public TestDBSequenceFactory() {
+    }
+
+    public TestDBSequenceFactory(String test) {
+        super(test);
+    }
+
+    /**
+     * Tests that all sequence numbers are unique and in order.
+     * Will fail for dbs without pessimistic locking.
+     */
+    public void testSequence()
+        throws Exception {
+        _broker = getBrokerFactory().newBroker();
+
+        Set set = Collections.synchronizedSet(new HashSet());
+        Thread t1 = new UpdateThread(set);
+        Thread t2 = new UpdateThread(set);
+
+        t1.start();
+        t2.start();
+        t1.join(5 * 60 * 1000);
+        t2.join(5 * 60 * 1000);
+
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
+
+        assertEquals(102, set.size());
+    }
+
+    public static void main(String[] args) {
+        //main();
+    }
+
+    private class UpdateThread
+        extends Thread {
+
+        private Set _set = null;
+
+        public UpdateThread(Set set) {
+            _set = set;
+        }
+
+        public void run() {
+            try {
+                JDBCConfiguration conf = new JDBCConfigurationImpl();
+                TableJDBCSeq seq = new TableJDBCSeq();
+                seq.setConfiguration(conf);
+                seq.startConfiguration();
+                seq.endConfiguration();
+                DataSource ds = conf.getDataSource2(null);
+                for (int i = 0; i < 51; i++)
+                    _set.add(seq.next(_broker, 
+                        conf.getMetaDataRepositoryInstance().
+                        getMetaData(RuntimeTest1.class, null, true)));
+            } catch (Exception e) {
+                throw new RuntimeException(e.getMessage());
+            }
+        }
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDynamicSchemaFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDynamicSchemaFactory.java
index 43653bd..9080d60 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDynamicSchemaFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestDynamicSchemaFactory.java
@@ -1,98 +1,98 @@
-/*
- * TestDynamicSchemaFactory.java
- *
- * Created on October 6, 2006, 1:34 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.sql.Types;
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.Discriminator;
-import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.meta.Version;
-import org.apache.openjpa.jdbc.schema.DynamicSchemaFactory;
-import org.apache.openjpa.jdbc.schema.Schemas;
-import org.apache.openjpa.jdbc.schema.Table;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestDynamicSchemaFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    private ClassMapping _mapping = null;    
-    
-    /** Creates a new instance of TestDynamicSchemaFactory */
-    public TestDynamicSchemaFactory() {
-    }
-    public TestDynamicSchemaFactory(String test) {
-        super(test);
-    }
-
-    public void setUp()
-        throws Exception {
-        JDBCConfiguration conf = new JDBCConfigurationImpl();
-        conf.setSchemaFactory(DynamicSchemaFactory.class.getName());
-        MappingRepository repos = conf.newMappingRepositoryInstance();
-        _mapping = repos.getMapping(MappingTest1.class, null, true);
-    }
-
-    public void testClassMapping() {
-        Table table = _mapping.getTable();
-        assertEquals("MAPPINGTEST1", table.getName().toUpperCase());
-        assertEquals(1, table.getPrimaryKey().getColumns().length);
-        int type = table.getPrimaryKey().getColumns()[0].getType();
-        assertEquals(Schemas.getJDBCName(type), Types.INTEGER, type);
-    }
-
-    public void testIndicators() {
-        Version vers = _mapping.getVersion();
-        assertNotNull(vers);
-        assertEquals("MAPPINGTEST1", vers.getColumns()[0].getTable().
-            getName().toUpperCase());
-        assertEquals(Types.INTEGER, vers.getColumns()[0].getType());
-
-        Discriminator cls = _mapping.getDiscriminator();
-        assertNotNull(cls);
-        assertEquals("MAPPINGTEST1", cls.getColumns()[0].getTable().
-            getName().toUpperCase());
-        assertEquals(Types.VARCHAR, cls.getColumns()[0].getType());
-    }
-
-    public static void main(String[] args) {
-       // main(TestDynamicSchemaFactory.class);
-    }
-    
-}
+/*
+ * TestDynamicSchemaFactory.java
+ *
+ * Created on October 6, 2006, 1:34 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.sql.Types;
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
+import org.apache.openjpa.jdbc.meta.MappingRepository;
+import org.apache.openjpa.jdbc.meta.Version;
+import org.apache.openjpa.jdbc.schema.DynamicSchemaFactory;
+import org.apache.openjpa.jdbc.schema.Schemas;
+import org.apache.openjpa.jdbc.schema.Table;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestDynamicSchemaFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    private ClassMapping _mapping = null;    
+    
+    /** Creates a new instance of TestDynamicSchemaFactory */
+    public TestDynamicSchemaFactory() {
+    }
+    public TestDynamicSchemaFactory(String test) {
+        super(test);
+    }
+
+    public void setUp()
+        throws Exception {
+        JDBCConfiguration conf = new JDBCConfigurationImpl();
+        conf.setSchemaFactory(DynamicSchemaFactory.class.getName());
+        MappingRepository repos = conf.newMappingRepositoryInstance();
+        _mapping = repos.getMapping(MappingTest1.class, null, true);
+    }
+
+    public void testClassMapping() {
+        Table table = _mapping.getTable();
+        assertEquals("MAPPINGTEST1", table.getName().toUpperCase());
+        assertEquals(1, table.getPrimaryKey().getColumns().length);
+        int type = table.getPrimaryKey().getColumns()[0].getType();
+        assertEquals(Schemas.getJDBCName(type), Types.INTEGER, type);
+    }
+
+    public void testIndicators() {
+        Version vers = _mapping.getVersion();
+        assertNotNull(vers);
+        assertEquals("MAPPINGTEST1", vers.getColumns()[0].getTable().
+            getName().toUpperCase());
+        assertEquals(Types.INTEGER, vers.getColumns()[0].getType());
+
+        Discriminator cls = _mapping.getDiscriminator();
+        assertNotNull(cls);
+        assertEquals("MAPPINGTEST1", cls.getColumns()[0].getTable().
+            getName().toUpperCase());
+        assertEquals(Types.VARCHAR, cls.getColumns()[0].getType());
+    }
+
+    public static void main(String[] args) {
+       // main(TestDynamicSchemaFactory.class);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestJDBCListener.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestJDBCListener.java
index 4590a1d..0888dd4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestJDBCListener.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestJDBCListener.java
@@ -1,83 +1,83 @@
-/*
- * TestJDBCListener.java
- *
- * Created on October 6, 2006, 1:38 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
-import org.apache.openjpa.lib.jdbc.JDBCEvent;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestJDBCListener extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    public static boolean commitOccurred;    
-    
-    /** Creates a new instance of TestJDBCListener */
-    public TestJDBCListener() {
-    }
-
-    public TestJDBCListener(String name) {
-        super(name);
-    }
-
-    public void testJDBCListener() {
-        Map props=new HashMap();
-        props.put("openjpa.jdbc.JDBCListeners", Listener.class.getName());
-        
-        OpenJPAEntityManagerFactory factory =(OpenJPAEntityManagerFactory)
-                getEmf(props);
-
-        commitOccurred = false;
-        OpenJPAEntityManager pm = factory.createEntityManager();     
-        
-        pm.getTransaction().begin();
-        assertFalse(commitOccurred);
-        pm.persist(new RuntimeTest1("Listener test", 99));
-        pm.getTransaction().commit();
-        assertTrue("Commit event should have occurred, but did not",
-            commitOccurred);
-        pm.close();
-    }
-    
-    public static class Listener
-        extends AbstractJDBCListener {
-
-        public void beforeCommit(JDBCEvent event) {
-            commitOccurred = true;
-        }
-    }    
-}
+/*
+ * TestJDBCListener.java
+ *
+ * Created on October 6, 2006, 1:38 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
+import org.apache.openjpa.lib.jdbc.JDBCEvent;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestJDBCListener extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    public static boolean commitOccurred;    
+    
+    /** Creates a new instance of TestJDBCListener */
+    public TestJDBCListener() {
+    }
+
+    public TestJDBCListener(String name) {
+        super(name);
+    }
+
+    public void testJDBCListener() {
+        Map props=new HashMap();
+        props.put("openjpa.jdbc.JDBCListeners", Listener.class.getName());
+        
+        OpenJPAEntityManagerFactory factory =(OpenJPAEntityManagerFactory)
+                getEmf(props);
+
+        commitOccurred = false;
+        OpenJPAEntityManager pm = factory.createEntityManager();     
+        
+        pm.getTransaction().begin();
+        assertFalse(commitOccurred);
+        pm.persist(new RuntimeTest1("Listener test", 99));
+        pm.getTransaction().commit();
+        assertTrue("Commit event should have occurred, but did not",
+            commitOccurred);
+        pm.close();
+    }
+    
+    public static class Listener
+        extends AbstractJDBCListener {
+
+        public void beforeCommit(JDBCEvent event) {
+            commitOccurred = true;
+        }
+    }    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestLazySchemaFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestLazySchemaFactory.java
index 91d5bc6..fbc3220 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestLazySchemaFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestLazySchemaFactory.java
@@ -1,117 +1,117 @@
-/*
- * TestLazySchemaFactory.java
- *
- * Created on October 6, 2006, 1:47 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.schema.LazySchemaFactory;
-import org.apache.openjpa.jdbc.schema.SchemaGroup;
-import org.apache.openjpa.jdbc.schema.Table;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestLazySchemaFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-       
-    private SchemaGroup _group = null;
-    private boolean _fks = true;
-    
-    /** Creates a new instance of TestLazySchemaFactory */
-    public TestLazySchemaFactory() {
-    }
-
-    public TestLazySchemaFactory(String test) {
-        super(test);
-    }
-
-    public void setUp()
-        throws Exception {
-        // see if the dict supports foreign keys; mysql can support them, but
-        // can't detect keys added through alter table commands, which is what
-        // kodo uses
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        _fks = conf.getDBDictionaryInstance().supportsForeignKeys
-            && getCurrentPlatform() != AbstractTestCase.Platform.MYSQL;
-
-        LazySchemaFactory factory = new LazySchemaFactory();
-        factory.setConfiguration(conf);
-        factory.setPrimaryKeys(true);
-        factory.setIndexes(true);
-        factory.setForeignKeys(true);
-        _group = factory;
-    }
-
-    public void testLazySchemaFactory() {
-        // should read tables 1 and 2...
-        Table table = _group.findTable("T1");
-        assertNotNull(table);
-        Table table2 = _group.findTable("t1");
-        assertTrue(table == table2);
-
-        int expectedColumns = 2;
-
-        // Sybase has an extra "UNQ_INDEX" column.
-        if (getCurrentPlatform() == AbstractTestCase.Platform.SYBASE)
-            expectedColumns++;
-
-        assertEquals(expectedColumns, table.getColumns().length);
-        if (_fks)
-            assertEquals(1, table.getForeignKeys().length);
-
-        table2 = _group.findTable("T2");
-        assertNotNull(table2);
-        if (_fks)
-            assertTrue(table.getForeignKeys()[0].getPrimaryKeyColumns()[0].
-                getTable() == table2);
-
-        assertNull(table.getSchema().getTable("T3"));
-
-        // should read table 3 only...
-        Table table3 = _group.findTable("T3");
-        assertNotNull(table3);
-        assertTrue(table.getSchema().getTable("T3") == table3);
-        if (_fks)
-            assertTrue(table3.getForeignKeys()[0].getPrimaryKeyColumns()[0].
-                getTable() == table);
-
-        assertNull(table3.getSchema().getTable("T4"));
-    }
-
-    public static void main(String[] args) {
-        //main(TestLazySchemaFactory.class);
-    }
-    
-}
+/*
+ * TestLazySchemaFactory.java
+ *
+ * Created on October 6, 2006, 1:47 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.schema.LazySchemaFactory;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.Table;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestLazySchemaFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+       
+    private SchemaGroup _group = null;
+    private boolean _fks = true;
+    
+    /** Creates a new instance of TestLazySchemaFactory */
+    public TestLazySchemaFactory() {
+    }
+
+    public TestLazySchemaFactory(String test) {
+        super(test);
+    }
+
+    public void setUp()
+        throws Exception {
+        // see if the dict supports foreign keys; mysql can support them, but
+        // can't detect keys added through alter table commands, which is what
+        // kodo uses
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        _fks = conf.getDBDictionaryInstance().supportsForeignKeys
+            && getCurrentPlatform() != AbstractTestCase.Platform.MYSQL;
+
+        LazySchemaFactory factory = new LazySchemaFactory();
+        factory.setConfiguration(conf);
+        factory.setPrimaryKeys(true);
+        factory.setIndexes(true);
+        factory.setForeignKeys(true);
+        _group = factory;
+    }
+
+    public void testLazySchemaFactory() {
+        // should read tables 1 and 2...
+        Table table = _group.findTable("T1");
+        assertNotNull(table);
+        Table table2 = _group.findTable("t1");
+        assertTrue(table == table2);
+
+        int expectedColumns = 2;
+
+        // Sybase has an extra "UNQ_INDEX" column.
+        if (getCurrentPlatform() == AbstractTestCase.Platform.SYBASE)
+            expectedColumns++;
+
+        assertEquals(expectedColumns, table.getColumns().length);
+        if (_fks)
+            assertEquals(1, table.getForeignKeys().length);
+
+        table2 = _group.findTable("T2");
+        assertNotNull(table2);
+        if (_fks)
+            assertTrue(table.getForeignKeys()[0].getPrimaryKeyColumns()[0].
+                getTable() == table2);
+
+        assertNull(table.getSchema().getTable("T3"));
+
+        // should read table 3 only...
+        Table table3 = _group.findTable("T3");
+        assertNotNull(table3);
+        assertTrue(table.getSchema().getTable("T3") == table3);
+        if (_fks)
+            assertTrue(table3.getForeignKeys()[0].getPrimaryKeyColumns()[0].
+                getTable() == table);
+
+        assertNull(table3.getSchema().getTable("T4"));
+    }
+
+    public static void main(String[] args) {
+        //main(TestLazySchemaFactory.class);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestPerClassSequenceFactory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestPerClassSequenceFactory.java
index 241dd8f..028b753 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestPerClassSequenceFactory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestPerClassSequenceFactory.java
@@ -1,118 +1,118 @@
-/*
- * TestPerClassSequenceFactory.java
- *
- * Created on October 6, 2006, 2:25 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.schema.Sequence;
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.meta.ClassMetaData;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestPerClassSequenceFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-   
-    /** Creates a new instance of TestPerClassSequenceFactory */
-    public TestPerClassSequenceFactory() {
-    }
-    public TestPerClassSequenceFactory(String test) {
-        super(test);
-    }
-
-    public void testPerClassSequenceFactory()
-        throws Exception {
-        Map props=new HashMap();
-        props.put("openjpa.Sequence", "table");
-        
-        OpenJPAEntityManagerFactory factory =(OpenJPAEntityManagerFactory)
-                getEmf(props);
-
-        JDBCConfiguration conf = (JDBCConfiguration)
-            factory.getConfiguration();
-        ClassMapping mapping1 = conf.getMappingRepositoryInstance().
-            getMapping(RuntimeTest1.class, null, true);
-        ClassMapping mapping2 = conf.getMappingRepositoryInstance().
-            getMapping(PerClassTestObject.class, null, true);
-        ClassMapping mapping3 = conf.getMappingRepositoryInstance().
-            getMapping(PerClassTestObject2.class, null, true);
-
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        //FIXME jthomas
-        /*
-        Sequence s1 = pm.getIdentitySequence(mapping1.getDescribedType());
-        Sequence s2 = pm.getIdentitySequence(mapping2.getDescribedType());
-        Sequence s3 = pm.getFieldSequence(mapping3.getDescribedType(), "age");
-        assertTrue(((SequenceImpl) s1).getDelegate()
-            instanceof TableJDBCSeq);
-        assertTrue(((SequenceImpl) s2).getDelegate().toString(),
-            ((SequenceImpl) s2).getDelegate()
-                instanceof DummySequenceFactory);
-        assertTrue(((SequenceImpl) s2).getDelegate().toString(),
-            ((SequenceImpl) s3).getDelegate()
-                instanceof DummySequenceFactory);
-         */
-    }
-
-    public static class DummySequenceFactory
-        implements Seq {
-
-        private long _val = 1;
-
-        public void setType(int type) {
-        }
-
-        public Object next(StoreContext ctx, ClassMetaData meta) {
-            _val++;
-            return current(ctx, meta);
-        }
-
-        public Object current(StoreContext ctx, ClassMetaData meta) {
-            return new Long(_val);
-        }
-
-        public void allocate(int num, StoreContext ctx, ClassMetaData meta) {
-        }
-
-        public void close() {
-        }
-    }
-    
-    
-}
+/*
+ * TestPerClassSequenceFactory.java
+ *
+ * Created on October 6, 2006, 2:25 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.schema.Sequence;
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.meta.ClassMetaData;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestPerClassSequenceFactory extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+   
+    /** Creates a new instance of TestPerClassSequenceFactory */
+    public TestPerClassSequenceFactory() {
+    }
+    public TestPerClassSequenceFactory(String test) {
+        super(test);
+    }
+
+    public void testPerClassSequenceFactory()
+        throws Exception {
+        Map props=new HashMap();
+        props.put("openjpa.Sequence", "table");
+        
+        OpenJPAEntityManagerFactory factory =(OpenJPAEntityManagerFactory)
+                getEmf(props);
+
+        JDBCConfiguration conf = (JDBCConfiguration)
+            factory.getConfiguration();
+        ClassMapping mapping1 = conf.getMappingRepositoryInstance().
+            getMapping(RuntimeTest1.class, null, true);
+        ClassMapping mapping2 = conf.getMappingRepositoryInstance().
+            getMapping(PerClassTestObject.class, null, true);
+        ClassMapping mapping3 = conf.getMappingRepositoryInstance().
+            getMapping(PerClassTestObject2.class, null, true);
+
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        //FIXME jthomas
+        /*
+        Sequence s1 = pm.getIdentitySequence(mapping1.getDescribedType());
+        Sequence s2 = pm.getIdentitySequence(mapping2.getDescribedType());
+        Sequence s3 = pm.getFieldSequence(mapping3.getDescribedType(), "age");
+        assertTrue(((SequenceImpl) s1).getDelegate()
+            instanceof TableJDBCSeq);
+        assertTrue(((SequenceImpl) s2).getDelegate().toString(),
+            ((SequenceImpl) s2).getDelegate()
+                instanceof DummySequenceFactory);
+        assertTrue(((SequenceImpl) s2).getDelegate().toString(),
+            ((SequenceImpl) s3).getDelegate()
+                instanceof DummySequenceFactory);
+         */
+    }
+
+    public static class DummySequenceFactory
+        implements Seq {
+
+        private long _val = 1;
+
+        public void setType(int type) {
+        }
+
+        public Object next(StoreContext ctx, ClassMetaData meta) {
+            _val++;
+            return current(ctx, meta);
+        }
+
+        public Object current(StoreContext ctx, ClassMetaData meta) {
+            return new Long(_val);
+        }
+
+        public void allocate(int num, StoreContext ctx, ClassMetaData meta) {
+        }
+
+        public void close() {
+        }
+    }
+    
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchema.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchema.java
index e1698e4..ca68ecb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchema.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchema.java
@@ -1,331 +1,331 @@
-/*
- * TestSchema.java
- *
- * Created on October 6, 2006, 2:36 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.ForeignKey;
-import org.apache.openjpa.jdbc.schema.Index;
-import org.apache.openjpa.jdbc.schema.PrimaryKey;
-import org.apache.openjpa.jdbc.schema.Schema;
-import org.apache.openjpa.jdbc.schema.SchemaGroup;
-import org.apache.openjpa.jdbc.schema.Table;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestSchema extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-    
-    private Schema _schema = new SchemaGroup().addSchema("schema");
-    
-    /** Creates a new instance of TestSchema */
-    public TestSchema() {
-    }
-    public TestSchema(String test) {
-        super(test);
-    }
-
-    /**
-     * Test the {@link Schema} class.
-     */
-    public void testSchema() {
-        assertEquals("schema", _schema.getName());
-        assertTrue(_schema.getSchemaGroup().isNameTaken("schema"));
-
-        assertTrue(!_schema.getSchemaGroup().isNameTaken("table1"));
-        Table table1 = _schema.addTable("table1");
-        assertTrue(_schema.getSchemaGroup().isNameTaken("table1"));
-        Table table2 = _schema.addTable("table2");
-        assertTrue(_schema.getSchemaGroup().isNameTaken("table2"));
-
-        Table[] tables = _schema.getTables();
-        assertEquals(2, tables.length);
-        assertEquals(table1, tables[0]);
-        assertEquals(table2, tables[1]);
-        assertEquals(table1, _schema.getTable("table1"));
-        assertEquals(table2, _schema.getTable("table2"));
-        assertNull(_schema.getTable("table3"));
-
-        assertTrue(_schema.removeTable(table1));
-        assertTrue(!_schema.getSchemaGroup().isNameTaken("table1"));
-        assertNull(_schema.getTable("table1"));
-        assertEquals(table2, _schema.getTable("table2"));
-        assertTrue(_schema.removeTable(table2));
-        assertTrue(!_schema.getSchemaGroup().isNameTaken("table2"));
-        assertNull(_schema.getTable("table2"));
-        assertEquals(0, _schema.getTables().length);
-    }
-
-    /**
-     * Test the {@link Table} class.
-     */
-    public void testTable() {
-        Table table = _schema.addTable("table");
-        assertEquals(_schema, table.getSchema());
-        assertEquals("table", table.getName());
-
-        assertTrue(!table.isNameTaken("schema"));
-        assertTrue(table.isNameTaken("table"));
-
-        // pk testing
-        assertNull(table.getPrimaryKey());
-        PrimaryKey pk = table.addPrimaryKey("pk");
-        assertEquals(table, pk.getTable());
-        assertEquals(pk, table.getPrimaryKey());
-        assertTrue(!table.isNameTaken("pk"));
-        assertTrue(_schema.getSchemaGroup().isNameTaken("pk"));
-
-        table.removePrimaryKey();
-        assertNull(table.getPrimaryKey());
-        assertTrue(!_schema.getSchemaGroup().isNameTaken("pk"));
-
-        // column testing
-        Column c2 = table.addColumn("c2");
-        Column c1 = table.addColumn("c1");
-        assertTrue(table.isNameTaken("c1"));
-        assertTrue(!_schema.getSchemaGroup().isNameTaken("c1"));
-        assertEquals(table, c1.getTable());
-        Column[] cols = table.getColumns();
-        assertEquals(2, cols.length);
-        assertEquals(c2, cols[0]);
-        assertEquals(c1, cols[1]);
-
-        assertEquals(c1, table.getColumn("c1"));
-        assertEquals(c2, table.getColumn("c2"));
-
-        assertTrue(table.removeColumn(c1));
-        assertTrue(!table.isNameTaken("c1"));
-        assertNull(table.getColumn("c1"));
-
-        // foreign key testing
-        ForeignKey fk = table.addForeignKey("fk");
-        assertTrue(_schema.getSchemaGroup().isNameTaken("fk"));
-        assertTrue(!table.isNameTaken("fk"));
-        assertEquals(table, fk.getTable());
-        ForeignKey[] fks = table.getForeignKeys();
-        assertEquals(1, fks.length);
-        assertEquals(fk, fks[0]);
-
-        assertTrue(table.removeForeignKey(fk));
-        assertTrue(!_schema.getSchemaGroup().isNameTaken("fk"));
-        assertEquals(0, table.getForeignKeys().length);
-
-        // index testing
-        Index idx = table.addIndex("idx");
-        assertTrue(_schema.getSchemaGroup().isNameTaken("idx"));
-        assertTrue(!table.isNameTaken("idx"));
-        assertEquals(table, idx.getTable());
-        Index[] idxs = table.getIndexes();
-        assertEquals(1, idxs.length);
-        assertEquals(idx, idxs[0]);
-
-        assertEquals(idx, table.getIndex("idx"));
-        assertTrue(table.removeIndex(idx));
-        assertTrue(!table.isNameTaken("idx"));
-        assertNull(table.getIndex("idx"));
-    }
-
-    /**
-     * Test the {@link Index} class.
-     */
-    public void testIndex() {
-        Table table = _schema.addTable("table");
-        Column c1 = table.addColumn("c1");
-        Column c2 = table.addColumn("c2");
-        Table table2 = _schema.addTable("table2");
-        Column c3 = table2.addColumn("c3");
-
-        Index idx = table.addIndex("idx");
-        try {
-            idx.addColumn(c3);
-            fail("Allowed addition of column of another table.");
-        } catch (RuntimeException re) {
-        }
-
-        Column[] cols = idx.getColumns();
-        assertEquals(0, cols.length);
-
-        idx.addColumn(c1);
-        idx.addColumn(c2);
-        cols = idx.getColumns();
-        assertEquals(2, cols.length);
-        assertEquals(c1, cols[0]);
-        assertEquals(c2, cols[1]);
-
-        assertTrue(idx.removeColumn(c1));
-        cols = idx.getColumns();
-        assertEquals(1, cols.length);
-        assertEquals(c2, cols[0]);
-        assertTrue(idx.removeColumn(c2));
-        cols = idx.getColumns();
-        assertEquals(0, cols.length);
-
-        assertTrue(!idx.isUnique());
-        idx.setUnique(true);
-        assertTrue(idx.isUnique());
-    }
-
-    /**
-     * Test the {@link ForeignKey} class.
-     */
-    public void testForeignKey() {
-        Table table = _schema.addTable("table");
-        Column c1 = table.addColumn("c1");
-        Column c2 = table.addColumn("c2");
-        Table table2 = _schema.addTable("table2");
-        Column c3 = table2.addColumn("c3");
-        Column c4 = table2.addColumn("c4");
-
-        ForeignKey fk = table.addForeignKey("fk");
-        try {
-            fk.join(c4, c2);
-            fail("Allowed addition of column of another table.");
-        } catch (RuntimeException re) {
-        }
-
-        Column[] cols = fk.getColumns();
-        Column[] pkCols = fk.getPrimaryKeyColumns();
-        assertEquals(0, cols.length);
-        assertEquals(0, pkCols.length);
-        PrimaryKey pk = table2.addPrimaryKey("pk");
-        pk.addColumn(c3);
-        fk.join(c1, c3);
-        pk.addColumn(c4);
-        fk.join(c2, c4);
-        cols = fk.getColumns();
-        pkCols = fk.getPrimaryKeyColumns();
-        assertEquals(2, cols.length);
-        assertEquals(c1, cols[0]);
-        assertEquals(c2, cols[1]);
-        assertEquals(c3, pkCols[0]);
-        assertEquals(c4, pkCols[1]);
-
-        assertTrue(fk.removeJoin(c1));
-        cols = fk.getColumns();
-        pkCols = fk.getPrimaryKeyColumns();
-        assertEquals(1, cols.length);
-        assertEquals(1, pkCols.length);
-        assertEquals(c2, cols[0]);
-        assertEquals(c4, pkCols[0]);
-        assertTrue(fk.removeJoin(c2));
-        cols = fk.getColumns();
-        pkCols = fk.getPrimaryKeyColumns();
-        assertEquals(0, cols.length);
-        assertEquals(0, pkCols.length);
-
-        assertEquals(ForeignKey.ACTION_NONE, fk.getDeleteAction());
-        assertTrue(fk.isLogical());
-        fk.setDeleteAction(ForeignKey.ACTION_RESTRICT);
-        assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
-        assertFalse(fk.isLogical());
-    }
-
-    /**
-     * Tests the {@link SchemaGroup} class.
-     */
-    public void testSchemaGroup() {
-        SchemaGroup group = _schema.getSchemaGroup();
-        assertEquals(_schema, group.getSchema("schema"));
-        Table foo1 = _schema.addTable("foo");
-
-        Schema schema2 = group.addSchema("schema2");
-        assertNull(schema2.getTable("foo"));
-        Table foo2 = schema2.addTable("foo");
-        assertEquals(foo2, schema2.getTable("foo"));
-        assertEquals(foo1, _schema.getTable("foo"));
-
-        assertEquals(foo1, group.findTable("schema.foo"));
-        assertEquals(foo2, group.findTable("schema2.foo"));
-    }
-
-    /**
-     * Test primary key removal.
-     */
-    public void testPrimaryKeyRemoval() {
-        Table table = _schema.addTable("table");
-        Column c1 = table.addColumn("c1");
-        Column c2 = table.addColumn("c2");
-        Table table2 = _schema.addTable("table2");
-        Column c3 = table2.addColumn("c3");
-        Column c4 = table2.addColumn("c4");
-        PrimaryKey pk = table2.addPrimaryKey("pk");
-        pk.addColumn(c3);
-        pk.addColumn(c4);
-        ForeignKey fk = table.addForeignKey("fk");
-        fk.join(c1, c3);
-        fk.join(c2, c4);
-
-        table2.removePrimaryKey();
-        assertNull(pk.getTable());
-        assertNull(table2.getPrimaryKey());
-        assertEquals(0, table.getForeignKeys().length);
-    }
-
-    /**
-     * Test column removal.
-     */
-    public void testColumnRemoval() {
-        Table table = _schema.addTable("table");
-        Column c1 = table.addColumn("c1");
-        Column c2 = table.addColumn("c2");
-        PrimaryKey pk = table.addPrimaryKey("pk");
-        pk.addColumn(c1);
-        Index idx1 = table.addIndex("idx1");
-        idx1.addColumn(c1);
-        Index idx2 = table.addIndex("idx2");
-        idx2.addColumn(c1);
-        idx2.addColumn(c2);
-
-        Table table2 = _schema.addTable("table2");
-        Column c3 = table2.addColumn("c3");
-        Column c4 = table2.addColumn("c4");
-        pk = table2.addPrimaryKey("pk2");
-        pk.addColumn(c3);
-        ForeignKey fk = table.addForeignKey("fk");
-        fk.join(c1, c3);
-
-        table.removeColumn(c1);
-        assertNull(table.getPrimaryKey());
-        assertNull(table.getIndex("idx1"));
-        assertEquals(1, idx2.getColumns().length);
-        assertEquals(0, table.getForeignKeys().length);
-    }
-
-    public static void main(String[] args) {
-        //main(TestSchema.class);
-	}
-    
-}
+/*
+ * TestSchema.java
+ *
+ * Created on October 6, 2006, 2:36 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.schema.Schema;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.Table;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestSchema extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+    
+    private Schema _schema = new SchemaGroup().addSchema("schema");
+    
+    /** Creates a new instance of TestSchema */
+    public TestSchema() {
+    }
+    public TestSchema(String test) {
+        super(test);
+    }
+
+    /**
+     * Test the {@link Schema} class.
+     */
+    public void testSchema() {
+        assertEquals("schema", _schema.getName());
+        assertTrue(_schema.getSchemaGroup().isNameTaken("schema"));
+
+        assertTrue(!_schema.getSchemaGroup().isNameTaken("table1"));
+        Table table1 = _schema.addTable("table1");
+        assertTrue(_schema.getSchemaGroup().isNameTaken("table1"));
+        Table table2 = _schema.addTable("table2");
+        assertTrue(_schema.getSchemaGroup().isNameTaken("table2"));
+
+        Table[] tables = _schema.getTables();
+        assertEquals(2, tables.length);
+        assertEquals(table1, tables[0]);
+        assertEquals(table2, tables[1]);
+        assertEquals(table1, _schema.getTable("table1"));
+        assertEquals(table2, _schema.getTable("table2"));
+        assertNull(_schema.getTable("table3"));
+
+        assertTrue(_schema.removeTable(table1));
+        assertTrue(!_schema.getSchemaGroup().isNameTaken("table1"));
+        assertNull(_schema.getTable("table1"));
+        assertEquals(table2, _schema.getTable("table2"));
+        assertTrue(_schema.removeTable(table2));
+        assertTrue(!_schema.getSchemaGroup().isNameTaken("table2"));
+        assertNull(_schema.getTable("table2"));
+        assertEquals(0, _schema.getTables().length);
+    }
+
+    /**
+     * Test the {@link Table} class.
+     */
+    public void testTable() {
+        Table table = _schema.addTable("table");
+        assertEquals(_schema, table.getSchema());
+        assertEquals("table", table.getName());
+
+        assertTrue(!table.isNameTaken("schema"));
+        assertTrue(table.isNameTaken("table"));
+
+        // pk testing
+        assertNull(table.getPrimaryKey());
+        PrimaryKey pk = table.addPrimaryKey("pk");
+        assertEquals(table, pk.getTable());
+        assertEquals(pk, table.getPrimaryKey());
+        assertTrue(!table.isNameTaken("pk"));
+        assertTrue(_schema.getSchemaGroup().isNameTaken("pk"));
+
+        table.removePrimaryKey();
+        assertNull(table.getPrimaryKey());
+        assertTrue(!_schema.getSchemaGroup().isNameTaken("pk"));
+
+        // column testing
+        Column c2 = table.addColumn("c2");
+        Column c1 = table.addColumn("c1");
+        assertTrue(table.isNameTaken("c1"));
+        assertTrue(!_schema.getSchemaGroup().isNameTaken("c1"));
+        assertEquals(table, c1.getTable());
+        Column[] cols = table.getColumns();
+        assertEquals(2, cols.length);
+        assertEquals(c2, cols[0]);
+        assertEquals(c1, cols[1]);
+
+        assertEquals(c1, table.getColumn("c1"));
+        assertEquals(c2, table.getColumn("c2"));
+
+        assertTrue(table.removeColumn(c1));
+        assertTrue(!table.isNameTaken("c1"));
+        assertNull(table.getColumn("c1"));
+
+        // foreign key testing
+        ForeignKey fk = table.addForeignKey("fk");
+        assertTrue(_schema.getSchemaGroup().isNameTaken("fk"));
+        assertTrue(!table.isNameTaken("fk"));
+        assertEquals(table, fk.getTable());
+        ForeignKey[] fks = table.getForeignKeys();
+        assertEquals(1, fks.length);
+        assertEquals(fk, fks[0]);
+
+        assertTrue(table.removeForeignKey(fk));
+        assertTrue(!_schema.getSchemaGroup().isNameTaken("fk"));
+        assertEquals(0, table.getForeignKeys().length);
+
+        // index testing
+        Index idx = table.addIndex("idx");
+        assertTrue(_schema.getSchemaGroup().isNameTaken("idx"));
+        assertTrue(!table.isNameTaken("idx"));
+        assertEquals(table, idx.getTable());
+        Index[] idxs = table.getIndexes();
+        assertEquals(1, idxs.length);
+        assertEquals(idx, idxs[0]);
+
+        assertEquals(idx, table.getIndex("idx"));
+        assertTrue(table.removeIndex(idx));
+        assertTrue(!table.isNameTaken("idx"));
+        assertNull(table.getIndex("idx"));
+    }
+
+    /**
+     * Test the {@link Index} class.
+     */
+    public void testIndex() {
+        Table table = _schema.addTable("table");
+        Column c1 = table.addColumn("c1");
+        Column c2 = table.addColumn("c2");
+        Table table2 = _schema.addTable("table2");
+        Column c3 = table2.addColumn("c3");
+
+        Index idx = table.addIndex("idx");
+        try {
+            idx.addColumn(c3);
+            fail("Allowed addition of column of another table.");
+        } catch (RuntimeException re) {
+        }
+
+        Column[] cols = idx.getColumns();
+        assertEquals(0, cols.length);
+
+        idx.addColumn(c1);
+        idx.addColumn(c2);
+        cols = idx.getColumns();
+        assertEquals(2, cols.length);
+        assertEquals(c1, cols[0]);
+        assertEquals(c2, cols[1]);
+
+        assertTrue(idx.removeColumn(c1));
+        cols = idx.getColumns();
+        assertEquals(1, cols.length);
+        assertEquals(c2, cols[0]);
+        assertTrue(idx.removeColumn(c2));
+        cols = idx.getColumns();
+        assertEquals(0, cols.length);
+
+        assertTrue(!idx.isUnique());
+        idx.setUnique(true);
+        assertTrue(idx.isUnique());
+    }
+
+    /**
+     * Test the {@link ForeignKey} class.
+     */
+    public void testForeignKey() {
+        Table table = _schema.addTable("table");
+        Column c1 = table.addColumn("c1");
+        Column c2 = table.addColumn("c2");
+        Table table2 = _schema.addTable("table2");
+        Column c3 = table2.addColumn("c3");
+        Column c4 = table2.addColumn("c4");
+
+        ForeignKey fk = table.addForeignKey("fk");
+        try {
+            fk.join(c4, c2);
+            fail("Allowed addition of column of another table.");
+        } catch (RuntimeException re) {
+        }
+
+        Column[] cols = fk.getColumns();
+        Column[] pkCols = fk.getPrimaryKeyColumns();
+        assertEquals(0, cols.length);
+        assertEquals(0, pkCols.length);
+        PrimaryKey pk = table2.addPrimaryKey("pk");
+        pk.addColumn(c3);
+        fk.join(c1, c3);
+        pk.addColumn(c4);
+        fk.join(c2, c4);
+        cols = fk.getColumns();
+        pkCols = fk.getPrimaryKeyColumns();
+        assertEquals(2, cols.length);
+        assertEquals(c1, cols[0]);
+        assertEquals(c2, cols[1]);
+        assertEquals(c3, pkCols[0]);
+        assertEquals(c4, pkCols[1]);
+
+        assertTrue(fk.removeJoin(c1));
+        cols = fk.getColumns();
+        pkCols = fk.getPrimaryKeyColumns();
+        assertEquals(1, cols.length);
+        assertEquals(1, pkCols.length);
+        assertEquals(c2, cols[0]);
+        assertEquals(c4, pkCols[0]);
+        assertTrue(fk.removeJoin(c2));
+        cols = fk.getColumns();
+        pkCols = fk.getPrimaryKeyColumns();
+        assertEquals(0, cols.length);
+        assertEquals(0, pkCols.length);
+
+        assertEquals(ForeignKey.ACTION_NONE, fk.getDeleteAction());
+        assertTrue(fk.isLogical());
+        fk.setDeleteAction(ForeignKey.ACTION_RESTRICT);
+        assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
+        assertFalse(fk.isLogical());
+    }
+
+    /**
+     * Tests the {@link SchemaGroup} class.
+     */
+    public void testSchemaGroup() {
+        SchemaGroup group = _schema.getSchemaGroup();
+        assertEquals(_schema, group.getSchema("schema"));
+        Table foo1 = _schema.addTable("foo");
+
+        Schema schema2 = group.addSchema("schema2");
+        assertNull(schema2.getTable("foo"));
+        Table foo2 = schema2.addTable("foo");
+        assertEquals(foo2, schema2.getTable("foo"));
+        assertEquals(foo1, _schema.getTable("foo"));
+
+        assertEquals(foo1, group.findTable("schema.foo"));
+        assertEquals(foo2, group.findTable("schema2.foo"));
+    }
+
+    /**
+     * Test primary key removal.
+     */
+    public void testPrimaryKeyRemoval() {
+        Table table = _schema.addTable("table");
+        Column c1 = table.addColumn("c1");
+        Column c2 = table.addColumn("c2");
+        Table table2 = _schema.addTable("table2");
+        Column c3 = table2.addColumn("c3");
+        Column c4 = table2.addColumn("c4");
+        PrimaryKey pk = table2.addPrimaryKey("pk");
+        pk.addColumn(c3);
+        pk.addColumn(c4);
+        ForeignKey fk = table.addForeignKey("fk");
+        fk.join(c1, c3);
+        fk.join(c2, c4);
+
+        table2.removePrimaryKey();
+        assertNull(pk.getTable());
+        assertNull(table2.getPrimaryKey());
+        assertEquals(0, table.getForeignKeys().length);
+    }
+
+    /**
+     * Test column removal.
+     */
+    public void testColumnRemoval() {
+        Table table = _schema.addTable("table");
+        Column c1 = table.addColumn("c1");
+        Column c2 = table.addColumn("c2");
+        PrimaryKey pk = table.addPrimaryKey("pk");
+        pk.addColumn(c1);
+        Index idx1 = table.addIndex("idx1");
+        idx1.addColumn(c1);
+        Index idx2 = table.addIndex("idx2");
+        idx2.addColumn(c1);
+        idx2.addColumn(c2);
+
+        Table table2 = _schema.addTable("table2");
+        Column c3 = table2.addColumn("c3");
+        Column c4 = table2.addColumn("c4");
+        pk = table2.addPrimaryKey("pk2");
+        pk.addColumn(c3);
+        ForeignKey fk = table.addForeignKey("fk");
+        fk.join(c1, c3);
+
+        table.removeColumn(c1);
+        assertNull(table.getPrimaryKey());
+        assertNull(table.getIndex("idx1"));
+        assertEquals(1, idx2.getColumns().length);
+        assertEquals(0, table.getForeignKeys().length);
+    }
+
+    public static void main(String[] args) {
+        //main(TestSchema.class);
+	}
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaClone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaClone.java
index f0c75ea..1e869d7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaClone.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaClone.java
@@ -1,65 +1,65 @@
-/*
- * TestSchemaClone.java
- *
- * Created on October 6, 2006, 2:40 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.jdbc.schema.SchemaGroup;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestSchemaClone extends TestXMLSchemaParser {
-    
-    /** Creates a new instance of TestSchemaClone */
-    public TestSchemaClone() {
-    }
-    
-    public TestSchemaClone(String test) {
-        super(test);
-    }
-    
-    protected SchemaGroup getSchemaGroup()
-    throws Exception {
-        // parse in the schema group, then clone it, and test against clone
-        SchemaGroup group = parseSchemaGroup();
-        return (SchemaGroup) group.clone();
-    }
-    
-    public static void main(String[] args) {
-        //main(TestSchemaClone.class);
-    }
-    
-}
+/*
+ * TestSchemaClone.java
+ *
+ * Created on October 6, 2006, 2:40 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestSchemaClone extends TestXMLSchemaParser {
+    
+    /** Creates a new instance of TestSchemaClone */
+    public TestSchemaClone() {
+    }
+    
+    public TestSchemaClone(String test) {
+        super(test);
+    }
+    
+    protected SchemaGroup getSchemaGroup()
+    throws Exception {
+        // parse in the schema group, then clone it, and test against clone
+        SchemaGroup group = parseSchemaGroup();
+        return (SchemaGroup) group.clone();
+    }
+    
+    public static void main(String[] args) {
+        //main(TestSchemaClone.class);
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaGenerator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaGenerator.java
index 57bc6da..52e6269 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaGenerator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSchemaGenerator.java
@@ -1,131 +1,131 @@
-/*
- * TestSchemaGenerator.java
- *
- * Created on October 6, 2006, 2:57 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.io.StringWriter;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.util.*;
-import javax.sql.DataSource;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.SchemaTool;
-import org.apache.openjpa.jdbc.schema.Table;
-import org.apache.openjpa.jdbc.sql.DBDictionary;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-
-public class TestSchemaGenerator extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-        
-    /** Creates a new instance of TestSchemaGenerator */
-    public TestSchemaGenerator(String name) 
-    {
-    	super(name);
-    }
-    
-    public void DBMetadataTest()
-    throws Exception {
-        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
-        getEmf();
-        //FIXME jthomas
-        
-        //ClassMapping cm = (ClassMapping) KodoJDOHelper.getMetaData
-        //    (pmf, RuntimeTest1.class);
-        ClassMapping cm =null;
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-        
-        DataSource ds = (DataSource) conf.getDataSource2(null);
-        Connection c = ds.getConnection();
-        DatabaseMetaData meta = c.getMetaData();
-        DBDictionary dict = conf.getDBDictionaryInstance();
-        
-        String schema = cm.getTable().getSchema().getName();
-        Table[] tables = dict.getTables(meta, c.getCatalog(), schema,
-                cm.getTable().getName(), c);
-        assertEquals(1, tables.length);
-        
-        Column[] columns = dict.getColumns(meta, c.getCatalog(), schema,
-                cm.getTable().getName(), null, c);
-        for (int i = 0; i < columns.length; i++)
-            System.out.println("### " + columns[i].getName());
-    }
-    
-    public void testSchemaGen()
-    throws Exception {
-        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
-        getEmf();
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-        JDBCConfiguration con = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) pm).getConfiguration();
-        DBDictionary dict = con.getDBDictionaryInstance();
-        MappingRepository repos = con.getMappingRepositoryInstance();
-        ClassMapping cm = repos.getMapping(RuntimeTest1.class,
-                pm.getClassLoader(), true);
-        String schemas = cm.getTable().getSchema().getName();
-        if (schemas == null)
-            schemas = "";
-        schemas += "." + cm.getTable().getName();
-        
-        Map props=new HashMap();
-        props.put("openjpa.jdbc.Schemas", schemas);
-        
-        OpenJPAEntityManagerFactory kpmf =(OpenJPAEntityManagerFactory)
-                getEmf(props);
-        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) kpmf).getConfiguration();
-        
-        StringWriter sw = new StringWriter();
-        
-        SchemaTool.Flags flags = new SchemaTool.Flags();
-        flags.writer = sw;
-        flags.primaryKeys = true;
-        flags.foreignKeys = true;
-        flags.indexes = true;
-        flags.openjpaTables = true;
-        flags.action = SchemaTool.ACTION_REFLECT;
-        
-        SchemaTool.run(conf, new String[0], flags,
-                getClass().getClassLoader());
-        
-        sw.flush();
-        String data = sw.toString();
-        assertTrue(data.length() > 0);
-    }
-}
+/*
+ * TestSchemaGenerator.java
+ *
+ * Created on October 6, 2006, 2:57 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.io.StringWriter;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.util.*;
+import javax.sql.DataSource;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.MappingRepository;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.SchemaTool;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+
+public class TestSchemaGenerator extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+        
+    /** Creates a new instance of TestSchemaGenerator */
+    public TestSchemaGenerator(String name) 
+    {
+    	super(name);
+    }
+    
+    public void DBMetadataTest()
+    throws Exception {
+        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
+        getEmf();
+        //FIXME jthomas
+        
+        //ClassMapping cm = (ClassMapping) KodoJDOHelper.getMetaData
+        //    (pmf, RuntimeTest1.class);
+        ClassMapping cm =null;
+        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+        
+        DataSource ds = (DataSource) conf.getDataSource2(null);
+        Connection c = ds.getConnection();
+        DatabaseMetaData meta = c.getMetaData();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        
+        String schema = cm.getTable().getSchema().getName();
+        Table[] tables = dict.getTables(meta, c.getCatalog(), schema,
+                cm.getTable().getName(), c);
+        assertEquals(1, tables.length);
+        
+        Column[] columns = dict.getColumns(meta, c.getCatalog(), schema,
+                cm.getTable().getName(), null, c);
+        for (int i = 0; i < columns.length; i++)
+            System.out.println("### " + columns[i].getName());
+    }
+    
+    public void testSchemaGen()
+    throws Exception {
+        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
+        getEmf();
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+        JDBCConfiguration con = (JDBCConfiguration) ((OpenJPAEntityManagerSPI) pm).getConfiguration();
+        DBDictionary dict = con.getDBDictionaryInstance();
+        MappingRepository repos = con.getMappingRepositoryInstance();
+        ClassMapping cm = repos.getMapping(RuntimeTest1.class,
+                pm.getClassLoader(), true);
+        String schemas = cm.getTable().getSchema().getName();
+        if (schemas == null)
+            schemas = "";
+        schemas += "." + cm.getTable().getName();
+        
+        Map props=new HashMap();
+        props.put("openjpa.jdbc.Schemas", schemas);
+        
+        OpenJPAEntityManagerFactory kpmf =(OpenJPAEntityManagerFactory)
+                getEmf(props);
+        JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactorySPI) kpmf).getConfiguration();
+        
+        StringWriter sw = new StringWriter();
+        
+        SchemaTool.Flags flags = new SchemaTool.Flags();
+        flags.writer = sw;
+        flags.primaryKeys = true;
+        flags.foreignKeys = true;
+        flags.indexes = true;
+        flags.openjpaTables = true;
+        flags.action = SchemaTool.ACTION_REFLECT;
+        
+        SchemaTool.run(conf, new String[0], flags,
+                getClass().getClassLoader());
+        
+        sw.flush();
+        String data = sw.toString();
+        assertTrue(data.length() > 0);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSequenceGeneratorEnsureCapacityCall.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSequenceGeneratorEnsureCapacityCall.java
index 3941581..1881eb9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSequenceGeneratorEnsureCapacityCall.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestSequenceGeneratorEnsureCapacityCall.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.util.*;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
-import org.apache.openjpa.jdbc.kernel.TableJDBCSeq;
-import org.apache.openjpa.jdbc.schema.Sequence;
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.SequenceMetaData;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestSequenceGeneratorEnsureCapacityCall 
-        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
-   
-    
-    
-    /** Creates a new instance of TestSequenceGeneratorEnsureCapacityCall */
-    public TestSequenceGeneratorEnsureCapacityCall(String name) 
-    {
-    	super(name);
-    }
-
-    // class SeqA uses the default sequence factory.
-    public void testDBSequenceFactory() {
-        TableJDBCSeq seq = (TableJDBCSeq) seqForClass(SeqA.class);
-        incrementTest(SeqA.class, seq.getAllocate());
-    }
-
-    // class SeqD uses the db-class sequence factory.
-    public void testClassDBSequenceFactory() {
-        ClassTableJDBCSeq seq = (ClassTableJDBCSeq) seqForClass(SeqD.class);
-        incrementTest(SeqD.class, seq.getAllocate());
-    }
-
-    private void incrementTest(Class cls, int generatorIncrement) {
-        // guaranteed to be more than a single batch, so ensureCapacity should
-        // do its thing.
-        int amountToIncrement = generatorIncrement * 2;
-
-        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
-        //FIXME jthomas
-        //Sequence s = pm.getIdentitySequence(cls);
-        Sequence s =null;
-        s.setAllocate(amountToIncrement);
-
-        sql.clear();
-        for (int i = 0; i < amountToIncrement; i++) {
-            s.getIncrement();
-            assertEquals("SQL list should have been empty on sequence"
-                + " fetch #" + i + " of #" + amountToIncrement
-                + ", but contained: " + sql, 0, sql.size());
-        }
-    }
-
-    private Seq seqForClass(Class cls) {
-        OpenJPAConfiguration conf = getConfiguration();
-        ClassMetaData meta = conf.getMetaDataRepositoryInstance().getMetaData
-            (cls, null, true);
-        SequenceMetaData smeta = meta.getIdentitySequenceMetaData();
-        return (smeta == null) ? conf.getSequenceInstance()
-            : smeta.getInstance(null);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.util.*;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
+import org.apache.openjpa.jdbc.kernel.TableJDBCSeq;
+import org.apache.openjpa.jdbc.schema.Sequence;
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.SequenceMetaData;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestSequenceGeneratorEnsureCapacityCall 
+        extends org.apache.openjpa.persistence.jdbc.kernel.TestSQLListenerTestCase{
+   
+    
+    
+    /** Creates a new instance of TestSequenceGeneratorEnsureCapacityCall */
+    public TestSequenceGeneratorEnsureCapacityCall(String name) 
+    {
+    	super(name);
+    }
+
+    // class SeqA uses the default sequence factory.
+    public void testDBSequenceFactory() {
+        TableJDBCSeq seq = (TableJDBCSeq) seqForClass(SeqA.class);
+        incrementTest(SeqA.class, seq.getAllocate());
+    }
+
+    // class SeqD uses the db-class sequence factory.
+    public void testClassDBSequenceFactory() {
+        ClassTableJDBCSeq seq = (ClassTableJDBCSeq) seqForClass(SeqD.class);
+        incrementTest(SeqD.class, seq.getAllocate());
+    }
+
+    private void incrementTest(Class cls, int generatorIncrement) {
+        // guaranteed to be more than a single batch, so ensureCapacity should
+        // do its thing.
+        int amountToIncrement = generatorIncrement * 2;
+
+        OpenJPAEntityManager pm =(OpenJPAEntityManager)currentEntityManager();
+        //FIXME jthomas
+        //Sequence s = pm.getIdentitySequence(cls);
+        Sequence s =null;
+        s.setAllocate(amountToIncrement);
+
+        sql.clear();
+        for (int i = 0; i < amountToIncrement; i++) {
+            s.getIncrement();
+            assertEquals("SQL list should have been empty on sequence"
+                + " fetch #" + i + " of #" + amountToIncrement
+                + ", but contained: " + sql, 0, sql.size());
+        }
+    }
+
+    private Seq seqForClass(Class cls) {
+        OpenJPAConfiguration conf = getConfiguration();
+        ClassMetaData meta = conf.getMetaDataRepositoryInstance().getMetaData
+            (cls, null, true);
+        SequenceMetaData smeta = meta.getIdentitySequenceMetaData();
+        return (smeta == null) ? conf.getSequenceInstance()
+            : smeta.getInstance(null);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaParser.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaParser.java
index c3cf9d4..629407d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaParser.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaParser.java
@@ -1,239 +1,239 @@
-/*
- * TestXMLSchemaParser.java
- *
- * Created on October 6, 2006, 2:42 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.io.IOException;
-import java.sql.Types;
-import java.util.*;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
-import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.ForeignKey;
-import org.apache.openjpa.jdbc.schema.Index;
-import org.apache.openjpa.jdbc.schema.PrimaryKey;
-import org.apache.openjpa.jdbc.schema.Schema;
-import org.apache.openjpa.jdbc.schema.SchemaGroup;
-import org.apache.openjpa.jdbc.schema.Sequence;
-import org.apache.openjpa.jdbc.schema.Table;
-import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestXMLSchemaParser extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
-        
-    protected JDBCConfiguration conf = null;
-    private SchemaGroup _group = null;
-    
-    
-    /** Creates a new instance of TestXMLSchemaParser */
-    public TestXMLSchemaParser() {
-    }
-    
-    public TestXMLSchemaParser(String test) {
-        super(test);
-    }
-    
-    public void setUp()
-    throws Exception {
-        this.conf = new JDBCConfigurationImpl();
-        _group = getSchemaGroup();
-    }
-    
-    /**
-     * Parses the schema group from the schema XML
-     * resources in this package.
-     */
-    protected SchemaGroup parseSchemaGroup()
-    throws IOException {
-        XMLSchemaParser parser = new SCMSchemaParser(this.conf);
-        parser.parse(TestXMLSchemaParser.class, false);
-        parser.parse(TestSchema.class, false);    // will go up to package level
-        return parser.getSchemaGroup();
-    }
-    
-    /**
-     * Return the schema group to use in testing.  Returns
-     * {@link #parseSchemaGroup} by default.
-     */
-    protected SchemaGroup getSchemaGroup()
-    throws Exception {
-        return parseSchemaGroup();
-    }
-    
-    /**
-     * Checks the generated schema group for accuracy.
-     */
-    public void testSchemaParsing() {
-        assertEquals(2, _group.getSchemas().length);
-        assertEquals("SCHEMA1", _group.getSchema("SCHEMA1").getName());
-        assertEquals("SCHEMA2", _group.getSchema("SCHEMA2").getName());
-    }
-    
-    /**
-     * Checks the pased sequences.
-     */
-    public void testSequenceParsing() {
-        Schema schema = _group.getSchema("SCHEMA1");
-        assertEquals(2, schema.getSequences().length);
-        assertEquals(0, _group.getSchema("SCHEMA2").getSequences().length);
-        
-        Sequence seq1 = schema.getSequence("SEQ1");
-        assertNotNull(seq1);
-        assertEquals("SEQ1", seq1.getName());
-        assertEquals(seq1, _group.findSequence("SEQ1"));
-        assertEquals(seq1, _group.findSequence("SCHEMA1.SEQ1"));
-        assertEquals(1, seq1.getInitialValue());
-        assertEquals(1, seq1.getIncrement());
-        assertEquals(0, seq1.getAllocate());
-        
-        Sequence seq2 = schema.getSequence("SEQ2");
-        assertNotNull(seq2);
-        assertEquals(3, seq2.getInitialValue());
-        assertEquals(5, seq2.getIncrement());
-        assertEquals(50, seq2.getAllocate());
-    }
-    
-    /**
-     * Checks table and column parsing.
-     */
-    public void testTableColumnParsing() {
-        Schema schema1 = _group.getSchema("SCHEMA1");
-        Table[] tables = schema1.getTables();
-        assertEquals(2, tables.length);
-        assertEquals("TABLE1", tables[0].getName());
-        assertEquals("TABLE3", tables[1].getName());
-        
-        Column[] cols = tables[0].getColumns();
-        assertEquals(2, cols.length);
-        assertEquals("COL1", cols[0].getName());
-        assertEquals("COL2", cols[1].getName());
-        assertEquals(Types.VARCHAR, cols[0].getType());
-        assertEquals(Types.FLOAT, cols[1].getType());
-        assertTrue(cols[0].isNotNull());
-        assertTrue(!cols[1].isNotNull());
-        assertEquals("def", cols[0].getDefault());
-        assertNull(cols[1].getDefault());
-    }
-    
-    /**
-     * Test that primary keys are resolved correctly.
-     */
-    public void testPrimaryKeyParsing() {
-        Table table = _group.getSchema("SCHEMA1").getTable("TABLE1");
-        PrimaryKey pk = table.getPrimaryKey();
-        assertNotNull(pk);
-        assertEquals("PK1", pk.getName());
-        assertTrue(pk.isLogical());
-        assertEquals(1, pk.getColumns().length);
-        assertEquals(table.getColumn("COL1"), pk.getColumns()[0]);
-        
-        table = _group.getSchema("SCHEMA2").getTable("TABLE2");
-        pk = table.getPrimaryKey();
-        assertNotNull(pk);
-        assertEquals("PK2", pk.getName());
-        assertTrue(!pk.isLogical());
-        assertEquals(2, pk.getColumns().length);
-        assertEquals(table.getColumn("COL1"), pk.getColumns()[0]);
-        assertEquals(table.getColumn("COL2"), pk.getColumns()[1]);
-    }
-    
-    /**
-     * Test that indexes are resolved correctly.
-     */
-    public void testIndexParsing() {
-        Table table = _group.getSchema("SCHEMA1").getTable("TABLE1");
-        Index idx = table.getIndex("IDX1");
-        assertNotNull(idx);
-        assertTrue(idx.isUnique());
-        assertEquals(1, idx.getColumns().length);
-        assertEquals(table.getColumn("COL2"), idx.getColumns()[0]);
-        
-        table = _group.getSchema("SCHEMA2").getTable("TABLE2");
-        idx = table.getIndex("IDX2");
-        assertNotNull(idx);
-        assertTrue(!idx.isUnique());
-        assertEquals(2, idx.getColumns().length);
-        assertEquals(table.getColumn("COL1"), idx.getColumns()[0]);
-        assertEquals(table.getColumn("COL2"), idx.getColumns()[1]);
-    }
-    
-    /**
-     * Test that foreign keys are resolved correctly.
-     */
-    public void testForeignKeyParsing() {
-        Table table1 = _group.getSchema("SCHEMA1").getTable("TABLE1");
-        Table table2 = _group.getSchema("SCHEMA2").getTable("TABLE2");
-        
-        ForeignKey fk = table1.getForeignKeys()[0];
-        assertEquals("FK1", fk.getName());
-        assertNotNull(fk);
-        assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
-        Column[] cols = fk.getColumns();
-        Column[] pkCols = fk.getPrimaryKeyColumns();
-        assertEquals(2, cols.length);
-        assertEquals(2, pkCols.length);
-        assertEquals(table1.getColumn("COL1"), cols[0]);
-        assertEquals(table2.getColumn("COL1"), pkCols[0]);
-        assertEquals(table1.getColumn("COL2"), cols[1]);
-        assertEquals(table2.getColumn("COL2"), pkCols[1]);
-        
-        fk = table2.getForeignKeys()[0];
-        assertEquals("FK2", fk.getName());
-        assertNotNull(fk);
-        assertEquals(ForeignKey.ACTION_NONE, fk.getDeleteAction());
-        cols = fk.getColumns();
-        pkCols = fk.getPrimaryKeyColumns();
-        assertEquals(1, cols.length);
-        assertEquals(1, pkCols.length);
-        assertEquals(table2.getColumn("COL2"), cols[0]);
-        assertEquals(table1.getColumn("COL1"), pkCols[0]);
-    }
-    
-    public static void main(String[] args) {
-        //main(TestXMLSchemaParser.class);
-    }
-    
-    public static class SCMSchemaParser
-            extends XMLSchemaParser {
-        
-        public SCMSchemaParser(JDBCConfiguration conf) {
-            super(conf);
-            setSuffix(".scm");
-        }
-    }
-    
-}
+/*
+ * TestXMLSchemaParser.java
+ *
+ * Created on October 6, 2006, 2:42 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.io.IOException;
+import java.sql.Types;
+import java.util.*;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.schema.Schema;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.Sequence;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestXMLSchemaParser extends org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest{
+        
+    protected JDBCConfiguration conf = null;
+    private SchemaGroup _group = null;
+    
+    
+    /** Creates a new instance of TestXMLSchemaParser */
+    public TestXMLSchemaParser() {
+    }
+    
+    public TestXMLSchemaParser(String test) {
+        super(test);
+    }
+    
+    public void setUp()
+    throws Exception {
+        this.conf = new JDBCConfigurationImpl();
+        _group = getSchemaGroup();
+    }
+    
+    /**
+     * Parses the schema group from the schema XML
+     * resources in this package.
+     */
+    protected SchemaGroup parseSchemaGroup()
+    throws IOException {
+        XMLSchemaParser parser = new SCMSchemaParser(this.conf);
+        parser.parse(TestXMLSchemaParser.class, false);
+        parser.parse(TestSchema.class, false);    // will go up to package level
+        return parser.getSchemaGroup();
+    }
+    
+    /**
+     * Return the schema group to use in testing.  Returns
+     * {@link #parseSchemaGroup} by default.
+     */
+    protected SchemaGroup getSchemaGroup()
+    throws Exception {
+        return parseSchemaGroup();
+    }
+    
+    /**
+     * Checks the generated schema group for accuracy.
+     */
+    public void testSchemaParsing() {
+        assertEquals(2, _group.getSchemas().length);
+        assertEquals("SCHEMA1", _group.getSchema("SCHEMA1").getName());
+        assertEquals("SCHEMA2", _group.getSchema("SCHEMA2").getName());
+    }
+    
+    /**
+     * Checks the pased sequences.
+     */
+    public void testSequenceParsing() {
+        Schema schema = _group.getSchema("SCHEMA1");
+        assertEquals(2, schema.getSequences().length);
+        assertEquals(0, _group.getSchema("SCHEMA2").getSequences().length);
+        
+        Sequence seq1 = schema.getSequence("SEQ1");
+        assertNotNull(seq1);
+        assertEquals("SEQ1", seq1.getName());
+        assertEquals(seq1, _group.findSequence("SEQ1"));
+        assertEquals(seq1, _group.findSequence("SCHEMA1.SEQ1"));
+        assertEquals(1, seq1.getInitialValue());
+        assertEquals(1, seq1.getIncrement());
+        assertEquals(0, seq1.getAllocate());
+        
+        Sequence seq2 = schema.getSequence("SEQ2");
+        assertNotNull(seq2);
+        assertEquals(3, seq2.getInitialValue());
+        assertEquals(5, seq2.getIncrement());
+        assertEquals(50, seq2.getAllocate());
+    }
+    
+    /**
+     * Checks table and column parsing.
+     */
+    public void testTableColumnParsing() {
+        Schema schema1 = _group.getSchema("SCHEMA1");
+        Table[] tables = schema1.getTables();
+        assertEquals(2, tables.length);
+        assertEquals("TABLE1", tables[0].getName());
+        assertEquals("TABLE3", tables[1].getName());
+        
+        Column[] cols = tables[0].getColumns();
+        assertEquals(2, cols.length);
+        assertEquals("COL1", cols[0].getName());
+        assertEquals("COL2", cols[1].getName());
+        assertEquals(Types.VARCHAR, cols[0].getType());
+        assertEquals(Types.FLOAT, cols[1].getType());
+        assertTrue(cols[0].isNotNull());
+        assertTrue(!cols[1].isNotNull());
+        assertEquals("def", cols[0].getDefault());
+        assertNull(cols[1].getDefault());
+    }
+    
+    /**
+     * Test that primary keys are resolved correctly.
+     */
+    public void testPrimaryKeyParsing() {
+        Table table = _group.getSchema("SCHEMA1").getTable("TABLE1");
+        PrimaryKey pk = table.getPrimaryKey();
+        assertNotNull(pk);
+        assertEquals("PK1", pk.getName());
+        assertTrue(pk.isLogical());
+        assertEquals(1, pk.getColumns().length);
+        assertEquals(table.getColumn("COL1"), pk.getColumns()[0]);
+        
+        table = _group.getSchema("SCHEMA2").getTable("TABLE2");
+        pk = table.getPrimaryKey();
+        assertNotNull(pk);
+        assertEquals("PK2", pk.getName());
+        assertTrue(!pk.isLogical());
+        assertEquals(2, pk.getColumns().length);
+        assertEquals(table.getColumn("COL1"), pk.getColumns()[0]);
+        assertEquals(table.getColumn("COL2"), pk.getColumns()[1]);
+    }
+    
+    /**
+     * Test that indexes are resolved correctly.
+     */
+    public void testIndexParsing() {
+        Table table = _group.getSchema("SCHEMA1").getTable("TABLE1");
+        Index idx = table.getIndex("IDX1");
+        assertNotNull(idx);
+        assertTrue(idx.isUnique());
+        assertEquals(1, idx.getColumns().length);
+        assertEquals(table.getColumn("COL2"), idx.getColumns()[0]);
+        
+        table = _group.getSchema("SCHEMA2").getTable("TABLE2");
+        idx = table.getIndex("IDX2");
+        assertNotNull(idx);
+        assertTrue(!idx.isUnique());
+        assertEquals(2, idx.getColumns().length);
+        assertEquals(table.getColumn("COL1"), idx.getColumns()[0]);
+        assertEquals(table.getColumn("COL2"), idx.getColumns()[1]);
+    }
+    
+    /**
+     * Test that foreign keys are resolved correctly.
+     */
+    public void testForeignKeyParsing() {
+        Table table1 = _group.getSchema("SCHEMA1").getTable("TABLE1");
+        Table table2 = _group.getSchema("SCHEMA2").getTable("TABLE2");
+        
+        ForeignKey fk = table1.getForeignKeys()[0];
+        assertEquals("FK1", fk.getName());
+        assertNotNull(fk);
+        assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
+        Column[] cols = fk.getColumns();
+        Column[] pkCols = fk.getPrimaryKeyColumns();
+        assertEquals(2, cols.length);
+        assertEquals(2, pkCols.length);
+        assertEquals(table1.getColumn("COL1"), cols[0]);
+        assertEquals(table2.getColumn("COL1"), pkCols[0]);
+        assertEquals(table1.getColumn("COL2"), cols[1]);
+        assertEquals(table2.getColumn("COL2"), pkCols[1]);
+        
+        fk = table2.getForeignKeys()[0];
+        assertEquals("FK2", fk.getName());
+        assertNotNull(fk);
+        assertEquals(ForeignKey.ACTION_NONE, fk.getDeleteAction());
+        cols = fk.getColumns();
+        pkCols = fk.getPrimaryKeyColumns();
+        assertEquals(1, cols.length);
+        assertEquals(1, pkCols.length);
+        assertEquals(table2.getColumn("COL2"), cols[0]);
+        assertEquals(table1.getColumn("COL1"), pkCols[0]);
+    }
+    
+    public static void main(String[] args) {
+        //main(TestXMLSchemaParser.class);
+    }
+    
+    public static class SCMSchemaParser
+            extends XMLSchemaParser {
+        
+        public SCMSchemaParser(JDBCConfiguration conf) {
+            super(conf);
+            setSuffix(".scm");
+        }
+    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaSerializer.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaSerializer.java
index 7c12fd9..04d1248 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaSerializer.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/schema/TestXMLSchemaSerializer.java
@@ -1,86 +1,86 @@
-/*
- * TestXMLSchemaSerializer.java
- *
- * Created on October 6, 2006, 4:47 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.schema;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.util.*;
-import org.apache.openjpa.jdbc.schema.SchemaGroup;
-import org.apache.openjpa.jdbc.schema.SchemaParser;
-import org.apache.openjpa.jdbc.schema.SchemaSerializer;
-import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
-import org.apache.openjpa.jdbc.schema.XMLSchemaSerializer;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.*;
-
-
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public class TestXMLSchemaSerializer extends TestXMLSchemaParser{
-    
-    
-    /** Creates a new instance of TestXMLSchemaSerializer */
-    public TestXMLSchemaSerializer() {
-    }
-    
-    
-    public TestXMLSchemaSerializer(String test) {
-        super(test);
-    }
-    
-    protected SchemaGroup getSchemaGroup()
-    throws Exception {
-        // parse in the schema group, then serialize it to a buffer, then
-        // recreate it and test againt that to make sure it's the same as the
-        // original
-        SchemaGroup group = parseSchemaGroup();
-        SchemaSerializer ser = new XMLSchemaSerializer(this.conf);
-        ser.addAll(group);
-        
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ser.serialize(new OutputStreamWriter(out), ser.PRETTY);
-        byte[] bytes = out.toByteArray();
-        
-        SchemaParser parser = new XMLSchemaParser(this.conf);
-        parser.parse(new InputStreamReader
-                (new ByteArrayInputStream(bytes)), "bytes");
-        return parser.getSchemaGroup();
-    }
-    
-    public static void main(String[] args) {
-        //   main(TestXMLSchemaSerializer.class);
-    }
-}
+/*
+ * TestXMLSchemaSerializer.java
+ *
+ * Created on October 6, 2006, 4:47 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.schema;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.*;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.SchemaParser;
+import org.apache.openjpa.jdbc.schema.SchemaSerializer;
+import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
+import org.apache.openjpa.jdbc.schema.XMLSchemaSerializer;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.*;
+
+
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public class TestXMLSchemaSerializer extends TestXMLSchemaParser{
+    
+    
+    /** Creates a new instance of TestXMLSchemaSerializer */
+    public TestXMLSchemaSerializer() {
+    }
+    
+    
+    public TestXMLSchemaSerializer(String test) {
+        super(test);
+    }
+    
+    protected SchemaGroup getSchemaGroup()
+    throws Exception {
+        // parse in the schema group, then serialize it to a buffer, then
+        // recreate it and test againt that to make sure it's the same as the
+        // original
+        SchemaGroup group = parseSchemaGroup();
+        SchemaSerializer ser = new XMLSchemaSerializer(this.conf);
+        ser.addAll(group);
+        
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ser.serialize(new OutputStreamWriter(out), ser.PRETTY);
+        byte[] bytes = out.toByteArray();
+        
+        SchemaParser parser = new XMLSchemaParser(this.conf);
+        parser.parse(new InputStreamReader
+                (new ByteArrayInputStream(bytes)), "bytes");
+        return parser.getSchemaGroup();
+    }
+    
+    public static void main(String[] args) {
+        //   main(TestXMLSchemaSerializer.class);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraint.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraint.java
index c8a7aa7..1fb87f9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraint.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraint.java
@@ -1,79 +1,79 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.unique;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.jdbc.SQLSniffer;
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-
-/**
- * Tests unique constraints specified via annotations for primary/secondary
- * table, sequence generator, join tables have been defined on database by
- * examining DDL statements.
- * 
- * @see resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml defines
- * the ORM mapping.
- * 
- * @author Pinaki Poddar
- *
- */
-public class TestUniqueConstraint extends SQLListenerTestCase {
-    @Override
-    public void setUp(Object... props) {
-    	super.setUp(DROP_TABLES, UniqueA.class, UniqueB.class);    			    
-    }
-    
-	public void testMapping() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		em.getTransaction().commit();
-		em.close();
-		// The above should trigger schema definition
-		
-		List<String> sqls = super.sql;
-		
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_A",
-				"UNIQUE \\w*\\(a1, a2\\)", 
-				"UNIQUE \\w*\\(a3, a4\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_B",
-				"UNIQUE \\w*\\(b1, b2\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_SECONDARY",
-				"UNIQUE \\w*\\(sa1\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_GENERATOR",
-				"UNIQUE \\w*\\(GEN1, GEN2\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_JOINTABLE",
-				"UNIQUE \\w*\\(FK_A, FK_B\\)");
-	}
-	
-	void assertSQLFragnments(List<String> list, String... keys) {
-		if (SQLSniffer.matches(list, keys))
-			return;
-		int i = 0;
-		for (String sql : list) {
-			i++;
-			System.out.println("" + i + ":" + sql);
-		}
-		fail("None of the " + sql.size() + " SQL contains all keys "
-				+ Arrays.toString(keys));
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.jdbc.SQLSniffer;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * Tests unique constraints specified via annotations for primary/secondary
+ * table, sequence generator, join tables have been defined on database by
+ * examining DDL statements.
+ * 
+ * @see resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml defines
+ * the ORM mapping.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestUniqueConstraint extends SQLListenerTestCase {
+    @Override
+    public void setUp(Object... props) {
+    	super.setUp(DROP_TABLES, UniqueA.class, UniqueB.class);    			    
+    }
+    
+	public void testMapping() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		em.getTransaction().commit();
+		em.close();
+		// The above should trigger schema definition
+		
+		List<String> sqls = super.sql;
+		
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_A",
+				"UNIQUE \\w*\\(a1, a2\\)", 
+				"UNIQUE \\w*\\(a3, a4\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_B",
+				"UNIQUE \\w*\\(b1, b2\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_SECONDARY",
+				"UNIQUE \\w*\\(sa1\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_GENERATOR",
+				"UNIQUE \\w*\\(GEN1, GEN2\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_JOINTABLE",
+				"UNIQUE \\w*\\(FK_A, FK_B\\)");
+	}
+	
+	void assertSQLFragnments(List<String> list, String... keys) {
+		if (SQLSniffer.matches(list, keys))
+			return;
+		int i = 0;
+		for (String sql : list) {
+			i++;
+			System.out.println("" + i + ":" + sql);
+		}
+		fail("None of the " + sql.size() + " SQL contains all keys "
+				+ Arrays.toString(keys));
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraintWithXMLDescriptor.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraintWithXMLDescriptor.java
index c4a1f68..f237937 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraintWithXMLDescriptor.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUniqueConstraintWithXMLDescriptor.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.unique;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.jdbc.SQLSniffer;
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-
-/**
- * Tests unique constraints specified via XML Descriptor for primary/secondary
- * table, sequence generator, join tables have been defined on database by
- * examining DDL statements.
- * 
- * @see resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml 
- * defines the ORM mapping. 
- * 
- * @author Pinaki Poddar
- *
- */
-public class TestUniqueConstraintWithXMLDescriptor extends SQLListenerTestCase {
-	@Override
-	public void setUp(Object... props) {
-		super.setUp(DROP_TABLES, UniqueA.class, UniqueB.class);
-	}
-
-	protected String getPersistenceUnitName() {
-		return "test-unique-constraint";
-	}
-
-	public void testMapping() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		em.getTransaction().commit();
-		em.close();
-		// The above should trigger schema definition
-
-		List<String> sqls = super.sql;
-		assertFalse("No SQL DDL registered", sqls.isEmpty());
-
-		// Following verification techniques is fragile as databases DDL
-		// syntax vary greatly on UNIQUE CONSTRAINT
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_A_XML",
-				"UNIQUE \\w*\\(a1x, a2x\\)", 
-				"UNIQUE \\w*\\(a3x, a4x\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_B_XML",
-				"UNIQUE \\w*\\(b1x, b2x\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_SECONDARY_XML",
-				"UNIQUE \\w*\\(sa1x\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_GENERATOR_XML",
-				"UNIQUE \\w*\\(GEN1_XML, GEN2_XML\\)");
-		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_JOINTABLE_XML",
-				"UNIQUE \\w*\\(FK_A_XML, FK_B_XML\\)");
-	}
-
-	void assertSQLFragnments(List<String> list, String... keys) {
-		if (SQLSniffer.matches(list, keys))
-			return;
-		int i = 0;
-		for (String sql : list) {
-			i++;
-			System.out.println("" + i + ":" + sql);
-		}
-		fail("None of the " + sql.size() + " SQL contains all keys "
-				+ Arrays.toString(keys));
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.jdbc.SQLSniffer;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * Tests unique constraints specified via XML Descriptor for primary/secondary
+ * table, sequence generator, join tables have been defined on database by
+ * examining DDL statements.
+ * 
+ * @see resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml 
+ * defines the ORM mapping. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestUniqueConstraintWithXMLDescriptor extends SQLListenerTestCase {
+	@Override
+	public void setUp(Object... props) {
+		super.setUp(DROP_TABLES, UniqueA.class, UniqueB.class);
+	}
+
+	protected String getPersistenceUnitName() {
+		return "test-unique-constraint";
+	}
+
+	public void testMapping() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		em.getTransaction().commit();
+		em.close();
+		// The above should trigger schema definition
+
+		List<String> sqls = super.sql;
+		assertFalse("No SQL DDL registered", sqls.isEmpty());
+
+		// Following verification techniques is fragile as databases DDL
+		// syntax vary greatly on UNIQUE CONSTRAINT
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_A_XML",
+				"UNIQUE \\w*\\(a1x, a2x\\)", 
+				"UNIQUE \\w*\\(a3x, a4x\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_B_XML",
+				"UNIQUE \\w*\\(b1x, b2x\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_SECONDARY_XML",
+				"UNIQUE \\w*\\(sa1x\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_GENERATOR_XML",
+				"UNIQUE \\w*\\(GEN1_XML, GEN2_XML\\)");
+		assertSQLFragnments(sqls, "CREATE TABLE UNIQUE_JOINTABLE_XML",
+				"UNIQUE \\w*\\(FK_A_XML, FK_B_XML\\)");
+	}
+
+	void assertSQLFragnments(List<String> list, String... keys) {
+		if (SQLSniffer.matches(list, keys))
+			return;
+		int i = 0;
+		for (String sql : list) {
+			i++;
+			System.out.println("" + i + ":" + sql);
+		}
+		fail("None of the " + sql.size() + " SQL contains all keys "
+				+ Arrays.toString(keys));
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java
index d6a5582..7adcf44 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.unique;
-
-import java.util.Collection;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.SecondaryTable;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-
-/**
- * Data structures for testing unique constraint settings
- * on ORM Annotations.
- * @UniqueConstraint annotation is declared at class-level with @Table, 
- * @SecondaryTable annotations and at field-level with @JoinTable annotation.
- * 
- * The columns included in unique constraint must be non-nullable. This is 
- * recommended that the non-nullability of the column is explictly set by the
- * user, though the implementation forces a column to non-nullable as a column
- * is included in a unique constraint.
- * 
- * @author Pinaki Poddar
- *
- */
-@Entity
-@Table(name="UNIQUE_A",
-	   uniqueConstraints={@UniqueConstraint(columnNames={"a1","a2"}),
-		                  @UniqueConstraint(columnNames={"a3","a4"})})
-@SecondaryTable(name="UNIQUE_SECONDARY",
-		uniqueConstraints=@UniqueConstraint(columnNames={"sa1"}))
-
-public class UniqueA {
-	@Id
-	private int aid;
-
-	@Column(unique=true, nullable=false)
-	private int a1;
-	
-	@Column(nullable=false)
-	private int a2;
-	
-	@Column(nullable=false)
-	private int a3;
-	
-	@Column(nullable=false)
-	private int a4;
-	
-	
-	private int a5;
-	private int a6;
-	
-	@Column(table="UNIQUE_SECONDARY", nullable=false)
-	private short sa1;
-	@Column(table="UNIQUE_SECONDARY")
-	private short sa2;
-	
-	@ManyToMany
-	@JoinTable(name="UNIQUE_JOINTABLE",
-			joinColumns={@JoinColumn(name="FK_A", nullable=false, 
-					referencedColumnName="aid")},
-			inverseJoinColumns={@JoinColumn(name="FK_B", nullable=false, 
-					referencedColumnName="bid")},
-			uniqueConstraints=@UniqueConstraint(columnNames={"FK_A","FK_B"}))
-	private Collection<UniqueB> bs;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import java.util.Collection;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.SecondaryTable;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+/**
+ * Data structures for testing unique constraint settings
+ * on ORM Annotations.
+ * @UniqueConstraint annotation is declared at class-level with @Table, 
+ * @SecondaryTable annotations and at field-level with @JoinTable annotation.
+ * 
+ * The columns included in unique constraint must be non-nullable. This is 
+ * recommended that the non-nullability of the column is explictly set by the
+ * user, though the implementation forces a column to non-nullable as a column
+ * is included in a unique constraint.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Table(name="UNIQUE_A",
+	   uniqueConstraints={@UniqueConstraint(columnNames={"a1","a2"}),
+		                  @UniqueConstraint(columnNames={"a3","a4"})})
+@SecondaryTable(name="UNIQUE_SECONDARY",
+		uniqueConstraints=@UniqueConstraint(columnNames={"sa1"}))
+
+public class UniqueA {
+	@Id
+	private int aid;
+
+	@Column(unique=true, nullable=false)
+	private int a1;
+	
+	@Column(nullable=false)
+	private int a2;
+	
+	@Column(nullable=false)
+	private int a3;
+	
+	@Column(nullable=false)
+	private int a4;
+	
+	
+	private int a5;
+	private int a6;
+	
+	@Column(table="UNIQUE_SECONDARY", nullable=false)
+	private short sa1;
+	@Column(table="UNIQUE_SECONDARY")
+	private short sa2;
+	
+	@ManyToMany
+	@JoinTable(name="UNIQUE_JOINTABLE",
+			joinColumns={@JoinColumn(name="FK_A", nullable=false, 
+					referencedColumnName="aid")},
+			inverseJoinColumns={@JoinColumn(name="FK_B", nullable=false, 
+					referencedColumnName="bid")},
+			uniqueConstraints=@UniqueConstraint(columnNames={"FK_A","FK_B"}))
+	private Collection<UniqueB> bs;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java
index db39129..ccbce74 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jdbc.unique;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name="UNIQUE_B",
-	   uniqueConstraints={@UniqueConstraint(columnNames={"b1","b2"})})
-public class UniqueB {
-	@Id
-	@GeneratedValue(strategy=GenerationType.TABLE, generator="testGenerator")
-	@TableGenerator(name="testGenerator", table="UNIQUE_GENERATOR", 
-			pkColumnName="GEN1", valueColumnName="GEN2",
-			uniqueConstraints={@UniqueConstraint(columnNames={"GEN1","GEN2"})})
-	private int bid;
-	
-	@Column(nullable=false)
-	private int b1;
-	@Column(nullable=false)
-	private int b2;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="UNIQUE_B",
+	   uniqueConstraints={@UniqueConstraint(columnNames={"b1","b2"})})
+public class UniqueB {
+	@Id
+	@GeneratedValue(strategy=GenerationType.TABLE, generator="testGenerator")
+	@TableGenerator(name="testGenerator", table="UNIQUE_GENERATOR", 
+			pkColumnName="GEN1", valueColumnName="GEN2",
+			uniqueConstraints={@UniqueConstraint(columnNames={"GEN1","GEN2"})})
+	private int bid;
+	
+	@Column(nullable=false)
+	private int b1;
+	@Column(nullable=false)
+	private int b2;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestBulkUpdate.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestBulkUpdate.java
index b67b47c..541b81d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestBulkUpdate.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestBulkUpdate.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.clauses;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestBulkUpdate extends AbstractTestCase {
-
-    public TestBulkUpdate(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(Entity1.class);
-        deleteAll(Entity2.class);
-    }
-
-    public void testSimpleBulkUpdate() {
-        for (int i = 1; i < 5; i++)
-            testSimpleBulkUpdate(i);
-    }
-
-    public void testSimpleBulkUpdate(int num) {
-        deleteAll(Entity1.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        for (int i = 0; i < num; i++) {
-            Entity1 e = new Entity1(i, "value1", i);
-            em.persist(e);
-        }
-        endTx(em);
-
-        // test update
-        startTx(em);
-        Query updateQuery1 = em.createQuery("update Entity1 e"
-            + " set e.stringField = 'value2', e.intField = 2"
-            + " where e.stringField = :val").
-            setParameter("val", "value1");
-        assertEquals(num, updateQuery1.executeUpdate());
-        assertEquals(0, updateQuery1.executeUpdate()); // should be updated
-        endTx(em);
-
-        // test update with parameter
-        startTx(em);
-        Query updateQuery2 = em.createQuery("update Entity1 e"
-            + " set e.stringField = :newval where e.stringField = :val").
-            setParameter("val", "value2").
-            setParameter("newval", "value3");
-        assertEquals(num, updateQuery2.executeUpdate());
-        assertEquals(0, updateQuery2.executeUpdate()); // should be updated
-        endTx(em);
-
-        // test update with 2 parameters
-        startTx(em);
-        Query updateQuery3 = em.createQuery("update Entity1 e"
-            + " set e.stringField = :newval, e.intField = 999"
-            + " where e.stringField = :val").
-            setParameter("val", "value3").
-            setParameter("newval", "value4");
-        assertEquals(num, updateQuery3.executeUpdate());
-        assertEquals(0, updateQuery3.executeUpdate()); // should be updated
-        endTx(em);
-
-        // test update with null value
-        startTx(em);
-        Query updateQuery4 = em.createQuery("update Entity1 e"
-            + " set e.stringField = :nullval, e.intField = :intval"
-            + " where e.stringField = :val"
-            + " and e.intField = 999").
-            setParameter("val", "value4").
-            setParameter("intval", new Integer(987)).
-            setParameter("nullval", null);
-        assertEquals(num, updateQuery4.executeUpdate());
-        assertEquals(0, updateQuery4.executeUpdate()); // should be updated
-        endTx(em);
-
-        // test update with field refernece in update value
-        // ### this seems to not be working
-        startTx(em);
-        Query updateFieldValue = em.createQuery("update Entity1 e"
-            + " set e.intField = e.intField + 1");
-        assertEquals(num, updateFieldValue.executeUpdate());
-        endTx(em);
-
-        startTx(em);
-        Query deleteQuery = em.createQuery
-            ("delete from Entity1 e where e.stringField = :val").
-            setParameter("val", null);
-        assertEquals(num, deleteQuery.executeUpdate());
-        assertEquals(0, deleteQuery.executeUpdate());
-        endTx(em);
-
-        endEm(em);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.clauses;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestBulkUpdate extends AbstractTestCase {
+
+    public TestBulkUpdate(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(Entity1.class);
+        deleteAll(Entity2.class);
+    }
+
+    public void testSimpleBulkUpdate() {
+        for (int i = 1; i < 5; i++)
+            testSimpleBulkUpdate(i);
+    }
+
+    public void testSimpleBulkUpdate(int num) {
+        deleteAll(Entity1.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        for (int i = 0; i < num; i++) {
+            Entity1 e = new Entity1(i, "value1", i);
+            em.persist(e);
+        }
+        endTx(em);
+
+        // test update
+        startTx(em);
+        Query updateQuery1 = em.createQuery("update Entity1 e"
+            + " set e.stringField = 'value2', e.intField = 2"
+            + " where e.stringField = :val").
+            setParameter("val", "value1");
+        assertEquals(num, updateQuery1.executeUpdate());
+        assertEquals(0, updateQuery1.executeUpdate()); // should be updated
+        endTx(em);
+
+        // test update with parameter
+        startTx(em);
+        Query updateQuery2 = em.createQuery("update Entity1 e"
+            + " set e.stringField = :newval where e.stringField = :val").
+            setParameter("val", "value2").
+            setParameter("newval", "value3");
+        assertEquals(num, updateQuery2.executeUpdate());
+        assertEquals(0, updateQuery2.executeUpdate()); // should be updated
+        endTx(em);
+
+        // test update with 2 parameters
+        startTx(em);
+        Query updateQuery3 = em.createQuery("update Entity1 e"
+            + " set e.stringField = :newval, e.intField = 999"
+            + " where e.stringField = :val").
+            setParameter("val", "value3").
+            setParameter("newval", "value4");
+        assertEquals(num, updateQuery3.executeUpdate());
+        assertEquals(0, updateQuery3.executeUpdate()); // should be updated
+        endTx(em);
+
+        // test update with null value
+        startTx(em);
+        Query updateQuery4 = em.createQuery("update Entity1 e"
+            + " set e.stringField = :nullval, e.intField = :intval"
+            + " where e.stringField = :val"
+            + " and e.intField = 999").
+            setParameter("val", "value4").
+            setParameter("intval", new Integer(987)).
+            setParameter("nullval", null);
+        assertEquals(num, updateQuery4.executeUpdate());
+        assertEquals(0, updateQuery4.executeUpdate()); // should be updated
+        endTx(em);
+
+        // test update with field refernece in update value
+        // ### this seems to not be working
+        startTx(em);
+        Query updateFieldValue = em.createQuery("update Entity1 e"
+            + " set e.intField = e.intField + 1");
+        assertEquals(num, updateFieldValue.executeUpdate());
+        endTx(em);
+
+        startTx(em);
+        Query deleteQuery = em.createQuery
+            ("delete from Entity1 e where e.stringField = :val").
+            setParameter("val", null);
+        assertEquals(num, deleteQuery.executeUpdate());
+        assertEquals(0, deleteQuery.executeUpdate());
+        endTx(em);
+
+        endEm(em);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBClauses.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBClauses.java
index 72685e2..ac9cd90 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBClauses.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBClauses.java
@@ -1,213 +1,213 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.clauses;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.common.apps.Course;
-import org.apache.openjpa.persistence.common.apps.ArtCourse;
-import org.apache.openjpa.persistence.common.apps.Department;
-import org.apache.openjpa.persistence.common.apps.Student;
-
-public class TestEJBClauses extends AbstractTestCase {
-
-    public TestEJBClauses(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(Course.class);
-        deleteAll(Student.class);
-        deleteAll(Department.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        String name = "";
-        List<Course> clist = new ArrayList<Course>();
-        List<Department> dlist = new ArrayList<Department>();
-
-        for (int i = 0; i < 5; i++) {
-            Course curr = new Course("Math " + i, i * 2, i);
-            Course acurr = new ArtCourse(i + 20, "English" + (2 * i));
-            Department durr = new Department("CompSci" + i, null, i + 2);
-            clist.add(curr);
-            clist.add(acurr);
-            dlist.add(durr);
-        }
-
-        Student stud = new Student("Jonathan", clist, dlist);
-        Student stud2 = new Student("Stam", null, dlist);
-        Student stud3 = new Student("John", clist, null);
-        Student stud4 = new Student("Bill", null, null);
-
-        em.persist(stud);
-        em.persist(stud2);
-        em.persist(stud3);
-        em.persist(stud4);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testFromClause1() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT o.name FROM Student o";
-
-        List result = em.createQuery(query)
-            .getResultList();
-
-        assertNotNull(result);
-        assertEquals(4, result.size());
-
-        endEm(em);
-    }
-
-    public void testFromClause2() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT NEW apps.ArtCourse(e.name)" +
-            "FROM Student e";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(4, result.size());
-
-        endEm(em);
-    }
-
-    public void testFromClause3() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT o.name " +
-            "FROM Student o, Course c " +
-            "WHERE o.course IS NULL AND o.department IS NULL";
-
-        List ls = (List) em.createQuery(query)
-            .getResultList();
-        String uno = (String) ls.get(0);
-
-        assertNotNull(ls);
-        assertEquals(1, ls.size());
-        assertEquals("Bill", uno);
-
-        endEm(em);
-    }
-
-    public void testWhereClause1() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT distinct s.name " +
-            "FROM Student s, Course d " +
-            "WHERE d.courseId >= 4 AND s.department IS NOT NULL";
-
-        List ls = em.createQuery(query).getResultList();
-
-        assertNotNull(ls);
-        assertEquals(2, ls.size());
-
-        endEm(em);
-    }
-
-    public void testWhereClause2() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT distinct s.name " +
-            "FROM Student s " +
-            "WHERE" +
-            " Exists(SELECT c FROM s.course c WHERE c.name LIKE 'Math%')";
-
-        List ls = em.createQuery(query).getResultList();
-
-        assertNotNull(ls);
-        assertEquals(2, ls.size());
-        assertTrue(ls.contains("Jonathan"));
-        assertTrue(ls.contains("John"));
-
-        endEm(em);
-    }
-
-    public void testClauseRangeVar() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT DISTINCT s FROM Student s, Student s2 " +
-            "WHERE s.name = 'John' AND s2.name = 'Jonathan'";
-
-        List ls = em.createQuery(query).getResultList();
-
-        assertNotNull(ls);
-        assertEquals(1, ls.size());
-
-        Student ret = (Student) ls.get(0);
-        assertEquals("John", ret.getName());
-
-        endEm(em);
-    }
-
-    public void testClausePathExpr() {
-        EntityManager em = currentEntityManager();
-        String failure = "SELECT DISTINCT s " +
-            "FROM Student s WHERE" +
-            " s.department.name = 'CompSci1'";
-        // Changes related to OPENJPA-485 allows this query to pass.
-        // The query is not kosher as it does navigate through a 
-        // collection-valued-path-expression (s.department.name) where
-        // department is a Collection. 
-        // But we allow this because of the convenience of the query expression 
-        List ls = em.createQuery(failure).getResultList();
-        assertFalse(ls.isEmpty());
-        endEm(em);
-    }
-
-    public void testClausePathExpr2() {
-        EntityManager em = currentEntityManager();
-        String success =
-            "SELECT DISTINCT d.name FROM Student AS s, IN(s.department) d ";
-
-        List ls2 = em.createQuery(success).getResultList();
-
-        assertNotNull(ls2);
-        assertEquals(5, ls2.size());
-
-        endEm(em);
-    }
-
-    public void testCollMemberDecl() {
-        EntityManager em = currentEntityManager();
-
-        String colldec = "SELECT DISTINCT s.name " +
-            "FROM Student s," +
-            " IN(s.department) d" +
-            " WHERE d.name = 'CompSci2'";
-
-        List ls = em.createQuery(colldec).getResultList();
-
-        assertNotNull(ls);
-        assertEquals(2, ls.size());
-        assertTrue(ls.contains("Jonathan"));
-        assertTrue(ls.contains("Stam"));
-
-        endEm(em);
-    }
-
-    /**
-     * GroupBy , OrderBy clause is tested by testejbqlfunction under
-     * functional directory.
-     */
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.clauses;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.common.apps.Course;
+import org.apache.openjpa.persistence.common.apps.ArtCourse;
+import org.apache.openjpa.persistence.common.apps.Department;
+import org.apache.openjpa.persistence.common.apps.Student;
+
+public class TestEJBClauses extends AbstractTestCase {
+
+    public TestEJBClauses(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(Course.class);
+        deleteAll(Student.class);
+        deleteAll(Department.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        String name = "";
+        List<Course> clist = new ArrayList<Course>();
+        List<Department> dlist = new ArrayList<Department>();
+
+        for (int i = 0; i < 5; i++) {
+            Course curr = new Course("Math " + i, i * 2, i);
+            Course acurr = new ArtCourse(i + 20, "English" + (2 * i));
+            Department durr = new Department("CompSci" + i, null, i + 2);
+            clist.add(curr);
+            clist.add(acurr);
+            dlist.add(durr);
+        }
+
+        Student stud = new Student("Jonathan", clist, dlist);
+        Student stud2 = new Student("Stam", null, dlist);
+        Student stud3 = new Student("John", clist, null);
+        Student stud4 = new Student("Bill", null, null);
+
+        em.persist(stud);
+        em.persist(stud2);
+        em.persist(stud3);
+        em.persist(stud4);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testFromClause1() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT o.name FROM Student o";
+
+        List result = em.createQuery(query)
+            .getResultList();
+
+        assertNotNull(result);
+        assertEquals(4, result.size());
+
+        endEm(em);
+    }
+
+    public void testFromClause2() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT NEW apps.ArtCourse(e.name)" +
+            "FROM Student e";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(4, result.size());
+
+        endEm(em);
+    }
+
+    public void testFromClause3() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT o.name " +
+            "FROM Student o, Course c " +
+            "WHERE o.course IS NULL AND o.department IS NULL";
+
+        List ls = (List) em.createQuery(query)
+            .getResultList();
+        String uno = (String) ls.get(0);
+
+        assertNotNull(ls);
+        assertEquals(1, ls.size());
+        assertEquals("Bill", uno);
+
+        endEm(em);
+    }
+
+    public void testWhereClause1() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT distinct s.name " +
+            "FROM Student s, Course d " +
+            "WHERE d.courseId >= 4 AND s.department IS NOT NULL";
+
+        List ls = em.createQuery(query).getResultList();
+
+        assertNotNull(ls);
+        assertEquals(2, ls.size());
+
+        endEm(em);
+    }
+
+    public void testWhereClause2() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT distinct s.name " +
+            "FROM Student s " +
+            "WHERE" +
+            " Exists(SELECT c FROM s.course c WHERE c.name LIKE 'Math%')";
+
+        List ls = em.createQuery(query).getResultList();
+
+        assertNotNull(ls);
+        assertEquals(2, ls.size());
+        assertTrue(ls.contains("Jonathan"));
+        assertTrue(ls.contains("John"));
+
+        endEm(em);
+    }
+
+    public void testClauseRangeVar() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT DISTINCT s FROM Student s, Student s2 " +
+            "WHERE s.name = 'John' AND s2.name = 'Jonathan'";
+
+        List ls = em.createQuery(query).getResultList();
+
+        assertNotNull(ls);
+        assertEquals(1, ls.size());
+
+        Student ret = (Student) ls.get(0);
+        assertEquals("John", ret.getName());
+
+        endEm(em);
+    }
+
+    public void testClausePathExpr() {
+        EntityManager em = currentEntityManager();
+        String failure = "SELECT DISTINCT s " +
+            "FROM Student s WHERE" +
+            " s.department.name = 'CompSci1'";
+        // Changes related to OPENJPA-485 allows this query to pass.
+        // The query is not kosher as it does navigate through a 
+        // collection-valued-path-expression (s.department.name) where
+        // department is a Collection. 
+        // But we allow this because of the convenience of the query expression 
+        List ls = em.createQuery(failure).getResultList();
+        assertFalse(ls.isEmpty());
+        endEm(em);
+    }
+
+    public void testClausePathExpr2() {
+        EntityManager em = currentEntityManager();
+        String success =
+            "SELECT DISTINCT d.name FROM Student AS s, IN(s.department) d ";
+
+        List ls2 = em.createQuery(success).getResultList();
+
+        assertNotNull(ls2);
+        assertEquals(5, ls2.size());
+
+        endEm(em);
+    }
+
+    public void testCollMemberDecl() {
+        EntityManager em = currentEntityManager();
+
+        String colldec = "SELECT DISTINCT s.name " +
+            "FROM Student s," +
+            " IN(s.department) d" +
+            " WHERE d.name = 'CompSci2'";
+
+        List ls = em.createQuery(colldec).getResultList();
+
+        assertNotNull(ls);
+        assertEquals(2, ls.size());
+        assertTrue(ls.contains("Jonathan"));
+        assertTrue(ls.contains("Stam"));
+
+        endEm(em);
+    }
+
+    /**
+     * GroupBy , OrderBy clause is tested by testejbqlfunction under
+     * functional directory.
+     */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBDeleteUpdateImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBDeleteUpdateImpl.java
index 9695742..87096d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBDeleteUpdateImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBDeleteUpdateImpl.java
@@ -1,163 +1,163 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.clauses;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBDeleteUpdateImpl extends AbstractTestCase {
-
-    public TestEJBDeleteUpdateImpl() {
-    }
-
-    public TestEJBDeleteUpdateImpl(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 runt1 = new RuntimeTest1(1);
-        runt1.setStringField("runt1");
-        runt1.setSelfOneOne(new RuntimeTest1(2));
-        RuntimeTest2 runt2 = new RuntimeTest2(3);
-        runt2.setStringField("runt2");
-
-        em.persist(runt1);
-        em.persist(runt2);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testUpdate1() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 ret = em.find(RuntimeTest1.class, 1);
-
-        assertNotNull(ret);
-        assertEquals("runt1", ret.getStringField());
-        assertNotNull(ret.getSelfOneOne());
-
-        String ejbqlUpdate =
-            "UPDATE RuntimeTest1 x SET x.stringField = :strngfld WHERE x.stringField = :stdfield";
-        int updatedEntities = em.createQuery(ejbqlUpdate)
-            .setParameter("strngfld", "runner13")
-            .setParameter("stdfield", "runt1")
-            .executeUpdate();
-
-        assertEquals(1, updatedEntities);
-
-        endTx(em);
-
-        RuntimeTest1 ret2 = em.find(RuntimeTest1.class, 1);
-        em.refresh(ret2);
-
-        assertNotNull(ret2);
-        assertEquals("runner13", ret2.getStringField());
-
-        em.close();
-    }
-
-    public void testUpdate2() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 run = em.find(RuntimeTest1.class, 1);
-        assertNotNull(run);
-        assertEquals("runt1", run.getStringField());
-        assertNotNull(run.getSelfOneOne());
-
-        String ejbqlUpdate = "UPDATE RuntimeTest1 x " +
-            "SET x.stringField = :strngfld " +
-            "WHERE x.stringField = :field " +
-            "AND x.selfOneOne " +
-            "IS NOT NULL";
-
-        int upEntities = em.createQuery(ejbqlUpdate)
-            .setParameter("strngfld", "upd")
-            .setParameter("field", "runt1")
-            .executeUpdate();
-
-        assertEquals(1, upEntities);
-
-        RuntimeTest1 inst = em.find(RuntimeTest1.class, 1);
-        em.refresh(inst);
-
-        assertNotNull(inst);
-//		assertEquals("upd", inst.getStringField());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testDelete1() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 run = em.find(RuntimeTest1.class, 1);
-        assertNotNull(run);
-        assertEquals("runt1", run.getStringField());
-        assertNotNull(run.getSelfOneOne());
-
-        String ejbdelUpdate = "DELETE FROM RuntimeTest1 s " +
-            "WHERE s.stringField = :strngfld";
-        int delEntity = em.createQuery(ejbdelUpdate)
-            .setParameter("strngfld", "runt1")
-            .executeUpdate();
-
-        assertEquals(1, delEntity);
-
-        RuntimeTest1 del = em.find(RuntimeTest1.class, 1);
-        assertNull(del);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testDelete2() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 run = em.find(RuntimeTest1.class, 1);
-        assertNotNull(run);
-        assertEquals("runt1", run.getStringField());
-        assertNotNull(run.getSelfOneOne());
-
-        String ejbdelUpdate =
-            "DELETE FROM RuntimeTest1 r WHERE r.stringField = ?1";
-        Query query = em.createQuery(ejbdelUpdate);
-
-        query.setParameter(1, "runt1");
-        int ok = query.executeUpdate();
-
-        assertEquals(1, ok);
-
-        endTx(em);
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.clauses;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBDeleteUpdateImpl extends AbstractTestCase {
+
+    public TestEJBDeleteUpdateImpl() {
+    }
+
+    public TestEJBDeleteUpdateImpl(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 runt1 = new RuntimeTest1(1);
+        runt1.setStringField("runt1");
+        runt1.setSelfOneOne(new RuntimeTest1(2));
+        RuntimeTest2 runt2 = new RuntimeTest2(3);
+        runt2.setStringField("runt2");
+
+        em.persist(runt1);
+        em.persist(runt2);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testUpdate1() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 ret = em.find(RuntimeTest1.class, 1);
+
+        assertNotNull(ret);
+        assertEquals("runt1", ret.getStringField());
+        assertNotNull(ret.getSelfOneOne());
+
+        String ejbqlUpdate =
+            "UPDATE RuntimeTest1 x SET x.stringField = :strngfld WHERE x.stringField = :stdfield";
+        int updatedEntities = em.createQuery(ejbqlUpdate)
+            .setParameter("strngfld", "runner13")
+            .setParameter("stdfield", "runt1")
+            .executeUpdate();
+
+        assertEquals(1, updatedEntities);
+
+        endTx(em);
+
+        RuntimeTest1 ret2 = em.find(RuntimeTest1.class, 1);
+        em.refresh(ret2);
+
+        assertNotNull(ret2);
+        assertEquals("runner13", ret2.getStringField());
+
+        em.close();
+    }
+
+    public void testUpdate2() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 run = em.find(RuntimeTest1.class, 1);
+        assertNotNull(run);
+        assertEquals("runt1", run.getStringField());
+        assertNotNull(run.getSelfOneOne());
+
+        String ejbqlUpdate = "UPDATE RuntimeTest1 x " +
+            "SET x.stringField = :strngfld " +
+            "WHERE x.stringField = :field " +
+            "AND x.selfOneOne " +
+            "IS NOT NULL";
+
+        int upEntities = em.createQuery(ejbqlUpdate)
+            .setParameter("strngfld", "upd")
+            .setParameter("field", "runt1")
+            .executeUpdate();
+
+        assertEquals(1, upEntities);
+
+        RuntimeTest1 inst = em.find(RuntimeTest1.class, 1);
+        em.refresh(inst);
+
+        assertNotNull(inst);
+//		assertEquals("upd", inst.getStringField());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testDelete1() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 run = em.find(RuntimeTest1.class, 1);
+        assertNotNull(run);
+        assertEquals("runt1", run.getStringField());
+        assertNotNull(run.getSelfOneOne());
+
+        String ejbdelUpdate = "DELETE FROM RuntimeTest1 s " +
+            "WHERE s.stringField = :strngfld";
+        int delEntity = em.createQuery(ejbdelUpdate)
+            .setParameter("strngfld", "runt1")
+            .executeUpdate();
+
+        assertEquals(1, delEntity);
+
+        RuntimeTest1 del = em.find(RuntimeTest1.class, 1);
+        assertNull(del);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testDelete2() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 run = em.find(RuntimeTest1.class, 1);
+        assertNotNull(run);
+        assertEquals("runt1", run.getStringField());
+        assertNotNull(run.getSelfOneOne());
+
+        String ejbdelUpdate =
+            "DELETE FROM RuntimeTest1 r WHERE r.stringField = ?1";
+        Query query = em.createQuery(ejbdelUpdate);
+
+        query.setParameter(1, "runt1");
+        int ok = query.executeUpdate();
+
+        assertEquals(1, ok);
+
+        endTx(em);
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBPolymorphicQuery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBPolymorphicQuery.java
index 68601d3..a64df99 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBPolymorphicQuery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBPolymorphicQuery.java
@@ -1,88 +1,88 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.clauses;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.apps.Entity1;
-import org.apache.openjpa.persistence.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBPolymorphicQuery extends AbstractTestCase {
-
-    public TestEJBPolymorphicQuery(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        int run1 = 10;
-        int run2 = 15;
-
-        for (int i = 0; i < run1; i++) {
-            RuntimeTest1 rt = new RuntimeTest1(i);
-            rt.setStringField("foo " + i);
-            em.persist(rt);
-        }
-
-        for (int i = 10; i < run2; i++) {
-            em.persist(new RuntimeTest2(i));
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    /**
-     * Ensures that when a select query is ran against an entity at the top of the hierarchy
-     * that the result is its instances and that of all its subclass.
-     */
-    public void testPolymorphicSelect() {
-        EntityManager em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from RuntimeTest1 o")
-            .getResultList();
-
-        assertNotNull(l);
-        assertEquals(15, l.size());
-
-        endEm(em);
-    }
-
-    public void testPolymorphicDelete() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        int l = em.createQuery("Delete from RuntimeTest1")
-            .executeUpdate();
-
-        assertNotNull(l);
-        assertEquals(15, l);
-
-        endTx(em);
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.clauses;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.apps.Entity1;
+import org.apache.openjpa.persistence.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBPolymorphicQuery extends AbstractTestCase {
+
+    public TestEJBPolymorphicQuery(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        int run1 = 10;
+        int run2 = 15;
+
+        for (int i = 0; i < run1; i++) {
+            RuntimeTest1 rt = new RuntimeTest1(i);
+            rt.setStringField("foo " + i);
+            em.persist(rt);
+        }
+
+        for (int i = 10; i < run2; i++) {
+            em.persist(new RuntimeTest2(i));
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    /**
+     * Ensures that when a select query is ran against an entity at the top of the hierarchy
+     * that the result is its instances and that of all its subclass.
+     */
+    public void testPolymorphicSelect() {
+        EntityManager em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from RuntimeTest1 o")
+            .getResultList();
+
+        assertNotNull(l);
+        assertEquals(15, l.size());
+
+        endEm(em);
+    }
+
+    public void testPolymorphicDelete() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        int l = em.createQuery("Delete from RuntimeTest1")
+            .executeUpdate();
+
+        assertNotNull(l);
+        assertEquals(15, l);
+
+        endTx(em);
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBQueryInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBQueryInterface.java
index 7c38762..34cb00c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBQueryInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/clauses/TestEJBQueryInterface.java
@@ -1,152 +1,152 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.clauses;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.NamedQuery;
-
-import org.apache.openjpa.persistence.common.apps.Entity1;
-import org.apache.openjpa.persistence.common.apps.Entity2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-@NamedQuery(name = "setParam1",
-    query = "SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-public class TestEJBQueryInterface extends AbstractTestCase {
-
-    public TestEJBQueryInterface(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(Entity1.class);
-
-        int instNum = 10;
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        //create and persist multiple entity1 instances
-        for (int i = 0; i < instNum; i++) {
-            Entity1 ent = new Entity1(i, "string" + i, i + 2);
-            Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
-            ent.setEntity2Field(ent2);
-            em.persist(ent);
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testResultList() {
-        EntityManager em = currentEntityManager();
-        List list = em.createQuery("Select object(o) from Entity1 o")
-            .getResultList();
-
-        assertEquals(10, list.size());
-
-        endEm(em);
-    }
-
-    public void testGetSingleList() {
-        EntityManager em = currentEntityManager();
-        String curr = 2 + "";
-
-        Entity1 ret =
-            (Entity1) em.createQuery("SELECT o FROM Entity1 o WHERE o.pk = 2")
-                .getSingleResult();
-
-        assertNotNull(ret);
-        assertEquals("string2", ret.getStringField());
-        assertEquals(4, ret.getIntField());
-
-        endEm(em);
-    }
-
-    public void testExecuteUpdate() {
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk = 2")
-            .executeUpdate();
-
-        assertEquals(ret, 1);
-
-        int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk = 22")
-            .executeUpdate();
-
-        assertEquals(ret2, 0);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testSetMaxResults() {
-        EntityManager em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from Entity1 o")
-            .setMaxResults(5)
-            .getResultList();
-
-        assertNotNull(l);
-        assertEquals(5, l.size());
-
-        endEm(em);
-    }
-
-    public void testSetFirstResults() {
-        EntityManager em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from Entity1 o")
-            .setFirstResult(3)
-            .getResultList();
-
-        Entity1 ent = (Entity1) l.get(0);
-
-        assertNotNull(ent);
-        assertEquals("string3", ent.getStringField());
-        assertEquals(5, ent.getIntField());
-
-        endEm(em);
-    }
-
-    // Tests Binding an argument to a named parameter.
-    // pk, the named parameter --Not working yet--
-    public void xxxtestSetParameter1() {
-
-        EntityManager em = currentEntityManager();
-        String curr = 2 + "";
-
-        List ret = em.createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
-            .setParameter("pk", curr)
-            .getResultList();
-
-        assertNotNull(ret);
-        assertEquals(1, ret.size());
-
-        ret = em.createNamedQuery("setParam1")
-            .setParameter("pk", curr)
-            .getResultList();
-
-        assertNotNull(ret);
-        assertEquals(1, ret.size());
-
-        endTx(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.clauses;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.NamedQuery;
+
+import org.apache.openjpa.persistence.common.apps.Entity1;
+import org.apache.openjpa.persistence.common.apps.Entity2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+@NamedQuery(name = "setParam1",
+    query = "SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
+public class TestEJBQueryInterface extends AbstractTestCase {
+
+    public TestEJBQueryInterface(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(Entity1.class);
+
+        int instNum = 10;
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        //create and persist multiple entity1 instances
+        for (int i = 0; i < instNum; i++) {
+            Entity1 ent = new Entity1(i, "string" + i, i + 2);
+            Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
+            ent.setEntity2Field(ent2);
+            em.persist(ent);
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testResultList() {
+        EntityManager em = currentEntityManager();
+        List list = em.createQuery("Select object(o) from Entity1 o")
+            .getResultList();
+
+        assertEquals(10, list.size());
+
+        endEm(em);
+    }
+
+    public void testGetSingleList() {
+        EntityManager em = currentEntityManager();
+        String curr = 2 + "";
+
+        Entity1 ret =
+            (Entity1) em.createQuery("SELECT o FROM Entity1 o WHERE o.pk = 2")
+                .getSingleResult();
+
+        assertNotNull(ret);
+        assertEquals("string2", ret.getStringField());
+        assertEquals(4, ret.getIntField());
+
+        endEm(em);
+    }
+
+    public void testExecuteUpdate() {
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        int ret = em.createQuery("Delete FROM Entity1 o WHERE o.pk = 2")
+            .executeUpdate();
+
+        assertEquals(ret, 1);
+
+        int ret2 = em.createQuery("Delete FROM Entity1 o WHERE o.pk = 22")
+            .executeUpdate();
+
+        assertEquals(ret2, 0);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testSetMaxResults() {
+        EntityManager em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from Entity1 o")
+            .setMaxResults(5)
+            .getResultList();
+
+        assertNotNull(l);
+        assertEquals(5, l.size());
+
+        endEm(em);
+    }
+
+    public void testSetFirstResults() {
+        EntityManager em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from Entity1 o")
+            .setFirstResult(3)
+            .getResultList();
+
+        Entity1 ent = (Entity1) l.get(0);
+
+        assertNotNull(ent);
+        assertEquals("string3", ent.getStringField());
+        assertEquals(5, ent.getIntField());
+
+        endEm(em);
+    }
+
+    // Tests Binding an argument to a named parameter.
+    // pk, the named parameter --Not working yet--
+    public void xxxtestSetParameter1() {
+
+        EntityManager em = currentEntityManager();
+        String curr = 2 + "";
+
+        List ret = em.createQuery("SELECT o FROM Entity1 o WHERE o.pk LIKE :pk")
+            .setParameter("pk", curr)
+            .getResultList();
+
+        assertNotNull(ret);
+        assertEquals(1, ret.size());
+
+        ret = em.createNamedQuery("setParam1")
+            .setParameter("pk", curr)
+            .getResultList();
+
+        assertNotNull(ret);
+        assertEquals(1, ret.size());
+
+        endTx(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEJBQLCondExpression.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEJBQLCondExpression.java
index 4e71644..c9d2b28 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEJBQLCondExpression.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEJBQLCondExpression.java
@@ -1,323 +1,325 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.expressions;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.apps.*;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBQLCondExpression extends AbstractTestCase {
-
-    private int userid1, userid2, userid3, userid4, userid5;
-
-    public TestEJBQLCondExpression(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(CompUser.class);
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        Address[] add =
-            new Address[]{ new Address("43 Sansome", "SF", "USA", "94104"),
-                new Address("24 Mink", "ANTIOCH", "USA", "94513"),
-                new Address("23 Ogbete", "CoalCamp", "NIGERIA", "00000"),
-                new Address("10 Wilshire", "Worcester", "CANADA", "80080"),
-                new Address("23 Bellflower", "Ogui", "NIGERIA", "02000") };
-
-        CompUser user1 = createUser("Seetha", "MAC", add[0], 40, true);
-        CompUser user2 = createUser("Shannon", "PC", add[1], 36, false);
-        CompUser user3 = createUser("Ugo", "PC", add[2], 19, true);
-        CompUser user4 = createUser("Jacob", "LINUX", add[3], 10, true);
-        CompUser user5 = createUser("Famzy", "UNIX", add[4], 29, false);
-
-        em.persist(user1);
-        userid1 = user1.getUserid();
-        em.persist(user2);
-        userid2 = user2.getUserid();
-        em.persist(user3);
-        userid3 = user3.getUserid();
-        em.persist(user4);
-        userid4 = user4.getUserid();
-        em.persist(user5);
-        userid5 = user5.getUserid();
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testNothing() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT o FROM CompUser o";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("the size of the list is not 5", 5, result.size());
-
-        endEm(em);
-    }
-
-    public void testBetweenExpr() {
-        EntityManager em = currentEntityManager();
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.age BETWEEN 19 AND 40 AND o.computerName = 'PC'";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("they are not equal", 2, result.size());
-        assertTrue("result dont contain shannon", result.contains("Shannon"));
-        assertTrue("result dont contain ugo", result.contains("Ugo"));
-
-        endEm(em);
-    }
-
-    public void testNotBetweenExpr() {
-        EntityManager em = currentEntityManager();
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.age NOT BETWEEN 19 AND 40 AND o.computerName= 'PC'";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("they are not equal", 0, result.size());
-
-        endEm(em);
-    }
-
-    public void testInExpr() {
-        EntityManager em = currentEntityManager();
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.age IN (29, 40, 10)";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals(3, result.size());
-        assertTrue("seetha is not in the list", result.contains("Seetha"));
-        assertTrue("jacob is not in the list", result.contains("Jacob"));
-        assertTrue("famzy is not in the list", result.contains("Famzy"));
-
-        endEm(em);
-    }
-
-    public void testNotInExpr() {
-        EntityManager em = currentEntityManager();
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.age NOT IN (29, 40, 10)";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(2, result.size());
-        assertTrue(result.contains("Ugo"));
-        assertTrue(result.contains("Shannon"));
-
-        endEm(em);
-    }
-
-    public void testLikeExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT o.computerName FROM CompUser o WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(0, result.size());
-
-        query =
-            "SELECT o.computerName FROM CompUser o WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX')";
-
-        result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-
-        query = "SELECT o.name FROM CompUser o WHERE o.name LIKE '_J%'";
-
-        result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(0, result.size());
-
-        query = "SELECT o.name FROM CompUser o WHERE o.name LIKE ?1 ESCAPE '|'";
-
-        result = em.createQuery(query).setParameter(1, "%|_%").getResultList();
-
-        assertNotNull(result);
-        assertEquals(0, result.size());
-
-        endEm(em);
-    }
-
-    public void testNullExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.age IS NOT NULL AND o.computerName = 'PC' ";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("the list size is not 2", 2, result.size());
-        assertTrue("the result doesnt contain ugo", result.contains("Ugo"));
-        assertTrue("the result doesnt contain shannon",
-            result.contains("Shannon"));
-
-        endEm(em);
-    }
-
-    public void testNullExpr2() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.address.country IS NULL";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("they are not equal", 0, result.size());
-
-        endEm(em);
-    }
-
-    public void testIsEmptyExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.nicknames IS NOT EMPTY";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("they are not equal", 0, result.size());
-
-        endEm(em);
-    }
-
-    public void testIsEmptyExpr2() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.nicknames IS EMPTY";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("they are not equal", 5, result.size());
-
-        endEm(em);
-    }
-
-    /**
-     * TO BE TESTED LATER WITH A DIFF DATABASE
-     * public void testMemberOfExpr(){}
-     */
-
-    public void testExistExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT DISTINCT o.name FROM CompUser o WHERE EXISTS" +
-            " (SELECT c FROM Address c WHERE c = o.address )";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("the list is null", result);
-        assertEquals("they are not equal", 5, result.size());
-        assertTrue("Seetha is not list", result.contains("Seetha"));
-        assertTrue("Shannon is not list", result.contains("Shannon"));
-        assertTrue("jacob is not list", result.contains("Jacob"));
-        assertTrue("ugo is not list", result.contains("Ugo"));
-
-        endEm(em);
-    }
-
-    public void testNotExistExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT DISTINCT o.name FROM CompUser o WHERE NOT EXISTS" +
-                " (SELECT s FROM CompUser s WHERE s.address.country = o.address.country)";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("list is null", result);
-        assertEquals("they are not equal", 0, result.size());
-
-        endEm(em);
-    }
-
-    public void testAnyExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT o.name FROM CompUser o WHERE o.address.zipcode = ANY (" +
-                " SELECT s.computerName FROM CompUser s WHERE s.address.country IS NOT NULL )";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull("list is null", result);
-        assertEquals("they are not equal", 0, result.size());
-
-        endEm(em);
-    }
-
-    public void testConstructorExpr() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT NEW org.apache.openjpa.persistence.common.apps.MaleUser(c.name, c.computerName, c.address, c.age, c.userid)" +
-                " FROM CompUser c WHERE c.name = 'Seetha'";
-
-        MaleUser male = (MaleUser) em.createQuery(query).getSingleResult();
-
-        assertNotNull("the list is null", male);
-        assertEquals("the names dont match", "Seetha", male.getName());
-        assertEquals("computer names dont match", "MAC",
-            male.getComputerName());
-        assertEquals("the ages dont match", 40, male.getAge());
-
-        endEm(em);
-    }
-
-    public CompUser createUser(String name, String cName, Address add, int age,
-        boolean isMale) {
-        CompUser user = null;
-        if (isMale) {
-            user = new MaleUser();
-            user.setName(name);
-            user.setComputerName(cName);
-            user.setAddress(add);
-            user.setAge(age);
-        } else {
-            user = new FemaleUser();
-            user.setName(name);
-            user.setComputerName(cName);
-            user.setAddress(add);
-            user.setAge(age);
-        }
-        return user;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.expressions;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBQLCondExpression extends AbstractTestCase {
+
+    private int userid1, userid2, userid3, userid4, userid5;
+
+    public TestEJBQLCondExpression(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(CompUser.class);
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        Address[] add =
+            new Address[]{ new Address("43 Sansome", "SF", "USA", "94104"),
+                new Address("24 Mink", "ANTIOCH", "USA", "94513"),
+                new Address("23 Ogbete", "CoalCamp", "NIGERIA", "00000"),
+                new Address("10 Wilshire", "Worcester", "CANADA", "80080"),
+                new Address("23 Bellflower", "Ogui", "NIGERIA", "02000") };
+
+        CompUser user1 = createUser("Seetha", "MAC", add[0], 40, true);
+        CompUser user2 = createUser("Shannon", "PC", add[1], 36, false);
+        CompUser user3 = createUser("Ugo", "PC", add[2], 19, true);
+        CompUser user4 = createUser("Jacob", "LINUX", add[3], 10, true);
+        CompUser user5 = createUser("Famzy", "UNIX", add[4], 29, false);
+
+        em.persist(user1);
+        userid1 = user1.getUserid();
+        em.persist(user2);
+        userid2 = user2.getUserid();
+        em.persist(user3);
+        userid3 = user3.getUserid();
+        em.persist(user4);
+        userid4 = user4.getUserid();
+        em.persist(user5);
+        userid5 = user5.getUserid();
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testNothing() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT o FROM CompUser o";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("the size of the list is not 5", 5, result.size());
+
+        endEm(em);
+    }
+
+    public void testBetweenExpr() {
+        EntityManager em = currentEntityManager();
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.age BETWEEN 19 AND 40 AND o.computerName = 'PC'";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("they are not equal", 2, result.size());
+        assertTrue("result dont contain shannon", result.contains("Shannon"));
+        assertTrue("result dont contain ugo", result.contains("Ugo"));
+
+        endEm(em);
+    }
+
+    public void testNotBetweenExpr() {
+        EntityManager em = currentEntityManager();
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.age NOT BETWEEN 19 AND 40 AND o.computerName= 'PC'";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("they are not equal", 0, result.size());
+
+        endEm(em);
+    }
+
+    public void testInExpr() {
+        EntityManager em = currentEntityManager();
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.age IN (29, 40, 10)";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals(3, result.size());
+        assertTrue("seetha is not in the list", result.contains("Seetha"));
+        assertTrue("jacob is not in the list", result.contains("Jacob"));
+        assertTrue("famzy is not in the list", result.contains("Famzy"));
+
+        endEm(em);
+    }
+
+    public void testNotInExpr() {
+        EntityManager em = currentEntityManager();
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.age NOT IN (29, 40, 10)";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(2, result.size());
+        assertTrue(result.contains("Ugo"));
+        assertTrue(result.contains("Shannon"));
+
+        endEm(em);
+    }
+
+    public void testLikeExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT o.computerName FROM CompUser o WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(0, result.size());
+
+        query =
+            "SELECT o.computerName FROM CompUser o WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX')";
+
+        result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+
+        query = "SELECT o.name FROM CompUser o WHERE o.name LIKE '_J%'";
+
+        result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(0, result.size());
+
+        query = "SELECT o.name FROM CompUser o WHERE o.name LIKE ?1 ESCAPE '|'";
+
+        result = em.createQuery(query).setParameter(1, "%|_%").getResultList();
+
+        assertNotNull(result);
+        assertEquals(0, result.size());
+
+        endEm(em);
+    }
+
+    public void testNullExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.age IS NOT NULL AND o.computerName = 'PC' ";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("the list size is not 2", 2, result.size());
+        assertTrue("the result doesnt contain ugo", result.contains("Ugo"));
+        assertTrue("the result doesnt contain shannon",
+            result.contains("Shannon"));
+
+        endEm(em);
+    }
+
+    public void testNullExpr2() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.address.country IS NULL";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("they are not equal", 0, result.size());
+
+        endEm(em);
+    }
+
+    public void testIsEmptyExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.nicknames IS NOT EMPTY";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("they are not equal", 0, result.size());
+
+        endEm(em);
+    }
+
+    public void testIsEmptyExpr2() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.nicknames IS EMPTY";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("they are not equal", 5, result.size());
+
+        endEm(em);
+    }
+
+    /**
+     * TO BE TESTED LATER WITH A DIFF DATABASE
+     * public void testMemberOfExpr(){}
+     */
+
+    public void testExistExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT DISTINCT o.name FROM CompUser o WHERE EXISTS" +
+            " (SELECT c FROM Address c WHERE c = o.address )";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("the list is null", result);
+        assertEquals("they are not equal", 5, result.size());
+        assertTrue("Seetha is not list", result.contains("Seetha"));
+        assertTrue("Shannon is not list", result.contains("Shannon"));
+        assertTrue("jacob is not list", result.contains("Jacob"));
+        assertTrue("ugo is not list", result.contains("Ugo"));
+
+        endEm(em);
+    }
+
+    public void testNotExistExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT DISTINCT o.name FROM CompUser o WHERE NOT EXISTS" +
+                " (SELECT s FROM CompUser s WHERE s.address.country = o.address.country)";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("list is null", result);
+        assertEquals("they are not equal", 0, result.size());
+
+        endEm(em);
+    }
+
+    public void testAnyExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT o.name FROM CompUser o WHERE o.address.zipcode = ANY (" +
+                " SELECT s.computerName FROM CompUser s WHERE s.address.country IS NOT NULL )";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull("list is null", result);
+        assertEquals("they are not equal", 0, result.size());
+
+        endEm(em);
+    }
+
+    public void testConstructorExpr() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT NEW org.apache.openjpa.persistence.common.apps.MaleUser(c.name, c.computerName, c.address, c.age, c.userid)" +
+                " FROM CompUser c WHERE c.name = 'Seetha'";
+
+        MaleUser male = (MaleUser) em.createQuery(query).getSingleResult();
+
+        assertNotNull("the list is null", male);
+        assertEquals("the names dont match", "Seetha", male.getName());
+        assertEquals("computer names dont match", "MAC",
+            male.getComputerName());
+        assertEquals("the ages dont match", 40, male.getAge());
+
+        endEm(em);
+    }
+
+    public CompUser createUser(String name, String cName, Address add, int age,
+        boolean isMale) {
+        CompUser user = null;
+        if (isMale) {
+            user = new MaleUser();
+            user.setName(name);
+            user.setComputerName(cName);
+            user.setAddress(add);
+            user.setAge(age);
+            user.setNameAsLob(name);
+        } else {
+            user = new FemaleUser();
+            user.setName(name);
+            user.setComputerName(cName);
+            user.setAddress(add);
+            user.setAge(age);
+            user.setNameAsLob(name);
+        }
+        return user;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
index 670e08f..13eb2b1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
@@ -1,397 +1,460 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.functions;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.apps.Address;
-import org.apache.openjpa.persistence.common.apps.CompUser;
-import org.apache.openjpa.persistence.common.apps.FemaleUser;
-import org.apache.openjpa.persistence.common.apps.MaleUser;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBQLFunction extends AbstractTestCase {
-
-    private int userid1, userid2, userid3, userid4, userid5, userid6;
-
-    public TestEJBQLFunction(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(CompUser.class);
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        Address[] add = new Address[]{
-            new Address("43 Sansome", "SF", "United-Kingdom", "94104"),
-            new Address("24 Mink", "ANTIOCH", "USA", "94513"),
-            new Address("23 Ogbete", "CoalCamp", "NIGERIA", "00000"),
-            new Address("10 Wilshire", "Worcester", "CANADA", "80080"),
-            new Address("23 Bellflower", "Ogui", null, "02000"),
-            new Address("22 Montgomery", "SF", null, "50054") };
-
-        CompUser user1 = createUser("Seetha", "MAC", add[0], 36, true);
-        CompUser user2 = createUser("Shannon ", "PC", add[1], 36, false);
-        CompUser user3 = createUser("Ugo", "PC", add[2], 19, true);
-        CompUser user4 = createUser("_Jacob", "LINUX", add[3], 10, true);
-        CompUser user5 = createUser("Famzy", "UNIX", add[4], 29, false);
-        CompUser user6 = createUser("Shade", "UNIX", add[5], 23, false);
-
-        em.persist(user1);
-        userid1 = user1.getUserid();
-        em.persist(user2);
-        userid2 = user2.getUserid();
-        em.persist(user3);
-        userid3 = user3.getUserid();
-        em.persist(user4);
-        userid4 = user4.getUserid();
-        em.persist(user5);
-        userid5 = user5.getUserid();
-        em.persist(user6);
-        userid6 = user6.getUserid();
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testConcatSubStringFunc() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        CompUser user = em.find(CompUser.class, userid1);
-        assertNotNull("user is null", user);
-        assertEquals("the name is not seetha", "Seetha", user.getName());
-
-        String query = "UPDATE CompUser e SET e.name = " +
-            "CONCAT('Ablahum', SUBSTRING(e.name, LOCATE('e', e.name), 4)) " +
-            "WHERE e.name='Seetha'";
-        int result = em.createQuery(query).executeUpdate();
-
-        assertEquals("the result is not 1", 1, result);
-
-        user = em.find(CompUser.class, userid1);
-        em.refresh(user);
-
-        assertNotNull("the user is null", user);
-        assertEquals("the users name is not AblahumSeet", "Ablahumeeth",
-            user.getName());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testConcatFunc2() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        CompUser user = em.find(CompUser.class, userid1);
-        assertNotNull("the user is null", user);
-        assertEquals("the users name is not seetha", user.getName(), "Seetha");
-
-        String query = "UPDATE CompUser e " +
-            "SET e.name = " +
-            "CONCAT('', '') WHERE e.name='Seetha'";
-        int result = em.createQuery(query).executeUpdate();
-
-        assertEquals(1, result);
-
-        user = em.find(CompUser.class, userid1);
-        em.refresh(user);
-        assertNotNull(user);
-        assertEquals("", user.getName());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testTrimFunc3() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        CompUser user = em.find(CompUser.class, userid2);
-        assertNotNull(user);
-        assertEquals("Shannon ", user.getName());
-
-        String query = "UPDATE CompUser e SET " +
-            "e.name = Trim(e.name) WHERE " +
-            "e.name='Shannon '";
-        int result = em.createQuery(query).executeUpdate();
-
-        user = em.find(CompUser.class, userid2);
-        em.refresh(user);
-        assertNotNull(user);
-        assertEquals("Shannon", user.getName());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testLowerFunc() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        CompUser user = em.find(CompUser.class, userid3);
-        assertNotNull(user);
-        assertEquals("Ugo", user.getName());
-
-        String query = "UPDATE CompUser e SET " +
-            "e.name = LOWER(e.name) WHERE e.name='Ugo'";
-
-        int result = em.createQuery(query).executeUpdate();
-
-        user = em.find(CompUser.class, userid3);
-        em.refresh(user);
-        assertNotNull(user);
-        assertEquals("ugo", user.getName());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testUpperFunc() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        CompUser user = em.find(CompUser.class, userid3);
-        assertNotNull(user);
-        assertEquals("Ugo", user.getName());
-
-        String query = "UPDATE CompUser e SET " +
-            "e.name = UPPER(e.name) WHERE e.name='Ugo'";
-
-        int result = em.createQuery(query).executeUpdate();
-
-        user = em.find(CompUser.class, userid3);
-        em.refresh(user);
-        assertNotNull(user);
-        assertEquals("UGO", user.getName());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testLengthFunc() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT o.name " +
-            "FROM CompUser o " +
-            "WHERE LENGTH(o.address.country) = 3";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-        assertTrue(result.contains("Shannon "));
-
-        endEm(em);
-    }
-
-    public void testArithmFunc() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        CompUser user = em.find(CompUser.class, userid1);
-
-        assertNotNull(user);
-        assertEquals("Seetha", user.getName());
-        assertEquals(36, user.getAge());
-
-        String query =
-            "UPDATE CompUser e SET e.age = ABS(e.age) WHERE e.name='Seetha'";
-        int num = em.createQuery(query).executeUpdate();
-
-        assertNotNull(num);
-        assertEquals(1, num);
-
-        user = em.find(CompUser.class, userid1);
-        em.refresh(user);
-
-        assertEquals(36, user.getAge());
-
-        //----------------------ABS Tested
-
-        query =
-            "UPDATE CompUser e SET e.age = SQRT(e.age) WHERE e.name='Seetha'";
-        num = em.createQuery(query).executeUpdate();
-
-        assertNotNull(num);
-        assertEquals(1, num);
-
-        user = em.find(CompUser.class, userid1);
-        em.refresh(user);
-
-        assertEquals(6, user.getAge());
-
-        //-------------------------SQRT Tested
-
-        query =
-            "UPDATE CompUser e SET e.age = MOD(e.age, 4) WHERE e.name='Seetha'";
-        num = em.createQuery(query).executeUpdate();
-
-        assertNotNull(num);
-        assertEquals(1, num);
-
-        user = em.find(CompUser.class, userid1);
-        em.refresh(user);
-
-        assertEquals(2, user.getAge());
-
-        //-------------------------MOD Tested
-
-        query = "SELECT e.name FROM CompUser e WHERE SIZE(e.nicknames) = 6";
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(0, result.size());
-
-        //------------------------SIZE Tested
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testGroupByHavingClause() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT c.name FROM CompUser c GROUP BY c.name HAVING c.name LIKE 'S%'";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(3, result.size());
-        assertTrue(result.contains("Shannon "));
-        assertTrue(result.contains("Shade"));
-        assertTrue(result.contains("Seetha"));
-
-        endEm(em);
-    }
-
-    public void testOrderByClause() {
-        EntityManager em = currentEntityManager();
-
-        String query =
-            "SELECT c.name FROM CompUser c WHERE c.name LIKE 'S%' ORDER BY c.name";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(3, result.size());
-        assertTrue(result.contains("Shannon "));
-        assertTrue(result.contains("Seetha"));
-        assertTrue(result.contains("Shade"));
-
-        endEm(em);
-    }
-
-    public void testAVGAggregFunc() {
-        /**
-         * To be Tested: AVG, COUNT, MAX, MIN, SUM
-         */
-
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT AVG(e.age) FROM CompUser e";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-        assertTrue(result.contains(25));
-
-        endEm(em);
-    }
-
-    public void testCOUNTAggregFunc() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT COUNT(c.name) FROM CompUser c";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-        assertTrue(result.contains(6l));
-
-        endEm(em);
-    }
-
-    public void testMAXAggregFunc() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT DISTINCT MAX(c.age) FROM CompUser c";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-        assertTrue(result.contains(36));
-
-        endEm(em);
-    }
-
-    public void testMINAggregFunc() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT DISTINCT MIN(c.age) FROM CompUser c";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-        assertTrue(result.contains(10));
-
-        endEm(em);
-    }
-
-    public void testSUMAggregFunc() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT SUM(c.age) FROM CompUser c";
-
-        List result = em.createQuery(query).getResultList();
-
-        assertNotNull(result);
-        assertEquals(1, result.size());
-        assertTrue(result.contains(153l));
-
-        endEm(em);
-    }
-
-    public CompUser createUser(String name, String cName, Address add, int age,
-        boolean isMale) {
-        CompUser user = null;
-        if (isMale) {
-            user = new MaleUser();
-            user.setName(name);
-            user.setComputerName(cName);
-            user.setAddress(add);
-            user.setAge(age);
-        } else {
-            user = new FemaleUser();
-            user.setName(name);
-            user.setComputerName(cName);
-            user.setAddress(add);
-            user.setAge(age);
-        }
-        return user;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.functions;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.common.apps.Address;
+import org.apache.openjpa.persistence.common.apps.CompUser;
+import org.apache.openjpa.persistence.common.apps.FemaleUser;
+import org.apache.openjpa.persistence.common.apps.MaleUser;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBQLFunction extends AbstractTestCase {
+
+    private int userid1, userid2, userid3, userid4, userid5, userid6;
+
+    public TestEJBQLFunction(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(CompUser.class);
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        Address[] add = new Address[]{
+            new Address("43 Sansome", "SF", "United-Kingdom", "94104"),
+            new Address("24 Mink", "ANTIOCH", "USA", "94513"),
+            new Address("23 Ogbete", "CoalCamp", "NIGERIA", "00000"),
+            new Address("10 Wilshire", "Worcester", "CANADA", "80080"),
+            new Address("23 Bellflower", "Ogui", null, "02000"),
+            new Address("22 Montgomery", "SF", null, "50054") };
+
+        CompUser user1 = createUser("Seetha", "MAC", add[0], 36, true);
+        CompUser user2 = createUser("Shannon ", "PC", add[1], 36, false);
+        CompUser user3 = createUser("Ugo", "PC", add[2], 19, true);
+        CompUser user4 = createUser("_Jacob", "LINUX", add[3], 10, true);
+        CompUser user5 = createUser("Famzy", "UNIX", add[4], 29, false);
+        CompUser user6 = createUser("Shade", "UNIX", add[5], 23, false);
+
+        em.persist(user1);
+        userid1 = user1.getUserid();
+        em.persist(user2);
+        userid2 = user2.getUserid();
+        em.persist(user3);
+        userid3 = user3.getUserid();
+        em.persist(user4);
+        userid4 = user4.getUserid();
+        em.persist(user5);
+        userid5 = user5.getUserid();
+        em.persist(user6);
+        userid6 = user6.getUserid();
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testConcatSubStringFunc() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid1);
+        assertNotNull("user is null", user);
+        assertEquals("the name is not seetha", "Seetha", user.getName());
+
+        String query = "UPDATE CompUser e SET e.name = " +
+            "CONCAT('Ablahum', SUBSTRING(e.name, LOCATE('e', e.name), 4)) " +
+            "WHERE e.name='Seetha'";
+        int result = em.createQuery(query).executeUpdate();
+
+        assertEquals("the result is not 1", 1, result);
+
+        user = em.find(CompUser.class, userid1);
+        em.refresh(user);
+
+        assertNotNull("the user is null", user);
+        assertEquals("the users name is not AblahumSeet", "Ablahumeeth",
+            user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testConcatFunc2() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid1);
+        assertNotNull("the user is null", user);
+        assertEquals("the users name is not seetha", user.getName(), "Seetha");
+
+        String query = "UPDATE CompUser e " +
+            "SET e.name = " +
+            "CONCAT('', '') WHERE e.name='Seetha'";
+        int result = em.createQuery(query).executeUpdate();
+
+        assertEquals(1, result);
+
+        user = em.find(CompUser.class, userid1);
+        em.refresh(user);
+        assertNotNull(user);
+        assertEquals("", user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testTrimFunc3() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid2);
+        assertNotNull(user);
+        assertEquals("Shannon ", user.getName());
+
+        String query = "UPDATE CompUser e SET " +
+            "e.name = Trim(e.name) WHERE " +
+            "e.name='Shannon '";
+        int result = em.createQuery(query).executeUpdate();
+
+        user = em.find(CompUser.class, userid2);
+        em.refresh(user);
+        assertNotNull(user);
+        assertEquals("Shannon", user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testLowerFunc() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid3);
+        assertNotNull(user);
+        assertEquals("Ugo", user.getName());
+
+        String query = "UPDATE CompUser e SET " +
+            "e.name = LOWER(e.name) WHERE e.name='Ugo'";
+
+        int result = em.createQuery(query).executeUpdate();
+
+        user = em.find(CompUser.class, userid3);
+        em.refresh(user);
+        assertNotNull(user);
+        assertEquals("ugo", user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testLowerClobFunc() {
+        OpenJPAEntityManagerSPI em = (OpenJPAEntityManagerSPI) currentEntityManager();
+        // some databases do not support case conversion on LOBs,
+        // just skip this test case
+        DBDictionary dict = ((JDBCConfiguration) em.getConfiguration())
+            .getDBDictionaryInstance();
+        if (!dict.supportsCaseConversionForLob) {
+            return;
+        }
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid5);
+        assertNotNull(user);
+        assertEquals("Famzy", user.getName());
+
+        String query = "UPDATE CompUser e SET " +
+                "e.name = LOWER(e.name) WHERE LOWER(e.nameAsLob)='famzy'";
+
+        int result = em.createQuery(query).executeUpdate();
+
+        user = em.find(CompUser.class, userid5);
+        em.refresh(user);
+        assertNotNull(user);
+        assertEquals("famzy", user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testUpperFunc() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid3);
+        assertNotNull(user);
+        assertEquals("Ugo", user.getName());
+
+        String query = "UPDATE CompUser e SET " +
+            "e.name = UPPER(e.name) WHERE e.name='Ugo'";
+
+        int result = em.createQuery(query).executeUpdate();
+
+        user = em.find(CompUser.class, userid3);
+        em.refresh(user);
+        assertNotNull(user);
+        assertEquals("UGO", user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testUpperClobFunc() {
+        OpenJPAEntityManagerSPI em = (OpenJPAEntityManagerSPI) currentEntityManager();
+        // some databases do not support case conversion on LOBs,
+        // just skip this test case
+        DBDictionary dict = ((JDBCConfiguration) em.getConfiguration())
+            .getDBDictionaryInstance();
+        if (!dict.supportsCaseConversionForLob) {
+            return;
+        }
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid5);
+        assertNotNull(user);
+        assertEquals("Famzy", user.getName());
+
+        String query = "UPDATE CompUser e SET " +
+                "e.name = UPPER(e.name) WHERE UPPER(e.nameAsLob)='FAMZY'";
+
+        int result = em.createQuery(query).executeUpdate();
+
+        user = em.find(CompUser.class, userid5);
+        em.refresh(user);
+        assertNotNull(user);
+        assertEquals("FAMZY", user.getName());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testLengthFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT o.name " +
+            "FROM CompUser o " +
+            "WHERE LENGTH(o.address.country) = 3";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.contains("Shannon "));
+
+        endEm(em);
+    }
+
+    public void testArithmFunc() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        CompUser user = em.find(CompUser.class, userid1);
+
+        assertNotNull(user);
+        assertEquals("Seetha", user.getName());
+        assertEquals(36, user.getAge());
+
+        String query =
+            "UPDATE CompUser e SET e.age = ABS(e.age) WHERE e.name='Seetha'";
+        int num = em.createQuery(query).executeUpdate();
+
+        assertNotNull(num);
+        assertEquals(1, num);
+
+        user = em.find(CompUser.class, userid1);
+        em.refresh(user);
+
+        assertEquals(36, user.getAge());
+
+        //----------------------ABS Tested
+
+        query =
+            "UPDATE CompUser e SET e.age = SQRT(e.age) WHERE e.name='Seetha'";
+        num = em.createQuery(query).executeUpdate();
+
+        assertNotNull(num);
+        assertEquals(1, num);
+
+        user = em.find(CompUser.class, userid1);
+        em.refresh(user);
+
+        assertEquals(6, user.getAge());
+
+        //-------------------------SQRT Tested
+
+        query =
+            "UPDATE CompUser e SET e.age = MOD(e.age, 4) WHERE e.name='Seetha'";
+        num = em.createQuery(query).executeUpdate();
+
+        assertNotNull(num);
+        assertEquals(1, num);
+
+        user = em.find(CompUser.class, userid1);
+        em.refresh(user);
+
+        assertEquals(2, user.getAge());
+
+        //-------------------------MOD Tested
+
+        query = "SELECT e.name FROM CompUser e WHERE SIZE(e.nicknames) = 6";
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(0, result.size());
+
+        //------------------------SIZE Tested
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testGroupByHavingClause() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT c.name FROM CompUser c GROUP BY c.name HAVING c.name LIKE 'S%'";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(3, result.size());
+        assertTrue(result.contains("Shannon "));
+        assertTrue(result.contains("Shade"));
+        assertTrue(result.contains("Seetha"));
+
+        endEm(em);
+    }
+
+    public void testOrderByClause() {
+        EntityManager em = currentEntityManager();
+
+        String query =
+            "SELECT c.name FROM CompUser c WHERE c.name LIKE 'S%' ORDER BY c.name";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(3, result.size());
+        assertTrue(result.contains("Shannon "));
+        assertTrue(result.contains("Seetha"));
+        assertTrue(result.contains("Shade"));
+
+        endEm(em);
+    }
+
+    public void testAVGAggregFunc() {
+        /**
+         * To be Tested: AVG, COUNT, MAX, MIN, SUM
+         */
+
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT AVG(e.age) FROM CompUser e";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.contains(25));
+
+        endEm(em);
+    }
+
+    public void testCOUNTAggregFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT COUNT(c.name) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.contains(6l));
+
+        endEm(em);
+    }
+
+    public void testMAXAggregFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT DISTINCT MAX(c.age) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.contains(36));
+
+        endEm(em);
+    }
+
+    public void testMINAggregFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT DISTINCT MIN(c.age) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.contains(10));
+
+        endEm(em);
+    }
+
+    public void testSUMAggregFunc() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT SUM(c.age) FROM CompUser c";
+
+        List result = em.createQuery(query).getResultList();
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        assertTrue(result.contains(153l));
+
+        endEm(em);
+    }
+
+    public CompUser createUser(String name, String cName, Address add, int age,
+        boolean isMale) {
+        CompUser user = null;
+        if (isMale) {
+            user = new MaleUser();
+            user.setName(name);
+            user.setComputerName(cName);
+            user.setAddress(add);
+            user.setAge(age);
+            user.setNameAsLob(name);
+        } else {
+            user = new FemaleUser();
+            user.setName(name);
+            user.setComputerName(cName);
+            user.setAddress(add);
+            user.setAge(age);
+            user.setNameAsLob(name);
+        }
+        return user;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/joins/TestEJBJoins.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/joins/TestEJBJoins.java
index a9cd704..360c81d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/joins/TestEJBJoins.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/joins/TestEJBJoins.java
@@ -1,180 +1,180 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.jpql.joins;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.common.apps.ArtCourse;
-import org.apache.openjpa.persistence.common.apps.Course;
-import org.apache.openjpa.persistence.common.apps.Department;
-import org.apache.openjpa.persistence.common.apps.Student;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBJoins extends AbstractTestCase {
-
-    public TestEJBJoins(String name) {
-        super(name, "jpqlclausescactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(Course.class);
-        deleteAll(Student.class);
-        deleteAll(Department.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        String name = "";
-        List<Course> clist = new ArrayList<Course>();
-        List<Department> dlist = new ArrayList<Department>();
-
-        for (int i = 0; i < 5; i++) {
-            Course curr = new Course("Math " + i, i * 2, i);
-            Course acurr = new ArtCourse(i + 20, "English" + (2 * i));
-            Department durr = new Department("CompSci" + i, null, i + 2);
-            clist.add(curr);
-            clist.add(acurr);
-            dlist.add(durr);
-        }
-
-        Student stud = new Student("Jonathan", clist, dlist);
-        Student stud2 = new Student("Stam", null, dlist);
-        Student stud3 = new Student("John", clist, null);
-        Student stud4 = new Student("Bill", null, null);
-
-        em.persist(stud);
-        em.persist(stud2);
-        em.persist(stud3);
-        em.persist(stud4);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testInnerJoin() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT distinct o.name from Student o JOIN " +
-            "o.course d WHERE d.name" +
-            "='Math 4'";
-
-        List ls = (List) em.createQuery(query)
-            .getResultList();
-
-        assertNotNull(ls);
-
-        if (ls != null) {
-            assertEquals(2, ls.size());
-        }
-        endEm(em);
-    }
-
-    public void testOuterJoin() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT distinct s.name FROM Student " +
-            "s LEFT JOIN s.department d";
-
-        List ls = (List) em.createQuery(query)
-            .getResultList();
-
-        assertNotNull(ls);
-        assertEquals(4, ls.size());
-
-        endEm(em);
-    }
-
-    public void testFetchJoin1() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT s FROM Student s JOIN FETCH s.name";
-
-        List ls = em.createQuery(query).getResultList();
-
-        assertNotNull(ls);
-        assertEquals(4, ls.size());
-
-        endEm(em);
-    }
-
-    public void testFetchJoin2() {
-        EntityManager em = currentEntityManager();
-        String query = "SELECT s " +
-            "FROM Student s " +
-            "JOIN FETCH s.name d";
-
-        try {
-            List ls = em.createQuery(query).getResultList();
-            fail(
-                "Not permitted to specify an id variable for entities ref. by the right side of fetch join");
-        }
-        catch (Exception e) {
-            //suppose to throw an exception..should not pass
-        }
-
-        endEm(em);
-    }
-
-    public void testLeftOuterJoin() {
-        EntityManager em = currentEntityManager();
-
-        String ljoin =
-            "SELECT DISTINCT s.name FROM Student s LEFT OUTER JOIN s.department d " +
-                "WHERE d.name = 'CompSci2'";
-
-        List ls = em.createQuery(ljoin).getResultList();
-
-        assertNotNull(ls);
-        assertEquals(2, ls.size());
-
-        assertTrue(ls.contains("Jonathan"));
-        assertTrue(ls.contains("Stam"));
-
-        endEm(em);
-    }
-
-    public void testInnerJoinFetch() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT s FROM Student " +
-            "s JOIN FETCH s.department";
-
-        List ls = (List) em.createQuery(query)
-            .getResultList();
-
-        assertNotNull(ls);
-        assertEquals(2, ls.size());
-
-        em.close();
-    }
-
-    public void testLeftJoinFetch() {
-        EntityManager em = currentEntityManager();
-
-        String query = "SELECT s FROM Student " +
-            "s LEFT JOIN FETCH s.department";
-
-        List ls = (List) em.createQuery(query)
-            .getResultList();
-
-        assertNotNull(ls);
-        assertEquals(4, ls.size());
-
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.jpql.joins;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.apps.ArtCourse;
+import org.apache.openjpa.persistence.common.apps.Course;
+import org.apache.openjpa.persistence.common.apps.Department;
+import org.apache.openjpa.persistence.common.apps.Student;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBJoins extends AbstractTestCase {
+
+    public TestEJBJoins(String name) {
+        super(name, "jpqlclausescactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(Course.class);
+        deleteAll(Student.class);
+        deleteAll(Department.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        String name = "";
+        List<Course> clist = new ArrayList<Course>();
+        List<Department> dlist = new ArrayList<Department>();
+
+        for (int i = 0; i < 5; i++) {
+            Course curr = new Course("Math " + i, i * 2, i);
+            Course acurr = new ArtCourse(i + 20, "English" + (2 * i));
+            Department durr = new Department("CompSci" + i, null, i + 2);
+            clist.add(curr);
+            clist.add(acurr);
+            dlist.add(durr);
+        }
+
+        Student stud = new Student("Jonathan", clist, dlist);
+        Student stud2 = new Student("Stam", null, dlist);
+        Student stud3 = new Student("John", clist, null);
+        Student stud4 = new Student("Bill", null, null);
+
+        em.persist(stud);
+        em.persist(stud2);
+        em.persist(stud3);
+        em.persist(stud4);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testInnerJoin() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT distinct o.name from Student o JOIN " +
+            "o.course d WHERE d.name" +
+            "='Math 4'";
+
+        List ls = (List) em.createQuery(query)
+            .getResultList();
+
+        assertNotNull(ls);
+
+        if (ls != null) {
+            assertEquals(2, ls.size());
+        }
+        endEm(em);
+    }
+
+    public void testOuterJoin() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT distinct s.name FROM Student " +
+            "s LEFT JOIN s.department d";
+
+        List ls = (List) em.createQuery(query)
+            .getResultList();
+
+        assertNotNull(ls);
+        assertEquals(4, ls.size());
+
+        endEm(em);
+    }
+
+    public void testFetchJoin1() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT s FROM Student s JOIN FETCH s.name";
+
+        List ls = em.createQuery(query).getResultList();
+
+        assertNotNull(ls);
+        assertEquals(4, ls.size());
+
+        endEm(em);
+    }
+
+    public void testFetchJoin2() {
+        EntityManager em = currentEntityManager();
+        String query = "SELECT s " +
+            "FROM Student s " +
+            "JOIN FETCH s.name d";
+
+        try {
+            List ls = em.createQuery(query).getResultList();
+            fail(
+                "Not permitted to specify an id variable for entities ref. by the right side of fetch join");
+        }
+        catch (Exception e) {
+            //suppose to throw an exception..should not pass
+        }
+
+        endEm(em);
+    }
+
+    public void testLeftOuterJoin() {
+        EntityManager em = currentEntityManager();
+
+        String ljoin =
+            "SELECT DISTINCT s.name FROM Student s LEFT OUTER JOIN s.department d " +
+                "WHERE d.name = 'CompSci2'";
+
+        List ls = em.createQuery(ljoin).getResultList();
+
+        assertNotNull(ls);
+        assertEquals(2, ls.size());
+
+        assertTrue(ls.contains("Jonathan"));
+        assertTrue(ls.contains("Stam"));
+
+        endEm(em);
+    }
+
+    public void testInnerJoinFetch() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT s FROM Student " +
+            "s JOIN FETCH s.department";
+
+        List ls = (List) em.createQuery(query)
+            .getResultList();
+
+        assertNotNull(ls);
+        assertEquals(2, ls.size());
+
+        em.close();
+    }
+
+    public void testLeftJoinFetch() {
+        EntityManager em = currentEntityManager();
+
+        String query = "SELECT s FROM Student " +
+            "s LEFT JOIN FETCH s.department";
+
+        List ls = (List) em.createQuery(query)
+            .getResultList();
+
+        assertNotNull(ls);
+        assertEquals(4, ls.size());
+
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/BaseKernelTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/BaseKernelTest.java
index d84d131..c3817cf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/BaseKernelTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/BaseKernelTest.java
@@ -1,207 +1,207 @@
-/*
- * BaseKernelTest.java
- *
- * Created on October 9, 2006, 12:56 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.*;
-import javax.management.IntrospectionException;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.kernel.common.apps.*;
-import java.lang.annotation.Annotation;
-import junit.framework.*;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-
-public abstract class BaseKernelTest extends org.apache.openjpa.persistence.common.utils.AbstractTestCase
-{    
-    private static Map _sysprops = new HashMap();    
-    
-    /** Creates a new instance of BaseKernelTest */
-    public BaseKernelTest() {
-    }
-    
-    public BaseKernelTest(String name) {
-        super(name, "kernelcactusapp");
-    }
-    
-    protected OpenJPAEntityManager getPM() {
-        return currentEntityManager();
-    }
-    
-    protected OpenJPAEntityManager getPM(boolean optimistic,boolean retainValues) 
-    {
-        OpenJPAEntityManager em = currentEntityManager();
-        em.setNontransactionalRead(true);
-        em.setRetainState(retainValues);
-        if(em.getTransaction().isActive())
-        {
-            em.getTransaction().commit();
-            em.setOptimistic(optimistic);
-        }
-
-        return em;
-    }
-    
-    protected Object persist(Object ob) {
-        //FIXME  - this is just a workaround 
-        //  Broker broker = .getBrokerFactory().newBroker();
-        Broker broker = JPAFacadeHelper.toBroker(currentEntityManager());
-        broker.begin();
-        broker.persist(ob, null);
-        Object id = broker.getObjectId(ob);
-        broker.commit();
-        broker.close();
-        return id;
-    }
-    
-
-    protected Properties getProperties() {
-        return getProperties(null);
-    }
-
-    /**
-     * Return the runtime properties, optionally overriding or setting
-     * some via the given array, which should be in the form
-     * { key, val, key, val, ... }.
-     */
-    protected synchronized Properties getProperties(String[] props) {
-        Properties p = new Properties(System.getProperties());
-        String str = p.getProperty("openjpa.properties", "kodo.properties");
-        if (str != null && str.length() > 0) {
-            // cache system properties to reduce load on file system
-            Properties loaded = (Properties) _sysprops.get(str);
-            if (loaded == null) {
-                loaded = new Properties();
-                ConfigurationProvider cp = (ConfigurationProvider) Configurations.getProperty(str, null);
-
-                if (cp != null)
-                    loaded.putAll(cp.getProperties());
-                _sysprops.put(str, loaded);
-            }
-            p.putAll(loaded);
-        }
-
-        for (int i = 0; props != null && i < props.length; i += 2) {
-            if (props[i + 1] != null) {
-                // remove any duplicate kodo/openjpa property so we don't clash
-                if (props[i].startsWith("openjpa."))
-                    p.remove("openjpa." + props[i].substring(5));
-                else if (props[i].startsWith("openjpa."))
-                    p.remove("openjpa." + props[i].substring(8));
-
-                p.setProperty(props[i], props[i + 1]);
-            } else {
-                p.remove(props[i]);
-            }
-        }
-        return p;
-    }
-//
-//
-//    /**
-//     * Assert that the given List contain the exact same
-//     * elements. This is different than the normal List contract, which
-//     * states that list1.equals(list2) if each element e1.equals(e2).
-//     * This method asserts that e1 == n2.
-//     */
-//    public static void assertIdentical(List c1, List c2) {
-//        assertEquals(c1.size(), c2.size());
-//        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
-//            i1.hasNext() && i2.hasNext();)
-//            assertTrue(i1.next() == i2.next());
-//    }
-//
-//    /**
-//     * Assert that the collection parameter is already ordered
-//     * according to the specified comparator.
-//     */
-//    public void assertOrdered(Collection c, Comparator comp) {
-//        List l1 = new LinkedList(c);
-//        List l2 = new LinkedList(c);
-//        assertEquals(l1, l2);
-//        Collections.sort(l2, comp);
-//        assertEquals(l1, l2);
-//        Collections.sort(l1, comp);
-//        assertEquals(l1, l2);
-//    }
-//
-//    ////////////////////
-//    // Assertion Helpers
-//    ////////////////////
-//
-//    public void assertNotEquals(Object a, Object b) {
-//        if (a == null && b != null)
-//            return;
-//        if (a != null && b == null)
-//            return;
-//        if (!(a.equals(b)))
-//            return;
-//        if (!(b.equals(a)))
-//            return;
-//
-//        fail("expected !<" + a + ">.equals(<" + b + ">)");
-//    }
-//
-//    public void assertSize(int size, Object ob) {
-//        if (ob == null) {
-//            assertEquals(size, 0);
-//            return;
-//        }
-//
-//        if (ob instanceof Collection)
-//            ob = ((Collection) ob).iterator();
-//        if (ob instanceof Iterator) {
-//            Iterator i = (Iterator) ob;
-//            int count = 0;
-//            while (i.hasNext()) {
-//                count++;
-//                i.next();
-//            }
-//
-//            assertEquals(size, count);
-//        } else
-//            fail("assertSize: expected Collection, Iterator, "
-//                + "Query, or Extent, but got "
-//                + ob.getClass().getName());
-//    }
-    
-}
+/*
+ * BaseKernelTest.java
+ *
+ * Created on October 9, 2006, 12:56 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+import javax.management.IntrospectionException;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.kernel.common.apps.*;
+import java.lang.annotation.Annotation;
+import junit.framework.*;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+
+public abstract class BaseKernelTest extends org.apache.openjpa.persistence.common.utils.AbstractTestCase
+{    
+    private static Map _sysprops = new HashMap();    
+    
+    /** Creates a new instance of BaseKernelTest */
+    public BaseKernelTest() {
+    }
+    
+    public BaseKernelTest(String name) {
+        super(name, "kernelcactusapp");
+    }
+    
+    protected OpenJPAEntityManager getPM() {
+        return currentEntityManager();
+    }
+    
+    protected OpenJPAEntityManager getPM(boolean optimistic,boolean retainValues) 
+    {
+        OpenJPAEntityManager em = currentEntityManager();
+        em.setNontransactionalRead(true);
+        em.setRetainState(retainValues);
+        if(em.getTransaction().isActive())
+        {
+            em.getTransaction().commit();
+            em.setOptimistic(optimistic);
+        }
+
+        return em;
+    }
+    
+    protected Object persist(Object ob) {
+        //FIXME  - this is just a workaround 
+        //  Broker broker = .getBrokerFactory().newBroker();
+        Broker broker = JPAFacadeHelper.toBroker(currentEntityManager());
+        broker.begin();
+        broker.persist(ob, null);
+        Object id = broker.getObjectId(ob);
+        broker.commit();
+        broker.close();
+        return id;
+    }
+    
+
+    protected Properties getProperties() {
+        return getProperties(null);
+    }
+
+    /**
+     * Return the runtime properties, optionally overriding or setting
+     * some via the given array, which should be in the form
+     * { key, val, key, val, ... }.
+     */
+    protected synchronized Properties getProperties(String[] props) {
+        Properties p = new Properties(System.getProperties());
+        String str = p.getProperty("openjpa.properties", "kodo.properties");
+        if (str != null && str.length() > 0) {
+            // cache system properties to reduce load on file system
+            Properties loaded = (Properties) _sysprops.get(str);
+            if (loaded == null) {
+                loaded = new Properties();
+                ConfigurationProvider cp = (ConfigurationProvider) Configurations.getProperty(str, null);
+
+                if (cp != null)
+                    loaded.putAll(cp.getProperties());
+                _sysprops.put(str, loaded);
+            }
+            p.putAll(loaded);
+        }
+
+        for (int i = 0; props != null && i < props.length; i += 2) {
+            if (props[i + 1] != null) {
+                // remove any duplicate kodo/openjpa property so we don't clash
+                if (props[i].startsWith("openjpa."))
+                    p.remove("openjpa." + props[i].substring(5));
+                else if (props[i].startsWith("openjpa."))
+                    p.remove("openjpa." + props[i].substring(8));
+
+                p.setProperty(props[i], props[i + 1]);
+            } else {
+                p.remove(props[i]);
+            }
+        }
+        return p;
+    }
+//
+//
+//    /**
+//     * Assert that the given List contain the exact same
+//     * elements. This is different than the normal List contract, which
+//     * states that list1.equals(list2) if each element e1.equals(e2).
+//     * This method asserts that e1 == n2.
+//     */
+//    public static void assertIdentical(List c1, List c2) {
+//        assertEquals(c1.size(), c2.size());
+//        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
+//            i1.hasNext() && i2.hasNext();)
+//            assertTrue(i1.next() == i2.next());
+//    }
+//
+//    /**
+//     * Assert that the collection parameter is already ordered
+//     * according to the specified comparator.
+//     */
+//    public void assertOrdered(Collection c, Comparator comp) {
+//        List l1 = new LinkedList(c);
+//        List l2 = new LinkedList(c);
+//        assertEquals(l1, l2);
+//        Collections.sort(l2, comp);
+//        assertEquals(l1, l2);
+//        Collections.sort(l1, comp);
+//        assertEquals(l1, l2);
+//    }
+//
+//    ////////////////////
+//    // Assertion Helpers
+//    ////////////////////
+//
+//    public void assertNotEquals(Object a, Object b) {
+//        if (a == null && b != null)
+//            return;
+//        if (a != null && b == null)
+//            return;
+//        if (!(a.equals(b)))
+//            return;
+//        if (!(b.equals(a)))
+//            return;
+//
+//        fail("expected !<" + a + ">.equals(<" + b + ">)");
+//    }
+//
+//    public void assertSize(int size, Object ob) {
+//        if (ob == null) {
+//            assertEquals(size, 0);
+//            return;
+//        }
+//
+//        if (ob instanceof Collection)
+//            ob = ((Collection) ob).iterator();
+//        if (ob instanceof Iterator) {
+//            Iterator i = (Iterator) ob;
+//            int count = 0;
+//            while (i.hasNext()) {
+//                count++;
+//                i.next();
+//            }
+//
+//            assertEquals(size, count);
+//        } else
+//            fail("assertSize: expected Collection, Iterator, "
+//                + "Query, or Extent, but got "
+//                + ob.getClass().getName());
+//    }
+    
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/Test2EJBConcurrency.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/Test2EJBConcurrency.java
index 8d81f7c..e7bf984 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/Test2EJBConcurrency.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/Test2EJBConcurrency.java
@@ -1,135 +1,135 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.Entity1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class Test2EJBConcurrency extends AbstractTestCase {
-
-    private Object _id = null;
-
-    public Test2EJBConcurrency(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(Entity1.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        Entity1 b = new Entity1(3, "STRING", 10);
-        em.persist(b);
-        em.flush();
-
-        endTx(em);
-        endEm(em);
-    }
-
-    /**
-     * Test optimistic concurrency.
-     */
-    public void testOptConcurrency1()
-        throws Exception {
-        EntityManager em1 = currentEntityManager();
-        startTx(em1);
-
-        EntityManager em2 = currentEntityManager();
-        startTx(em2);
-
-        Entity1 b1 = (Entity1) em1.find(Entity1.class, 3);
-        b1.setStringField("STRING2");
-        endTx(em1);
-        assertEquals("b1.getstringField is not STRING2 as exp.", "STRING2",
-            b1.getStringField());
-
-        Entity1 b2 = (Entity1) em2.find(Entity1.class, 3);
-        assertEquals("b2.getstringField is not STRING2 as exp.", "STRING2",
-            b2.getStringField());
-        b2.setStringField("STRING3");
-        endTx(em2);
-        assertEquals("b2.getstringField is not STRING3 as exp.", "STRING3",
-            b2.getStringField());
-
-        startTx(em1);
-        b1 = (Entity1) em1.find(Entity1.class, 3);
-        em1.refresh(b1);
-        assertEquals("b1.getstringField is not STRING3 as exp.", "STRING2",
-            b1.getStringField());
-        b1.setStringField("STRING4");
-        endTx(em1);
-
-        b2 = (Entity1) em2.find(Entity1.class, 3);
-        assertEquals("b2.getstringField is not STRING3 as exp.", "STRING3",
-            b2.getStringField());
-
-        endEm(em1);
-        endEm(em2);
-    }
-
-    /**
-     *	Test optimistic concurrency.
-     */
-//	public void testOptConcurrency2 ()
-//		throws Exception
-//	{
-//		EntityManager em1 = currentEntityManager();		
-//		startTx(em1);
-//
-//		EntityManager em2 = currentEntityManager();		
-//		startTx(em2);
-//
-//		Entity1 b1 = (Entity1) em1.find (Entity1.class, 3);
-//		Entity1 b2 = (Entity1) em2.find (Entity1.class, 3);
-//
-//		assertEquals ("b1.getstringField is not STRING as exp.","STRING", b1.getStringField ());
-//		assertEquals ("b2.getstringField is not STRING as exp.","STRING", b2.getStringField ());
-//
-//		b1.setStringField ("STRING2");
-//		endTx(em1);
-//		assertEquals ("b1.getstringField is not STRING as exp.","STRING2", b1.getStringField ());
-//
-//		assertEquals ("b2.getstringField is not STRING as exp.","STRING", b2.getStringField ());
-//		b2.setStringField ("STRING3");
-//
-//		try
-//		{
-//			endTx(em2);
-//			fail ("OL Violation");
-//		}
-//		catch (Exception ole)
-//		{
-//			// expected
-//		}
-//		
-//		rollbackTx(em2);
-//		
-//
-//    	b2 = (Entity1) em2.find (Entity1.class, 3);
-//		assertEquals ("b2.getstringField is not STRING2 as exp.","STRING2", b2.getStringField ());
-//    	
-//		endEm(em1);
-//		endEm(em2);
-//	}
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.Entity1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class Test2EJBConcurrency extends AbstractTestCase {
+
+    private Object _id = null;
+
+    public Test2EJBConcurrency(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(Entity1.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        Entity1 b = new Entity1(3, "STRING", 10);
+        em.persist(b);
+        em.flush();
+
+        endTx(em);
+        endEm(em);
+    }
+
+    /**
+     * Test optimistic concurrency.
+     */
+    public void testOptConcurrency1()
+        throws Exception {
+        EntityManager em1 = currentEntityManager();
+        startTx(em1);
+
+        EntityManager em2 = currentEntityManager();
+        startTx(em2);
+
+        Entity1 b1 = (Entity1) em1.find(Entity1.class, 3);
+        b1.setStringField("STRING2");
+        endTx(em1);
+        assertEquals("b1.getstringField is not STRING2 as exp.", "STRING2",
+            b1.getStringField());
+
+        Entity1 b2 = (Entity1) em2.find(Entity1.class, 3);
+        assertEquals("b2.getstringField is not STRING2 as exp.", "STRING2",
+            b2.getStringField());
+        b2.setStringField("STRING3");
+        endTx(em2);
+        assertEquals("b2.getstringField is not STRING3 as exp.", "STRING3",
+            b2.getStringField());
+
+        startTx(em1);
+        b1 = (Entity1) em1.find(Entity1.class, 3);
+        em1.refresh(b1);
+        assertEquals("b1.getstringField is not STRING3 as exp.", "STRING2",
+            b1.getStringField());
+        b1.setStringField("STRING4");
+        endTx(em1);
+
+        b2 = (Entity1) em2.find(Entity1.class, 3);
+        assertEquals("b2.getstringField is not STRING3 as exp.", "STRING3",
+            b2.getStringField());
+
+        endEm(em1);
+        endEm(em2);
+    }
+
+    /**
+     *	Test optimistic concurrency.
+     */
+//	public void testOptConcurrency2 ()
+//		throws Exception
+//	{
+//		EntityManager em1 = currentEntityManager();		
+//		startTx(em1);
+//
+//		EntityManager em2 = currentEntityManager();		
+//		startTx(em2);
+//
+//		Entity1 b1 = (Entity1) em1.find (Entity1.class, 3);
+//		Entity1 b2 = (Entity1) em2.find (Entity1.class, 3);
+//
+//		assertEquals ("b1.getstringField is not STRING as exp.","STRING", b1.getStringField ());
+//		assertEquals ("b2.getstringField is not STRING as exp.","STRING", b2.getStringField ());
+//
+//		b1.setStringField ("STRING2");
+//		endTx(em1);
+//		assertEquals ("b1.getstringField is not STRING as exp.","STRING2", b1.getStringField ());
+//
+//		assertEquals ("b2.getstringField is not STRING as exp.","STRING", b2.getStringField ());
+//		b2.setStringField ("STRING3");
+//
+//		try
+//		{
+//			endTx(em2);
+//			fail ("OL Violation");
+//		}
+//		catch (Exception ole)
+//		{
+//			// expected
+//		}
+//		
+//		rollbackTx(em2);
+//		
+//
+//    	b2 = (Entity1) em2.find (Entity1.class, 3);
+//		assertEquals ("b2.getstringField is not STRING2 as exp.","STRING2", b2.getStringField ());
+//    	
+//		endEm(em1);
+//		endEm(em2);
+//	}
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestAbstractMappedAppIdSuper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestAbstractMappedAppIdSuper.java
index 176046a..ae11278 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestAbstractMappedAppIdSuper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestAbstractMappedAppIdSuper.java
@@ -1,85 +1,85 @@
-/*
- * TestAbstractMappedAppIdSuper.java
- *
- * Created on October 16, 2006, 2:00 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-
-
-public class TestAbstractMappedAppIdSuper extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestAbstractMappedAppIdSuper
-     */
-    public TestAbstractMappedAppIdSuper(String name) {
-        super(name);
-    }
-
-    /* Fix Me - aokeke - Takes so much time to run */
-//    public void testQuerySubclassWithDifferentIdClass()
-//    throws Exception {
-//        ConcreteMappedAppIdSub pc = new ConcreteMappedAppIdSub();
-//        String pk = String.valueOf(System.currentTimeMillis());
-//        pc.setPk(pk);
-//        pc.setName("name");
-//        
-//        OpenJPAEntityManager pm = getPM();
-//        pm.begin();
-//        pm.persist(pc);
-//        pm.commit();
-//        String pkd = pc.getPk();
-//        Object oid = pm.getObjectId(pc);
-//        endEm(pm,());
-//        
-//        pm = getPM();
-//        String query = "SELECT DISTINCT o FROM ConcreteMappedAppIdSub o WHERE o.pk = :p ";
-//        OpenJPAQuery q = pm.createQuery(query);
-//        
-////        OpenJPAQuery q = pm.createNativeQuery("pk == :p", ConcreteMappedAppIdSub.class);
-//        //FIXME jthomas
-//        
-//        try 
-//        {
-//            pc = (ConcreteMappedAppIdSub) q.setParameter("p", pkd).getSingleResult();
-//        } 
-//        catch (RuntimeException re) 
-//        {
-////            bug(1170, re, "Cannot query subclass of abstract mapped "
-////                    + "appid type.");
-////            return;
-//        }
-//         
-//        assertNotNull(pc);
-//        assertEquals(pk, pc.getPk());
-//        
-//        pm.begin();
-//        pm.remove(pc);
-//        pm.commit();
-//        endEm(pm,());
-//    }
-}
+/*
+ * TestAbstractMappedAppIdSuper.java
+ *
+ * Created on October 16, 2006, 2:00 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+
+
+public class TestAbstractMappedAppIdSuper extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestAbstractMappedAppIdSuper
+     */
+    public TestAbstractMappedAppIdSuper(String name) {
+        super(name);
+    }
+
+    /* Fix Me - aokeke - Takes so much time to run */
+//    public void testQuerySubclassWithDifferentIdClass()
+//    throws Exception {
+//        ConcreteMappedAppIdSub pc = new ConcreteMappedAppIdSub();
+//        String pk = String.valueOf(System.currentTimeMillis());
+//        pc.setPk(pk);
+//        pc.setName("name");
+//        
+//        OpenJPAEntityManager pm = getPM();
+//        pm.begin();
+//        pm.persist(pc);
+//        pm.commit();
+//        String pkd = pc.getPk();
+//        Object oid = pm.getObjectId(pc);
+//        endEm(pm,());
+//        
+//        pm = getPM();
+//        String query = "SELECT DISTINCT o FROM ConcreteMappedAppIdSub o WHERE o.pk = :p ";
+//        OpenJPAQuery q = pm.createQuery(query);
+//        
+////        OpenJPAQuery q = pm.createNativeQuery("pk == :p", ConcreteMappedAppIdSub.class);
+//        //FIXME jthomas
+//        
+//        try 
+//        {
+//            pc = (ConcreteMappedAppIdSub) q.setParameter("p", pkd).getSingleResult();
+//        } 
+//        catch (RuntimeException re) 
+//        {
+////            bug(1170, re, "Cannot query subclass of abstract mapped "
+////                    + "appid type.");
+////            return;
+//        }
+//         
+//        assertNotNull(pc);
+//        assertEquals(pk, pc.getPk());
+//        
+//        pm.begin();
+//        pm.remove(pc);
+//        pm.commit();
+//        endEm(pm,());
+//    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestArrayValues2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestArrayValues2.java
index c488c07..8d6383d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestArrayValues2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestArrayValues2.java
@@ -1,466 +1,466 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.lang.reflect.Array;
-import java.text.Collator;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Date;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ArraysTest;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.AssertionFailedError;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * Test varying kinds of array values.
- *
- * @author Marc Prud'hommeaux
- * @author Abe White
- */
-public class TestArrayValues2 extends BaseKernelTest {
-
-    private static double DOUBLE_PRECISION = 0.01D;
-    public static float FLOAT_PRECISION = 0.01F;
-
-    public void testStringArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        String[] array = new String[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomString();
-        saveArray(array, false, false);
-    }
-
-    public void testLongArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Long[] array = new Long[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomLong();
-        try {
-            saveArray(array, false, false);
-        } catch (AssertionFailedError afe) {
-        }
-    }
-
-    public void testLongPrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        long[] array = new long[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomLong().longValue();
-        try {
-            saveArray(array, true, false);
-        } catch (AssertionFailedError afe) {
-        }
-    }
-
-    public void testShortArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Short[] array = new Short[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomShort();
-        saveArray(array, false, false);
-    }
-
-    public void testShortPrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        short[] array = new short[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomShort().shortValue();
-        saveArray(array, true, false);
-    }
-
-    public void testIntArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Integer[] array = new Integer[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomInt();
-        saveArray(array, false, false);
-    }
-
-    public void testIntPrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        int[] array = new int[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomInt().intValue();
-        saveArray(array, true, false);
-    }
-// FixMe: Both tests hangs on Mysql
-    /*public void testByteArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Byte[] array = new Byte[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomByte();
-        saveArray(array, false, false);
-    }
-
-    public void testBytePrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        byte[] array = new byte[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomByte().byteValue();
-        saveArray(array, true, false);
-    }*/
-
-    public void testBooleanArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Boolean[] array = new Boolean[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomBoolean();
-        saveArray(array, false, false);
-    }
-
-    public void testCharacterArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Character[] array = new Character[max];
-        array[0] = new Character((char) 1);
-        for (int i = 1; i < max; i++)
-            array[i] = randomChar();
-        saveArray(array, false, false);
-    }
-
-    public void testCharacterPrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        char[] array = new char[max];
-        array[0] = 1;
-        for (int i = 1; i < max; i++)
-            array[i] = randomChar().charValue();
-        saveArray(array, true, false);
-    }
-
-    public void testCharacterPrimitiveClobArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        char[] array = new char[max];
-        array[0] = 1;
-        for (int i = 1; i < max; i++)
-            array[i] = randomChar().charValue();
-        saveArray(array, true, true);
-    }
-
-    public void testBooleanPrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        boolean[] array = new boolean[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomBoolean().booleanValue();
-        saveArray(array, true, false);
-    }
-
-    public void testFloatArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Float[] array = new Float[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomFloat();
-        saveArray(array, false, false);
-    }
-
-    public void testFloatPrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        float[] array = new float[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomFloat().floatValue();
-        saveArray(array, true, false);
-    }
-
-    public void testDoubleArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Double[] array = new Double[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomDouble();
-        saveArray(array, false, false);
-    }
-
-    public void testDoublePrimitiveArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        double[] array = new double[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomDouble().doubleValue();
-        saveArray(array, true, false);
-    }
-
-    public void testDateArray()
-        throws Exception {
-        int max = ((int) (Math.random() * 20)) + 5;
-        Date[] array = new Date[max];
-        for (int i = 0; i < max; i++)
-            array[i] = randomDate();
-        saveArray(array, false, false);
-    }
-
-    /*Fix Me aokeke - Takes a lot of time to run */
-//    public void testFirstClassObjectArray()throws Exception 
-//    {
-//        int max = ((int) (Math.random() * 20)) + 5;
-//        ArraysTest[] array = new ArraysTest[max];
-//        for (int i = 0; i < max; i++)
-//            array[i] = new ArraysTest();
-//        saveArray(array, false, false);
-//    }
-
-    private void saveArray(Object array, boolean primitive, boolean lob)
-        throws Exception {
-        try {
-            saveArrayInternal(array, primitive, lob);
-        } catch (Exception e) {
-            throw e;
-        } catch (Error error) {
-            throw error;
-        } finally {
-            //
-        }
-    }
-
-    private void saveArrayInternal(Object vals, boolean primitive, boolean lob)
-        throws Exception {
-        Object[] array;
-        if (primitive)
-            array = convertPrimitiveArray(vals);
-        else
-            array = (Object[]) vals;
-        Arrays.sort(array, new TestArraySorter());
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-
-        ArraysTest test = new ArraysTest();
-        pm.persist(test);
-        int testID = test.getId();
-
-        setGetTestArray(test, vals, primitive, lob, true);
-        endTx(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        ArraysTest retrievedObject = pm.find(ArraysTest.class, testID);
-
-        Object retrievedVals = setGetTestArray(retrievedObject, vals,
-            primitive, lob, false);
-        Object[] retrievedArray;
-        if (primitive)
-            retrievedArray = convertPrimitiveArray(retrievedVals);
-        else
-            retrievedArray = (Object[]) retrievedVals;
-
-        assertNotNull(retrievedArray);
-        assertTrue(array.length != 0);
-        assertEquals(array.length, retrievedArray.length);
-        assertNotNull(array[0]);
-        assertNotNull(retrievedArray[0]);
-
-        // make sure the classes of the keys are the same.
-        assertEquals(array[0].getClass(), retrievedArray[0].getClass());
-        Arrays.sort(retrievedArray, new TestArraySorter());
-        for (int i = 0; i < array.length; i++)
-            assertClassAndValueEquals(array[i], retrievedArray[i]);
-
-        pm.remove(retrievedObject);
-        endTx(pm);
-    }
-
-    private Object[] convertPrimitiveArray(Object array) throws Exception {
-        int length = Array.getLength(array);
-        Class type = Array.get(array, 0).getClass();
-
-        Object[] copy = (Object[]) Array.newInstance(type, length);
-        for (int i = 0; i < length; i++)
-            copy[i] = Array.get(array, i);
-
-        return copy;
-    }
-
-    private void assertClassAndValueEquals(Object o1, Object o2) {
-        assertTrue("First object was null", o1 != null);
-        assertTrue("Second object was null", o2 != null);
-
-        assertTrue("Types did not match (class1="
-            + o1.getClass().getName() + ", class2="
-            + o2.getClass().getName() + ")",
-            o1.getClass().isAssignableFrom(o2.getClass()));
-
-        // floats and doubles are a little special: we only
-        // compare them to a certain precision, after which
-        // we give up.
-        if (o1 instanceof Double)
-            assertEquals(((Double) o1).doubleValue(),
-                ((Double) o2).doubleValue(),
-                DOUBLE_PRECISION);
-        else if (o1 instanceof Float)
-            assertEquals(((Float) o1).floatValue(),
-                ((Float) o2).floatValue(),
-                FLOAT_PRECISION);
-        else
-            assertEquals("Object did not match (class1="
-                + o1.getClass().getName() + ", class2="
-                + o2.getClass().getName() + ")",
-                o1, o2);
-    }
-
-    /**
-     * Generic setter/getter for setting the array.
-     */
-    private Object setGetTestArray(ArraysTest test, Object array,
-        boolean primitive, boolean lob, boolean doSet)
-        throws Exception {
-        if (array == null)
-            return null;
-
-        Object first = Array.get(array, 0);
-        if (first instanceof Date) {
-            if (doSet)
-                test.setDate((Date[]) array);
-            return test.getDate();
-        } else if (first instanceof String) {
-            if (doSet)
-                test.setString((String[]) array);
-            return test.getString();
-        } else if (first instanceof Character) {
-            if (doSet && !primitive)
-                test.setCharacter((Character[]) array);
-            else if (doSet && !lob)
-                test.setCharacterP((char[]) array);
-            else if (doSet)
-                test.setCharacterPClob((char[]) array);
-            else if (!primitive)
-                return test.getCharacter();
-            else if (!lob)
-                return test.getCharacterP();
-            else
-                return test.getCharacterPClob();
-            return null;
-        } else if (first instanceof Double) {
-            if (doSet && !primitive)
-                test.setDouble((Double[]) array);
-            else if (doSet)
-                test.setDoubleP((double[]) array);
-            else if (!primitive)
-                return test.getDouble();
-            else
-                return test.getDoubleP();
-            return null;
-        } else if (first instanceof Byte) {
-            if (doSet && !primitive)
-                test.setByte((Byte[]) array);
-            else if (doSet)
-                test.setByteP((byte[]) array);
-            else if (!primitive)
-                return test.getByte();
-            else
-                return test.getByteP();
-            return null;
-        } else if (first instanceof Float) {
-            if (doSet && !primitive)
-                test.setFloat((Float[]) array);
-            else if (doSet)
-                test.setFloatP((float[]) array);
-            else if (!primitive)
-                return test.getFloat();
-            else
-                return test.getFloatP();
-            return null;
-        } else if (first instanceof Long) {
-            if (doSet && !primitive)
-                test.setLong((Long[]) array);
-            else if (doSet)
-                test.setLongP((long[]) array);
-            else if (!primitive)
-                return test.getLong();
-            else
-                return test.getLongP();
-            return null;
-        } else if (first instanceof Integer) {
-            if (doSet && !primitive)
-                test.setInt((Integer[]) array);
-            else if (doSet)
-                test.setIntP((int[]) array);
-            else if (!primitive)
-                return test.getInt();
-            else
-                return test.getIntP();
-            return null;
-        } else if (first instanceof Short) {
-            if (doSet && !primitive)
-                test.setShort((Short[]) array);
-            else if (doSet)
-                test.setShortP((short[]) array);
-            else if (!primitive)
-                return test.getShort();
-            else
-                return test.getShortP();
-            return null;
-        } else if (first instanceof Boolean) {
-            if (doSet && !primitive)
-                test.setBoolean((Boolean[]) array);
-            else if (doSet)
-                test.setBooleanP((boolean[]) array);
-            else if (!primitive)
-                return test.getBoolean();
-            else
-                return test.getBooleanP();
-            return null;
-        } else if (first instanceof ArraysTest) {
-            if (doSet)
-                test.setArraysTest((ArraysTest[]) array);
-            return test.getArraysTest();
-        }
-
-        fail("Unknown array type");
-        return null;
-    }
-
-    private static class TestArraySorter
-        implements Comparator {
-
-        private Collator collator = Collator.getInstance();
-
-        public int compare(Object o1, Object o2) {
-            if (o1.equals(o2))
-                return 0;
-
-            if (o1 instanceof Number) {
-                return ((Number) o1).doubleValue() >
-                    ((Number) o2).doubleValue() ? 1 : -1;
-            } else if (o1 instanceof Date) {
-                return ((Date) o1).before((Date) o2) ? 1 : -1;
-            } else if (o1 instanceof ArraysTest) {
-                return ((ArraysTest) o1).compareTo(o2);
-            }
-            return collator.compare(o1.toString(), o2.toString());
-        }
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.lang.reflect.Array;
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ArraysTest;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * Test varying kinds of array values.
+ *
+ * @author Marc Prud'hommeaux
+ * @author Abe White
+ */
+public class TestArrayValues2 extends BaseKernelTest {
+
+    private static double DOUBLE_PRECISION = 0.01D;
+    public static float FLOAT_PRECISION = 0.01F;
+
+    public void testStringArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        String[] array = new String[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomString();
+        saveArray(array, false, false);
+    }
+
+    public void testLongArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Long[] array = new Long[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomLong();
+        try {
+            saveArray(array, false, false);
+        } catch (AssertionFailedError afe) {
+        }
+    }
+
+    public void testLongPrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        long[] array = new long[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomLong().longValue();
+        try {
+            saveArray(array, true, false);
+        } catch (AssertionFailedError afe) {
+        }
+    }
+
+    public void testShortArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Short[] array = new Short[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomShort();
+        saveArray(array, false, false);
+    }
+
+    public void testShortPrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        short[] array = new short[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomShort().shortValue();
+        saveArray(array, true, false);
+    }
+
+    public void testIntArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Integer[] array = new Integer[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomInt();
+        saveArray(array, false, false);
+    }
+
+    public void testIntPrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        int[] array = new int[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomInt().intValue();
+        saveArray(array, true, false);
+    }
+// FixMe: Both tests hangs on Mysql
+    /*public void testByteArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Byte[] array = new Byte[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomByte();
+        saveArray(array, false, false);
+    }
+
+    public void testBytePrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        byte[] array = new byte[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomByte().byteValue();
+        saveArray(array, true, false);
+    }*/
+
+    public void testBooleanArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Boolean[] array = new Boolean[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomBoolean();
+        saveArray(array, false, false);
+    }
+
+    public void testCharacterArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Character[] array = new Character[max];
+        array[0] = new Character((char) 1);
+        for (int i = 1; i < max; i++)
+            array[i] = randomChar();
+        saveArray(array, false, false);
+    }
+
+    public void testCharacterPrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        char[] array = new char[max];
+        array[0] = 1;
+        for (int i = 1; i < max; i++)
+            array[i] = randomChar().charValue();
+        saveArray(array, true, false);
+    }
+
+    public void testCharacterPrimitiveClobArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        char[] array = new char[max];
+        array[0] = 1;
+        for (int i = 1; i < max; i++)
+            array[i] = randomChar().charValue();
+        saveArray(array, true, true);
+    }
+
+    public void testBooleanPrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        boolean[] array = new boolean[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomBoolean().booleanValue();
+        saveArray(array, true, false);
+    }
+
+    public void testFloatArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Float[] array = new Float[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomFloat();
+        saveArray(array, false, false);
+    }
+
+    public void testFloatPrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        float[] array = new float[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomFloat().floatValue();
+        saveArray(array, true, false);
+    }
+
+    public void testDoubleArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Double[] array = new Double[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomDouble();
+        saveArray(array, false, false);
+    }
+
+    public void testDoublePrimitiveArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        double[] array = new double[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomDouble().doubleValue();
+        saveArray(array, true, false);
+    }
+
+    public void testDateArray()
+        throws Exception {
+        int max = ((int) (Math.random() * 20)) + 5;
+        Date[] array = new Date[max];
+        for (int i = 0; i < max; i++)
+            array[i] = randomDate();
+        saveArray(array, false, false);
+    }
+
+    /*Fix Me aokeke - Takes a lot of time to run */
+//    public void testFirstClassObjectArray()throws Exception 
+//    {
+//        int max = ((int) (Math.random() * 20)) + 5;
+//        ArraysTest[] array = new ArraysTest[max];
+//        for (int i = 0; i < max; i++)
+//            array[i] = new ArraysTest();
+//        saveArray(array, false, false);
+//    }
+
+    private void saveArray(Object array, boolean primitive, boolean lob)
+        throws Exception {
+        try {
+            saveArrayInternal(array, primitive, lob);
+        } catch (Exception e) {
+            throw e;
+        } catch (Error error) {
+            throw error;
+        } finally {
+            //
+        }
+    }
+
+    private void saveArrayInternal(Object vals, boolean primitive, boolean lob)
+        throws Exception {
+        Object[] array;
+        if (primitive)
+            array = convertPrimitiveArray(vals);
+        else
+            array = (Object[]) vals;
+        Arrays.sort(array, new TestArraySorter());
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+
+        ArraysTest test = new ArraysTest();
+        pm.persist(test);
+        int testID = test.getId();
+
+        setGetTestArray(test, vals, primitive, lob, true);
+        endTx(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        ArraysTest retrievedObject = pm.find(ArraysTest.class, testID);
+
+        Object retrievedVals = setGetTestArray(retrievedObject, vals,
+            primitive, lob, false);
+        Object[] retrievedArray;
+        if (primitive)
+            retrievedArray = convertPrimitiveArray(retrievedVals);
+        else
+            retrievedArray = (Object[]) retrievedVals;
+
+        assertNotNull(retrievedArray);
+        assertTrue(array.length != 0);
+        assertEquals(array.length, retrievedArray.length);
+        assertNotNull(array[0]);
+        assertNotNull(retrievedArray[0]);
+
+        // make sure the classes of the keys are the same.
+        assertEquals(array[0].getClass(), retrievedArray[0].getClass());
+        Arrays.sort(retrievedArray, new TestArraySorter());
+        for (int i = 0; i < array.length; i++)
+            assertClassAndValueEquals(array[i], retrievedArray[i]);
+
+        pm.remove(retrievedObject);
+        endTx(pm);
+    }
+
+    private Object[] convertPrimitiveArray(Object array) throws Exception {
+        int length = Array.getLength(array);
+        Class type = Array.get(array, 0).getClass();
+
+        Object[] copy = (Object[]) Array.newInstance(type, length);
+        for (int i = 0; i < length; i++)
+            copy[i] = Array.get(array, i);
+
+        return copy;
+    }
+
+    private void assertClassAndValueEquals(Object o1, Object o2) {
+        assertTrue("First object was null", o1 != null);
+        assertTrue("Second object was null", o2 != null);
+
+        assertTrue("Types did not match (class1="
+            + o1.getClass().getName() + ", class2="
+            + o2.getClass().getName() + ")",
+            o1.getClass().isAssignableFrom(o2.getClass()));
+
+        // floats and doubles are a little special: we only
+        // compare them to a certain precision, after which
+        // we give up.
+        if (o1 instanceof Double)
+            assertEquals(((Double) o1).doubleValue(),
+                ((Double) o2).doubleValue(),
+                DOUBLE_PRECISION);
+        else if (o1 instanceof Float)
+            assertEquals(((Float) o1).floatValue(),
+                ((Float) o2).floatValue(),
+                FLOAT_PRECISION);
+        else
+            assertEquals("Object did not match (class1="
+                + o1.getClass().getName() + ", class2="
+                + o2.getClass().getName() + ")",
+                o1, o2);
+    }
+
+    /**
+     * Generic setter/getter for setting the array.
+     */
+    private Object setGetTestArray(ArraysTest test, Object array,
+        boolean primitive, boolean lob, boolean doSet)
+        throws Exception {
+        if (array == null)
+            return null;
+
+        Object first = Array.get(array, 0);
+        if (first instanceof Date) {
+            if (doSet)
+                test.setDate((Date[]) array);
+            return test.getDate();
+        } else if (first instanceof String) {
+            if (doSet)
+                test.setString((String[]) array);
+            return test.getString();
+        } else if (first instanceof Character) {
+            if (doSet && !primitive)
+                test.setCharacter((Character[]) array);
+            else if (doSet && !lob)
+                test.setCharacterP((char[]) array);
+            else if (doSet)
+                test.setCharacterPClob((char[]) array);
+            else if (!primitive)
+                return test.getCharacter();
+            else if (!lob)
+                return test.getCharacterP();
+            else
+                return test.getCharacterPClob();
+            return null;
+        } else if (first instanceof Double) {
+            if (doSet && !primitive)
+                test.setDouble((Double[]) array);
+            else if (doSet)
+                test.setDoubleP((double[]) array);
+            else if (!primitive)
+                return test.getDouble();
+            else
+                return test.getDoubleP();
+            return null;
+        } else if (first instanceof Byte) {
+            if (doSet && !primitive)
+                test.setByte((Byte[]) array);
+            else if (doSet)
+                test.setByteP((byte[]) array);
+            else if (!primitive)
+                return test.getByte();
+            else
+                return test.getByteP();
+            return null;
+        } else if (first instanceof Float) {
+            if (doSet && !primitive)
+                test.setFloat((Float[]) array);
+            else if (doSet)
+                test.setFloatP((float[]) array);
+            else if (!primitive)
+                return test.getFloat();
+            else
+                return test.getFloatP();
+            return null;
+        } else if (first instanceof Long) {
+            if (doSet && !primitive)
+                test.setLong((Long[]) array);
+            else if (doSet)
+                test.setLongP((long[]) array);
+            else if (!primitive)
+                return test.getLong();
+            else
+                return test.getLongP();
+            return null;
+        } else if (first instanceof Integer) {
+            if (doSet && !primitive)
+                test.setInt((Integer[]) array);
+            else if (doSet)
+                test.setIntP((int[]) array);
+            else if (!primitive)
+                return test.getInt();
+            else
+                return test.getIntP();
+            return null;
+        } else if (first instanceof Short) {
+            if (doSet && !primitive)
+                test.setShort((Short[]) array);
+            else if (doSet)
+                test.setShortP((short[]) array);
+            else if (!primitive)
+                return test.getShort();
+            else
+                return test.getShortP();
+            return null;
+        } else if (first instanceof Boolean) {
+            if (doSet && !primitive)
+                test.setBoolean((Boolean[]) array);
+            else if (doSet)
+                test.setBooleanP((boolean[]) array);
+            else if (!primitive)
+                return test.getBoolean();
+            else
+                return test.getBooleanP();
+            return null;
+        } else if (first instanceof ArraysTest) {
+            if (doSet)
+                test.setArraysTest((ArraysTest[]) array);
+            return test.getArraysTest();
+        }
+
+        fail("Unknown array type");
+        return null;
+    }
+
+    private static class TestArraySorter
+        implements Comparator {
+
+        private Collator collator = Collator.getInstance();
+
+        public int compare(Object o1, Object o2) {
+            if (o1.equals(o2))
+                return 0;
+
+            if (o1 instanceof Number) {
+                return ((Number) o1).doubleValue() >
+                    ((Number) o2).doubleValue() ? 1 : -1;
+            } else if (o1 instanceof Date) {
+                return ((Date) o1).before((Date) o2) ? 1 : -1;
+            } else if (o1 instanceof ArraysTest) {
+                return ((ArraysTest) o1).compareTo(o2);
+            }
+            return collator.compare(o1.toString(), o2.toString());
+        }
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBigDecimals.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBigDecimals.java
index c9b5d14..6a4415e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBigDecimals.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBigDecimals.java
@@ -1,125 +1,125 @@
-/*
- * TestBigDecimals.java
- *
- * Created on October 9, 2006, 6:07 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.math.BigDecimal;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestBigDecimals extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestBigDecimals
-     */
-    public TestBigDecimals() {
-    }
-
-    public TestBigDecimals(String name) {
-        super(name);
-    }
-
-    public void testBigDecimalDataIntegrity()
-        throws Exception {
-        try {
-            BigDecimal bd = new BigDecimal(Math.random() * 10000000 + "");
-            bd = bd.setScale(100);
-            for (int i = 0; i < 50; i++) {
-                bd = bd.movePointLeft(1);
-                bigDecimalTest(bd);
-            }
-        }
-        catch (AssertionFailedError e) {
-            bug(3, e, "Precision loss for BigDecimals");
-        }
-    }
-//    FixMe aokeke: Passes but takes a long time --commenting for resource sake
-//    public void testBigBigDecimals()
-//        throws Exception {
-//        try {
-//            BigDecimal bd = new BigDecimal("1234567890."
-//                + "12345678901234567890123456789012345678901234567890"
-//                + "12345678901234567890123456789012345678901234567890");
-//
-//            bigDecimalTest(bd);
-//        } catch (AssertionFailedError e) {
-//            bug(3, e, "Precision loss for BigDecimals");
-//        }
-//    }
-
-    public void bigDecimalTest(final BigDecimal bd) {
-        OpenJPAEntityManager pm = null, pm2 = null;
-
-        try {
-            pm = getPM();
-            startTx(pm);
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestBigDecimal(bd);
-            pm.persist(aftt);
-            endTx(pm);
-            Object id = pm.getObjectId(aftt);
-            pm.evict(aftt);
-
-            pm2 = getPM();
-            startTx(pm);
-            AllFieldTypesTest aftt2 = (AllFieldTypesTest) pm2.getObjectId(id);
-
-            // why wouldn't they be two different objects?
-            assertTrue("identitcal field values",
-                bd != aftt2.getTestBigDecimal());
-
-            // this should always succeed
-            assertEquals(bd,
-                aftt2.getTestBigDecimal().setScale(bd.scale()));
-
-            // this will fail if we are losing scale
-            assertEquals(bd, aftt2.getTestBigDecimal());
-
-            rollbackTx(pm);
-        } catch (Throwable afe) {
-            bug(3, afe, "floating point precision loss");
-        } finally {
-            if (pm != null) {
-                //if (pm.getTransaction().isActive())
-                //rollbackTx(pm,());
-                endEm(pm);
-            }
-
-            if (pm2 != null) {
-                //if (pm2.getTransaction().isActive())
-                //rollbackTx(pm2,());
-                //pm2.close();
-                endEm(pm2);
-            }
-        }
-    }
-}
+/*
+ * TestBigDecimals.java
+ *
+ * Created on October 9, 2006, 6:07 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.math.BigDecimal;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestBigDecimals extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestBigDecimals
+     */
+    public TestBigDecimals() {
+    }
+
+    public TestBigDecimals(String name) {
+        super(name);
+    }
+
+    public void testBigDecimalDataIntegrity()
+        throws Exception {
+        try {
+            BigDecimal bd = new BigDecimal(Math.random() * 10000000 + "");
+            bd = bd.setScale(100);
+            for (int i = 0; i < 50; i++) {
+                bd = bd.movePointLeft(1);
+                bigDecimalTest(bd);
+            }
+        }
+        catch (AssertionFailedError e) {
+            bug(3, e, "Precision loss for BigDecimals");
+        }
+    }
+//    FixMe aokeke: Passes but takes a long time --commenting for resource sake
+//    public void testBigBigDecimals()
+//        throws Exception {
+//        try {
+//            BigDecimal bd = new BigDecimal("1234567890."
+//                + "12345678901234567890123456789012345678901234567890"
+//                + "12345678901234567890123456789012345678901234567890");
+//
+//            bigDecimalTest(bd);
+//        } catch (AssertionFailedError e) {
+//            bug(3, e, "Precision loss for BigDecimals");
+//        }
+//    }
+
+    public void bigDecimalTest(final BigDecimal bd) {
+        OpenJPAEntityManager pm = null, pm2 = null;
+
+        try {
+            pm = getPM();
+            startTx(pm);
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestBigDecimal(bd);
+            pm.persist(aftt);
+            endTx(pm);
+            Object id = pm.getObjectId(aftt);
+            pm.evict(aftt);
+
+            pm2 = getPM();
+            startTx(pm);
+            AllFieldTypesTest aftt2 = (AllFieldTypesTest) pm2.getObjectId(id);
+
+            // why wouldn't they be two different objects?
+            assertTrue("identitcal field values",
+                bd != aftt2.getTestBigDecimal());
+
+            // this should always succeed
+            assertEquals(bd,
+                aftt2.getTestBigDecimal().setScale(bd.scale()));
+
+            // this will fail if we are losing scale
+            assertEquals(bd, aftt2.getTestBigDecimal());
+
+            rollbackTx(pm);
+        } catch (Throwable afe) {
+            bug(3, afe, "floating point precision loss");
+        } finally {
+            if (pm != null) {
+                //if (pm.getTransaction().isActive())
+                //rollbackTx(pm,());
+                endEm(pm);
+            }
+
+            if (pm2 != null) {
+                //if (pm2.getTransaction().isActive())
+                //rollbackTx(pm2,());
+                //pm2.close();
+                endEm(pm2);
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBrokerFactoryPooling.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBrokerFactoryPooling.java
index be38150..78b0e70 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBrokerFactoryPooling.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestBrokerFactoryPooling.java
@@ -1,50 +1,50 @@
-/*
- * TestBrokerFactoryPooling.java
- *
- * Created on October 9, 2006, 6:10 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-
-import org.apache.openjpa.kernel.Bootstrap;
-import org.apache.openjpa.kernel.BrokerFactory;
-
-public class TestBrokerFactoryPooling extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestBrokerFactoryPooling
-     */
-    public TestBrokerFactoryPooling(String name) {
-        super(name);
-    }
-
-    public void testPooling() {
-        BrokerFactory bf0 = Bootstrap.getBrokerFactory();
-        BrokerFactory bf1 = Bootstrap.getBrokerFactory();
-        assertSame(bf0, bf1);
-    }
-}
+/*
+ * TestBrokerFactoryPooling.java
+ *
+ * Created on October 9, 2006, 6:10 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+
+import org.apache.openjpa.kernel.Bootstrap;
+import org.apache.openjpa.kernel.BrokerFactory;
+
+public class TestBrokerFactoryPooling extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestBrokerFactoryPooling
+     */
+    public TestBrokerFactoryPooling(String name) {
+        super(name);
+    }
+
+    public void testPooling() {
+        BrokerFactory bf0 = Bootstrap.getBrokerFactory();
+        BrokerFactory bf1 = Bootstrap.getBrokerFactory();
+        assertSame(bf0, bf1);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCalendarFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCalendarFields.java
index 9dd2141..b0920bb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCalendarFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCalendarFields.java
@@ -1,242 +1,242 @@
-/*
- * TestCalendarFields.java
- *
- * Created on October 9, 2006, 6:12 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.CalendarFields;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.util.JavaVersions;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestCalendarFields extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestCalendarFields
-     */
-    public TestCalendarFields(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(CalendarFields.class);
-    }
-
-    public void testFieldDefaultTimeZone() {
-        CalendarFields cal = new CalendarFields();
-
-        OpenJPAEntityManager pm;
-
-        pm = getPM();
-        startTx(pm);
-        cal.setSingapore(Calendar.
-            getInstance(TimeZone.getTimeZone("America/New_York")));
-        pm.persist(cal);
-        int id = cal.getId();
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        cal = (CalendarFields) pm.find(CalendarFields.class, id);
-        assertEquals(TimeZone.getTimeZone("Asia/Singapore"),
-            cal.getSingapore().getTimeZone());
-        endEm(pm);
-    }
-
-    public void testTimeZoneEquals() {
-        CalendarFields c1 = new CalendarFields();
-        CalendarFields c2 = new CalendarFields();
-        assertTimeZonesEquals(c1, c2);
-
-        OpenJPAEntityManager pm;
-
-        pm = getPM();
-        startTx(pm);
-        pm.persist(c2);
-        int id2 = c2.getId();
-        assertTimeZonesEquals(c1, c2);
-        endTx(pm);
-        assertTimeZonesEquals(c1, c2);
-        endEm(pm);
-
-        pm = getPM();
-        c2 = (CalendarFields) pm.find(CalendarFields.class, id2);
-        assertTimeZonesEquals(c1, c2);
-        assertTimeZonesEquals(c1, (CalendarFields) pm.detach(c2));
-        endEm(pm);
-    }
-
-    public void testCalendarQuery() {
-        long time = 1136660560572L;
-
-        CalendarFields cal = new CalendarFields();
-
-        OpenJPAEntityManager pm;
-
-        pm = getPM();
-        startTx(pm);
-        cal.getSingapore().setTime(new Date(time));
-        pm.persist(cal);
-        int id = cal.getId();
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-
-        //FIXME jthomas       
-        Date date = new Date(time + 100000);
-        Calendar cals = Calendar.getInstance();
-        cals.setTime(date);
-
-        String query =
-            "SELECT o FROM CalendarFields o WHERE o.singapore < :cal";
-        int size = pm.createQuery(query).setParameter("cal", cals).
-            getResultList().size();
-
-        assertEquals(1, size);
-
-//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore < :date").execute(new Date(time - 100000)));
-//
-//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore > :date").execute(new Date(time + 100000)));
-//        assertSize(1, pm.newQuery(CalendarFields.class, "singapore > :date").execute(new Date(time - 100000)));
-//
-//        assertSize(1, pm.newQuery(CalendarFields.class, "singapore < :date").execute(newCalendar(new Date(time + 100000), null)));
-//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore < :date").execute(newCalendar(new Date(time - 100000), null)));
-//
-//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore > :date").execute(newCalendar(new Date(time + 100000), null)));
-//        assertSize(1, pm.newQuery(CalendarFields.class, "singapore > :date").execute(newCalendar(new Date(time - 100000), null)));
-
-        endEm(pm);
-    }
-
-    private static Calendar newCalendar(Date date, String tz) {
-        Calendar cal = Calendar.getInstance(
-            tz == null ? TimeZone.getDefault() : TimeZone.getTimeZone(tz));
-        cal.setTime(date);
-        return cal;
-    }
-
-    public void testMutateCalendarDirties() {
-        CalendarFields c1 = new CalendarFields();
-
-        OpenJPAEntityManager pm;
-
-        pm = getPM();
-        startTx(pm);
-        pm.persist(c1);
-        int id = c1.getId();
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        c1 = pm.find(CalendarFields.class, id);
-
-        startTx(pm);
-
-        OpenJPAStateManager sm = getStateManager(c1, pm);
-
-        assertFalse(sm.getDirty().get(sm.getMetaData().
-            getField("gmt").getIndex()));
-
-        // test setting to same value doesn't dirty the field
-        /*
-        setTimeInMillis(c1.getGmtc1.getGmt().getTime().getTime());
-        c1.getGmt().setTime(c1.getGmt().getTime());
-        assertFalse(sm.getDirty().get(sm.getMetaData().
-            getField("gmt").getIndex()));
-        */
-
-        // test changing time
-        setTimeInMillis(c1.getGmt(), 12345);
-        assertTrue(sm.getDirty().get(sm.getMetaData().
-            getField("gmt").getIndex()));
-
-        assertFalse(sm.getDirty().get(sm.getMetaData().
-            getField("newYork").getIndex()));
-        // test mutate via "add()" method
-        c1.getNewYork().add(Calendar.SECOND, -1);
-        assertTrue(sm.getDirty().get(sm.getMetaData().
-            getField("newYork").getIndex()));
-
-        assertFalse(sm.getDirty().get(sm.getMetaData().
-            getField("berlin").getIndex()));
-        // test mutate via "setTimeZone()" method
-        c1.getBerlin().setTimeZone(TimeZone.getTimeZone("GMT"));
-        assertTrue(sm.getDirty().get(sm.getMetaData().
-            getField("berlin").getIndex()));
-
-        // Calendar.set can only be subclassed in JDK 1.4+ (it is final in
-        // 1.3), so we only run this test in JDK 1.4+
-        if (JavaVersions.VERSION >= 4) {
-            assertFalse(sm.getDirty().get(sm.getMetaData().
-                getField("singapore").getIndex()));
-            // test mutate via "set()" method
-            c1.getSingapore().set(Calendar.YEAR, 1998);
-            assertTrue(sm.getDirty().get(sm.getMetaData().
-                getField("singapore").getIndex()));
-        }
-
-        assertFalse(sm.getDirty().get(sm.getMetaData().
-            getField("pacific").getIndex()));
-        // test mutate via "roll()" method
-        c1.getPacific().roll(Calendar.YEAR, 5);
-        assertTrue(sm.getDirty().get(sm.getMetaData().
-            getField("pacific").getIndex()));
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    private static void setTimeInMillis(Calendar cal, long millis) {
-        // "setTimeInMillis" is protected in JDK 1.3, put public in 1.4 & 1.5
-        try {
-            // Equivalent to: cal.setTimeInMillis (millis);
-            cal.getClass().getMethod("setTimeInMillis",
-                new Class[]{ long.class }).invoke(cal,
-                new Object[]{ new Long(millis) });
-        } catch (Exception e) {
-            cal.setTime(new Date(millis));
-        }
-    }
-
-    private void assertTimeZonesEquals(CalendarFields c1, CalendarFields c2) {
-        for (int i = 0; i < c1.getCalendars().size(); i++) {
-            Calendar cal1 = (Calendar) c1.getCalendars().get(i);
-            Calendar cal2 = (Calendar) c2.getCalendars().get(i);
-
-            if (cal1 != null && cal2 != null)
-                assertEquals(cal1.getTimeZone().getID(),
-                    cal2.getTimeZone().getID());
-        }
-    }
-}
+/*
+ * TestCalendarFields.java
+ *
+ * Created on October 9, 2006, 6:12 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.CalendarFields;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.JavaVersions;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestCalendarFields extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestCalendarFields
+     */
+    public TestCalendarFields(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(CalendarFields.class);
+    }
+
+    public void testFieldDefaultTimeZone() {
+        CalendarFields cal = new CalendarFields();
+
+        OpenJPAEntityManager pm;
+
+        pm = getPM();
+        startTx(pm);
+        cal.setSingapore(Calendar.
+            getInstance(TimeZone.getTimeZone("America/New_York")));
+        pm.persist(cal);
+        int id = cal.getId();
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        cal = (CalendarFields) pm.find(CalendarFields.class, id);
+        assertEquals(TimeZone.getTimeZone("Asia/Singapore"),
+            cal.getSingapore().getTimeZone());
+        endEm(pm);
+    }
+
+    public void testTimeZoneEquals() {
+        CalendarFields c1 = new CalendarFields();
+        CalendarFields c2 = new CalendarFields();
+        assertTimeZonesEquals(c1, c2);
+
+        OpenJPAEntityManager pm;
+
+        pm = getPM();
+        startTx(pm);
+        pm.persist(c2);
+        int id2 = c2.getId();
+        assertTimeZonesEquals(c1, c2);
+        endTx(pm);
+        assertTimeZonesEquals(c1, c2);
+        endEm(pm);
+
+        pm = getPM();
+        c2 = (CalendarFields) pm.find(CalendarFields.class, id2);
+        assertTimeZonesEquals(c1, c2);
+        assertTimeZonesEquals(c1, (CalendarFields) pm.detach(c2));
+        endEm(pm);
+    }
+
+    public void testCalendarQuery() {
+        long time = 1136660560572L;
+
+        CalendarFields cal = new CalendarFields();
+
+        OpenJPAEntityManager pm;
+
+        pm = getPM();
+        startTx(pm);
+        cal.getSingapore().setTime(new Date(time));
+        pm.persist(cal);
+        int id = cal.getId();
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+
+        //FIXME jthomas       
+        Date date = new Date(time + 100000);
+        Calendar cals = Calendar.getInstance();
+        cals.setTime(date);
+
+        String query =
+            "SELECT o FROM CalendarFields o WHERE o.singapore < :cal";
+        int size = pm.createQuery(query).setParameter("cal", cals).
+            getResultList().size();
+
+        assertEquals(1, size);
+
+//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore < :date").execute(new Date(time - 100000)));
+//
+//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore > :date").execute(new Date(time + 100000)));
+//        assertSize(1, pm.newQuery(CalendarFields.class, "singapore > :date").execute(new Date(time - 100000)));
+//
+//        assertSize(1, pm.newQuery(CalendarFields.class, "singapore < :date").execute(newCalendar(new Date(time + 100000), null)));
+//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore < :date").execute(newCalendar(new Date(time - 100000), null)));
+//
+//        assertSize(0, pm.newQuery(CalendarFields.class, "singapore > :date").execute(newCalendar(new Date(time + 100000), null)));
+//        assertSize(1, pm.newQuery(CalendarFields.class, "singapore > :date").execute(newCalendar(new Date(time - 100000), null)));
+
+        endEm(pm);
+    }
+
+    private static Calendar newCalendar(Date date, String tz) {
+        Calendar cal = Calendar.getInstance(
+            tz == null ? TimeZone.getDefault() : TimeZone.getTimeZone(tz));
+        cal.setTime(date);
+        return cal;
+    }
+
+    public void testMutateCalendarDirties() {
+        CalendarFields c1 = new CalendarFields();
+
+        OpenJPAEntityManager pm;
+
+        pm = getPM();
+        startTx(pm);
+        pm.persist(c1);
+        int id = c1.getId();
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        c1 = pm.find(CalendarFields.class, id);
+
+        startTx(pm);
+
+        OpenJPAStateManager sm = getStateManager(c1, pm);
+
+        assertFalse(sm.getDirty().get(sm.getMetaData().
+            getField("gmt").getIndex()));
+
+        // test setting to same value doesn't dirty the field
+        /*
+        setTimeInMillis(c1.getGmtc1.getGmt().getTime().getTime());
+        c1.getGmt().setTime(c1.getGmt().getTime());
+        assertFalse(sm.getDirty().get(sm.getMetaData().
+            getField("gmt").getIndex()));
+        */
+
+        // test changing time
+        setTimeInMillis(c1.getGmt(), 12345);
+        assertTrue(sm.getDirty().get(sm.getMetaData().
+            getField("gmt").getIndex()));
+
+        assertFalse(sm.getDirty().get(sm.getMetaData().
+            getField("newYork").getIndex()));
+        // test mutate via "add()" method
+        c1.getNewYork().add(Calendar.SECOND, -1);
+        assertTrue(sm.getDirty().get(sm.getMetaData().
+            getField("newYork").getIndex()));
+
+        assertFalse(sm.getDirty().get(sm.getMetaData().
+            getField("berlin").getIndex()));
+        // test mutate via "setTimeZone()" method
+        c1.getBerlin().setTimeZone(TimeZone.getTimeZone("GMT"));
+        assertTrue(sm.getDirty().get(sm.getMetaData().
+            getField("berlin").getIndex()));
+
+        // Calendar.set can only be subclassed in JDK 1.4+ (it is final in
+        // 1.3), so we only run this test in JDK 1.4+
+        if (JavaVersions.VERSION >= 4) {
+            assertFalse(sm.getDirty().get(sm.getMetaData().
+                getField("singapore").getIndex()));
+            // test mutate via "set()" method
+            c1.getSingapore().set(Calendar.YEAR, 1998);
+            assertTrue(sm.getDirty().get(sm.getMetaData().
+                getField("singapore").getIndex()));
+        }
+
+        assertFalse(sm.getDirty().get(sm.getMetaData().
+            getField("pacific").getIndex()));
+        // test mutate via "roll()" method
+        c1.getPacific().roll(Calendar.YEAR, 5);
+        assertTrue(sm.getDirty().get(sm.getMetaData().
+            getField("pacific").getIndex()));
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    private static void setTimeInMillis(Calendar cal, long millis) {
+        // "setTimeInMillis" is protected in JDK 1.3, put public in 1.4 & 1.5
+        try {
+            // Equivalent to: cal.setTimeInMillis (millis);
+            cal.getClass().getMethod("setTimeInMillis",
+                new Class[]{ long.class }).invoke(cal,
+                new Object[]{ new Long(millis) });
+        } catch (Exception e) {
+            cal.setTime(new Date(millis));
+        }
+    }
+
+    private void assertTimeZonesEquals(CalendarFields c1, CalendarFields c2) {
+        for (int i = 0; i < c1.getCalendars().size(); i++) {
+            Calendar cal1 = (Calendar) c1.getCalendars().get(i);
+            Calendar cal2 = (Calendar) c2.getCalendars().get(i);
+
+            if (cal1 != null && cal2 != null)
+                assertEquals(cal1.getTimeZone().getID(),
+                    cal2.getTimeZone().getID());
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCheckConsistency.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCheckConsistency.java
index b7fcf05..47206ac 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCheckConsistency.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestCheckConsistency.java
@@ -1,404 +1,404 @@
-/*
- * TestCheckConsistency.java
- *
- * Created on October 9, 2006, 6:23 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestCheckConsistency extends BaseKernelTest {
-
-    private Object _oid = null;
-
-    /**
-     * Creates a new instance of TestCheckConsistency
-     */
-    public TestCheckConsistency(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        RuntimeTest1 pc = new RuntimeTest1();
-        pc.setIntField(1);
-        pc.setIntField1(1);
-        _oid = persist(pc);
-    }
-
-    public void testConsistentDatastoreTransaction() {
-
-        OpenJPAEntityManager pm = getPM();
-        pm.setOptimistic(false);
-        pm.validateChanges();        // no-op outside trans
-        startTx(pm);
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        pc.setIntField1(100);
-
-        RuntimeTest1 npc = new RuntimeTest1();
-        npc.setIntField(2);
-        npc.setIntField1(2);
-        pm.persist(npc);
-        pm.validateChanges();
-
-        assertEquals(100, pc.getIntField1());
-        assertTrue(pm.isPersistent(npc));
-
-        pc.setIntField1(200);
-        npc.setIntField1(300);
-        endTx(pm);
-
-        assertEquals(200, pc.getIntField1());
-        assertTrue(pm.isPersistent(npc));
-        assertEquals(300, npc.getIntField1());
-        endEm(pm);
-    }
-
-    public void testConsistentDatastoreTransactionWithRollback() {
-        OpenJPAEntityManager pm = getPM();
-        pm.setOptimistic(false);
-        pm.validateChanges();        // no-op outside trans
-        startTx(pm);
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        pc.setIntField1(100);
-
-        RuntimeTest1 npc = new RuntimeTest1();
-        pm.persist(npc);
-        Object noid = pm.getObjectId(npc);
-
-        pm.validateChanges();
-        assertEquals(100, pc.getIntField1());
-        assertTrue(pm.isPersistent(npc));
-
-        pc.setIntField1(200);
-        npc.setIntField1(300);
-        rollbackTx(pm);
-
-        assertEquals(1, pc.getIntField1());
-        assertFalse(pm.isPersistent(npc));
-        assertEquals(0, npc.getIntField1());
-        endEm(pm);
-
-        pm = getPM();
-        try {
-            RuntimeTest1 temp =
-                (RuntimeTest1) pm.find(RuntimeTest1.class, noid);
-            fail("Object should not exist." + temp.getIntField() + "::" +
-                temp.getIntField1());
-        } catch (Exception jonfe) {
-        }
-        endEm(pm);
-    }
-
-    //FIXME jthomas
-/*    
-    public void testInconsistentDatastoreTransaction() {
-        OpenJPAEntityManager pm = getPM();
-        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
-        pm.setOptimistic(false);
-        pm.setRetainState(false);
-        pm.validateChanges();        // no-op outside trans
-        pm.begin();
-  */
-    //FIXME jthomas
-    /*
-   fetch.setReadLockLevel(pm.LOCK_NONE);
-   fetch.setWriteLockLevel(pm.LOCK_NONE);
-    */
-    /*
-RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class,_oid);
-pc.setIntField(100);
-
-OpenJPAEntityManager pm2 = getPM();
-pm2.begin();
-RuntimeTest1 copy = (RuntimeTest1) pm2.find(RuntimeTest1.class,_oid);
-copy.setIntField(-1);
-pm2.commit();
-pm2.close();
-
-RuntimeTest1 npc = new RuntimeTest1();
-pm.persist(npc);
-
-try {
-   pm.validateChanges();
-   fail("Didn't find inconsistency.");
-} catch (Exception jove) {
-   //FIXME
-   /*
-   Throwable[] t = jove.getNestedExceptions();
-   assertEquals(1, t.length);
-   assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
-    */
-//        }
-
-    /*        assertTrue(pm.getRollbackOnly());
-           pm.rollback();
-
-           assertEquals(-1, pc.getIntField());
-           assertFalse(pm.isPersistent(npc));
-           endEm(pm,());
-       }
-    */
-    public void testConsistentOptimisticTransaction() {
-        OpenJPAEntityManager pm = getPM();
-        pm.setOptimistic(true);
-        pm.validateChanges();        // no-op outside trans
-        startTx(pm);
-        boolean hasConn = hasConnection(pm);
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        pc.setIntField1(100);
-
-        RuntimeTest1 npc = new RuntimeTest1();
-        npc.setIntField(2);
-        npc.setIntField1(2);
-        pm.persist(npc);
-
-        pm.validateChanges();
-        if (!hasConn)
-            assertFalse(hasConnection(pm));
-
-        assertEquals(100, pc.getIntField1());
-        assertTrue(pm.isPersistent(npc));
-
-        pc.setIntField1(200);
-        npc.setIntField1(300);
-        endTx(pm);
-
-        assertEquals(200, pc.getIntField1());
-        assertTrue(pm.isPersistent(npc));
-        assertEquals(300, npc.getIntField1());
-        endEm(pm);
-    }
-
-    private boolean hasConnection(OpenJPAEntityManager pm) {
-        return JPAFacadeHelper.toBroker(pm).hasConnection();
-    }
-
-    public void testConsistentOptimisticTransactionWithRollback() {
-        OpenJPAEntityManager pm = getPM();
-        pm.setOptimistic(true);
-        pm.validateChanges();        // no-op outside trans
-        startTx(pm);
-        boolean hasConn = hasConnection(pm);
-
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-        pc.setIntField1(100);
-
-        RuntimeTest1 npc = new RuntimeTest1();
-        pm.persist(npc);
-        Object noid = pm.getObjectId(npc);
-
-        pm.validateChanges();
-        if (!hasConn)
-            assertFalse(hasConnection(pm));
-
-        assertEquals(100, pc.getIntField1());
-        assertTrue(pm.isPersistent(npc));
-
-        pc.setIntField1(200);
-        npc.setIntField1(300);
-        rollbackTx(pm);
-
-        assertEquals(1, pc.getIntField1());
-        assertFalse(pm.isPersistent(npc));
-        assertEquals(0, npc.getIntField1());
-        endEm(pm);
-
-        pm = getPM();
-        try {
-            RuntimeTest1 temp =
-                (RuntimeTest1) pm.find(RuntimeTest1.class, noid);
-
-            fail("Object should not exist." + temp.getIntField() + "::" +
-                temp.getIntField1());
-        } catch (Exception jonfe) {
-        }
-    }
-//FIXME 
-    /*
-public void testInconsistentOptimisticTransactionWithoutRefresh() {
-OpenJPAEntityManager pm = getPM();
-pm.setRetainState(false);
-pm.setOptimistic(true);
-pm.validateChanges();        // no-op outside trans
-pm.begin();
-
-RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class,_oid);
-pc.setIntField(100);
-
-OpenJPAEntityManager pm2 = getPM();
-pm2.begin();
-RuntimeTest1 copy = (RuntimeTest1) pm2.find(RuntimeTest1.class,_oid);
-copy.setIntField(-1);
-pm2.commit();
-pm2.close();
-
-RuntimeTest1 npc = new RuntimeTest1();
-pm.persist(npc);
-Object noid = pm.getObjectId(npc);
-
-try {
-   pm.validateChanges();
-   fail("Didn't find inconsistency.");
-} catch (Exception jove) {
-   //FIXME jthomas
-   /*
-   Throwable[] t = jove.getNestedExceptions();
-   assertEquals(1, t.length);
-   assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
-    */
-    //     }
-/*     assertFalse(pm.getRollbackOnly());
-        
-        try {
-            pm.commit();
-            fail("Committed inconsistent transaction.");
-        } catch (Exception je) {
-        }
-        
-        assertEquals(-1, pc.getIntField());
-        assertFalse(pm.isPersistent(npc));
-        endEm(pm,());
-        
-        pm = getPM();
-        try {
-            pm.find(RuntimeTest1.class,noid);
-            fail("Object should not exist.");
-        } catch (Exception jonfe) {
-        }
-        endEm(pm,());
-    }
- */
-
-//FIXME 
-/*    
-    public void testInconsistentOptimisticTransactionWithRefresh() {
-        OpenJPAEntityManager pm = getPM();
-        pm.setOptimistic(true);
-        pm.validateChanges();        // no-op outside trans
-        pm.begin();
-        
-        RuntimeTest1 pc = pm.find(RuntimeTest1.class,_oid);
-        pc.setIntField(100);
-        
-        OpenJPAEntityManager pm2 = getPM();
-        pm2.begin();
-        RuntimeTest1 copy = pm2.find(RuntimeTest1.class,_oid);
-        copy.setIntField(-1);
-        pm2.commit();
-        pm2.close();
-        
-        RuntimeTest1 npc = new RuntimeTest1();
-        pm.persist(npc);
-        try {
-            pm.validateChanges();
-            fail("Didn't find inconsistency.");
-        } catch (Exception jove) {
-            //FIXME jthomas
-            /*
-            Throwable[] t = jove.getNestedExceptions();
-            assertEquals(1, t.length);
-            assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
-             */
-    //      }
-    /*       assertFalse(pm.getRollbackOnly());
-         pm.refresh(pc);
-
-         assertEquals(-1, pc.getIntField());
-         assertTrue(pm.isPersistent(npc));
-
-         pc.setIntField(200);
-         npc.setIntField(300);
-         pm.commit();
-
-         assertEquals(200, pc.getIntField());
-         assertTrue(pm.isPersistent(npc));
-         assertEquals(300, npc.getIntField());
-         endEm(pm,());
-     }
-    */
-
-//FIXME 
-
-/*    
-public void testInconsistentOptimisticTransactionWithRollback() {
-OpenJPAEntityManager pm = getPM();
-pm.setRetainState(false);
-pm.setOptimistic(true);
-pm.validateChanges();        // no-op outside trans
-pm.begin();
-
-RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class,_oid);
-pc.setIntField(100);
-
-OpenJPAEntityManager pm2 = getPM();
-pm2.begin();
-RuntimeTest1 copy = (RuntimeTest1) pm2.find(RuntimeTest1.class,_oid);
-copy.setIntField(-1);
-pm2.commit();
-pm2.close();
-
-RuntimeTest1 npc = new RuntimeTest1();
-pm.persist(npc);
-Object noid = pm.getObjectId(npc);
-
-try {
-pm.validateChanges();
-fail("Didn't find inconsistency.");
-} catch (Exception jove) {
-//FIXME jthomas
-/*
-Throwable[] t = jove.getNestedExceptions();
-assertEquals(1, t.length);
-assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
-*/
-    //      }
-    /*       assertFalse(pm.getRollbackOnly());
-          pm.rollback();
-
-          assertEquals(-1, pc.getIntField());
-          assertFalse(pm.isPersistent(npc));
-          endEm(pm,());
-
-          pm = getPM();
-          try {
-              pm.find(RuntimeTest1.class,_oid);
-              fail("Object should not exist.");
-          } catch (Exception jonfe) {
-          }
-          endEm(pm,());
-      }
-
-    */
-}
+/*
+ * TestCheckConsistency.java
+ *
+ * Created on October 9, 2006, 6:23 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestCheckConsistency extends BaseKernelTest {
+
+    private Object _oid = null;
+
+    /**
+     * Creates a new instance of TestCheckConsistency
+     */
+    public TestCheckConsistency(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        RuntimeTest1 pc = new RuntimeTest1();
+        pc.setIntField(1);
+        pc.setIntField1(1);
+        _oid = persist(pc);
+    }
+
+    public void testConsistentDatastoreTransaction() {
+
+        OpenJPAEntityManager pm = getPM();
+        pm.setOptimistic(false);
+        pm.validateChanges();        // no-op outside trans
+        startTx(pm);
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        pc.setIntField1(100);
+
+        RuntimeTest1 npc = new RuntimeTest1();
+        npc.setIntField(2);
+        npc.setIntField1(2);
+        pm.persist(npc);
+        pm.validateChanges();
+
+        assertEquals(100, pc.getIntField1());
+        assertTrue(pm.isPersistent(npc));
+
+        pc.setIntField1(200);
+        npc.setIntField1(300);
+        endTx(pm);
+
+        assertEquals(200, pc.getIntField1());
+        assertTrue(pm.isPersistent(npc));
+        assertEquals(300, npc.getIntField1());
+        endEm(pm);
+    }
+
+    public void testConsistentDatastoreTransactionWithRollback() {
+        OpenJPAEntityManager pm = getPM();
+        pm.setOptimistic(false);
+        pm.validateChanges();        // no-op outside trans
+        startTx(pm);
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        pc.setIntField1(100);
+
+        RuntimeTest1 npc = new RuntimeTest1();
+        pm.persist(npc);
+        Object noid = pm.getObjectId(npc);
+
+        pm.validateChanges();
+        assertEquals(100, pc.getIntField1());
+        assertTrue(pm.isPersistent(npc));
+
+        pc.setIntField1(200);
+        npc.setIntField1(300);
+        rollbackTx(pm);
+
+        assertEquals(1, pc.getIntField1());
+        assertFalse(pm.isPersistent(npc));
+        assertEquals(0, npc.getIntField1());
+        endEm(pm);
+
+        pm = getPM();
+        try {
+            RuntimeTest1 temp =
+                (RuntimeTest1) pm.find(RuntimeTest1.class, noid);
+            fail("Object should not exist." + temp.getIntField() + "::" +
+                temp.getIntField1());
+        } catch (Exception jonfe) {
+        }
+        endEm(pm);
+    }
+
+    //FIXME jthomas
+/*    
+    public void testInconsistentDatastoreTransaction() {
+        OpenJPAEntityManager pm = getPM();
+        FetchPlan fetch = (FetchPlan) pm.getFetchPlan();
+        pm.setOptimistic(false);
+        pm.setRetainState(false);
+        pm.validateChanges();        // no-op outside trans
+        pm.begin();
+  */
+    //FIXME jthomas
+    /*
+   fetch.setReadLockLevel(pm.LOCK_NONE);
+   fetch.setWriteLockLevel(pm.LOCK_NONE);
+    */
+    /*
+RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class,_oid);
+pc.setIntField(100);
+
+OpenJPAEntityManager pm2 = getPM();
+pm2.begin();
+RuntimeTest1 copy = (RuntimeTest1) pm2.find(RuntimeTest1.class,_oid);
+copy.setIntField(-1);
+pm2.commit();
+pm2.close();
+
+RuntimeTest1 npc = new RuntimeTest1();
+pm.persist(npc);
+
+try {
+   pm.validateChanges();
+   fail("Didn't find inconsistency.");
+} catch (Exception jove) {
+   //FIXME
+   /*
+   Throwable[] t = jove.getNestedExceptions();
+   assertEquals(1, t.length);
+   assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
+    */
+//        }
+
+    /*        assertTrue(pm.getRollbackOnly());
+           pm.rollback();
+
+           assertEquals(-1, pc.getIntField());
+           assertFalse(pm.isPersistent(npc));
+           endEm(pm,());
+       }
+    */
+    public void testConsistentOptimisticTransaction() {
+        OpenJPAEntityManager pm = getPM();
+        pm.setOptimistic(true);
+        pm.validateChanges();        // no-op outside trans
+        startTx(pm);
+        boolean hasConn = hasConnection(pm);
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        pc.setIntField1(100);
+
+        RuntimeTest1 npc = new RuntimeTest1();
+        npc.setIntField(2);
+        npc.setIntField1(2);
+        pm.persist(npc);
+
+        pm.validateChanges();
+        if (!hasConn)
+            assertFalse(hasConnection(pm));
+
+        assertEquals(100, pc.getIntField1());
+        assertTrue(pm.isPersistent(npc));
+
+        pc.setIntField1(200);
+        npc.setIntField1(300);
+        endTx(pm);
+
+        assertEquals(200, pc.getIntField1());
+        assertTrue(pm.isPersistent(npc));
+        assertEquals(300, npc.getIntField1());
+        endEm(pm);
+    }
+
+    private boolean hasConnection(OpenJPAEntityManager pm) {
+        return JPAFacadeHelper.toBroker(pm).hasConnection();
+    }
+
+    public void testConsistentOptimisticTransactionWithRollback() {
+        OpenJPAEntityManager pm = getPM();
+        pm.setOptimistic(true);
+        pm.validateChanges();        // no-op outside trans
+        startTx(pm);
+        boolean hasConn = hasConnection(pm);
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        pc.setIntField1(100);
+
+        RuntimeTest1 npc = new RuntimeTest1();
+        pm.persist(npc);
+        Object noid = pm.getObjectId(npc);
+
+        pm.validateChanges();
+        if (!hasConn)
+            assertFalse(hasConnection(pm));
+
+        assertEquals(100, pc.getIntField1());
+        assertTrue(pm.isPersistent(npc));
+
+        pc.setIntField1(200);
+        npc.setIntField1(300);
+        rollbackTx(pm);
+
+        assertEquals(1, pc.getIntField1());
+        assertFalse(pm.isPersistent(npc));
+        assertEquals(0, npc.getIntField1());
+        endEm(pm);
+
+        pm = getPM();
+        try {
+            RuntimeTest1 temp =
+                (RuntimeTest1) pm.find(RuntimeTest1.class, noid);
+
+            fail("Object should not exist." + temp.getIntField() + "::" +
+                temp.getIntField1());
+        } catch (Exception jonfe) {
+        }
+    }
+//FIXME 
+    /*
+public void testInconsistentOptimisticTransactionWithoutRefresh() {
+OpenJPAEntityManager pm = getPM();
+pm.setRetainState(false);
+pm.setOptimistic(true);
+pm.validateChanges();        // no-op outside trans
+pm.begin();
+
+RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class,_oid);
+pc.setIntField(100);
+
+OpenJPAEntityManager pm2 = getPM();
+pm2.begin();
+RuntimeTest1 copy = (RuntimeTest1) pm2.find(RuntimeTest1.class,_oid);
+copy.setIntField(-1);
+pm2.commit();
+pm2.close();
+
+RuntimeTest1 npc = new RuntimeTest1();
+pm.persist(npc);
+Object noid = pm.getObjectId(npc);
+
+try {
+   pm.validateChanges();
+   fail("Didn't find inconsistency.");
+} catch (Exception jove) {
+   //FIXME jthomas
+   /*
+   Throwable[] t = jove.getNestedExceptions();
+   assertEquals(1, t.length);
+   assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
+    */
+    //     }
+/*     assertFalse(pm.getRollbackOnly());
+        
+        try {
+            pm.commit();
+            fail("Committed inconsistent transaction.");
+        } catch (Exception je) {
+        }
+        
+        assertEquals(-1, pc.getIntField());
+        assertFalse(pm.isPersistent(npc));
+        endEm(pm,());
+        
+        pm = getPM();
+        try {
+            pm.find(RuntimeTest1.class,noid);
+            fail("Object should not exist.");
+        } catch (Exception jonfe) {
+        }
+        endEm(pm,());
+    }
+ */
+
+//FIXME 
+/*    
+    public void testInconsistentOptimisticTransactionWithRefresh() {
+        OpenJPAEntityManager pm = getPM();
+        pm.setOptimistic(true);
+        pm.validateChanges();        // no-op outside trans
+        pm.begin();
+        
+        RuntimeTest1 pc = pm.find(RuntimeTest1.class,_oid);
+        pc.setIntField(100);
+        
+        OpenJPAEntityManager pm2 = getPM();
+        pm2.begin();
+        RuntimeTest1 copy = pm2.find(RuntimeTest1.class,_oid);
+        copy.setIntField(-1);
+        pm2.commit();
+        pm2.close();
+        
+        RuntimeTest1 npc = new RuntimeTest1();
+        pm.persist(npc);
+        try {
+            pm.validateChanges();
+            fail("Didn't find inconsistency.");
+        } catch (Exception jove) {
+            //FIXME jthomas
+            /*
+            Throwable[] t = jove.getNestedExceptions();
+            assertEquals(1, t.length);
+            assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
+             */
+    //      }
+    /*       assertFalse(pm.getRollbackOnly());
+         pm.refresh(pc);
+
+         assertEquals(-1, pc.getIntField());
+         assertTrue(pm.isPersistent(npc));
+
+         pc.setIntField(200);
+         npc.setIntField(300);
+         pm.commit();
+
+         assertEquals(200, pc.getIntField());
+         assertTrue(pm.isPersistent(npc));
+         assertEquals(300, npc.getIntField());
+         endEm(pm,());
+     }
+    */
+
+//FIXME 
+
+/*    
+public void testInconsistentOptimisticTransactionWithRollback() {
+OpenJPAEntityManager pm = getPM();
+pm.setRetainState(false);
+pm.setOptimistic(true);
+pm.validateChanges();        // no-op outside trans
+pm.begin();
+
+RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class,_oid);
+pc.setIntField(100);
+
+OpenJPAEntityManager pm2 = getPM();
+pm2.begin();
+RuntimeTest1 copy = (RuntimeTest1) pm2.find(RuntimeTest1.class,_oid);
+copy.setIntField(-1);
+pm2.commit();
+pm2.close();
+
+RuntimeTest1 npc = new RuntimeTest1();
+pm.persist(npc);
+Object noid = pm.getObjectId(npc);
+
+try {
+pm.validateChanges();
+fail("Didn't find inconsistency.");
+} catch (Exception jove) {
+//FIXME jthomas
+/*
+Throwable[] t = jove.getNestedExceptions();
+assertEquals(1, t.length);
+assertEquals(pc, (((JDOException) t[0]).getFailedObject()));
+*/
+    //      }
+    /*       assertFalse(pm.getRollbackOnly());
+          pm.rollback();
+
+          assertEquals(-1, pc.getIntField());
+          assertFalse(pm.isPersistent(npc));
+          endEm(pm,());
+
+          pm = getPM();
+          try {
+              pm.find(RuntimeTest1.class,_oid);
+              fail("Object should not exist.");
+          } catch (Exception jonfe) {
+          }
+          endEm(pm,());
+      }
+
+    */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestClassStringConstructor.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestClassStringConstructor.java
index 1cc5faf..0c8d683 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestClassStringConstructor.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestClassStringConstructor.java
@@ -1,61 +1,61 @@
-/*
- * TestClassStringConstructor.java
- *
- * Created on October 16, 2006, 2:48 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AppIdClassString;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestClassStringConstructor extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestClassStringConstructor
-     */
-    public TestClassStringConstructor(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(AppIdClassString.class);
-    }
-
-    public void testConstructor() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        AppIdClassString pc = new AppIdClassString(5);
-        pm.persist(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = pm.find(AppIdClassString.class, new AppIdClassString.Idkey("5"));
-        assertEquals(5, pc.getPk());
-        endEm(pm);
-    }
-}
+/*
+ * TestClassStringConstructor.java
+ *
+ * Created on October 16, 2006, 2:48 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AppIdClassString;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestClassStringConstructor extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestClassStringConstructor
+     */
+    public TestClassStringConstructor(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(AppIdClassString.class);
+    }
+
+    public void testConstructor() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        AppIdClassString pc = new AppIdClassString(5);
+        pm.persist(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = pm.find(AppIdClassString.class, new AppIdClassString.Idkey("5"));
+        assertEquals(5, pc.getPk());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestConnectionRetainMode.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestConnectionRetainMode.java
index 22542de..e0eba01 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestConnectionRetainMode.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestConnectionRetainMode.java
@@ -1,118 +1,118 @@
-/*
- * TestConnectionRetainMode.java
- *
- * Created on October 10, 2006, 1:09 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.HashMap;
-import java.util.Map;
-
-
-
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestConnectionRetainMode extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestConnectionRetainMode
-     */
-    public TestConnectionRetainMode() {
-    }
-
-    public TestConnectionRetainMode(String str) {
-        super(str);
-    }
-
-    public void testOnDemand()
-        throws Exception {
-        doTest("on-demand");
-    }
-
-    public void testTransaction()
-        throws Exception {
-        doTest("transaction");
-    }
-
-    public void testPersistenceManager()
-        throws Exception {
-        doTest("persistence-manager");
-    }
-
-    public void doTest(String mode)
-        throws Exception {
-        Map props = new HashMap();
-        props.put("openjpa.ConnectionRetainMode", mode);
-
-        OpenJPAEntityManagerFactory factory = getEmf(props);
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) factory.createEntityManager();
-        Object initialConnection = pm.getConnection();
-
-        try {
-            checkPM(pm, initialConnection, mode);
-
-            pm.setOptimistic(true);
-            startTx(pm);
-
-            Object optimisticConnection = pm.getConnection();
-            checkPM(pm, initialConnection, mode);
-            checkTransaction(pm, optimisticConnection, mode);
-
-            rollbackTx(pm);
-            checkPM(pm, initialConnection, mode);
-
-            pm.setOptimistic(false);
-            startTx(pm);
-
-            Object pessimisticConnection = pm.getConnection();
-            checkPM(pm, initialConnection, mode);
-            checkTransaction(pm, pessimisticConnection, mode);
-
-            rollbackTx(pm);
-            checkPM(pm, initialConnection, mode);
-        } finally {
-
-            rollbackTx(pm);
-            endEm(pm);
-        }
-    }
-
-    private void checkPM(OpenJPAEntityManager pm, Object c, String mode)
-        throws Exception {
-        if ("persistence-manager".equals(mode))
-            assertEquals(c, pm.getConnection());
-    }
-
-    private void checkTransaction(OpenJPAEntityManager pm, Object c,
-        String mode)
-        throws Exception {
-        if (!"on-demand".equals(mode)
-            || !pm.getOptimistic())
-            assertEquals(c, pm.getConnection());
-    }
-}
+/*
+ * TestConnectionRetainMode.java
+ *
+ * Created on October 10, 2006, 1:09 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestConnectionRetainMode extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestConnectionRetainMode
+     */
+    public TestConnectionRetainMode() {
+    }
+
+    public TestConnectionRetainMode(String str) {
+        super(str);
+    }
+
+    public void testOnDemand()
+        throws Exception {
+        doTest("on-demand");
+    }
+
+    public void testTransaction()
+        throws Exception {
+        doTest("transaction");
+    }
+
+    public void testPersistenceManager()
+        throws Exception {
+        doTest("persistence-manager");
+    }
+
+    public void doTest(String mode)
+        throws Exception {
+        Map props = new HashMap();
+        props.put("openjpa.ConnectionRetainMode", mode);
+
+        OpenJPAEntityManagerFactory factory = getEmf(props);
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) factory.createEntityManager();
+        Object initialConnection = pm.getConnection();
+
+        try {
+            checkPM(pm, initialConnection, mode);
+
+            pm.setOptimistic(true);
+            startTx(pm);
+
+            Object optimisticConnection = pm.getConnection();
+            checkPM(pm, initialConnection, mode);
+            checkTransaction(pm, optimisticConnection, mode);
+
+            rollbackTx(pm);
+            checkPM(pm, initialConnection, mode);
+
+            pm.setOptimistic(false);
+            startTx(pm);
+
+            Object pessimisticConnection = pm.getConnection();
+            checkPM(pm, initialConnection, mode);
+            checkTransaction(pm, pessimisticConnection, mode);
+
+            rollbackTx(pm);
+            checkPM(pm, initialConnection, mode);
+        } finally {
+
+            rollbackTx(pm);
+            endEm(pm);
+        }
+    }
+
+    private void checkPM(OpenJPAEntityManager pm, Object c, String mode)
+        throws Exception {
+        if ("persistence-manager".equals(mode))
+            assertEquals(c, pm.getConnection());
+    }
+
+    private void checkTransaction(OpenJPAEntityManager pm, Object c,
+        String mode)
+        throws Exception {
+        if (!"on-demand".equals(mode)
+            || !pm.getOptimistic())
+            assertEquals(c, pm.getConnection());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
index cb600f2..77d253f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
@@ -1,134 +1,134 @@
-/*
- * TestDateQueries.java
- *
- * Created on October 10, 2006, 1:28 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestDateQueries extends BaseKernelTest {
-
-    private OpenJPAEntityManager _pm = null;
-    private Date _date = null;
-    private Date _before = null;
-    private Date _after = null;
-
-    /**
-     * Creates a new instance of TestDateQueries
-     */
-    public TestDateQueries() {
-    }
-
-    public TestDateQueries(String name) {
-        super(name);
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-
-        SimpleDateFormat sdf = new SimpleDateFormat("MMMMM dd, yyyy");
-        _date = sdf.parse("April 26, 1978");
-        _before = sdf.parse("April 25, 1978");
-        _after = sdf.parse("April 27, 1978");
-        _pm = getPM();
-
-        // delete all existing instances
-        deleteAll(AllFieldTypesTest.class);
-
-        // create some instances to query on
-        startTx(_pm);
-        AllFieldTypesTest test = new AllFieldTypesTest();
-        test.setTestDate(_date);
-        _pm.persist(test);
-
-        test = new AllFieldTypesTest();
-        test.setTestDate(_before);
-        _pm.persist(test);
-
-        test = new AllFieldTypesTest();
-        test.setTestDate(_after);
-        _pm.persist(test);
-        endTx(_pm);
-    }
-
-    public void testEquals() {
-        Collection vals = executeQuery("testDate = :date");
-        assertEquals(1, vals.size());
-        assertEquals(_date, ((AllFieldTypesTest) vals.iterator().next()).
-            getTestDate());
-    }
-
-    public void testNotEquals() {
-        Collection vals = executeQuery("testDate <> :date");
-        assertEquals(2, vals.size());
-    }
-
-    public void testBefore() {
-        Collection vals = executeQuery("testDate < :date");
-        assertEquals(1, vals.size());
-        assertEquals(_before, ((AllFieldTypesTest) vals.iterator().next()).
-            getTestDate());
-    }
-
-    public void testAfter() {
-        Collection vals = executeQuery("testDate > :date");
-        assertEquals(1, vals.size());
-        assertEquals(_after, ((AllFieldTypesTest) vals.iterator().next()).
-            getTestDate());
-    }
-
-    public void testOrderBy() {
-        String query =
-            "SELECT o FROM AllFieldTypesTest o ORDER BY o.testDate ASC";
-        OpenJPAQuery q = _pm.createQuery(query);
-        List vals = q.getResultList();
-        assertEquals(3, vals.size());
-
-        Iterator i = vals.iterator();
-        assertEquals(_before, ((AllFieldTypesTest) i.next()).getTestDate());
-        assertEquals(_date, ((AllFieldTypesTest) i.next()).getTestDate());
-        assertEquals(_after, ((AllFieldTypesTest) i.next()).getTestDate());
-    }
-
-    private List executeQuery(String filter) {
-        String query = "SELECT o FROM AllFieldTypesTest o WHERE o." + filter;
-        OpenJPAQuery q = _pm.createQuery(query);
-        q.setParameter("date", _date);
-        return q.getResultList();
-    }
-}
+/*
+ * TestDateQueries.java
+ *
+ * Created on October 10, 2006, 1:28 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestDateQueries extends BaseKernelTest {
+
+    private OpenJPAEntityManager _pm = null;
+    private Date _date = null;
+    private Date _before = null;
+    private Date _after = null;
+
+    /**
+     * Creates a new instance of TestDateQueries
+     */
+    public TestDateQueries() {
+    }
+
+    public TestDateQueries(String name) {
+        super(name);
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+
+        SimpleDateFormat sdf = new SimpleDateFormat("MMMMM dd, yyyy");
+        _date = sdf.parse("April 26, 1978");
+        _before = sdf.parse("April 25, 1978");
+        _after = sdf.parse("April 27, 1978");
+        _pm = getPM();
+
+        // delete all existing instances
+        deleteAll(AllFieldTypesTest.class);
+
+        // create some instances to query on
+        startTx(_pm);
+        AllFieldTypesTest test = new AllFieldTypesTest();
+        test.setTestDate(_date);
+        _pm.persist(test);
+
+        test = new AllFieldTypesTest();
+        test.setTestDate(_before);
+        _pm.persist(test);
+
+        test = new AllFieldTypesTest();
+        test.setTestDate(_after);
+        _pm.persist(test);
+        endTx(_pm);
+    }
+
+    public void testEquals() {
+        Collection vals = executeQuery("testDate = :date");
+        assertEquals(1, vals.size());
+        assertEquals(_date, ((AllFieldTypesTest) vals.iterator().next()).
+            getTestDate());
+    }
+
+    public void testNotEquals() {
+        Collection vals = executeQuery("testDate <> :date");
+        assertEquals(2, vals.size());
+    }
+
+    public void testBefore() {
+        Collection vals = executeQuery("testDate < :date");
+        assertEquals(1, vals.size());
+        assertEquals(_before, ((AllFieldTypesTest) vals.iterator().next()).
+            getTestDate());
+    }
+
+    public void testAfter() {
+        Collection vals = executeQuery("testDate > :date");
+        assertEquals(1, vals.size());
+        assertEquals(_after, ((AllFieldTypesTest) vals.iterator().next()).
+            getTestDate());
+    }
+
+    public void testOrderBy() {
+        String query =
+            "SELECT o FROM AllFieldTypesTest o ORDER BY o.testDate ASC";
+        OpenJPAQuery q = _pm.createQuery(query);
+        List vals = q.getResultList();
+        assertEquals(3, vals.size());
+
+        Iterator i = vals.iterator();
+        assertEquals(_before, ((AllFieldTypesTest) i.next()).getTestDate());
+        assertEquals(_date, ((AllFieldTypesTest) i.next()).getTestDate());
+        assertEquals(_after, ((AllFieldTypesTest) i.next()).getTestDate());
+    }
+
+    private List executeQuery(String filter) {
+        String query = "SELECT o FROM AllFieldTypesTest o WHERE o." + filter;
+        OpenJPAQuery q = _pm.createQuery(query);
+        q.setParameter("date", _date);
+        return q.getResultList();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDependentFields2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDependentFields2.java
index 3b2f1e7..a598c93 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDependentFields2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDependentFields2.java
@@ -1,566 +1,566 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.DependentFieldsPC;
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-public class TestDependentFields2 extends BaseKernelTest {
-
-    private static final int COMMIT = 0;
-    private static final int ROLLBACK = 1;
-    private static final int PRESTORE = 2;
-
-    private Object _root = null;
-    private Object _rel = null;
-    private Object _depRel = null;
-    private Object _deep = null;
-    private Object _coll = null;
-    private Object _depColl = null;
-    private Object _map = null;
-    private Object _depMap = null;
-    private Object _repeat = null;
-
-    public TestDependentFields2(String casename) {
-        super(casename);
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(DependentFieldsPC.class);
-
-        DependentFieldsPC root = new DependentFieldsPC();
-        root.setRelation(new DependentFieldsPC());
-        root.getList().add(new DependentFieldsPC());
-        root.getMap().put("key", new DependentFieldsPC());
-        root.setDependentRelation(new DependentFieldsPC());
-        root.getDependentRelation().setDependentRelation
-            (new DependentFieldsPC());
-        root.getDependentList().add(new DependentFieldsPC());
-        root.getDependentMap().put("key", new DependentFieldsPC());
-
-        DependentFieldsPC repeat = new DependentFieldsPC();
-        root.getDependentList().add(repeat);
-        root.getDependentMap().put("repeat", repeat);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(root);
-        endTx(pm);
-
-        _root = pm.getObjectId(root);
-        assertNotNull(_root);
-        _rel = pm.getObjectId(root.getRelation());
-        _depRel = pm.getObjectId(root.getDependentRelation());
-        _deep = pm.getObjectId(root.getDependentRelation().
-            getDependentRelation());
-        _coll = pm.getObjectId(root.getList().iterator().next());
-        Iterator itr = root.getDependentList().iterator();
-        _depColl = pm.getObjectId(itr.next());
-        _repeat = pm.getObjectId(itr.next());
-        _map = pm.getObjectId(root.getMap().get("key"));
-        _depMap = pm.getObjectId(root.getDependentMap().get("key"));
-
-        endEm(pm);
-    }
-
-    public void testDependentFieldsLoaded() {
-        delete(true, COMMIT);
-        checkFields();
-    }
-
-    public void testDependentFieldsLoadedWithRollback() {
-        delete(true, ROLLBACK);
-        checkFields();
-    }
-
-    public void testDependentFieldsLoadedWithPreStore() {
-        delete(true, PRESTORE);
-        checkFields();
-    }
-
-    public void testDependentFieldsUnloaded() {
-        delete(false, COMMIT);
-        checkFields();
-    }
-
-    public void testDependentFieldsUnloadedWithRollback() {
-        delete(false, ROLLBACK);
-        checkFields();
-    }
-
-    public void testDependentFieldsUnloadedWithPreStore() {
-        delete(false, PRESTORE);
-        checkFields();
-    }
-
-    private void delete(boolean load, int action) {
-        OpenJPAEntityManager pm = getPM(true, true);
-        DependentFieldsPC root;
-        Object rel = null;
-        Object depRel = null;
-        Object coll = null;
-        Object depColl = null;
-        Object map = null;
-        Object depMap = null;
-        Object repeat = null;
-        Object deep = null;
-        while (true) {
-            startTx(pm);
-            root = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
-            if (load) {
-                rel = root.getRelation();
-                assertNotNull(rel);
-                depRel = root.getDependentRelation();
-                assertNotNull(depRel);
-                deep = ((DependentFieldsPC) depRel).getDependentRelation();
-                assertNotNull(deep);
-                coll = root.getList().iterator().next();
-                assertNotNull(coll);
-                Iterator itr = root.getDependentList().iterator();
-                depColl = itr.next();
-                repeat = itr.next();
-                assertNotNull(depColl);
-                assertNotNull(repeat);
-                map = root.getMap().get("key");
-                assertNotNull(map);
-                depMap = root.getDependentMap().get("key");
-                assertNotNull(depMap);
-
-                // pcl: test both depColl and repeat, since they might
-                // have been out of order above.
-                Object o = root.getDependentMap().get("repeat");
-                if (o != repeat)
-                    fail("dependent map does not contain 'repeat'");
-            }
-            pm.remove(root);
-
-            if (action == ROLLBACK) {
-                rollbackTx(pm);
-                action = COMMIT;
-            } else if (action == COMMIT) {
-                endTx(pm);
-                break;
-            } else {
-                pm.preFlush();
-                break;
-            }
-        }
-
-        if (load) {
-            if (action == PRESTORE) {
-                assertFalse(pm.isRemoved(rel));
-                assertFalse(pm.isRemoved(coll));
-                assertFalse(pm.isRemoved(map));
-                assertTrue(pm.isRemoved(depRel));
-                assertTrue(pm.isRemoved(deep));
-                assertTrue(pm.isRemoved(depColl));
-                assertTrue(pm.isRemoved(depMap));
-                assertTrue(pm.isRemoved(repeat));
-            } else {
-                assertNotNull(OpenJPAPersistence.getEntityManager(rel));
-                assertNotNull(OpenJPAPersistence.getEntityManager(coll));
-                assertNotNull(OpenJPAPersistence.getEntityManager(map));
-                assertNull(OpenJPAPersistence.getEntityManager(depRel));
-                assertNull(OpenJPAPersistence.getEntityManager(deep));
-                assertNull(OpenJPAPersistence.getEntityManager(depColl));
-                assertNull(OpenJPAPersistence.getEntityManager(depMap));
-                assertNull(OpenJPAPersistence.getEntityManager(repeat));
-            }
-        }
-
-        if (action == PRESTORE)
-            endTx(pm);
-        endEm(pm);
-    }
-
-    private void checkFields() {
-        OpenJPAEntityManager pm = getPM(true, true);
-        assertNotNull(pm.find(DependentFieldsPC.class, _rel));
-        assertNotNull(pm.find(DependentFieldsPC.class, _coll));
-        assertNotNull(pm.find(DependentFieldsPC.class, _map));
-        assertNull(pm.find(DependentFieldsPC.class, _depRel));
-        assertNull(pm.find(DependentFieldsPC.class, _deep));
-        assertNull(pm.find(DependentFieldsPC.class, _depColl));
-        assertNull(pm.find(DependentFieldsPC.class, _depMap));
-
-        endEm(pm);
-    }
-
-    public void testNullDeletesDependent() {
-        nullDeletesDependent(COMMIT);
-    }
-
-    public void testNullDeletesDependentWithRollback() {
-        nullDeletesDependent(ROLLBACK);
-    }
-
-    public void testNullDeletesDependentWithPreStore() {
-        nullDeletesDependent(PRESTORE);
-    }
-
-    private void nullDeletesDependent(int action) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        DependentFieldsPC pc;
-        DependentFieldsPC depRel;
-        while (true) {
-            startTx(pm);
-            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
-            depRel = pc.getDependentRelation();
-            assertEquals(_depRel, pm.getObjectId(depRel));
-            pc.setDependentRelation(null);
-            if (action == ROLLBACK) {
-                rollbackTx(pm);
-                action = COMMIT;
-            } else if (action == COMMIT) {
-                endTx(pm);
-                break;
-            } else {
-                pm.preFlush();
-                break;
-            }
-        }
-
-        if (action == PRESTORE) {
-            assertTrue(pm.isRemoved(depRel));
-            endTx(pm);
-        }
-
-        assertTrue(!pm.isPersistent(depRel));
-        assertNull(pm.find(DependentFieldsPC.class, _depRel));
-        endEm(pm);
-    }
-
-    public void testRemoveDeletesDependent() {
-        removeDeletesDependent(COMMIT);
-    }
-
-    public void testRemoveDeletesDependentWithRollback() {
-        removeDeletesDependent(ROLLBACK);
-    }
-
-    public void testRemoveDeletesDependentWithPreStore() {
-        removeDeletesDependent(PRESTORE);
-    }
-
-    private void removeDeletesDependent(int action) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        DependentFieldsPC pc;
-        DependentFieldsPC depColl;
-        DependentFieldsPC depMap;
-        List list;
-        Map map;
-        while (true) {
-            startTx(pm);
-            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
-            list = pc.getDependentList();
-            assertEquals("list size =! 2", 2, list.size());
-            depColl = (DependentFieldsPC) list.remove(0);
-            assertEquals("_depColl is not pm.getObjectId(depColl)", _depColl,
-                pm.getObjectId(depColl));
-
-            map = pc.getDependentMap();
-            assertEquals("map size =! 2", 2, map.size());
-            depMap = (DependentFieldsPC) map.remove("key");
-            assertEquals("_depMap is not pm.getObjectId(depMap)", _depMap,
-                pm.getObjectId(depMap));
-
-            if (action == ROLLBACK) {
-                rollbackTx(pm);
-                action = COMMIT;
-            } else if (action == COMMIT) {
-                endTx(pm);
-                break;
-            } else {
-                pm.preFlush();
-                break;
-            }
-        }
-
-        if (action == PRESTORE) {
-            assertTrue(pm.isRemoved(depColl));
-            assertTrue(pm.isRemoved(depMap));
-            endTx(pm);
-        }
-
-//        assertTrue("depcoll is persistence", !pm.isPersistent(depColl));
-        assertNull(pm.find(DependentFieldsPC.class, _depColl));
-
-//        assertTrue("depMap is persistence", !pm.isPersistent(depMap));
-        assertNull(pm.find(DependentFieldsPC.class, _depMap));
-
-        assertNotNull("repeat is null",
-            pm.find(DependentFieldsPC.class, _repeat));
-        endEm(pm);
-    }
-
-    public void testMoveDependentInContainer() {
-        moveDependentInContainer(COMMIT);
-    }
-
-    public void testMoveDependentInContainerWithRollback() {
-        moveDependentInContainer(ROLLBACK);
-    }
-
-    public void testMoveDependentInContainerWithPreStore() {
-        moveDependentInContainer(PRESTORE);
-    }
-
-    private void moveDependentInContainer(int action) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        DependentFieldsPC pc;
-        DependentFieldsPC depColl;
-        DependentFieldsPC depMap;
-        List list;
-        Map map;
-        while (true) {
-            startTx(pm);
-            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
-            list = pc.getDependentList();
-            assertEquals(2, list.size());
-            depColl = (DependentFieldsPC) list.get(0);
-            assertEquals(_depColl, pm.getObjectId(depColl));
-            list.remove(0);
-            list.add(depColl);
-
-            map = pc.getDependentMap();
-            assertEquals(2, map.size());
-            depMap = (DependentFieldsPC) map.get("key");
-            assertEquals(_depMap, pm.getObjectId(depMap));
-            map.remove("key");
-            map.put("newkey", depMap);
-
-            if (action == ROLLBACK) {
-                rollbackTx(pm);
-                action = COMMIT;
-            } else if (action == COMMIT) {
-                endTx(pm);
-                break;
-            } else {
-                pm.preFlush();
-                break;
-            }
-        }
-
-        if (action == PRESTORE) {
-            assertFalse(pm.isRemoved(depColl));
-            assertFalse(pm.isRemoved(depMap));
-            endTx(pm);
-        }
-
-        assertTrue(pm.isPersistent(depColl));
-        assertNotNull(pm.find(DependentFieldsPC.class, _depColl));
-        assertTrue(pm.isPersistent(depMap));
-        assertNotNull(pm.find(DependentFieldsPC.class, _depMap));
-        assertNotNull(pm.find(DependentFieldsPC.class, _repeat));
-        endEm(pm);
-    }
-
-    public void testRefedDependentNotDeleted() {
-        refedDependentNotDeleted(COMMIT);
-    }
-
-    public void testRefedDependentNotDeletedWithRollback() {
-        refedDependentNotDeleted(ROLLBACK);
-    }
-
-    public void testRefedDependentNotDeletedWithPreStore() {
-        refedDependentNotDeleted(PRESTORE);
-    }
-
-    private void refedDependentNotDeleted(int action) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        DependentFieldsPC pc;
-        DependentFieldsPC newPC = null;
-        DependentFieldsPC depRel;
-        while (true) {
-            startTx(pm);
-            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
-            if (newPC == null)
-                newPC = new DependentFieldsPC();
-            depRel = pc.getDependentRelation();
-            newPC.setDependentRelation(depRel);
-            pc.setDependentRelation(null);
-            pm.persist(newPC);
-
-            if (action == ROLLBACK) {
-                rollbackTx(pm);
-                action = COMMIT;
-            } else if (action == COMMIT) {
-                endTx(pm);
-                break;
-            } else {
-                pm.preFlush();
-                break;
-            }
-        }
-
-        if (action == PRESTORE) {
-            assertFalse(pm.isRemoved(depRel));
-            endTx(pm);
-        }
-
-        assertTrue(pm.isPersistent(depRel));
-        assertNotNull(pm.find(DependentFieldsPC.class, _depRel));
-        endEm(pm);
-    }
-
-    public void testNullSharedDependent() {
-        nullSharedDependent(COMMIT);
-    }
-
-    public void testNullSharedDependentWithRollback() {
-        nullSharedDependent(ROLLBACK);
-    }
-
-    public void testNullSharedDependentWithPreStore() {
-        nullSharedDependent(PRESTORE);
-    }
-
-    private void nullSharedDependent(int action) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        DependentFieldsPC pc;
-        DependentFieldsPC repeat;
-        List list;
-        Map map;
-        while (true) {
-            startTx(pm);
-            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
-            list = pc.getDependentList();
-            assertEquals(2, list.size());
-            repeat = (DependentFieldsPC) list.get(1);
-            assertEquals(_repeat, pm.getObjectId(repeat));
-            list.remove(1);
-
-            map = pc.getDependentMap();
-            assertEquals(2, map.size());
-            assertEquals(repeat, (DependentFieldsPC) map.remove("repeat"));
-
-            if (action == PRESTORE)
-                pm.preFlush();
-            else
-                pm.flush();
-            assertTrue(pm.isRemoved(repeat));
-
-            // now after deleting on flush, assigning to another field and
-            // attempting to commit should throw an error -- can't undelete an
-            // object
-            pc.getList().add(repeat);
-
-            if (action == ROLLBACK) {
-                rollbackTx(pm);
-                action = COMMIT;
-            } else {
-                try {
-                    pm.getTransaction().commit();
-                    fail("Committed with ref to deleted dependent object");
-                } catch (Exception je) {
-                    rollbackTx(pm);
-                } finally {
-                }
-                break;
-            }
-        }
-
-        endEm(pm);
-    }
-
-    public void testClearMappedDependentOfDetached() {
-        clearDependentOfDetachedTest(true);
-    }
-
-    public void testClearInverseKeyDependentOfDetached() {
-        clearDependentOfDetachedTest(false);
-    }
-
-    private void clearDependentOfDetachedTest(boolean mapped) {
-        deleteAll(DependentFieldsPC.class);
-
-        DependentFieldsPC owner = new DependentFieldsPC();
-        for (int i = 0; i < 2; i++) {
-            DependentFieldsPC child = new DependentFieldsPC();
-            if (mapped) {
-                owner.getDependentMappedList().add(child);
-                child.setOwner(owner);
-            } else
-                owner.getDependentInverseKeyList().add(child);
-        }
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(owner);
-        endTx(pm);
-        Object oid = pm.getObjectId(owner);
-        assertEquals(3,
-            ((Extent) pm.createExtent(DependentFieldsPC.class, true))
-                .list().size());
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        owner = (DependentFieldsPC) pm.find(DependentFieldsPC.class, oid);
-        if (mapped)
-            assertEquals(2, owner.getDependentMappedList().size());
-        else
-            assertEquals(2, owner.getDependentInverseKeyList().size());
-        DependentFieldsPC detached = (DependentFieldsPC) pm.detach(owner);
-        endEm(pm);
-
-        if (mapped) {
-            assertEquals(2, detached.getDependentMappedList().size());
-            detached.getDependentMappedList().clear();
-        } else {
-            assertEquals(2, detached.getDependentInverseKeyList().size());
-            detached.getDependentInverseKeyList().clear();
-        }
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        owner = (DependentFieldsPC) pm.merge(detached);
-        if (mapped)
-            assertEquals(0, owner.getDependentMappedList().size());
-        else
-            assertEquals(0, owner.getDependentInverseKeyList().size());
-        endTx(pm);
-        assertEquals(1,
-            ((Extent) pm.createExtent(DependentFieldsPC.class, true)).
-                list().size());
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        owner = (DependentFieldsPC) pm.find(DependentFieldsPC.class, oid);
-        if (mapped)
-            assertEquals(0, owner.getDependentMappedList().size());
-        else
-            assertEquals(0, owner.getDependentInverseKeyList().size());
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.DependentFieldsPC;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+public class TestDependentFields2 extends BaseKernelTest {
+
+    private static final int COMMIT = 0;
+    private static final int ROLLBACK = 1;
+    private static final int PRESTORE = 2;
+
+    private Object _root = null;
+    private Object _rel = null;
+    private Object _depRel = null;
+    private Object _deep = null;
+    private Object _coll = null;
+    private Object _depColl = null;
+    private Object _map = null;
+    private Object _depMap = null;
+    private Object _repeat = null;
+
+    public TestDependentFields2(String casename) {
+        super(casename);
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(DependentFieldsPC.class);
+
+        DependentFieldsPC root = new DependentFieldsPC();
+        root.setRelation(new DependentFieldsPC());
+        root.getList().add(new DependentFieldsPC());
+        root.getMap().put("key", new DependentFieldsPC());
+        root.setDependentRelation(new DependentFieldsPC());
+        root.getDependentRelation().setDependentRelation
+            (new DependentFieldsPC());
+        root.getDependentList().add(new DependentFieldsPC());
+        root.getDependentMap().put("key", new DependentFieldsPC());
+
+        DependentFieldsPC repeat = new DependentFieldsPC();
+        root.getDependentList().add(repeat);
+        root.getDependentMap().put("repeat", repeat);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(root);
+        endTx(pm);
+
+        _root = pm.getObjectId(root);
+        assertNotNull(_root);
+        _rel = pm.getObjectId(root.getRelation());
+        _depRel = pm.getObjectId(root.getDependentRelation());
+        _deep = pm.getObjectId(root.getDependentRelation().
+            getDependentRelation());
+        _coll = pm.getObjectId(root.getList().iterator().next());
+        Iterator itr = root.getDependentList().iterator();
+        _depColl = pm.getObjectId(itr.next());
+        _repeat = pm.getObjectId(itr.next());
+        _map = pm.getObjectId(root.getMap().get("key"));
+        _depMap = pm.getObjectId(root.getDependentMap().get("key"));
+
+        endEm(pm);
+    }
+
+    public void testDependentFieldsLoaded() {
+        delete(true, COMMIT);
+        checkFields();
+    }
+
+    public void testDependentFieldsLoadedWithRollback() {
+        delete(true, ROLLBACK);
+        checkFields();
+    }
+
+    public void testDependentFieldsLoadedWithPreStore() {
+        delete(true, PRESTORE);
+        checkFields();
+    }
+
+    public void testDependentFieldsUnloaded() {
+        delete(false, COMMIT);
+        checkFields();
+    }
+
+    public void testDependentFieldsUnloadedWithRollback() {
+        delete(false, ROLLBACK);
+        checkFields();
+    }
+
+    public void testDependentFieldsUnloadedWithPreStore() {
+        delete(false, PRESTORE);
+        checkFields();
+    }
+
+    private void delete(boolean load, int action) {
+        OpenJPAEntityManager pm = getPM(true, true);
+        DependentFieldsPC root;
+        Object rel = null;
+        Object depRel = null;
+        Object coll = null;
+        Object depColl = null;
+        Object map = null;
+        Object depMap = null;
+        Object repeat = null;
+        Object deep = null;
+        while (true) {
+            startTx(pm);
+            root = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
+            if (load) {
+                rel = root.getRelation();
+                assertNotNull(rel);
+                depRel = root.getDependentRelation();
+                assertNotNull(depRel);
+                deep = ((DependentFieldsPC) depRel).getDependentRelation();
+                assertNotNull(deep);
+                coll = root.getList().iterator().next();
+                assertNotNull(coll);
+                Iterator itr = root.getDependentList().iterator();
+                depColl = itr.next();
+                repeat = itr.next();
+                assertNotNull(depColl);
+                assertNotNull(repeat);
+                map = root.getMap().get("key");
+                assertNotNull(map);
+                depMap = root.getDependentMap().get("key");
+                assertNotNull(depMap);
+
+                // pcl: test both depColl and repeat, since they might
+                // have been out of order above.
+                Object o = root.getDependentMap().get("repeat");
+                if (o != repeat)
+                    fail("dependent map does not contain 'repeat'");
+            }
+            pm.remove(root);
+
+            if (action == ROLLBACK) {
+                rollbackTx(pm);
+                action = COMMIT;
+            } else if (action == COMMIT) {
+                endTx(pm);
+                break;
+            } else {
+                pm.preFlush();
+                break;
+            }
+        }
+
+        if (load) {
+            if (action == PRESTORE) {
+                assertFalse(pm.isRemoved(rel));
+                assertFalse(pm.isRemoved(coll));
+                assertFalse(pm.isRemoved(map));
+                assertTrue(pm.isRemoved(depRel));
+                assertTrue(pm.isRemoved(deep));
+                assertTrue(pm.isRemoved(depColl));
+                assertTrue(pm.isRemoved(depMap));
+                assertTrue(pm.isRemoved(repeat));
+            } else {
+                assertNotNull(OpenJPAPersistence.getEntityManager(rel));
+                assertNotNull(OpenJPAPersistence.getEntityManager(coll));
+                assertNotNull(OpenJPAPersistence.getEntityManager(map));
+                assertNull(OpenJPAPersistence.getEntityManager(depRel));
+                assertNull(OpenJPAPersistence.getEntityManager(deep));
+                assertNull(OpenJPAPersistence.getEntityManager(depColl));
+                assertNull(OpenJPAPersistence.getEntityManager(depMap));
+                assertNull(OpenJPAPersistence.getEntityManager(repeat));
+            }
+        }
+
+        if (action == PRESTORE)
+            endTx(pm);
+        endEm(pm);
+    }
+
+    private void checkFields() {
+        OpenJPAEntityManager pm = getPM(true, true);
+        assertNotNull(pm.find(DependentFieldsPC.class, _rel));
+        assertNotNull(pm.find(DependentFieldsPC.class, _coll));
+        assertNotNull(pm.find(DependentFieldsPC.class, _map));
+        assertNull(pm.find(DependentFieldsPC.class, _depRel));
+        assertNull(pm.find(DependentFieldsPC.class, _deep));
+        assertNull(pm.find(DependentFieldsPC.class, _depColl));
+        assertNull(pm.find(DependentFieldsPC.class, _depMap));
+
+        endEm(pm);
+    }
+
+    public void testNullDeletesDependent() {
+        nullDeletesDependent(COMMIT);
+    }
+
+    public void testNullDeletesDependentWithRollback() {
+        nullDeletesDependent(ROLLBACK);
+    }
+
+    public void testNullDeletesDependentWithPreStore() {
+        nullDeletesDependent(PRESTORE);
+    }
+
+    private void nullDeletesDependent(int action) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        DependentFieldsPC pc;
+        DependentFieldsPC depRel;
+        while (true) {
+            startTx(pm);
+            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
+            depRel = pc.getDependentRelation();
+            assertEquals(_depRel, pm.getObjectId(depRel));
+            pc.setDependentRelation(null);
+            if (action == ROLLBACK) {
+                rollbackTx(pm);
+                action = COMMIT;
+            } else if (action == COMMIT) {
+                endTx(pm);
+                break;
+            } else {
+                pm.preFlush();
+                break;
+            }
+        }
+
+        if (action == PRESTORE) {
+            assertTrue(pm.isRemoved(depRel));
+            endTx(pm);
+        }
+
+        assertTrue(!pm.isPersistent(depRel));
+        assertNull(pm.find(DependentFieldsPC.class, _depRel));
+        endEm(pm);
+    }
+
+    public void testRemoveDeletesDependent() {
+        removeDeletesDependent(COMMIT);
+    }
+
+    public void testRemoveDeletesDependentWithRollback() {
+        removeDeletesDependent(ROLLBACK);
+    }
+
+    public void testRemoveDeletesDependentWithPreStore() {
+        removeDeletesDependent(PRESTORE);
+    }
+
+    private void removeDeletesDependent(int action) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        DependentFieldsPC pc;
+        DependentFieldsPC depColl;
+        DependentFieldsPC depMap;
+        List list;
+        Map map;
+        while (true) {
+            startTx(pm);
+            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
+            list = pc.getDependentList();
+            assertEquals("list size =! 2", 2, list.size());
+            depColl = (DependentFieldsPC) list.remove(0);
+            assertEquals("_depColl is not pm.getObjectId(depColl)", _depColl,
+                pm.getObjectId(depColl));
+
+            map = pc.getDependentMap();
+            assertEquals("map size =! 2", 2, map.size());
+            depMap = (DependentFieldsPC) map.remove("key");
+            assertEquals("_depMap is not pm.getObjectId(depMap)", _depMap,
+                pm.getObjectId(depMap));
+
+            if (action == ROLLBACK) {
+                rollbackTx(pm);
+                action = COMMIT;
+            } else if (action == COMMIT) {
+                endTx(pm);
+                break;
+            } else {
+                pm.preFlush();
+                break;
+            }
+        }
+
+        if (action == PRESTORE) {
+            assertTrue(pm.isRemoved(depColl));
+            assertTrue(pm.isRemoved(depMap));
+            endTx(pm);
+        }
+
+//        assertTrue("depcoll is persistence", !pm.isPersistent(depColl));
+        assertNull(pm.find(DependentFieldsPC.class, _depColl));
+
+//        assertTrue("depMap is persistence", !pm.isPersistent(depMap));
+        assertNull(pm.find(DependentFieldsPC.class, _depMap));
+
+        assertNotNull("repeat is null",
+            pm.find(DependentFieldsPC.class, _repeat));
+        endEm(pm);
+    }
+
+    public void testMoveDependentInContainer() {
+        moveDependentInContainer(COMMIT);
+    }
+
+    public void testMoveDependentInContainerWithRollback() {
+        moveDependentInContainer(ROLLBACK);
+    }
+
+    public void testMoveDependentInContainerWithPreStore() {
+        moveDependentInContainer(PRESTORE);
+    }
+
+    private void moveDependentInContainer(int action) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        DependentFieldsPC pc;
+        DependentFieldsPC depColl;
+        DependentFieldsPC depMap;
+        List list;
+        Map map;
+        while (true) {
+            startTx(pm);
+            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
+            list = pc.getDependentList();
+            assertEquals(2, list.size());
+            depColl = (DependentFieldsPC) list.get(0);
+            assertEquals(_depColl, pm.getObjectId(depColl));
+            list.remove(0);
+            list.add(depColl);
+
+            map = pc.getDependentMap();
+            assertEquals(2, map.size());
+            depMap = (DependentFieldsPC) map.get("key");
+            assertEquals(_depMap, pm.getObjectId(depMap));
+            map.remove("key");
+            map.put("newkey", depMap);
+
+            if (action == ROLLBACK) {
+                rollbackTx(pm);
+                action = COMMIT;
+            } else if (action == COMMIT) {
+                endTx(pm);
+                break;
+            } else {
+                pm.preFlush();
+                break;
+            }
+        }
+
+        if (action == PRESTORE) {
+            assertFalse(pm.isRemoved(depColl));
+            assertFalse(pm.isRemoved(depMap));
+            endTx(pm);
+        }
+
+        assertTrue(pm.isPersistent(depColl));
+        assertNotNull(pm.find(DependentFieldsPC.class, _depColl));
+        assertTrue(pm.isPersistent(depMap));
+        assertNotNull(pm.find(DependentFieldsPC.class, _depMap));
+        assertNotNull(pm.find(DependentFieldsPC.class, _repeat));
+        endEm(pm);
+    }
+
+    public void testRefedDependentNotDeleted() {
+        refedDependentNotDeleted(COMMIT);
+    }
+
+    public void testRefedDependentNotDeletedWithRollback() {
+        refedDependentNotDeleted(ROLLBACK);
+    }
+
+    public void testRefedDependentNotDeletedWithPreStore() {
+        refedDependentNotDeleted(PRESTORE);
+    }
+
+    private void refedDependentNotDeleted(int action) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        DependentFieldsPC pc;
+        DependentFieldsPC newPC = null;
+        DependentFieldsPC depRel;
+        while (true) {
+            startTx(pm);
+            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
+            if (newPC == null)
+                newPC = new DependentFieldsPC();
+            depRel = pc.getDependentRelation();
+            newPC.setDependentRelation(depRel);
+            pc.setDependentRelation(null);
+            pm.persist(newPC);
+
+            if (action == ROLLBACK) {
+                rollbackTx(pm);
+                action = COMMIT;
+            } else if (action == COMMIT) {
+                endTx(pm);
+                break;
+            } else {
+                pm.preFlush();
+                break;
+            }
+        }
+
+        if (action == PRESTORE) {
+            assertFalse(pm.isRemoved(depRel));
+            endTx(pm);
+        }
+
+        assertTrue(pm.isPersistent(depRel));
+        assertNotNull(pm.find(DependentFieldsPC.class, _depRel));
+        endEm(pm);
+    }
+
+    public void testNullSharedDependent() {
+        nullSharedDependent(COMMIT);
+    }
+
+    public void testNullSharedDependentWithRollback() {
+        nullSharedDependent(ROLLBACK);
+    }
+
+    public void testNullSharedDependentWithPreStore() {
+        nullSharedDependent(PRESTORE);
+    }
+
+    private void nullSharedDependent(int action) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        DependentFieldsPC pc;
+        DependentFieldsPC repeat;
+        List list;
+        Map map;
+        while (true) {
+            startTx(pm);
+            pc = (DependentFieldsPC) pm.find(DependentFieldsPC.class, _root);
+            list = pc.getDependentList();
+            assertEquals(2, list.size());
+            repeat = (DependentFieldsPC) list.get(1);
+            assertEquals(_repeat, pm.getObjectId(repeat));
+            list.remove(1);
+
+            map = pc.getDependentMap();
+            assertEquals(2, map.size());
+            assertEquals(repeat, (DependentFieldsPC) map.remove("repeat"));
+
+            if (action == PRESTORE)
+                pm.preFlush();
+            else
+                pm.flush();
+            assertTrue(pm.isRemoved(repeat));
+
+            // now after deleting on flush, assigning to another field and
+            // attempting to commit should throw an error -- can't undelete an
+            // object
+            pc.getList().add(repeat);
+
+            if (action == ROLLBACK) {
+                rollbackTx(pm);
+                action = COMMIT;
+            } else {
+                try {
+                    pm.getTransaction().commit();
+                    fail("Committed with ref to deleted dependent object");
+                } catch (Exception je) {
+                    rollbackTx(pm);
+                } finally {
+                }
+                break;
+            }
+        }
+
+        endEm(pm);
+    }
+
+    public void testClearMappedDependentOfDetached() {
+        clearDependentOfDetachedTest(true);
+    }
+
+    public void testClearInverseKeyDependentOfDetached() {
+        clearDependentOfDetachedTest(false);
+    }
+
+    private void clearDependentOfDetachedTest(boolean mapped) {
+        deleteAll(DependentFieldsPC.class);
+
+        DependentFieldsPC owner = new DependentFieldsPC();
+        for (int i = 0; i < 2; i++) {
+            DependentFieldsPC child = new DependentFieldsPC();
+            if (mapped) {
+                owner.getDependentMappedList().add(child);
+                child.setOwner(owner);
+            } else
+                owner.getDependentInverseKeyList().add(child);
+        }
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(owner);
+        endTx(pm);
+        Object oid = pm.getObjectId(owner);
+        assertEquals(3,
+            ((Extent) pm.createExtent(DependentFieldsPC.class, true))
+                .list().size());
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        owner = (DependentFieldsPC) pm.find(DependentFieldsPC.class, oid);
+        if (mapped)
+            assertEquals(2, owner.getDependentMappedList().size());
+        else
+            assertEquals(2, owner.getDependentInverseKeyList().size());
+        DependentFieldsPC detached = (DependentFieldsPC) pm.detach(owner);
+        endEm(pm);
+
+        if (mapped) {
+            assertEquals(2, detached.getDependentMappedList().size());
+            detached.getDependentMappedList().clear();
+        } else {
+            assertEquals(2, detached.getDependentInverseKeyList().size());
+            detached.getDependentInverseKeyList().clear();
+        }
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        owner = (DependentFieldsPC) pm.merge(detached);
+        if (mapped)
+            assertEquals(0, owner.getDependentMappedList().size());
+        else
+            assertEquals(0, owner.getDependentInverseKeyList().size());
+        endTx(pm);
+        assertEquals(1,
+            ((Extent) pm.createExtent(DependentFieldsPC.class, true)).
+                list().size());
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        owner = (DependentFieldsPC) pm.find(DependentFieldsPC.class, oid);
+        if (mapped)
+            assertEquals(0, owner.getDependentMappedList().size());
+        else
+            assertEquals(0, owner.getDependentInverseKeyList().size());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDetachedStateManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDetachedStateManager.java
index 5a1f903..230afe3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDetachedStateManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDetachedStateManager.java
@@ -1,542 +1,542 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TreeMap;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AttachA;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachB;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachD;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachE;
-import org.apache.openjpa.persistence.kernel.common.apps.DetachSMPC;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.enhance.PCEnhancer;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.kernel.DetachedStateManager;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.persistence.DetachStateType;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestDetachedStateManager extends BaseKernelTest {
-
-    private static boolean enhanced = false;
-
-    private int oid;
-    private int doid;
-
-    /**
-     * Creates a new instance of TestDetachedStateManager
-     */
-    public TestDetachedStateManager(String name) {
-        super(name);
-    }
-
-    private void deleteAll() {
-        deleteAll(AttachA.class);
-        deleteAll(AttachD.class);
-    }
-
-    public OpenJPAEntityManager getPM() {
-        OpenJPAEntityManager pm = super.getPM();
-        //FIXME jthomas
-        //pm.currentTransaction().setRestoreValues(false);
-        return pm;
-    }
-
-    public void setUp() throws Exception {
-        super.setUp();
-
-        deleteAll();
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        AttachB b = new AttachB();
-        pm.persist(b);
-        b.setAint(5);
-        b.setBstr("5");
-        b.getStringIntMap().put("5", new Integer(5));
-
-        AttachE e = new AttachE();
-        e.setEstr("E");
-        e.setEint(5);
-
-        AttachD d = new AttachD();
-        d.setDint(5);
-        d.setEmbeddedE(e);
-        b.getDs().add(d);
-
-        pm.persist(d);
-
-        oid = b.getId();
-        doid = d.getId();
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testDetach() {
-        OpenJPAEntityManager pm = getPM();
-        AttachB b = pm.find(AttachB.class, oid);
-
-        assertNotNull("b is null in testDetach", b);
-
-        b = (AttachB) pm.detach(b);
-        endEm(pm);
-
-        assertTrue(pm.isDetached(b));
-        assertEquals(5, b.getAint());
-        assertEquals("5", b.getBstr());
-        assertNull(b.getStringIntMap());
-
-        b.setAint(12);
-        b.setBstr("12");
-        TreeMap map = new TreeMap();
-        map.put("12", new Integer(12));
-        b.setStringIntMap(map);
-
-        pm = getPM();
-        startTx(pm);
-        AttachB attached = (AttachB) pm.merge(b);
-        assertEquals(12, attached.getAint());
-        assertEquals("12", attached.getBstr());
-        assertNull(attached.getStringIntMap().get("12"));
-        assertEquals(new Integer(5), attached.getStringIntMap().get("5"));
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        b = pm.find(AttachB.class, oid);
-        assertEquals(12, b.getAint());
-        assertEquals("12", b.getBstr());
-        assertNull(b.getStringIntMap().get("12"));
-        assertEquals(new Integer(5), b.getStringIntMap().get("5"));
-        endEm(pm);
-    }
-
-    public void testDetachWithGroups() {
-        OpenJPAEntityManager pm = getPM();
-        //FIXME jthomas
-//        pm.getFetchPlan().setDetachmentOptions(FetchPlanImpl.DETACH_LOAD_FIELDS | FetchPlanImpl.DETACH_UNLOAD_FIELDS);
-        pm.setDetachState(DetachStateType.FETCH_GROUPS);
-        pm.getFetchPlan().addFetchGroup("all");
-        AttachB b = pm.find(AttachB.class, oid);
-
-        assertNotNull("b is null in testDetachWithGroups", b);
-
-        b = (AttachB) pm.detach(b);
-        endEm(pm);
-
-        assertTrue(pm.isDetached(b));
-        assertEquals("b.getAint() not 5", 5, b.getAint());
-        assertEquals("b.getAint() not 5str", "5", b.getBstr());
-        assertEquals("b.getStringIntMap().size() not equal to 1", 1,
-            b.getStringIntMap().size());
-
-        b.setAint(12);
-        b.setBstr("12");
-        b.getStringIntMap().put("12", new Integer(12));
-
-        pm = getPM();
-        startTx(pm);
-        AttachB attached = (AttachB) pm.merge(b);
-        assertEquals("not 12", 12, attached.getAint());
-        assertEquals("not 12str", "12", attached.getBstr());
-        assertEquals("not newInteger(12)", new Integer(12),
-            attached.getStringIntMap().get("12"));
-        assertEquals("not newInteger(5)", new Integer(5),
-            attached.getStringIntMap().get("5"));
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        b = (AttachB) pm.find(AttachB.class, oid);
-        assertEquals("not equal 12", 12, b.getAint());
-        assertEquals("not equal 12str", "12", b.getBstr());
-        assertEquals("not equal newinteger(12)", new Integer(12),
-            b.getStringIntMap().get("12"));
-        assertEquals("not equal newInteger(5)", new Integer(5),
-            b.getStringIntMap().get("5"));
-        endEm(pm);
-    }
-
-    public void testDetachNoOverwrite() {
-        OpenJPAEntityManager pm = getPM();
-        AttachB b = (AttachB) pm.find(AttachB.class, oid);
-        b = (AttachB) pm.detach(b);
-        endEm(pm);
-
-        b.setBstr("12");
-
-        pm = getPM();
-        startTx(pm);
-        AttachB orig = pm.find(AttachB.class, oid);
-        orig.setAint(50);
-
-        AttachB attached = (AttachB) pm.merge(b);
-        assertEquals(attached, orig);
-        assertEquals(50, attached.getAint());
-        assertEquals("12", attached.getBstr());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        b = (AttachB) pm.find(AttachB.class, oid);
-        assertEquals(50, b.getAint());
-        assertEquals("12", b.getBstr());
-        endEm(pm);
-    }
-
-    public void testOptimisticLock() {
-        OpenJPAEntityManager pm = getPM();
-        AttachB b = (AttachB) pm.find(AttachB.class, oid);
-
-        assertNotNull("b is null in testOptimisticLock", b);
-
-        b = (AttachB) pm.detach(b);
-        endEm(pm);
-
-        b.setAint(12);
-        b.setBstr("12");
-        TreeMap map = new TreeMap();
-        map.put("12", new Integer(12));
-        b.setStringIntMap(map);
-
-        pm = getPM();
-        startTx(pm);
-        AttachB b2 = (AttachB) pm.find(AttachB.class, oid);
-        b2.setAint(15);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        startTx(pm);
-        try {
-            pm.merge(b);
-            endTx(pm);
-            fail("OL expected.");
-        } catch (Exception jove) {
-            rollbackTx(pm);
-        }
-        endEm(pm);
-    }
-
-    public void testEmbedded() {
-        OpenJPAEntityManager pm = getPM();
-        AttachD d = pm.find(AttachD.class, doid);
-
-        assertNotNull("d is null in testEmbedded", d);
-
-        d.getEmbeddedE().getEstr();
-        d = (AttachD) pm.detach(d);
-        endEm(pm);
-
-        d.getEmbeddedE().setEstr("E12");
-        pm = getPM();
-        startTx(pm);
-        AttachD d2 = (AttachD) pm.merge(d);
-        assertNotEquals(d.getEmbeddedE(), d2.getEmbeddedE());
-        assertEquals("E12", d2.getEmbeddedE().getEstr());
-        assertEquals(5, d2.getEmbeddedE().getEint());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        d2 = (AttachD) pm.find(AttachD.class, doid);
-
-        assertNotNull("d2 is null in testEmbedded", d2);
-
-        assertEquals("E12", d2.getEmbeddedE().getEstr());
-        assertEquals(5, d2.getEmbeddedE().getEint());
-        endEm(pm);
-    }
-
-    public void testNullEmbedded() {
-        OpenJPAEntityManager pm = getPM();
-        AttachD d = (AttachD) pm.find(AttachD.class, doid);
-
-        assertNotNull("d is null in testNullEmbedded", d);
-        d.getEmbeddedE().getEstr();
-        d = (AttachD) pm.detach(d);
-        endEm(pm);
-
-        d.setEmbeddedE(null);
-        pm = getPM();
-        startTx(pm);
-        AttachD d2 = (AttachD) pm.merge(d);
-        assertNull(d2.getEmbeddedE());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        d2 = (AttachD) pm.find(AttachD.class, doid);
-
-        assertNotNull("d2 is null in testNullEmbedded", d2);
-        // no null ind
-        if (d2.getEmbeddedE() != null) {
-            assertNull(d2.getEmbeddedE().getEstr());
-            assertEquals(0, d2.getEmbeddedE().getEint());
-        }
-        endEm(pm);
-    }
-
-    public void testNullEmbeddedRelated() {
-        OpenJPAEntityManager pm = getPM();
-        AttachD d = (AttachD) pm.find(AttachD.class, doid);
-
-        assertNotNull("d is null in testNullEmbeddedRelated", d);
-
-        d.getEmbeddedE().getEstr();
-        d = (AttachD) pm.detach(d);
-        endEm(pm);
-
-        d.getEmbeddedE().setEstr(null);
-        pm = getPM();
-        startTx(pm);
-        AttachD d2 = (AttachD) pm.merge(d);
-        assertNull("d2.getEmbeddedE().getEstr() is not null",
-            d2.getEmbeddedE().getEstr());
-        assertEquals("d2.getEmbeddedE().getEint() is not equal to 5", 5,
-            d2.getEmbeddedE().getEint());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        d2 = (AttachD) pm.find(AttachD.class, doid);
-        assertNull("d2.getEmbeddedE().getEstr() is not null",
-            d2.getEmbeddedE().getEstr());
-        assertEquals("d2.getEmbeddedE().getEint() is not 5", 5,
-            d2.getEmbeddedE().getEint());
-        endEm(pm);
-    }
-
-    public void testNullCollection() {
-        OpenJPAEntityManager pm = getPM();
-        AttachB b = (AttachB) pm.find(AttachB.class, oid);
-        b.getDs();
-        b = (AttachB) pm.detach(b);
-        endEm(pm);
-
-        assertEquals(1, b.getDs().size());
-        b.setDs(null);
-
-        pm = getPM();
-        startTx(pm);
-        b = (AttachB) pm.merge(b);
-        assertNull(b.getDs());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        b = (AttachB) pm.find(AttachB.class, oid);
-        assertTrue(b.getDs() == null || b.getDs().size() == 0);
-        endEm(pm);
-    }
-
-    public void testCollectionAdd() {
-        doCollectionTest(false);
-    }
-
-    public void testCollectionChanges() {
-        doCollectionTest(true);
-    }
-
-    private void doCollectionTest(boolean remove) {
-        OpenJPAEntityManager pm = getPM();
-        AttachB b = (AttachB) pm.find(AttachB.class, oid);
-
-        assertNotNull("b is null in doCollectionTest", b);
-        b.getDs();
-        b = (AttachB) pm.detach(b);
-        endEm(pm);
-
-        assertEquals("b is null in doCollectionTest", 1, b.getDs().size());
-        if (remove) {
-            for (Iterator it = b.getDs().iterator(); it.hasNext();) {
-                it.next();
-                it.remove();
-            }
-        }
-        AttachD d = new AttachD();
-        d.setDint(12);
-        b.getDs().add(d);
-
-        pm = getPM();
-        startTx(pm);
-        b = (AttachB) pm.merge(b);
-        assertSize(remove ? 1 : 2, b.getDs());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        b = (AttachB) pm.find(AttachB.class, oid);
-        assertSize(remove ? 1 : 2, b.getDs());
-        boolean found1 = false;
-        boolean found2 = false;
-        for (Iterator it = b.getDs().iterator(); it.hasNext();) {
-            d = (AttachD) it.next();
-            switch (d.getDint()) {
-                case 5:
-                    if (found1)
-                        fail("Refound.");
-                    found1 = true;
-                    break;
-                case 12:
-                    if (found2)
-                        fail("Refound.");
-                    found2 = true;
-                    break;
-                default:
-                    fail("Unknown d:" + d.getDint());
-            }
-        }
-
-        if (remove)
-            assertFalse(found1);
-
-        endEm(pm);
-    }
-
-    /*
-   //###
-   // No time to get these working right now.  Have to figure out how to
-   // enhance certain classes with different DetachState settings in autobuild.
-   public void testSerialization ()
-       throws Exception
-   {
-       doSerializationTest (false);
-   }
-
-
-   public void testSerializationAuto ()
-       throws Exception
-   {
-       doSerializationTest (true);
-   }
-    */
-
-    private void doSerializationTest(boolean auto) throws Exception {
-        enhance();
-        Map props = new HashMap();
-        props.put("openjpa.DetachState", "DetachedStateField=true");
-
-        OpenJPAEntityManagerFactory factory =
-            (OpenJPAEntityManagerFactory) getEmf(props);
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) factory.createEntityManager();
-
-        startTx(pm);
-        DetachSMPC pc = new DetachSMPC();
-        pc.setIntField(1);
-        DetachSMPC rel = new DetachSMPC();
-        rel.setIntField(2);
-        pc.getRelSet().add(rel);
-        pc.getStringIntMap().put("a", new Integer(99));
-        pm.persist(pc);
-        endTx(pm);
-        Object pcoid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) factory.createEntityManager();
-        pc = (DetachSMPC) pm.find(DetachSMPC.class, pcoid);
-        pc.getRelSet();
-        pc.getStringIntMap();
-        if (!auto) {
-            pc = (DetachSMPC) pm.detach(pc);
-            assertDetachedSM(pc);
-        }
-        pc = (DetachSMPC) roundtrip(pc, false);
-        assertDetachedSM(pc);
-        endEm(pm);
-
-        assertDetachedSM(pc);
-        assertSize(1, pc.getRelSet());
-        assertEquals(1, pc.getStringIntMap().size());
-
-        pc.setIntField(3);
-        ((DetachSMPC) pc.getRelSet().iterator().next()).setIntField(4);
-        pc.getStringIntMap().put("b", new Integer(100));
-
-        pc = (DetachSMPC) roundtrip(pc, false);
-
-        assertDetachedSM(pc);
-        assertEquals(3, pc.getIntField());
-        assertSize(1, pc.getRelSet());
-        //assertDetachedSM (b.getDs ().iterator ().next ());
-        assertEquals(4, ((DetachSMPC) pc.getRelSet().iterator().next())
-            .getIntField());
-        assertEquals(new Integer(100), pc.getStringIntMap().get("b"));
-
-        pm = (OpenJPAEntityManager) factory.createEntityManager();
-        startTx(pm);
-        pc = (DetachSMPC) pm.merge(pc);
-        assertEquals(3, pc.getIntField());
-        assertSize(1, pc.getRelSet());
-        assertEquals(4, ((DetachSMPC) pc.getRelSet().iterator().next())
-            .getIntField());
-        assertEquals(2, pc.getStringIntMap().size());
-        assertEquals(new Integer(100), pc.getStringIntMap().get("b"));
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) factory.createEntityManager();
-        pc = (DetachSMPC) pm.find(DetachSMPC.class, pcoid);
-        assertEquals(3, pc.getIntField());
-        assertSize(1, pc.getRelSet());
-        assertEquals(4, ((DetachSMPC) pc.getRelSet().iterator().next())
-            .getIntField());
-        assertEquals(2, pc.getStringIntMap().size());
-        assertEquals(new Integer(100), pc.getStringIntMap().get("b"));
-
-        startTx(pm);
-        deleteAll(DetachSMPC.class, pm);
-        endTx(pm);
-        endEm(pm);
-        factory.close();
-    }
-
-    private void enhance() throws Exception {
-        Properties props = getProperties(new String[]{
-            "openjpa.DetachState", "DetachedStateField=true",
-        });
-        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl(true, false);
-        conf.fromProperties(props);
-
-        Options opts = new Options();
-        opts.put("jdo", "true");
-        PCEnhancer.run(conf, new String[]{
-            "org.apache.openjpa.persistence.kernel.noenhance.DetachSMPC" }, opts);
-    }
-
-    private void assertDetachedSM(Object obj) {
-        OpenJPAEntityManager pm = getPM();
-        assertTrue(pm.isDetached(obj));
-        PersistenceCapable pc = (PersistenceCapable) obj;
-        assertEquals(DetachedStateManager.class,
-            pc.pcGetStateManager().getClass());
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AttachA;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachB;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachD;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachE;
+import org.apache.openjpa.persistence.kernel.common.apps.DetachSMPC;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.enhance.PCEnhancer;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.DetachedStateManager;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.persistence.DetachStateType;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestDetachedStateManager extends BaseKernelTest {
+
+    private static boolean enhanced = false;
+
+    private int oid;
+    private int doid;
+
+    /**
+     * Creates a new instance of TestDetachedStateManager
+     */
+    public TestDetachedStateManager(String name) {
+        super(name);
+    }
+
+    private void deleteAll() {
+        deleteAll(AttachA.class);
+        deleteAll(AttachD.class);
+    }
+
+    public OpenJPAEntityManager getPM() {
+        OpenJPAEntityManager pm = super.getPM();
+        //FIXME jthomas
+        //pm.currentTransaction().setRestoreValues(false);
+        return pm;
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+
+        deleteAll();
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        AttachB b = new AttachB();
+        pm.persist(b);
+        b.setAint(5);
+        b.setBstr("5");
+        b.getStringIntMap().put("5", new Integer(5));
+
+        AttachE e = new AttachE();
+        e.setEstr("E");
+        e.setEint(5);
+
+        AttachD d = new AttachD();
+        d.setDint(5);
+        d.setEmbeddedE(e);
+        b.getDs().add(d);
+
+        pm.persist(d);
+
+        oid = b.getId();
+        doid = d.getId();
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testDetach() {
+        OpenJPAEntityManager pm = getPM();
+        AttachB b = pm.find(AttachB.class, oid);
+
+        assertNotNull("b is null in testDetach", b);
+
+        b = (AttachB) pm.detach(b);
+        endEm(pm);
+
+        assertTrue(pm.isDetached(b));
+        assertEquals(5, b.getAint());
+        assertEquals("5", b.getBstr());
+        assertNull(b.getStringIntMap());
+
+        b.setAint(12);
+        b.setBstr("12");
+        TreeMap map = new TreeMap();
+        map.put("12", new Integer(12));
+        b.setStringIntMap(map);
+
+        pm = getPM();
+        startTx(pm);
+        AttachB attached = (AttachB) pm.merge(b);
+        assertEquals(12, attached.getAint());
+        assertEquals("12", attached.getBstr());
+        assertNull(attached.getStringIntMap().get("12"));
+        assertEquals(new Integer(5), attached.getStringIntMap().get("5"));
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        b = pm.find(AttachB.class, oid);
+        assertEquals(12, b.getAint());
+        assertEquals("12", b.getBstr());
+        assertNull(b.getStringIntMap().get("12"));
+        assertEquals(new Integer(5), b.getStringIntMap().get("5"));
+        endEm(pm);
+    }
+
+    public void testDetachWithGroups() {
+        OpenJPAEntityManager pm = getPM();
+        //FIXME jthomas
+//        pm.getFetchPlan().setDetachmentOptions(FetchPlanImpl.DETACH_LOAD_FIELDS | FetchPlanImpl.DETACH_UNLOAD_FIELDS);
+        pm.setDetachState(DetachStateType.FETCH_GROUPS);
+        pm.getFetchPlan().addFetchGroup("all");
+        AttachB b = pm.find(AttachB.class, oid);
+
+        assertNotNull("b is null in testDetachWithGroups", b);
+
+        b = (AttachB) pm.detach(b);
+        endEm(pm);
+
+        assertTrue(pm.isDetached(b));
+        assertEquals("b.getAint() not 5", 5, b.getAint());
+        assertEquals("b.getAint() not 5str", "5", b.getBstr());
+        assertEquals("b.getStringIntMap().size() not equal to 1", 1,
+            b.getStringIntMap().size());
+
+        b.setAint(12);
+        b.setBstr("12");
+        b.getStringIntMap().put("12", new Integer(12));
+
+        pm = getPM();
+        startTx(pm);
+        AttachB attached = (AttachB) pm.merge(b);
+        assertEquals("not 12", 12, attached.getAint());
+        assertEquals("not 12str", "12", attached.getBstr());
+        assertEquals("not newInteger(12)", new Integer(12),
+            attached.getStringIntMap().get("12"));
+        assertEquals("not newInteger(5)", new Integer(5),
+            attached.getStringIntMap().get("5"));
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        b = (AttachB) pm.find(AttachB.class, oid);
+        assertEquals("not equal 12", 12, b.getAint());
+        assertEquals("not equal 12str", "12", b.getBstr());
+        assertEquals("not equal newinteger(12)", new Integer(12),
+            b.getStringIntMap().get("12"));
+        assertEquals("not equal newInteger(5)", new Integer(5),
+            b.getStringIntMap().get("5"));
+        endEm(pm);
+    }
+
+    public void testDetachNoOverwrite() {
+        OpenJPAEntityManager pm = getPM();
+        AttachB b = (AttachB) pm.find(AttachB.class, oid);
+        b = (AttachB) pm.detach(b);
+        endEm(pm);
+
+        b.setBstr("12");
+
+        pm = getPM();
+        startTx(pm);
+        AttachB orig = pm.find(AttachB.class, oid);
+        orig.setAint(50);
+
+        AttachB attached = (AttachB) pm.merge(b);
+        assertEquals(attached, orig);
+        assertEquals(50, attached.getAint());
+        assertEquals("12", attached.getBstr());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        b = (AttachB) pm.find(AttachB.class, oid);
+        assertEquals(50, b.getAint());
+        assertEquals("12", b.getBstr());
+        endEm(pm);
+    }
+
+    public void testOptimisticLock() {
+        OpenJPAEntityManager pm = getPM();
+        AttachB b = (AttachB) pm.find(AttachB.class, oid);
+
+        assertNotNull("b is null in testOptimisticLock", b);
+
+        b = (AttachB) pm.detach(b);
+        endEm(pm);
+
+        b.setAint(12);
+        b.setBstr("12");
+        TreeMap map = new TreeMap();
+        map.put("12", new Integer(12));
+        b.setStringIntMap(map);
+
+        pm = getPM();
+        startTx(pm);
+        AttachB b2 = (AttachB) pm.find(AttachB.class, oid);
+        b2.setAint(15);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        startTx(pm);
+        try {
+            pm.merge(b);
+            endTx(pm);
+            fail("OL expected.");
+        } catch (Exception jove) {
+            rollbackTx(pm);
+        }
+        endEm(pm);
+    }
+
+    public void testEmbedded() {
+        OpenJPAEntityManager pm = getPM();
+        AttachD d = pm.find(AttachD.class, doid);
+
+        assertNotNull("d is null in testEmbedded", d);
+
+        d.getEmbeddedE().getEstr();
+        d = (AttachD) pm.detach(d);
+        endEm(pm);
+
+        d.getEmbeddedE().setEstr("E12");
+        pm = getPM();
+        startTx(pm);
+        AttachD d2 = (AttachD) pm.merge(d);
+        assertNotEquals(d.getEmbeddedE(), d2.getEmbeddedE());
+        assertEquals("E12", d2.getEmbeddedE().getEstr());
+        assertEquals(5, d2.getEmbeddedE().getEint());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        d2 = (AttachD) pm.find(AttachD.class, doid);
+
+        assertNotNull("d2 is null in testEmbedded", d2);
+
+        assertEquals("E12", d2.getEmbeddedE().getEstr());
+        assertEquals(5, d2.getEmbeddedE().getEint());
+        endEm(pm);
+    }
+
+    public void testNullEmbedded() {
+        OpenJPAEntityManager pm = getPM();
+        AttachD d = (AttachD) pm.find(AttachD.class, doid);
+
+        assertNotNull("d is null in testNullEmbedded", d);
+        d.getEmbeddedE().getEstr();
+        d = (AttachD) pm.detach(d);
+        endEm(pm);
+
+        d.setEmbeddedE(null);
+        pm = getPM();
+        startTx(pm);
+        AttachD d2 = (AttachD) pm.merge(d);
+        assertNull(d2.getEmbeddedE());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        d2 = (AttachD) pm.find(AttachD.class, doid);
+
+        assertNotNull("d2 is null in testNullEmbedded", d2);
+        // no null ind
+        if (d2.getEmbeddedE() != null) {
+            assertNull(d2.getEmbeddedE().getEstr());
+            assertEquals(0, d2.getEmbeddedE().getEint());
+        }
+        endEm(pm);
+    }
+
+    public void testNullEmbeddedRelated() {
+        OpenJPAEntityManager pm = getPM();
+        AttachD d = (AttachD) pm.find(AttachD.class, doid);
+
+        assertNotNull("d is null in testNullEmbeddedRelated", d);
+
+        d.getEmbeddedE().getEstr();
+        d = (AttachD) pm.detach(d);
+        endEm(pm);
+
+        d.getEmbeddedE().setEstr(null);
+        pm = getPM();
+        startTx(pm);
+        AttachD d2 = (AttachD) pm.merge(d);
+        assertNull("d2.getEmbeddedE().getEstr() is not null",
+            d2.getEmbeddedE().getEstr());
+        assertEquals("d2.getEmbeddedE().getEint() is not equal to 5", 5,
+            d2.getEmbeddedE().getEint());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        d2 = (AttachD) pm.find(AttachD.class, doid);
+        assertNull("d2.getEmbeddedE().getEstr() is not null",
+            d2.getEmbeddedE().getEstr());
+        assertEquals("d2.getEmbeddedE().getEint() is not 5", 5,
+            d2.getEmbeddedE().getEint());
+        endEm(pm);
+    }
+
+    public void testNullCollection() {
+        OpenJPAEntityManager pm = getPM();
+        AttachB b = (AttachB) pm.find(AttachB.class, oid);
+        b.getDs();
+        b = (AttachB) pm.detach(b);
+        endEm(pm);
+
+        assertEquals(1, b.getDs().size());
+        b.setDs(null);
+
+        pm = getPM();
+        startTx(pm);
+        b = (AttachB) pm.merge(b);
+        assertNull(b.getDs());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        b = (AttachB) pm.find(AttachB.class, oid);
+        assertTrue(b.getDs() == null || b.getDs().size() == 0);
+        endEm(pm);
+    }
+
+    public void testCollectionAdd() {
+        doCollectionTest(false);
+    }
+
+    public void testCollectionChanges() {
+        doCollectionTest(true);
+    }
+
+    private void doCollectionTest(boolean remove) {
+        OpenJPAEntityManager pm = getPM();
+        AttachB b = (AttachB) pm.find(AttachB.class, oid);
+
+        assertNotNull("b is null in doCollectionTest", b);
+        b.getDs();
+        b = (AttachB) pm.detach(b);
+        endEm(pm);
+
+        assertEquals("b is null in doCollectionTest", 1, b.getDs().size());
+        if (remove) {
+            for (Iterator it = b.getDs().iterator(); it.hasNext();) {
+                it.next();
+                it.remove();
+            }
+        }
+        AttachD d = new AttachD();
+        d.setDint(12);
+        b.getDs().add(d);
+
+        pm = getPM();
+        startTx(pm);
+        b = (AttachB) pm.merge(b);
+        assertSize(remove ? 1 : 2, b.getDs());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        b = (AttachB) pm.find(AttachB.class, oid);
+        assertSize(remove ? 1 : 2, b.getDs());
+        boolean found1 = false;
+        boolean found2 = false;
+        for (Iterator it = b.getDs().iterator(); it.hasNext();) {
+            d = (AttachD) it.next();
+            switch (d.getDint()) {
+                case 5:
+                    if (found1)
+                        fail("Refound.");
+                    found1 = true;
+                    break;
+                case 12:
+                    if (found2)
+                        fail("Refound.");
+                    found2 = true;
+                    break;
+                default:
+                    fail("Unknown d:" + d.getDint());
+            }
+        }
+
+        if (remove)
+            assertFalse(found1);
+
+        endEm(pm);
+    }
+
+    /*
+   //###
+   // No time to get these working right now.  Have to figure out how to
+   // enhance certain classes with different DetachState settings in autobuild.
+   public void testSerialization ()
+       throws Exception
+   {
+       doSerializationTest (false);
+   }
+
+
+   public void testSerializationAuto ()
+       throws Exception
+   {
+       doSerializationTest (true);
+   }
+    */
+
+    private void doSerializationTest(boolean auto) throws Exception {
+        enhance();
+        Map props = new HashMap();
+        props.put("openjpa.DetachState", "DetachedStateField=true");
+
+        OpenJPAEntityManagerFactory factory =
+            (OpenJPAEntityManagerFactory) getEmf(props);
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) factory.createEntityManager();
+
+        startTx(pm);
+        DetachSMPC pc = new DetachSMPC();
+        pc.setIntField(1);
+        DetachSMPC rel = new DetachSMPC();
+        rel.setIntField(2);
+        pc.getRelSet().add(rel);
+        pc.getStringIntMap().put("a", new Integer(99));
+        pm.persist(pc);
+        endTx(pm);
+        Object pcoid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) factory.createEntityManager();
+        pc = (DetachSMPC) pm.find(DetachSMPC.class, pcoid);
+        pc.getRelSet();
+        pc.getStringIntMap();
+        if (!auto) {
+            pc = (DetachSMPC) pm.detach(pc);
+            assertDetachedSM(pc);
+        }
+        pc = (DetachSMPC) roundtrip(pc, false);
+        assertDetachedSM(pc);
+        endEm(pm);
+
+        assertDetachedSM(pc);
+        assertSize(1, pc.getRelSet());
+        assertEquals(1, pc.getStringIntMap().size());
+
+        pc.setIntField(3);
+        ((DetachSMPC) pc.getRelSet().iterator().next()).setIntField(4);
+        pc.getStringIntMap().put("b", new Integer(100));
+
+        pc = (DetachSMPC) roundtrip(pc, false);
+
+        assertDetachedSM(pc);
+        assertEquals(3, pc.getIntField());
+        assertSize(1, pc.getRelSet());
+        //assertDetachedSM (b.getDs ().iterator ().next ());
+        assertEquals(4, ((DetachSMPC) pc.getRelSet().iterator().next())
+            .getIntField());
+        assertEquals(new Integer(100), pc.getStringIntMap().get("b"));
+
+        pm = (OpenJPAEntityManager) factory.createEntityManager();
+        startTx(pm);
+        pc = (DetachSMPC) pm.merge(pc);
+        assertEquals(3, pc.getIntField());
+        assertSize(1, pc.getRelSet());
+        assertEquals(4, ((DetachSMPC) pc.getRelSet().iterator().next())
+            .getIntField());
+        assertEquals(2, pc.getStringIntMap().size());
+        assertEquals(new Integer(100), pc.getStringIntMap().get("b"));
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) factory.createEntityManager();
+        pc = (DetachSMPC) pm.find(DetachSMPC.class, pcoid);
+        assertEquals(3, pc.getIntField());
+        assertSize(1, pc.getRelSet());
+        assertEquals(4, ((DetachSMPC) pc.getRelSet().iterator().next())
+            .getIntField());
+        assertEquals(2, pc.getStringIntMap().size());
+        assertEquals(new Integer(100), pc.getStringIntMap().get("b"));
+
+        startTx(pm);
+        deleteAll(DetachSMPC.class, pm);
+        endTx(pm);
+        endEm(pm);
+        factory.close();
+    }
+
+    private void enhance() throws Exception {
+        Properties props = getProperties(new String[]{
+            "openjpa.DetachState", "DetachedStateField=true",
+        });
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl(true, false);
+        conf.fromProperties(props);
+
+        Options opts = new Options();
+        opts.put("jdo", "true");
+        PCEnhancer.run(conf, new String[]{
+            "org.apache.openjpa.persistence.kernel.noenhance.DetachSMPC" }, opts);
+    }
+
+    private void assertDetachedSM(Object obj) {
+        OpenJPAEntityManager pm = getPM();
+        assertTrue(pm.isDetached(obj));
+        PersistenceCapable pc = (PersistenceCapable) obj;
+        assertEquals(DetachedStateManager.class,
+            pc.pcGetStateManager().getClass());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEmbedded.java
index e6ef668..30b10a6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEmbedded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEmbedded.java
@@ -1,246 +1,246 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ComplexEmbeddedPC;
-import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedOwnerPC;
-import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedPC;
-
-public class TestEJBEmbedded extends BaseKernelTest {
-
-    private Object _oid1 = null;
-    private Object _oid2 = null;
-
-    EmbeddedOwnerPC.EmbKey id1;
-    EmbeddedOwnerPC.EmbKey id2;
-
-    public TestEJBEmbedded(String name) {
-        super(name);
-    }
-
-    @SuppressWarnings("unchecked")
-    public void setUp() {
-        deleteAll(EmbeddedOwnerPC.class);
-        deleteAll(EmbeddedPC.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        EmbeddedOwnerPC pc1 = new EmbeddedOwnerPC(1, 2);
-        pc1.setStringField("string1");
-        EmbeddedPC embed1 = new EmbeddedPC();
-        embed1.setStringField("embedString1");
-        embed1.setIntField(1);
-        pc1.setEmbedded(embed1);
-
-        EmbeddedPC embed2 = new EmbeddedPC();
-        embed2.setStringField("embedString2");
-        embed2.setIntField(2);
-
-        EmbeddedOwnerPC pc2 = new EmbeddedOwnerPC(3, 4);
-
-        em.persist(pc1);
-        em.persist(pc2);
-
-        endTx(em);
-
-        id1 = new EmbeddedOwnerPC.EmbKey("1:2");
-
-        id2 = new EmbeddedOwnerPC.EmbKey();
-        id2.id1 = 3;
-        id2.id2 = 4;
-
-        endEm(em);
-    }
-
-    public void testInsert() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-
-        EmbeddedOwnerPC pc = pm.find(EmbeddedOwnerPC.class, id1);
-        EmbeddedOwnerPC pc2 = pm.find(EmbeddedOwnerPC.class, id2);
-        assertNotNull("pc is null in testInsert", pc);
-        assertNotNull("p2 is null in testInsert", pc2);
-
-        assertEquals("string1", pc.getStringField());
-        assertNotNull(pc.getEmbedded());
-        assertEquals("embedString1", pc.getEmbedded().getStringField());
-        assertEquals(1, pc.getEmbedded().getIntField());
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testDelete() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        EmbeddedOwnerPC pc =
-            (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, id1);
-
-        assertNotNull("pc is null in testDelete", pc);
-
-        EmbeddedPC embed = pc.getEmbedded();
-
-        pc.setEmbedded(null);
-
-        endTx(pm);
-
-        endEm(pm);
-
-        pm = currentEntityManager();
-        startTx(pm);
-        pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, id1);
-
-        assertEquals("the expt strng is not string1", "string1",
-            pc.getStringField());
-        assertNull("pc's embedded is null", pc.getEmbedded());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testUpdateRetain() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        EmbeddedOwnerPC pc =
-            (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, id1);
-
-        assertNotNull("pc is null testUpdateRetain", pc);
-
-        pc.setStringField("string2");
-        pc.getEmbedded().setStringField("embedString2");
-
-        endTx(pm);
-
-        assertEquals("string2", pc.getStringField());
-        assertNotNull(pc.getEmbedded());
-        assertEquals("embedString2", pc.getEmbedded().getStringField());
-        assertEquals(1, pc.getEmbedded().getIntField());
-
-        endEm(pm);
-    }
-
-    public void testReplace() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-
-        EmbeddedOwnerPC pc = pm.find(EmbeddedOwnerPC.class, id1);
-
-        EmbeddedPC newEmbed = new EmbeddedPC();
-        newEmbed.setStringField("embedString2");
-        pc.setEmbedded(newEmbed);
-
-        ComplexEmbeddedPC newComplexEmbed = new ComplexEmbeddedPC();
-        newEmbed = new EmbeddedPC();
-        newEmbed.setStringField("embedString3");
-        newComplexEmbed.setStringField("complexEmbedString3");
-        newComplexEmbed.setOwnerField(new EmbeddedOwnerPC(5, 6));
-        pc.setComplexEmbedded(newComplexEmbed);
-
-        endTx(pm);
-        endEm(pm);
-
-        pm = currentEntityManager();
-        startTx(pm);
-
-        pc = pm.find(EmbeddedOwnerPC.class, id1);
-        assertEquals("string1", pc.getStringField());
-        assertNotNull(pc.getEmbedded());
-        assertEquals("the exp strng is not embedString1", "embedString1",
-            pc.getEmbedded().getStringField());
-        assertEquals("intfield is not 1", 1, pc.getEmbedded().getIntField());
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testShare() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-
-        EmbeddedOwnerPC pc1 = pm.find(EmbeddedOwnerPC.class, id1);
-        assertNotNull("pc1 is null in testshare", pc1);
-
-        EmbeddedOwnerPC pc2 = pm.find(EmbeddedOwnerPC.class, id2);
-        assertNotNull("pc2 is null in testshare", pc2);
-
-        EmbeddedPC embed1 = pc1.getEmbedded();
-
-        pm.persist(embed1);
-        Integer oid = new Integer(1);
-        endTx(pm);
-
-        assertEquals("embedString1", embed1.getStringField());
-        assertEquals("embedString1", pc1.getEmbedded().getStringField());
-
-        endEm(pm);
-
-        // make sure the changes stick
-        pm = currentEntityManager();
-        startTx(pm);
-        pc1 = pm.find(EmbeddedOwnerPC.class, id1);
-        assertNotNull("pc1 is null in testshare 2nd find", pc1);
-        pc2 = pm.find(EmbeddedOwnerPC.class, id2);
-        assertNotNull("pc2 is null in testshare 2nd find", pc2);
-        embed1 = pm.find(EmbeddedPC.class, oid.intValue());
-
-        if (embed1 != null) {
-            assertEquals("embedString1", embed1.getStringField());
-            assertEquals("embedString1", pc1.getEmbedded().getStringField());
-        }
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testOptimisticLocking2() {
-        EntityManager pm1 = getPM(true, false);
-        startTx(pm1);
-
-        EmbeddedOwnerPC pc1 = pm1.find(EmbeddedOwnerPC.class, id1);
-        assertNotNull("pc1 is null in testoptlock2", pc1);
-
-        EntityManager pm2 = currentEntityManager();
-
-        startTx(pm2);
-        EmbeddedOwnerPC pc2 = pm1.find(EmbeddedOwnerPC.class, id1);
-
-        assertNotNull("pc2 is null in testoptlock2", pc2);
-
-        EmbeddedPC embed2 = pc2.getEmbedded();
-        embed2.setStringField("xxxx");
-
-        endTx(pm2);
-        endEm(pm2);
-
-        EmbeddedPC embed1 = pc1.getEmbedded();
-        embed1.setStringField("yyyy");
-        try {
-            endTx(pm1);
-            fail("Should have thrown an OL exception.");
-        }
-        catch (Exception ove) {
-        }
-        finally {
-            endEm(pm1);
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ComplexEmbeddedPC;
+import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedOwnerPC;
+import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedPC;
+
+public class TestEJBEmbedded extends BaseKernelTest {
+
+    private Object _oid1 = null;
+    private Object _oid2 = null;
+
+    EmbeddedOwnerPC.EmbKey id1;
+    EmbeddedOwnerPC.EmbKey id2;
+
+    public TestEJBEmbedded(String name) {
+        super(name);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setUp() {
+        deleteAll(EmbeddedOwnerPC.class);
+        deleteAll(EmbeddedPC.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        EmbeddedOwnerPC pc1 = new EmbeddedOwnerPC(1, 2);
+        pc1.setStringField("string1");
+        EmbeddedPC embed1 = new EmbeddedPC();
+        embed1.setStringField("embedString1");
+        embed1.setIntField(1);
+        pc1.setEmbedded(embed1);
+
+        EmbeddedPC embed2 = new EmbeddedPC();
+        embed2.setStringField("embedString2");
+        embed2.setIntField(2);
+
+        EmbeddedOwnerPC pc2 = new EmbeddedOwnerPC(3, 4);
+
+        em.persist(pc1);
+        em.persist(pc2);
+
+        endTx(em);
+
+        id1 = new EmbeddedOwnerPC.EmbKey("1:2");
+
+        id2 = new EmbeddedOwnerPC.EmbKey();
+        id2.id1 = 3;
+        id2.id2 = 4;
+
+        endEm(em);
+    }
+
+    public void testInsert() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+
+        EmbeddedOwnerPC pc = pm.find(EmbeddedOwnerPC.class, id1);
+        EmbeddedOwnerPC pc2 = pm.find(EmbeddedOwnerPC.class, id2);
+        assertNotNull("pc is null in testInsert", pc);
+        assertNotNull("p2 is null in testInsert", pc2);
+
+        assertEquals("string1", pc.getStringField());
+        assertNotNull(pc.getEmbedded());
+        assertEquals("embedString1", pc.getEmbedded().getStringField());
+        assertEquals(1, pc.getEmbedded().getIntField());
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testDelete() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        EmbeddedOwnerPC pc =
+            (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, id1);
+
+        assertNotNull("pc is null in testDelete", pc);
+
+        EmbeddedPC embed = pc.getEmbedded();
+
+        pc.setEmbedded(null);
+
+        endTx(pm);
+
+        endEm(pm);
+
+        pm = currentEntityManager();
+        startTx(pm);
+        pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, id1);
+
+        assertEquals("the expt strng is not string1", "string1",
+            pc.getStringField());
+        assertNull("pc's embedded is null", pc.getEmbedded());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testUpdateRetain() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        EmbeddedOwnerPC pc =
+            (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, id1);
+
+        assertNotNull("pc is null testUpdateRetain", pc);
+
+        pc.setStringField("string2");
+        pc.getEmbedded().setStringField("embedString2");
+
+        endTx(pm);
+
+        assertEquals("string2", pc.getStringField());
+        assertNotNull(pc.getEmbedded());
+        assertEquals("embedString2", pc.getEmbedded().getStringField());
+        assertEquals(1, pc.getEmbedded().getIntField());
+
+        endEm(pm);
+    }
+
+    public void testReplace() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+
+        EmbeddedOwnerPC pc = pm.find(EmbeddedOwnerPC.class, id1);
+
+        EmbeddedPC newEmbed = new EmbeddedPC();
+        newEmbed.setStringField("embedString2");
+        pc.setEmbedded(newEmbed);
+
+        ComplexEmbeddedPC newComplexEmbed = new ComplexEmbeddedPC();
+        newEmbed = new EmbeddedPC();
+        newEmbed.setStringField("embedString3");
+        newComplexEmbed.setStringField("complexEmbedString3");
+        newComplexEmbed.setOwnerField(new EmbeddedOwnerPC(5, 6));
+        pc.setComplexEmbedded(newComplexEmbed);
+
+        endTx(pm);
+        endEm(pm);
+
+        pm = currentEntityManager();
+        startTx(pm);
+
+        pc = pm.find(EmbeddedOwnerPC.class, id1);
+        assertEquals("string1", pc.getStringField());
+        assertNotNull(pc.getEmbedded());
+        assertEquals("the exp strng is not embedString1", "embedString1",
+            pc.getEmbedded().getStringField());
+        assertEquals("intfield is not 1", 1, pc.getEmbedded().getIntField());
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testShare() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+
+        EmbeddedOwnerPC pc1 = pm.find(EmbeddedOwnerPC.class, id1);
+        assertNotNull("pc1 is null in testshare", pc1);
+
+        EmbeddedOwnerPC pc2 = pm.find(EmbeddedOwnerPC.class, id2);
+        assertNotNull("pc2 is null in testshare", pc2);
+
+        EmbeddedPC embed1 = pc1.getEmbedded();
+
+        pm.persist(embed1);
+        Integer oid = new Integer(1);
+        endTx(pm);
+
+        assertEquals("embedString1", embed1.getStringField());
+        assertEquals("embedString1", pc1.getEmbedded().getStringField());
+
+        endEm(pm);
+
+        // make sure the changes stick
+        pm = currentEntityManager();
+        startTx(pm);
+        pc1 = pm.find(EmbeddedOwnerPC.class, id1);
+        assertNotNull("pc1 is null in testshare 2nd find", pc1);
+        pc2 = pm.find(EmbeddedOwnerPC.class, id2);
+        assertNotNull("pc2 is null in testshare 2nd find", pc2);
+        embed1 = pm.find(EmbeddedPC.class, oid.intValue());
+
+        if (embed1 != null) {
+            assertEquals("embedString1", embed1.getStringField());
+            assertEquals("embedString1", pc1.getEmbedded().getStringField());
+        }
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testOptimisticLocking2() {
+        EntityManager pm1 = getPM(true, false);
+        startTx(pm1);
+
+        EmbeddedOwnerPC pc1 = pm1.find(EmbeddedOwnerPC.class, id1);
+        assertNotNull("pc1 is null in testoptlock2", pc1);
+
+        EntityManager pm2 = currentEntityManager();
+
+        startTx(pm2);
+        EmbeddedOwnerPC pc2 = pm1.find(EmbeddedOwnerPC.class, id1);
+
+        assertNotNull("pc2 is null in testoptlock2", pc2);
+
+        EmbeddedPC embed2 = pc2.getEmbedded();
+        embed2.setStringField("xxxx");
+
+        endTx(pm2);
+        endEm(pm2);
+
+        EmbeddedPC embed1 = pc1.getEmbedded();
+        embed1.setStringField("yyyy");
+        try {
+            endTx(pm1);
+            fail("Should have thrown an OL exception.");
+        }
+        catch (Exception ove) {
+        }
+        finally {
+            endEm(pm1);
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEntityManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEntityManager.java
index 1dd5cd5..e497d6a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEntityManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBEntityManager.java
@@ -1,142 +1,142 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBEntityManager extends AbstractTestCase {
-
-    private Object _id = null;
-
-    private Object _id2 = null;
-
-    public TestEJBEntityManager(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(RuntimeTest1.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 a = new RuntimeTest1("STRING", 10);
-        RuntimeTest2 b = new RuntimeTest2("STRING2", 11);
-        em.persist(a);
-        em.persist(b);
-        _id = a.getIntField();
-        _id2 = b.getIntField();
-
-        endTx(em);
-        endEm(em);
-    }
-
-    /**
-     * Tests that the PM throws Exceptions on usage attempts after it has been
-     * closed.
-     */
-    /* Fix Me - aokeke - takes a lot of time to run */
-    // public void testClosed ()
-    // {
-    // EntityManager em = currentEntityManager();
-    // startTx(em);
-    // endEm(em);
-    //
-    // try
-    // {
-    // // this is the only method that should succeed
-    // if(em.isOpen ())
-    // fail("Supposed to be closed...but cannot be closed inside
-    // container..closed at the end of funct");
-    // }
-    // catch (RuntimeException re)
-    // {
-    // fail ("isClosed");
-    // }
-    // try
-    // {
-    // em.find(RuntimeTest1.class, _id);
-    // fail ("find");
-    // }
-    // catch (RuntimeException re)
-    // {
-    // }
-    // }
-    public void testMultipleCloseThreaded() throws Throwable {
-        final EntityManager em = currentEntityManager();
-        final List result = new ArrayList();
-        // EntityTransaction t = em.getTransaction();
-        // t.begin ();
-
-        em.close();
-
-        new Thread() {
-            @SuppressWarnings("unchecked")
-            public void run() {
-                try {
-                    em.close();
-                    result.add(new Integer(0));
-                }
-                catch (Exception jdoe) {
-                    result.add(jdoe);
-                }
-                catch (Throwable t) {
-                    result.add(t);
-                }
-            }
-        }.start();
-
-        while (result.size() == 0)
-            Thread.currentThread().yield(); // wait for results
-        Object ret = result.get(0);
-
-        if (ret instanceof Exception)
-            return; // good
-
-        if (ret instanceof Throwable)
-            throw (Throwable) ret;
-    }
-
-    /**
-     * This method tries to perform operations that should lead to illegal
-     * states, such as persisting instances outside of transactions, etc.
-     */
-    public void testIllegalState() {
-        EntityManager em = currentEntityManager();
-
-        RuntimeTest1 a = new RuntimeTest1("foo", 10);
-        RuntimeTest1 a2 = (RuntimeTest1) em.find(RuntimeTest1.class, _id);
-
-        try {
-            em.persist(a);
-            fail("persist...");
-        }
-        catch (Exception ise) {
-        }
-
-        endEm(em);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBEntityManager extends AbstractTestCase {
+
+    private Object _id = null;
+
+    private Object _id2 = null;
+
+    public TestEJBEntityManager(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(RuntimeTest1.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 a = new RuntimeTest1("STRING", 10);
+        RuntimeTest2 b = new RuntimeTest2("STRING2", 11);
+        em.persist(a);
+        em.persist(b);
+        _id = a.getIntField();
+        _id2 = b.getIntField();
+
+        endTx(em);
+        endEm(em);
+    }
+
+    /**
+     * Tests that the PM throws Exceptions on usage attempts after it has been
+     * closed.
+     */
+    /* Fix Me - aokeke - takes a lot of time to run */
+    // public void testClosed ()
+    // {
+    // EntityManager em = currentEntityManager();
+    // startTx(em);
+    // endEm(em);
+    //
+    // try
+    // {
+    // // this is the only method that should succeed
+    // if(em.isOpen ())
+    // fail("Supposed to be closed...but cannot be closed inside
+    // container..closed at the end of funct");
+    // }
+    // catch (RuntimeException re)
+    // {
+    // fail ("isClosed");
+    // }
+    // try
+    // {
+    // em.find(RuntimeTest1.class, _id);
+    // fail ("find");
+    // }
+    // catch (RuntimeException re)
+    // {
+    // }
+    // }
+    public void testMultipleCloseThreaded() throws Throwable {
+        final EntityManager em = currentEntityManager();
+        final List result = new ArrayList();
+        // EntityTransaction t = em.getTransaction();
+        // t.begin ();
+
+        em.close();
+
+        new Thread() {
+            @SuppressWarnings("unchecked")
+            public void run() {
+                try {
+                    em.close();
+                    result.add(new Integer(0));
+                }
+                catch (Exception jdoe) {
+                    result.add(jdoe);
+                }
+                catch (Throwable t) {
+                    result.add(t);
+                }
+            }
+        }.start();
+
+        while (result.size() == 0)
+            Thread.currentThread().yield(); // wait for results
+        Object ret = result.get(0);
+
+        if (ret instanceof Exception)
+            return; // good
+
+        if (ret instanceof Throwable)
+            throw (Throwable) ret;
+    }
+
+    /**
+     * This method tries to perform operations that should lead to illegal
+     * states, such as persisting instances outside of transactions, etc.
+     */
+    public void testIllegalState() {
+        EntityManager em = currentEntityManager();
+
+        RuntimeTest1 a = new RuntimeTest1("foo", 10);
+        RuntimeTest1 a2 = (RuntimeTest1) em.find(RuntimeTest1.class, _id);
+
+        try {
+            em.persist(a);
+            fail("persist...");
+        }
+        catch (Exception ise) {
+        }
+
+        endEm(em);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBGetObjectByIdValue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBGetObjectByIdValue.java
index c7303c1..a807c6c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBGetObjectByIdValue.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBGetObjectByIdValue.java
@@ -1,90 +1,90 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AImplB;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBGetObjectByIdValue extends AbstractTestCase {
-
-    private Object[] oids;
-
-    public TestEJBGetObjectByIdValue(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(AImplB.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        em.flush();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testDatastore() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 pc = new RuntimeTest1(1);
-        pc.setStringField("foo");
-        em.persist(pc);
-
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        pc = (RuntimeTest1) em.find(RuntimeTest1.class, 1);
-        assertEquals("foo", pc.getStringField());
-        em.close();
-
-        em = currentEntityManager();
-        pc = (RuntimeTest1) em.find(RuntimeTest1.class, pc.getIntField());
-        assertEquals("foo", pc.getStringField());
-        endEm(em);
-    }
-
-    public void testAppId() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        AImplB pc = new AImplB("foo", 1, "pk");
-        em.persist(pc);
-        AImplB.Idkey oid = new AImplB.Idkey();
-        oid.pk1 = 1;
-        oid.pk2 = "pk";
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        pc = (AImplB) em.find(AImplB.class, oid);
-        assertEquals("foo", pc.getName());
-        endEm(em);
-
-        em = currentEntityManager();
-        pc = (AImplB) em.find(AImplB.class, oid.toString());
-        assertEquals("foo", pc.getName());
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AImplB;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBGetObjectByIdValue extends AbstractTestCase {
+
+    private Object[] oids;
+
+    public TestEJBGetObjectByIdValue(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(AImplB.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        em.flush();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testDatastore() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 pc = new RuntimeTest1(1);
+        pc.setStringField("foo");
+        em.persist(pc);
+
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        pc = (RuntimeTest1) em.find(RuntimeTest1.class, 1);
+        assertEquals("foo", pc.getStringField());
+        em.close();
+
+        em = currentEntityManager();
+        pc = (RuntimeTest1) em.find(RuntimeTest1.class, pc.getIntField());
+        assertEquals("foo", pc.getStringField());
+        endEm(em);
+    }
+
+    public void testAppId() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        AImplB pc = new AImplB("foo", 1, "pk");
+        em.persist(pc);
+        AImplB.Idkey oid = new AImplB.Idkey();
+        oid.pk1 = 1;
+        oid.pk2 = "pk";
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        pc = (AImplB) em.find(AImplB.class, oid);
+        assertEquals("foo", pc.getName());
+        endEm(em);
+
+        em = currentEntityManager();
+        pc = (AImplB) em.find(AImplB.class, oid.toString());
+        assertEquals("foo", pc.getName());
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBIncrementalFlushes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBIncrementalFlushes.java
index ada5cb6..5db5402 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBIncrementalFlushes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBIncrementalFlushes.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.InstanceCallbacksTest;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBIncrementalFlushes extends AbstractTestCase {
-
-    public TestEJBIncrementalFlushes(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        endTx(em);
-        endEm(em);
-    }
-
-//	public void testBasicJdoPreStore ()
-//	{
-//		EntityManager em = getEm ();
-//		em.getTransaction ().begin ();
-//		InstanceCallbacksTest a = new InstanceCallbacksTest ("foo", 10);
-//		em.persist(a);
-//		em.flush ();
-//		assertTrue (a.preStoreCalled);
-//		em.getTransaction ().commit ();
-//	}
-
-    public void testFlushNoChange() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        InstanceCallbacksTest a = new InstanceCallbacksTest("foo", 10);
-        em.persist(a);
-        em.flush();
-        endTx(em);
-        //assertTrue (a.preStoreCalled);
-        assertEquals(10, a.getIntField());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testOptimisticLockGivesCorrectError() {
-        EntityManager pm1 = currentEntityManager();
-        EntityManager pm2 = currentEntityManager();
-
-        RuntimeTest1 a1 = new RuntimeTest1("foo", 10);
-        startTx(pm1);
-        pm1.persist(a1);
-        endTx(pm1);
-
-        RuntimeTest1 a2 = (RuntimeTest1) pm2.find(RuntimeTest1.class, 10);
-        startTx(pm2);
-        a2.setStringField("foobar");
-        startTx(pm2);
-
-        startTx(pm1);
-        a1.setStringField("foobarbaz");
-        try {
-            endTx(pm1);
-        }
-        catch (Exception ole) {
-            // expected case
-        }
-        finally {
-            if (pm1.getTransaction().isActive())
-                pm1.getTransaction().rollback();
-
-            endEm(pm1);
-            endEm(pm2);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.InstanceCallbacksTest;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBIncrementalFlushes extends AbstractTestCase {
+
+    public TestEJBIncrementalFlushes(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        endTx(em);
+        endEm(em);
+    }
+
+//	public void testBasicJdoPreStore ()
+//	{
+//		EntityManager em = getEm ();
+//		em.getTransaction ().begin ();
+//		InstanceCallbacksTest a = new InstanceCallbacksTest ("foo", 10);
+//		em.persist(a);
+//		em.flush ();
+//		assertTrue (a.preStoreCalled);
+//		em.getTransaction ().commit ();
+//	}
+
+    public void testFlushNoChange() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        InstanceCallbacksTest a = new InstanceCallbacksTest("foo", 10);
+        em.persist(a);
+        em.flush();
+        endTx(em);
+        //assertTrue (a.preStoreCalled);
+        assertEquals(10, a.getIntField());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testOptimisticLockGivesCorrectError() {
+        EntityManager pm1 = currentEntityManager();
+        EntityManager pm2 = currentEntityManager();
+
+        RuntimeTest1 a1 = new RuntimeTest1("foo", 10);
+        startTx(pm1);
+        pm1.persist(a1);
+        endTx(pm1);
+
+        RuntimeTest1 a2 = (RuntimeTest1) pm2.find(RuntimeTest1.class, 10);
+        startTx(pm2);
+        a2.setStringField("foobar");
+        startTx(pm2);
+
+        startTx(pm1);
+        a1.setStringField("foobarbaz");
+        try {
+            endTx(pm1);
+        }
+        catch (Exception ole) {
+            // expected case
+        }
+        finally {
+            if (pm1.getTransaction().isActive())
+                pm1.getTransaction().rollback();
+
+            endEm(pm1);
+            endEm(pm2);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBInterfaces.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBInterfaces.java
index 1fa4fbf..70893c4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBInterfaces.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBInterfaces.java
@@ -1,121 +1,121 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.InterfaceHolder;
-import org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl1;
-import org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl2;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-/**
- * Test for persistent interfaces.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public class TestEJBInterfaces extends AbstractTestCase {
-
-    public TestEJBInterfaces(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testInterfaceField() {
-        try {
-            deleteAll(InterfaceTestImpl1.class);
-            deleteAll(InterfaceTestImpl2.class);
-            deleteAll(InterfaceHolder.class);
-        }
-        catch (Exception e) {
-        }
-
-        EntityManager em2 = currentEntityManager();
-        startTx(em2);
-
-        em2.flush();
-        endTx(em2);
-        endEm(em2);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        InterfaceHolder holder = new InterfaceHolder(1);
-        em.persist(holder);
-        holder.setIntf(new InterfaceTestImpl1("intf-1-field"));
-        assertEquals("intf-1-field", holder.getIntf().getStringField());
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        startTx(em);
-        InterfaceHolder hold =
-            (InterfaceHolder) em.find(InterfaceHolder.class, 1);
-        assertNotNull(hold.getIntf());
-        assertEquals("intf-1-field", hold.getIntf().getStringField());
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        startTx(em);
-        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
-        hold.setIntf(null);
-        assertNull(hold.getIntf());
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        startTx(em);
-        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
-        assertNull(hold.getIntf());
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        startTx(em);
-        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
-        hold.setIntf(new InterfaceTestImpl2("intf-2-field"));
-        assertEquals("intf-2-field", hold.getIntf().getStringField());
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        startTx(em);
-        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
-        assertNotNull(hold.getIntf());
-        assertEquals("intf-2-field", hold.getIntf().getStringField());
-        endTx(em);
-        endEm(em);
-
-        em = currentEntityManager();
-        startTx(em);
-        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
-        hold.getIntfs().add(new InterfaceTestImpl1("intf-1-set"));
-        endTx(em);
-        endEm(em);
-
-//		em = currentEntityManager();
-//		startTx(em);
-//		hold = (InterfaceHolder)em.find(InterfaceHolder.class, 1);
-//		assertEquals (1, hold.getIntfs ().size ());
-//		assertEquals ("intf-1-set", ((InterfaceTest) hold.getIntfs ().iterator ().next ()).getStringField ());
-//		endTx(em);
-//		endEm(em);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.InterfaceHolder;
+import org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl1;
+import org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl2;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+/**
+ * Test for persistent interfaces.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class TestEJBInterfaces extends AbstractTestCase {
+
+    public TestEJBInterfaces(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    @SuppressWarnings("unchecked")
+    public void testInterfaceField() {
+        try {
+            deleteAll(InterfaceTestImpl1.class);
+            deleteAll(InterfaceTestImpl2.class);
+            deleteAll(InterfaceHolder.class);
+        }
+        catch (Exception e) {
+        }
+
+        EntityManager em2 = currentEntityManager();
+        startTx(em2);
+
+        em2.flush();
+        endTx(em2);
+        endEm(em2);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        InterfaceHolder holder = new InterfaceHolder(1);
+        em.persist(holder);
+        holder.setIntf(new InterfaceTestImpl1("intf-1-field"));
+        assertEquals("intf-1-field", holder.getIntf().getStringField());
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        startTx(em);
+        InterfaceHolder hold =
+            (InterfaceHolder) em.find(InterfaceHolder.class, 1);
+        assertNotNull(hold.getIntf());
+        assertEquals("intf-1-field", hold.getIntf().getStringField());
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        startTx(em);
+        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
+        hold.setIntf(null);
+        assertNull(hold.getIntf());
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        startTx(em);
+        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
+        assertNull(hold.getIntf());
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        startTx(em);
+        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
+        hold.setIntf(new InterfaceTestImpl2("intf-2-field"));
+        assertEquals("intf-2-field", hold.getIntf().getStringField());
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        startTx(em);
+        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
+        assertNotNull(hold.getIntf());
+        assertEquals("intf-2-field", hold.getIntf().getStringField());
+        endTx(em);
+        endEm(em);
+
+        em = currentEntityManager();
+        startTx(em);
+        hold = (InterfaceHolder) em.find(InterfaceHolder.class, 1);
+        hold.getIntfs().add(new InterfaceTestImpl1("intf-1-set"));
+        endTx(em);
+        endEm(em);
+
+//		em = currentEntityManager();
+//		startTx(em);
+//		hold = (InterfaceHolder)em.find(InterfaceHolder.class, 1);
+//		assertEquals (1, hold.getIntfs ().size ());
+//		assertEquals ("intf-1-set", ((InterfaceTest) hold.getIntfs ().iterator ().next ()).getStringField ());
+//		endTx(em);
+//		endEm(em);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLobs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLobs.java
index 00942c5..cd9c95f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLobs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLobs.java
@@ -1,176 +1,176 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.Serializable;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.EntityManager;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBLobs extends AbstractTestCase {
-
-    private EntityManager _pm = null;
-    private Inner _inner = null;
-
-    public TestEJBLobs(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(Inner.class);
-        deleteAll(Inner2.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        endTx(em);
-        endEm(em);
-
-        Inner inner = new Inner();
-        inner.setString("string");
-        inner.setClob("clobField");
-        inner.setEBlob("eblob");
-
-        Inner2 inner2 = new Inner2();
-        inner2.string = "inner2";
-        inner.setBlob(inner2);
-
-        _pm = currentEntityManager();
-        startTx(_pm);
-        _pm.persist(inner);
-        try {
-            endTx(_pm);
-        }
-        catch (Exception jdoe) {
-            System.out.println(
-                "An exception was thrown while persisting the entity : \n" +
-                    getStackTrace(jdoe));
-        }
-        endEm(_pm);
-
-        _pm = currentEntityManager();
-        _inner = (Inner) _pm.find(Inner.class, "string");
-    }
-
-    public void testOtherFields() {
-        assertEquals("string", _inner.getString());
-    }
-
-    public void testClob() {
-        assertEquals("clobField", _inner.getClob());
-    }
-
-    public void testBlob() {
-        assertNotNull(_inner.getBlob());
-        assertEquals("inner2", _inner.getBlob().string);
-    }
-
-    public void testSetNull() {
-        startTx(_pm);
-        _inner.setClob(null);
-        _inner.setBlob(null);
-        endTx(_pm);
-
-        assertEquals(null, _inner.getBlob());
-        assertEquals(null, _inner.getClob());
-    }
-
-    public void testDelete() {
-        deleteAll(Inner.class);
-    }
-
-    public void testUpdate() {
-        startTx(_pm);
-        _inner.setClob("newvalue");
-        Inner2 inner2 = new Inner2();
-        inner2.string = "newinner2";
-        _inner.setBlob(inner2);
-        endTx(_pm);
-
-        assertEquals("newvalue", _inner.getClob());
-        assertEquals("newinner2", _inner.getBlob().string);
-    }
-
-    @Entity
-    @Table(name = "inntable")
-    public static class Inner {
-
-        @Id
-        private String string = null;
-        private String clobField = null;
-        private Object eblob = null;
-
-        @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-        private Inner2 blobField = null;
-
-        public String getString() {
-            return string;
-        }
-
-        public void setString(String val) {
-            string = val;
-        }
-
-        public String getClob() {
-            return clobField;
-        }
-
-        public void setClob(String val) {
-            clobField = val;
-        }
-
-        public String getEBlob() {
-            return ((String) eblob);
-        }
-
-        public void setEBlob(String val) {
-            eblob = val;
-        }
-
-        public Inner2 getBlob() {
-            return blobField;
-        }
-
-        public void setBlob(Inner2 val) {
-            blobField = val;
-        }
-    }
-
-    @SuppressWarnings("serial")
-    @Entity
-    @Table(name="Inner2")
-    public static class Inner2 implements Serializable {
-
-        @Id
-        public String string = null;
-
-        public String getString() {
-            return string;
-        }
-
-        public void setString(String string) {
-            this.string = string;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.Serializable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBLobs extends AbstractTestCase {
+
+    private EntityManager _pm = null;
+    private Inner _inner = null;
+
+    public TestEJBLobs(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(Inner.class);
+        deleteAll(Inner2.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        endTx(em);
+        endEm(em);
+
+        Inner inner = new Inner();
+        inner.setString("string");
+        inner.setClob("clobField");
+        inner.setEBlob("eblob");
+
+        Inner2 inner2 = new Inner2();
+        inner2.string = "inner2";
+        inner.setBlob(inner2);
+
+        _pm = currentEntityManager();
+        startTx(_pm);
+        _pm.persist(inner);
+        try {
+            endTx(_pm);
+        }
+        catch (Exception jdoe) {
+            System.out.println(
+                "An exception was thrown while persisting the entity : \n" +
+                    getStackTrace(jdoe));
+        }
+        endEm(_pm);
+
+        _pm = currentEntityManager();
+        _inner = (Inner) _pm.find(Inner.class, "string");
+    }
+
+    public void testOtherFields() {
+        assertEquals("string", _inner.getString());
+    }
+
+    public void testClob() {
+        assertEquals("clobField", _inner.getClob());
+    }
+
+    public void testBlob() {
+        assertNotNull(_inner.getBlob());
+        assertEquals("inner2", _inner.getBlob().string);
+    }
+
+    public void testSetNull() {
+        startTx(_pm);
+        _inner.setClob(null);
+        _inner.setBlob(null);
+        endTx(_pm);
+
+        assertEquals(null, _inner.getBlob());
+        assertEquals(null, _inner.getClob());
+    }
+
+    public void testDelete() {
+        deleteAll(Inner.class);
+    }
+
+    public void testUpdate() {
+        startTx(_pm);
+        _inner.setClob("newvalue");
+        Inner2 inner2 = new Inner2();
+        inner2.string = "newinner2";
+        _inner.setBlob(inner2);
+        endTx(_pm);
+
+        assertEquals("newvalue", _inner.getClob());
+        assertEquals("newinner2", _inner.getBlob().string);
+    }
+
+    @Entity
+    @Table(name = "inntable")
+    public static class Inner {
+
+        @Id
+        private String string = null;
+        private String clobField = null;
+        private Object eblob = null;
+
+        @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+        private Inner2 blobField = null;
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(String val) {
+            string = val;
+        }
+
+        public String getClob() {
+            return clobField;
+        }
+
+        public void setClob(String val) {
+            clobField = val;
+        }
+
+        public String getEBlob() {
+            return ((String) eblob);
+        }
+
+        public void setEBlob(String val) {
+            eblob = val;
+        }
+
+        public Inner2 getBlob() {
+            return blobField;
+        }
+
+        public void setBlob(Inner2 val) {
+            blobField = val;
+        }
+    }
+
+    @SuppressWarnings("serial")
+    @Entity
+    @Table(name="Inner2")
+    public static class Inner2 implements Serializable {
+
+        @Id
+        public String string = null;
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(String string) {
+            this.string = string;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLocales.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLocales.java
index ba8b073..478c041 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLocales.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBLocales.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBLocales extends AbstractTestCase {
-
-    public TestEJBLocales(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testLocales() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        RuntimeTest1 t1 = new RuntimeTest1(1);
-        t1.setLocaleField(new Locale(Locale.FRANCE.getCountry(),
-            Locale.FRENCH.getLanguage()));
-        pm.persist(t1);
-        pm.persist(new RuntimeTest1(2));
-        endTx(pm);
-        endEm(pm);
-
-        pm = currentEntityManager();
-        List c = findAll(RuntimeTest1.class, pm);
-        assertEquals(2, c.size());
-
-        boolean foundNull = false;
-        boolean foundFrance = false;
-        Locale locale;
-
-        for (Iterator iter = c.iterator(); iter.hasNext();) {
-            t1 = (RuntimeTest1) iter.next();
-            locale = t1.getLocaleField();
-            if (locale == null)
-                foundNull = true;
-            else if (
-                (locale.getCountry().equals(Locale.FRANCE.getCountry())) &&
-                    (locale.getLanguage().equals(Locale.FRANCE.getLanguage())))
-                foundFrance = true;
-        }
-
-        assertTrue(foundNull);
-        assertTrue(foundFrance);
-        endEm(pm);
-    }
-
-    public List findAll(Class c, EntityManager em) {
-        List l = em.createQuery("Select object(o) from RuntimeTest1 o")
-            .getResultList();
-        return l;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBLocales extends AbstractTestCase {
+
+    public TestEJBLocales(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testLocales() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        RuntimeTest1 t1 = new RuntimeTest1(1);
+        t1.setLocaleField(new Locale(Locale.FRANCE.getCountry(),
+            Locale.FRENCH.getLanguage()));
+        pm.persist(t1);
+        pm.persist(new RuntimeTest1(2));
+        endTx(pm);
+        endEm(pm);
+
+        pm = currentEntityManager();
+        List c = findAll(RuntimeTest1.class, pm);
+        assertEquals(2, c.size());
+
+        boolean foundNull = false;
+        boolean foundFrance = false;
+        Locale locale;
+
+        for (Iterator iter = c.iterator(); iter.hasNext();) {
+            t1 = (RuntimeTest1) iter.next();
+            locale = t1.getLocaleField();
+            if (locale == null)
+                foundNull = true;
+            else if (
+                (locale.getCountry().equals(Locale.FRANCE.getCountry())) &&
+                    (locale.getLanguage().equals(Locale.FRANCE.getLanguage())))
+                foundFrance = true;
+        }
+
+        assertTrue(foundNull);
+        assertTrue(foundFrance);
+        endEm(pm);
+    }
+
+    public List findAll(Class c, EntityManager em) {
+        List l = em.createQuery("Select object(o) from RuntimeTest1 o")
+            .getResultList();
+        return l;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBManagedInverses.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBManagedInverses.java
index 3d29870..2900723 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBManagedInverses.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBManagedInverses.java
@@ -1,93 +1,93 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.InverseA;
-import org.apache.openjpa.persistence.kernel.common.apps.InverseB;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBManagedInverses extends AbstractTestCase {
-
-    public TestEJBManagedInverses(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(InverseA.class);
-        deleteAll(InverseB.class);
-    }
-
-    public void testOneOne() {
-        oneOneTest(true);
-    }
-
-    public void testOneOneWithPreStore() {
-        oneOneTest(false);
-    }
-
-    private void oneOneTest(boolean flush) {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        InverseA a = new InverseA();
-        InverseA a2 = new InverseA();
-        InverseA a3 = new InverseA();
-        a.setOneOne(a2);
-        a.setOneOneOwner(a2);
-        pm.persist(a);
-        pm.persist(a3);
-
-//		assertEquals (a, a2.getOneOne ());
-//		assertEquals (a, a2.getOneOneOwner ());
-        assertEquals("a.getOneOne is not a2", a2, a.getOneOne());
-        assertEquals("a.getOneOneOwner is not a2", a2, a.getOneOneOwner());
-        endTx(pm);
-
-        startTx(pm);
-        a2.setOneOne(a3);
-        a2.setOneOneOwner(a3);
-
-//		assertEquals (a2, a3.getOneOne ());
-//		assertEquals (a2, a3.getOneOneOwner ());
-        assertEquals(a3, a2.getOneOne());
-        assertEquals(a3, a2.getOneOneOwner());
-        endTx(pm);
-
-        // make sure commit doesn't retrigger changes
-//		assertEquals (a2, a3.getOneOne ());
-//		assertEquals (a2, a3.getOneOneOwner ());
-        assertEquals(a3, a2.getOneOne());
-        assertEquals(a3, a2.getOneOneOwner());
-
-        // test persistent -> dirty
-        startTx(pm);
-        a2.setOneOne(null);
-        a2.setOneOneOwner(null);
-//		if (flush)
-//			pm.flush ();
-//		else
-//			pm.setFlushMode(FlushModeType.AUTO);
-//		assertNull (a3.getOneOne ());
-//		assertNull (a3.getOneOneOwner ());
-        endTx(pm);
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.InverseA;
+import org.apache.openjpa.persistence.kernel.common.apps.InverseB;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBManagedInverses extends AbstractTestCase {
+
+    public TestEJBManagedInverses(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(InverseA.class);
+        deleteAll(InverseB.class);
+    }
+
+    public void testOneOne() {
+        oneOneTest(true);
+    }
+
+    public void testOneOneWithPreStore() {
+        oneOneTest(false);
+    }
+
+    private void oneOneTest(boolean flush) {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        InverseA a = new InverseA();
+        InverseA a2 = new InverseA();
+        InverseA a3 = new InverseA();
+        a.setOneOne(a2);
+        a.setOneOneOwner(a2);
+        pm.persist(a);
+        pm.persist(a3);
+
+//		assertEquals (a, a2.getOneOne ());
+//		assertEquals (a, a2.getOneOneOwner ());
+        assertEquals("a.getOneOne is not a2", a2, a.getOneOne());
+        assertEquals("a.getOneOneOwner is not a2", a2, a.getOneOneOwner());
+        endTx(pm);
+
+        startTx(pm);
+        a2.setOneOne(a3);
+        a2.setOneOneOwner(a3);
+
+//		assertEquals (a2, a3.getOneOne ());
+//		assertEquals (a2, a3.getOneOneOwner ());
+        assertEquals(a3, a2.getOneOne());
+        assertEquals(a3, a2.getOneOneOwner());
+        endTx(pm);
+
+        // make sure commit doesn't retrigger changes
+//		assertEquals (a2, a3.getOneOne ());
+//		assertEquals (a2, a3.getOneOneOwner ());
+        assertEquals(a3, a2.getOneOne());
+        assertEquals(a3, a2.getOneOneOwner());
+
+        // test persistent -> dirty
+        startTx(pm);
+        a2.setOneOne(null);
+        a2.setOneOneOwner(null);
+//		if (flush)
+//			pm.flush ();
+//		else
+//			pm.setFlushMode(FlushModeType.AUTO);
+//		assertNull (a3.getOneOne ());
+//		assertNull (a3.getOneOneOwner ());
+        endTx(pm);
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNoPersistentFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNoPersistentFields.java
index e32a2df..afca6c9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNoPersistentFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNoPersistentFields.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.Serializable;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.EntityManager;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBNoPersistentFields extends AbstractTestCase {
-
-    private Nholder holder;
-
-    public TestEJBNoPersistentFields(String test) {
-        super(test, "kernelcactusapp");
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(Nholder.class);
-    }
-
-    public void testNoPersistentFields() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        holder = new Nholder();
-        holder.setNpf(new NoPersistentFieldsPC());
-        holder.setIdKey(1);
-
-        em.persist(holder);
-        endTx(em);
-
-        Nholder holder2 = em.find(Nholder.class, 1);
-        assertEquals(1, holder2.getIdKey());
-        assertNotNull(holder2);
-        assertNotNull(holder2.getNpf());
-
-        endEm(em);
-    }
-
-    @SuppressWarnings("serial")
-    @Entity
-    @Table(name = "nholder2")
-    public static class Nholder implements Serializable {
-
-        @Id
-        private int idkey;
-
-        @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-        private NoPersistentFieldsPC npf;
-
-        public Nholder() {
-        }
-
-        public Nholder(NoPersistentFieldsPC npf, int idkey) {
-            this.npf = npf;
-            this.idkey = idkey;
-        }
-
-        public void setNpf(NoPersistentFieldsPC npf) {
-            this.npf = npf;
-        }
-
-        public NoPersistentFieldsPC getNpf() {
-            return this.npf;
-        }
-
-        public int getIdKey() {
-            return idkey;
-        }
-
-        public void setIdKey(int idkey) {
-            this.idkey = idkey;
-        }
-    }
-
-    @SuppressWarnings("serial")
-    @Entity
-    @Table(name = "npfp")
-    public static class NoPersistentFieldsPC implements Serializable {
-
-        public transient int blankInt;
-        public transient String blankString;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.Serializable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBNoPersistentFields extends AbstractTestCase {
+
+    private Nholder holder;
+
+    public TestEJBNoPersistentFields(String test) {
+        super(test, "kernelcactusapp");
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(Nholder.class);
+    }
+
+    public void testNoPersistentFields() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        holder = new Nholder();
+        holder.setNpf(new NoPersistentFieldsPC());
+        holder.setIdKey(1);
+
+        em.persist(holder);
+        endTx(em);
+
+        Nholder holder2 = em.find(Nholder.class, 1);
+        assertEquals(1, holder2.getIdKey());
+        assertNotNull(holder2);
+        assertNotNull(holder2.getNpf());
+
+        endEm(em);
+    }
+
+    @SuppressWarnings("serial")
+    @Entity
+    @Table(name = "nholder2")
+    public static class Nholder implements Serializable {
+
+        @Id
+        private int idkey;
+
+        @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+        private NoPersistentFieldsPC npf;
+
+        public Nholder() {
+        }
+
+        public Nholder(NoPersistentFieldsPC npf, int idkey) {
+            this.npf = npf;
+            this.idkey = idkey;
+        }
+
+        public void setNpf(NoPersistentFieldsPC npf) {
+            this.npf = npf;
+        }
+
+        public NoPersistentFieldsPC getNpf() {
+            return this.npf;
+        }
+
+        public int getIdKey() {
+            return idkey;
+        }
+
+        public void setIdKey(int idkey) {
+            this.idkey = idkey;
+        }
+    }
+
+    @SuppressWarnings("serial")
+    @Entity
+    @Table(name = "npfp")
+    public static class NoPersistentFieldsPC implements Serializable {
+
+        public transient int blankInt;
+        public transient String blankString;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNullValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNullValues.java
index 0d957e8..510a63d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNullValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBNullValues.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.Inner;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBNullValues extends AbstractTestCase {
-
-    public TestEJBNullValues(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(Inner.class);
-    }
-
-    public void testException() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        pm.persist(new Inner());
-        try {
-            endTx(pm);
-            fail("Null value allowed");
-        }
-        catch (Exception jfe) {
-            System.out
-                .println("Exception expected...Null value not allowed...");
-        }
-        endEm(pm);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.Inner;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBNullValues extends AbstractTestCase {
+
+    public TestEJBNullValues(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(Inner.class);
+    }
+
+    public void testException() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        pm.persist(new Inner());
+        try {
+            endTx(pm);
+            fail("Null value allowed");
+        }
+        catch (Exception jfe) {
+            System.out
+                .println("Exception expected...Null value not allowed...");
+        }
+        endEm(pm);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBObjectCollections.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBObjectCollections.java
index 2f6fbc9..87edfd1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBObjectCollections.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBObjectCollections.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldsTypeTest;
-import org.apache.openjpa.persistence.kernel.common.apps.ObjectCollectionHolder;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-/**
- * Tests that Collections of type {@link Object} can hold all
- * sorts of stuff (heterogeneous classes, persistent classes).
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public class TestEJBObjectCollections extends AbstractTestCase {
-
-    public TestEJBObjectCollections(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void testHashSet() {
-        assertEquals(1, add(new Object[]{ "Foo" }, 1).getHashSet().size());
-        assertEquals(1, add(new Object[]{ "Foo" }, 2).getHashSet().size());
-
-        assertEquals(2, add(
-            new Object[]{ "Foo", new AllFieldsTypeTest() }, 3)
-            .getHashSet().size());
-    }
-
-    public void setUp() {
-        deleteAll(ObjectCollectionHolder.class);
-        deleteAll(AllFieldsTypeTest.class);
-    }
-
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @SuppressWarnings("unchecked")
-    public ObjectCollectionHolder add(Object[] objects, int id) {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        ObjectCollectionHolder holder = new ObjectCollectionHolder();
-        holder.setId(id);
-        pm.persist(holder);
-        holder.setHashSet(new HashSet(Arrays.asList(objects)));
-        endTx(pm);
-        endEm(pm);
-
-        pm = currentEntityManager();
-        startTx(pm);
-        return (ObjectCollectionHolder) pm
-            .find(ObjectCollectionHolder.class, id);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldsTypeTest;
+import org.apache.openjpa.persistence.kernel.common.apps.ObjectCollectionHolder;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+/**
+ * Tests that Collections of type {@link Object} can hold all
+ * sorts of stuff (heterogeneous classes, persistent classes).
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class TestEJBObjectCollections extends AbstractTestCase {
+
+    public TestEJBObjectCollections(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void testHashSet() {
+        assertEquals(1, add(new Object[]{ "Foo" }, 1).getHashSet().size());
+        assertEquals(1, add(new Object[]{ "Foo" }, 2).getHashSet().size());
+
+        assertEquals(2, add(
+            new Object[]{ "Foo", new AllFieldsTypeTest() }, 3)
+            .getHashSet().size());
+    }
+
+    public void setUp() {
+        deleteAll(ObjectCollectionHolder.class);
+        deleteAll(AllFieldsTypeTest.class);
+    }
+
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @SuppressWarnings("unchecked")
+    public ObjectCollectionHolder add(Object[] objects, int id) {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        ObjectCollectionHolder holder = new ObjectCollectionHolder();
+        holder.setId(id);
+        pm.persist(holder);
+        holder.setHashSet(new HashSet(Arrays.asList(objects)));
+        endTx(pm);
+        endEm(pm);
+
+        pm = currentEntityManager();
+        startTx(pm);
+        return (ObjectCollectionHolder) pm
+            .find(ObjectCollectionHolder.class, id);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBRetainValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBRetainValues.java
index e68aa14..82294f8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBRetainValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBRetainValues.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBRetainValues extends AbstractTestCase {
-
-    public TestEJBRetainValues(String testName) {
-        super(testName, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    /**
-     * tests the behavior of the same object being viewed from
-     * different PersistenceManagers with RetainValues set to true
-     */
-    public void testRetainValues() {
-        // persist the object with field == "x"
-        RuntimeTest1 test = new RuntimeTest1();
-        test.setStringField("x");
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        pm.persist(test);
-        endTx(pm);
-
-        //	find the object in a different PM
-        EntityManager pm2 = currentEntityManager();
-        List l = (buildSelectQuery(pm2, "x"));
-        assertNotNull("l is null in testRetainValues", l);
-        RuntimeTest1 sameThing = (RuntimeTest1) l.iterator().next();
-
-        assertEquals("x", sameThing.getStringField());
-        assertEquals("x", test.getStringField());
-
-        //	set the second object field to "y"
-        startTx(pm2);
-        sameThing.setStringField("y");
-        endTx(pm2);
-        assertEquals("y", sameThing.getStringField());
-        assertEquals("x", test.getStringField());
-
-        //	do some searching in the first PM
-        List l2 = buildSelectQuery(pm, "x");
-        assertEquals(0,
-            l2.size());  //should be zero if retainvalue is set to true but that is kodo specific.
-
-        List l3 = buildSelectQuery(pm, "y");
-        assertEquals(1, l3.size());
-        assertEquals(test, l3.iterator().next());
-        assertEquals("x", test.getStringField());
-
-        endEm(pm2);
-        endEm(pm);
-    }
-
-    public static List buildSelectQuery(EntityManager em, String param) {
-        return em.createQuery(
-            "SELECT c FROM RuntimeTest1 c where c.stringField = :username")
-            .setParameter("username", param)
-            .getResultList();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBRetainValues extends AbstractTestCase {
+
+    public TestEJBRetainValues(String testName) {
+        super(testName, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    /**
+     * tests the behavior of the same object being viewed from
+     * different PersistenceManagers with RetainValues set to true
+     */
+    public void testRetainValues() {
+        // persist the object with field == "x"
+        RuntimeTest1 test = new RuntimeTest1();
+        test.setStringField("x");
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        pm.persist(test);
+        endTx(pm);
+
+        //	find the object in a different PM
+        EntityManager pm2 = currentEntityManager();
+        List l = (buildSelectQuery(pm2, "x"));
+        assertNotNull("l is null in testRetainValues", l);
+        RuntimeTest1 sameThing = (RuntimeTest1) l.iterator().next();
+
+        assertEquals("x", sameThing.getStringField());
+        assertEquals("x", test.getStringField());
+
+        //	set the second object field to "y"
+        startTx(pm2);
+        sameThing.setStringField("y");
+        endTx(pm2);
+        assertEquals("y", sameThing.getStringField());
+        assertEquals("x", test.getStringField());
+
+        //	do some searching in the first PM
+        List l2 = buildSelectQuery(pm, "x");
+        assertEquals(0,
+            l2.size());  //should be zero if retainvalue is set to true but that is kodo specific.
+
+        List l3 = buildSelectQuery(pm, "y");
+        assertEquals(1, l3.size());
+        assertEquals(test, l3.iterator().next());
+        assertEquals("x", test.getStringField());
+
+        endEm(pm2);
+        endEm(pm);
+    }
+
+    public static List buildSelectQuery(EntityManager em, String param) {
+        return em.createQuery(
+            "SELECT c FROM RuntimeTest1 c where c.stringField = :username")
+            .setParameter("username", param)
+            .getResultList();
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBState.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBState.java
index 3ad9479..747d17b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBState.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBState.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.math.BigDecimal;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldsTypeTest;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBState extends AbstractTestCase {
-
-    private static final int INSERT_COUNT = 20;
-
-    public TestEJBState(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(AllFieldsTypeTest.class);
-    }
-
-    public void testBigDecimalsLoseTrailingZeros() {
-        EntityManager pm1 = currentEntityManager();
-        startTx(pm1);
-        AllFieldsTypeTest aftt = new AllFieldsTypeTest();
-        aftt.setId(1);
-        aftt.setTestBigDecimal(new BigDecimal("5.760000"));
-        pm1.persist(aftt);
-
-        endTx(pm1);
-
-        EntityManager pm2 = currentEntityManager();
-        startTx(pm2);
-
-        Object retrieved = pm2.find(AllFieldsTypeTest.class, 1);
-        assertEquals(aftt, retrieved);
-        endTx(pm2);
-        endEm(pm2);
-        endEm(pm1);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.math.BigDecimal;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldsTypeTest;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBState extends AbstractTestCase {
+
+    private static final int INSERT_COUNT = 20;
+
+    public TestEJBState(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(AllFieldsTypeTest.class);
+    }
+
+    public void testBigDecimalsLoseTrailingZeros() {
+        EntityManager pm1 = currentEntityManager();
+        startTx(pm1);
+        AllFieldsTypeTest aftt = new AllFieldsTypeTest();
+        aftt.setId(1);
+        aftt.setTestBigDecimal(new BigDecimal("5.760000"));
+        pm1.persist(aftt);
+
+        endTx(pm1);
+
+        EntityManager pm2 = currentEntityManager();
+        startTx(pm2);
+
+        Object retrieved = pm2.find(AllFieldsTypeTest.class, 1);
+        assertEquals(aftt, retrieved);
+        endTx(pm2);
+        endEm(pm2);
+        endEm(pm1);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactionalClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactionalClass.java
index 5429612..459e50f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactionalClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactionalClass.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.TransactionalClassPC;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBTransactionalClass extends AbstractTestCase {
-
-    public TestEJBTransactionalClass(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void testTransactional() {
-        TransactionalClassPC pc = new TransactionalClassPC();
-        pc.setIntField(1);
-
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-        //pm.makeTransactional (pc);
-        pc.setIntField(2);
-        endTx(pm);
-
-        assertEquals(2, pc.getIntField());
-
-        startTx(pm);
-        pc.setIntField(3);
-        pm.getTransaction().rollback();
-
-        assertEquals(3, pc.getIntField());
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.TransactionalClassPC;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBTransactionalClass extends AbstractTestCase {
+
+    public TestEJBTransactionalClass(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void testTransactional() {
+        TransactionalClassPC pc = new TransactionalClassPC();
+        pc.setIntField(1);
+
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+        //pm.makeTransactional (pc);
+        pc.setIntField(2);
+        endTx(pm);
+
+        assertEquals(2, pc.getIntField());
+
+        startTx(pm);
+        pc.setIntField(3);
+        pm.getTransaction().rollback();
+
+        assertEquals(3, pc.getIntField());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactions.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactions.java
index b3e1cda..07afd5f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactions.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestEJBTransactions.java
@@ -1,119 +1,119 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.ArrayList;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-public class TestEJBTransactions extends AbstractTestCase {
-
-    public TestEJBTransactions(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-    }
-
-    public void testTxCannotBeCommittedTwiceInDiffThreads() throws Throwable {
-        final ArrayList list = new ArrayList();
-
-        final EntityManager em = currentEntityManager();
-        final EntityTransaction tx;
-
-        tx = em.getTransaction();
-        if (tx.isActive())
-            tx.rollback();
-        tx.begin();
-        endTx(em);
-
-        Thread thread = new Thread() {
-            @SuppressWarnings("unchecked")
-            public void run() {
-                try {
-                    endTx(em);
-                    list.add(new Integer(0));
-                }
-                catch (Exception e) {
-                    list.add(e);
-                }
-                catch (Throwable t) {
-                    list.add(t);
-                }
-            }
-        };
-
-        thread.start();
-
-        while (list.size() == 0) ;
-
-        Object result = list.get(0);
-
-        if (!(result instanceof Exception)) {
-            if (result instanceof Throwable)
-                throw (Throwable) result;
-        }
-        thread.join();
-    }
-
-    public void testTransactionsCannotBeCommittedTwice() {
-        EntityManager pm = currentEntityManager();
-        rollbackTx(pm);
-
-        startTx(pm);
-        endTx(pm);
-
-        try {
-            // second commit
-            endTx(pm);
-        }
-        catch (Exception e) {
-            // good: we should be throwing an exception here
-            System.out.println("Exception should be thrown here..." +
-                "Transactions cannot be committed twice...");
-        }
-    }
-
-    public void testTransactionsCannotBeRolledBackTwice() {
-        EntityManager pm = currentEntityManager();
-        startTx(pm);
-
-        EntityTransaction t;
-        t = pm.getTransaction();
-
-        if (t.isActive()) {
-            t.rollback();
-        } else {
-            t.begin();
-            t.rollback();
-        }
-
-        try {
-            // second rollback
-            t.rollback();
-        }
-        catch (Exception e) {
-            // good: we should be throwing an exception here
-            System.out.println("Exception should be thrown here..." +
-                "Transactions cannot be rolled back twice...");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.ArrayList;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEJBTransactions extends AbstractTestCase {
+
+    public TestEJBTransactions(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+    }
+
+    public void testTxCannotBeCommittedTwiceInDiffThreads() throws Throwable {
+        final ArrayList list = new ArrayList();
+
+        final EntityManager em = currentEntityManager();
+        final EntityTransaction tx;
+
+        tx = em.getTransaction();
+        if (tx.isActive())
+            tx.rollback();
+        tx.begin();
+        endTx(em);
+
+        Thread thread = new Thread() {
+            @SuppressWarnings("unchecked")
+            public void run() {
+                try {
+                    endTx(em);
+                    list.add(new Integer(0));
+                }
+                catch (Exception e) {
+                    list.add(e);
+                }
+                catch (Throwable t) {
+                    list.add(t);
+                }
+            }
+        };
+
+        thread.start();
+
+        while (list.size() == 0) ;
+
+        Object result = list.get(0);
+
+        if (!(result instanceof Exception)) {
+            if (result instanceof Throwable)
+                throw (Throwable) result;
+        }
+        thread.join();
+    }
+
+    public void testTransactionsCannotBeCommittedTwice() {
+        EntityManager pm = currentEntityManager();
+        rollbackTx(pm);
+
+        startTx(pm);
+        endTx(pm);
+
+        try {
+            // second commit
+            endTx(pm);
+        }
+        catch (Exception e) {
+            // good: we should be throwing an exception here
+            System.out.println("Exception should be thrown here..." +
+                "Transactions cannot be committed twice...");
+        }
+    }
+
+    public void testTransactionsCannotBeRolledBackTwice() {
+        EntityManager pm = currentEntityManager();
+        startTx(pm);
+
+        EntityTransaction t;
+        t = pm.getTransaction();
+
+        if (t.isActive()) {
+            t.rollback();
+        } else {
+            t.begin();
+            t.rollback();
+        }
+
+        try {
+            // second rollback
+            t.rollback();
+        }
+        catch (Exception e) {
+            // good: we should be throwing an exception here
+            System.out.println("Exception should be thrown here..." +
+                "Transactions cannot be rolled back twice...");
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents.java
index 7e21c07..60b63c3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents.java
@@ -1,125 +1,125 @@
-/*
- * TestExtents.java
- *
- * Created on October 10, 2006, 4:34 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
-
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestExtents extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestExtents
-     */
-    public TestExtents() {
-    }
-
-    public TestExtents(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        RuntimeTest1 b = new RuntimeTest1("STRING", 10);
-        RuntimeTest2 c = new RuntimeTest2("STRING2", 11);
-        pm.persist(b);
-        pm.persist(c);
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testExtent1() {
-
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = pm.createExtent(RuntimeTest1.class, false);
-
-        assertEquals(pm, ext.getEntityManager());
-
-        assertEquals(RuntimeTest1.class, ext.getElementClass());
-        assertTrue(!ext.hasSubclasses());
-    }
-
-    public void testExtent2() {
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = pm.createExtent(RuntimeTest1.class, false);
-
-        boolean found = false;
-        for (Iterator i = ext.iterator(); i.hasNext(); found = true)
-            assertEquals(RuntimeTest1.class, i.next().getClass());
-        assertTrue(found);
-    }
-
-    public void testExtent3() {
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = pm.createExtent(RuntimeTest1.class, true);
-
-        boolean foundB = false;
-        for (Iterator i = ext.iterator(); i.hasNext();)
-            if (i.next().getClass().equals(RuntimeTest2.class))
-                foundB = true;
-        assertTrue(foundB);
-    }
-
-    public void testExtent4() {
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = (Extent) pm.createExtent(RuntimeTest1.class, true);
-
-        List all = new LinkedList();
-        for (Iterator i = ext.iterator(); i.hasNext();)
-            all.add(i.next());
-
-        List aList = ext.list();
-        assertEquals(all.size(), aList.size());
-        assertContainsSame(all, aList);
-    }
-
-    private void assertContainsSame(List l, Collection c) {
-        int size = 0;
-        for (Iterator iter = c.iterator(); iter.hasNext(); iter.next())
-            size++;
-
-        assertEquals(l.size(), size);
-
-        for (Iterator iter = l.iterator(); iter.hasNext();)
-            assertTrue(c.contains(iter.next()));
-    }
-}
+/*
+ * TestExtents.java
+ *
+ * Created on October 10, 2006, 4:34 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
+
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestExtents extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestExtents
+     */
+    public TestExtents() {
+    }
+
+    public TestExtents(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        RuntimeTest1 b = new RuntimeTest1("STRING", 10);
+        RuntimeTest2 c = new RuntimeTest2("STRING2", 11);
+        pm.persist(b);
+        pm.persist(c);
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testExtent1() {
+
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = pm.createExtent(RuntimeTest1.class, false);
+
+        assertEquals(pm, ext.getEntityManager());
+
+        assertEquals(RuntimeTest1.class, ext.getElementClass());
+        assertTrue(!ext.hasSubclasses());
+    }
+
+    public void testExtent2() {
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = pm.createExtent(RuntimeTest1.class, false);
+
+        boolean found = false;
+        for (Iterator i = ext.iterator(); i.hasNext(); found = true)
+            assertEquals(RuntimeTest1.class, i.next().getClass());
+        assertTrue(found);
+    }
+
+    public void testExtent3() {
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = pm.createExtent(RuntimeTest1.class, true);
+
+        boolean foundB = false;
+        for (Iterator i = ext.iterator(); i.hasNext();)
+            if (i.next().getClass().equals(RuntimeTest2.class))
+                foundB = true;
+        assertTrue(foundB);
+    }
+
+    public void testExtent4() {
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = (Extent) pm.createExtent(RuntimeTest1.class, true);
+
+        List all = new LinkedList();
+        for (Iterator i = ext.iterator(); i.hasNext();)
+            all.add(i.next());
+
+        List aList = ext.list();
+        assertEquals(all.size(), aList.size());
+        assertContainsSame(all, aList);
+    }
+
+    private void assertContainsSame(List l, Collection c) {
+        int size = 0;
+        for (Iterator iter = c.iterator(); iter.hasNext(); iter.next())
+            size++;
+
+        assertEquals(l.size(), size);
+
+        for (Iterator iter = l.iterator(); iter.hasNext();)
+            assertTrue(c.contains(iter.next()));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents2.java
index f3dd415..98d2cef 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestExtents2.java
@@ -1,199 +1,199 @@
-/*
- * TestExtents2.java
- *
- * Created on October 10, 2006, 5:30 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Iterator;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest3;
-
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestExtents2 extends BaseKernelTest {
-
-    private Object _oid1 = null;
-    private Object _oid2 = null;
-    private Object _oid3 = null;
-
-    public TestExtents2(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates a new instance of TestExtents2
-     */
-    public TestExtents2() {
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        RuntimeTest1 test1 = new RuntimeTest1();
-        test1.setIntField(1);
-        RuntimeTest2 test2 = new RuntimeTest2();
-        test2.setIntField(2);
-        test2.setIntField2(2);
-        RuntimeTest3 test3 = new RuntimeTest3();
-        test3.setIntField(3);
-        test3.setIntField3(3);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(test1);
-        pm.persist(test2);
-        pm.persist(test3);
-        _oid1 = pm.getObjectId(test1);
-        _oid2 = pm.getObjectId(test2);
-        _oid3 = pm.getObjectId(test3);
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testProperties() {
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = pm.createExtent(RuntimeTest2.class, false);
-        assertEquals(pm, ext.getEntityManager());
-        assertEquals(RuntimeTest2.class, ext.getElementClass());
-        assertTrue(!ext.hasSubclasses());
-
-        ext = pm.createExtent(RuntimeTest1.class, true);
-        assertEquals(pm, ext.getEntityManager());
-        assertEquals(RuntimeTest1.class, ext.getElementClass());
-        assertTrue(ext.hasSubclasses());
-    }
-
-    public void testNoSubclasses() {
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = pm.createExtent(RuntimeTest1.class, false);
-        Iterator itr = ext.iterator();
-        assertTrue(itr.hasNext());
-        assertEquals(_oid1, pm.getObjectId(itr.next()));
-        assertTrue(!itr.hasNext());
-        ext.closeAll();
-    }
-
-    public void testSubclasses() {
-        OpenJPAEntityManager pm = getPM();
-        Extent ext = pm.createExtent(RuntimeTest1.class, true);
-
-        int test1Count = 0;
-        int test2Count = 0;
-        int test3Count = 0;
-        Object next;
-        for (Iterator itr = ext.iterator(); itr.hasNext();) {
-            next = pm.getObjectId(itr.next());
-            if (_oid1.equals(next))
-                test1Count++;
-            else if (_oid2.equals(next))
-                test2Count++;
-            else if (_oid3.equals(next))
-                test3Count++;
-        }
-        ext.closeAll();
-        assertEquals(1, test1Count);
-        assertEquals(1, test2Count);
-        assertEquals(1, test3Count);
-    }
-
-    public void testContainsNewlyPersisted() {
-        RuntimeTest1 test1 = new RuntimeTest1();
-        RuntimeTest1 test2 = new RuntimeTest2();
-
-        OpenJPAEntityManager pm = getPM();
-
-        // pcl: 14 Oct 2003: default in 3.0 is now true, but this test
-        // assumes false somewhere.
-
-        pm.setIgnoreChanges(false);
-        startTx(pm);
-        try {
-            pm.persist(test1);
-            pm.persist(test2);
-            Object newOid = pm.getObjectId(test1);
-
-            Extent ext = pm.createExtent(RuntimeTest1.class, false);
-            boolean foundOid1 = false;
-            boolean foundNew = false;
-            Object next;
-            for (Iterator itr = ext.iterator(); itr.hasNext();) {
-                next = pm.getObjectId(itr.next());
-                if (_oid1.equals(next))
-                    foundOid1 = true;
-                else if (newOid.equals(next))
-                    foundNew = true;
-                else
-                    fail("Bad object in extent.");
-            }
-            ext.closeAll();
-            assertTrue(foundOid1);
-            assertTrue(foundNew);
-        } finally {
-            rollbackTx(pm);
-        }
-    }
-
-    public void testNotContainsNewlyDeleted() {
-        OpenJPAEntityManager pm = getPM();
-
-        // pcl: 14 Oct 2003: default in 3.0 is now true, but this test
-        // assumes false somewhere.
-        pm.setIgnoreChanges(false);
-        startTx(pm);
-        try {
-            RuntimeTest2 test2 =
-                (RuntimeTest2) pm.find(RuntimeTest2.class, _oid2);
-            pm.remove(test2);
-            RuntimeTest1 test1 = new RuntimeTest1();
-            pm.persist(test1);
-            pm.remove(test1);
-
-            Extent ext = pm.createExtent(RuntimeTest1.class, true);
-            boolean foundOid1 = false;
-            boolean foundOid3 = false;
-            Object next;
-            for (Iterator itr = ext.iterator(); itr.hasNext();) {
-                next = pm.getObjectId(itr.next());
-                if (_oid1.equals(next))
-                    foundOid1 = true;
-                else if (_oid3.equals(next))
-                    foundOid3 = true;
-                else
-                    fail("Bad object in extent.");
-            }
-            ext.closeAll();
-            assertTrue(foundOid1);
-            assertTrue(foundOid3);
-        } finally {
-            rollbackTx(pm);
-        }
-    }
-}
+/*
+ * TestExtents2.java
+ *
+ * Created on October 10, 2006, 5:30 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Iterator;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest3;
+
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestExtents2 extends BaseKernelTest {
+
+    private Object _oid1 = null;
+    private Object _oid2 = null;
+    private Object _oid3 = null;
+
+    public TestExtents2(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates a new instance of TestExtents2
+     */
+    public TestExtents2() {
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        RuntimeTest1 test1 = new RuntimeTest1();
+        test1.setIntField(1);
+        RuntimeTest2 test2 = new RuntimeTest2();
+        test2.setIntField(2);
+        test2.setIntField2(2);
+        RuntimeTest3 test3 = new RuntimeTest3();
+        test3.setIntField(3);
+        test3.setIntField3(3);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(test1);
+        pm.persist(test2);
+        pm.persist(test3);
+        _oid1 = pm.getObjectId(test1);
+        _oid2 = pm.getObjectId(test2);
+        _oid3 = pm.getObjectId(test3);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testProperties() {
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = pm.createExtent(RuntimeTest2.class, false);
+        assertEquals(pm, ext.getEntityManager());
+        assertEquals(RuntimeTest2.class, ext.getElementClass());
+        assertTrue(!ext.hasSubclasses());
+
+        ext = pm.createExtent(RuntimeTest1.class, true);
+        assertEquals(pm, ext.getEntityManager());
+        assertEquals(RuntimeTest1.class, ext.getElementClass());
+        assertTrue(ext.hasSubclasses());
+    }
+
+    public void testNoSubclasses() {
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = pm.createExtent(RuntimeTest1.class, false);
+        Iterator itr = ext.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals(_oid1, pm.getObjectId(itr.next()));
+        assertTrue(!itr.hasNext());
+        ext.closeAll();
+    }
+
+    public void testSubclasses() {
+        OpenJPAEntityManager pm = getPM();
+        Extent ext = pm.createExtent(RuntimeTest1.class, true);
+
+        int test1Count = 0;
+        int test2Count = 0;
+        int test3Count = 0;
+        Object next;
+        for (Iterator itr = ext.iterator(); itr.hasNext();) {
+            next = pm.getObjectId(itr.next());
+            if (_oid1.equals(next))
+                test1Count++;
+            else if (_oid2.equals(next))
+                test2Count++;
+            else if (_oid3.equals(next))
+                test3Count++;
+        }
+        ext.closeAll();
+        assertEquals(1, test1Count);
+        assertEquals(1, test2Count);
+        assertEquals(1, test3Count);
+    }
+
+    public void testContainsNewlyPersisted() {
+        RuntimeTest1 test1 = new RuntimeTest1();
+        RuntimeTest1 test2 = new RuntimeTest2();
+
+        OpenJPAEntityManager pm = getPM();
+
+        // pcl: 14 Oct 2003: default in 3.0 is now true, but this test
+        // assumes false somewhere.
+
+        pm.setIgnoreChanges(false);
+        startTx(pm);
+        try {
+            pm.persist(test1);
+            pm.persist(test2);
+            Object newOid = pm.getObjectId(test1);
+
+            Extent ext = pm.createExtent(RuntimeTest1.class, false);
+            boolean foundOid1 = false;
+            boolean foundNew = false;
+            Object next;
+            for (Iterator itr = ext.iterator(); itr.hasNext();) {
+                next = pm.getObjectId(itr.next());
+                if (_oid1.equals(next))
+                    foundOid1 = true;
+                else if (newOid.equals(next))
+                    foundNew = true;
+                else
+                    fail("Bad object in extent.");
+            }
+            ext.closeAll();
+            assertTrue(foundOid1);
+            assertTrue(foundNew);
+        } finally {
+            rollbackTx(pm);
+        }
+    }
+
+    public void testNotContainsNewlyDeleted() {
+        OpenJPAEntityManager pm = getPM();
+
+        // pcl: 14 Oct 2003: default in 3.0 is now true, but this test
+        // assumes false somewhere.
+        pm.setIgnoreChanges(false);
+        startTx(pm);
+        try {
+            RuntimeTest2 test2 =
+                (RuntimeTest2) pm.find(RuntimeTest2.class, _oid2);
+            pm.remove(test2);
+            RuntimeTest1 test1 = new RuntimeTest1();
+            pm.persist(test1);
+            pm.remove(test1);
+
+            Extent ext = pm.createExtent(RuntimeTest1.class, true);
+            boolean foundOid1 = false;
+            boolean foundOid3 = false;
+            Object next;
+            for (Iterator itr = ext.iterator(); itr.hasNext();) {
+                next = pm.getObjectId(itr.next());
+                if (_oid1.equals(next))
+                    foundOid1 = true;
+                else if (_oid3.equals(next))
+                    foundOid3 = true;
+                else
+                    fail("Bad object in extent.");
+            }
+            ext.closeAll();
+            assertTrue(foundOid1);
+            assertTrue(foundOid3);
+        } finally {
+            rollbackTx(pm);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroups.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroups.java
index 3b58ec6..8df8554 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroups.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroups.java
@@ -1,403 +1,403 @@
-/*
- * TestFetchGroups.java
- *
- * Created on October 10, 2006, 5:46 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AttachA;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachB;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachC;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachD;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachE;
-import org.apache.openjpa.persistence.kernel.common.apps.AttachF;
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.FetchPlan;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestFetchGroups extends BaseKernelTest {
-
-    private int oid1;
-    private int oid2;
-    private int oidc1;
-
-    public TestFetchGroups(String s) {
-        super(s);
-    }
-
-    /**
-     * Creates a new instance of TestFetchGroups
-     */
-    public TestFetchGroups() {
-    }
-
-    public void setUp() {
-        deleteAll(FetchGroupTestObject.class);
-
-        FetchGroupTestObject o1 = new FetchGroupTestObject();
-        // the value that 'a' is set to is important -- TestFetchGroupsExtent
-        // and TestFetchGroupsQuery rely on this
-        o1.setA(5);
-        o1.setB("foo");
-        //o1.setC (new BigInteger (89));
-        o1.setD(new Date());
-        o1.setE("e-foo");
-        o1.setF("f-foo");
-
-        FetchGroupTestObject o2 = new FetchGroupTestObject();
-        // the value that 'a' is set to is important -- TestFetchGroupsExtent
-        // and TestFetchGroupsQuery rely on this
-        o2.setA(3);
-        o2.setB("bar");
-        //o2.setC (new BigInteger (13));
-        o2.setD(new Date());
-        o2.setE("e-bar");
-        o2.setF("f-bar");
-        o2.setG(o1);
-        o2.setH(o1);
-
-        FetchGroupTestObjectChild c1 = new FetchGroupTestObjectChild();
-        // the value that 'a' is set to is important -- TestFetchGroupsExtent
-        // and TestFetchGroupsQuery rely on this
-        c1.setA(4);
-        c1.setB("child");
-        c1.setD(new Date());
-        c1.setE("e-baz");
-        c1.setF("f-baz");
-        c1.setG(o1);
-        c1.setH(o1);
-        c1.setChildA(1);
-        c1.setChildB(2);
-        c1.setChildC(3);
-        c1.setChildD(4);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        pm.persist(o1);
-        pm.persist(o2);
-        pm.persist(c1);
-        endTx(pm);
-
-        oid1 = o1.getId();
-        oid2 = o2.getId();
-        oidc1 = c1.getId();
-
-        endEm(pm);
-    }
-
-    public void testFetchGroupsFromConfiguration() {
-        Map props = new HashMap();
-        props.put("openjpa.FetchGroups", "default,fg1,fg2");
-        OpenJPAEntityManagerFactory factory = getEmf(props);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) factory.createEntityManager();
-        checkGroups(pm, new String[]{ "fg1", "fg2" });
-        factory.close();
-    }
-
-    public void testFetchGroupsNoConfiguration() {
-        OpenJPAEntityManager pm = getPM();
-
-        FetchGroupTestObject o1 = getO1(pm);
-        FetchGroupTestObject o2 = getO2(pm);
-
-        // only field a should be loaded.
-        checkObject(pm, o1, true, false, false, false, false, false);
-
-        // upon loading field b, fields c and d should also be loaded,
-        // but e and f should not.
-        o1.getB();
-        checkObject(pm, o1, true, true, true, true, false, false);
-
-        // loading field h should not cause any of the others to be loaded.
-        assertEquals(o1, o2.getH());
-        checkObject(pm, o2, true, false, false, false, false, false);
-
-        // loading field g should cause e and f to be loaded.
-        assertEquals(o1, o2.getG());
-        checkObject(pm, o2, true, false, false, false, true, true);
-    }
-
-    public void testRetrieveAll() {
-        OpenJPAEntityManager pm = getPM();
-
-        FetchGroupTestObject o1 = getO1(pm);
-        FetchGroupTestObject o2 = getO2(pm);
-
-        // only field a should be loaded.
-        checkObject(pm, o1, true, false, false, false, false, false);
-        checkObject(pm, o2, true, false, false, false, false, false);
-
-        // only field a should be loaded.
-        pm.retrieve(o1);
-        checkObject(pm, o1, true, false, false, false, false, false);
-
-        // Add groups 1 and 3 to the default fetch configuration.
-        pm.getFetchPlan().addFetchGroup("g1");
-        pm.getFetchPlan().addFetchGroup("g3");
-
-        // Retrieve o1's "DFG" which will actually do all configured
-        // fetch groups.
-        // DFG fields and fields in groups 1 and 3 should be loaded
-        pm.retrieve(o1);
-        checkObject(pm, o1, true, true, true, true, false, false);
-    }
-
-    public void testFetchGroupConfiguration() {
-        OpenJPAEntityManager pm = getPM();
-        FetchPlan fetch = pm.getFetchPlan();
-
-        checkGroups(pm, new String[0]);
-
-        fetch.addFetchGroup("foo");
-        checkGroups(pm, new String[]{ "foo" });
-
-        fetch.addFetchGroup("bar");
-        fetch.addFetchGroup("baz");
-        checkGroups(pm, new String[]{ "foo", "bar", "baz" });
-
-        fetch.addFetchGroup("a");
-        fetch.addFetchGroup("b");
-        fetch.addFetchGroup("c");
-        fetch.addFetchGroup("d");
-        checkGroups(pm, new String[]
-            { "foo", "bar", "baz", "a", "b", "c", "d" });
-
-        fetch.removeFetchGroup("bar");
-        checkGroups(pm, new String[]{ "foo", "baz", "a", "b", "c", "d" });
-
-        fetch.removeFetchGroup("baz");
-        fetch.removeFetchGroup("c");
-        checkGroups(pm, new String[]{ "foo", "a", "b", "d" });
-
-        fetch.clearFetchGroups().addFetchGroup(FetchPlan.GROUP_DEFAULT);
-        checkGroups(pm, new String[0]);
-    }
-
-    private void checkGroups(OpenJPAEntityManager pm, String[] groups) {
-        HashSet groupSet = new HashSet(Arrays.asList(groups));
-        groupSet.add(FetchPlan.GROUP_DEFAULT);
-        assertEquals("groupSet dont match", groupSet,
-            new HashSet(pm.getFetchPlan().getFetchGroups()));
-    }
-
-    public void testFetchGroupsChildWithConfiguration() {
-        OpenJPAEntityManager pm = getPM();
-        pm.getFetchPlan().addFetchGroup("g1");
-        pm.getFetchPlan().addFetchGroup("g3");
-
-        // get this so that h's value is loaded into cache.
-        FetchGroupTestObject o1 = getO1(pm);
-
-        FetchGroupTestObjectChild c1 = getC1(pm);
-
-        // DFG fields and fields in groups 1 and 3 should be loaded
-        checkChildObject(pm, c1, true, true, true, true, false, false,
-            true, true, false, true);
-
-        // upon accessing field b, nothing should change.
-        c1.getB();
-        checkChildObject(pm, c1, true, true, true, true, false, false,
-            true, true, false, true);
-
-        c1.getH();
-    }
-
-    public void testFetchGroupsWithConfiguration() {
-        OpenJPAEntityManager pm = getPM();
-
-        pm.getFetchPlan().addFetchGroup("g1");
-        pm.getFetchPlan().addFetchGroup("g3");
-
-        FetchGroupTestObject o1 = getO1(pm);
-        FetchGroupTestObject o2 = getO2(pm);
-
-        // DFG fields and fields in groups 1 and 3 should be loaded
-        checkObject(pm, o1, true, true, true, true, false, false);
-
-        // upon accessing field b, nothing should change.
-        o1.getB();
-        checkObject(pm, o1, true, true, true, true, false, false);
-
-        // loading field h should not cause any of the others to be loaded.
-        assertEquals(o1, o2.getH());
-        checkObject(pm, o2, true, true, true, true, false, false);
-
-        // loading field g should cause e and f to be loaded.
-        assertEquals(o1, o2.getG());
-        checkObject(pm, o2, true, true, true, true, true, true);
-    }
-
-    /**
-     * Tests that relation fields are loaded immediately when
-     * they are in one of the PM's configured fetch groups.
-     */
-    public void testRelationsLoaded() {
-        OpenJPAEntityManager pm = getPM();
-        pm.getFetchPlan().addFetchGroup("g2");
-
-        // note: important the o1 is *not* in pm's cache at this point, so that
-        // we know it takes another datastore trip to get o1
-
-        // load o2 and retrieve its state manager
-        OpenJPAStateManager sm = getStateManager(getO2(pm), pm);
-        assertNotNull("SM is NULL", sm);
-
-        // 'g' is the name of a 1-1 relation field to o1 in configured
-        // fetch group 'g2'; make sure it is loaded
-        int field = sm.getMetaData().getField("g").getIndex();
-        try {
-            assertTrue(sm.getLoaded().get(field));
-            assertEquals(oid1,
-                ((FetchGroupTestObject) sm.fetchObjectField(field)).getId());
-        } catch (junit.framework.AssertionFailedError afe) {
-            bug(623, afe, "One to one mappings do not work with custom "
-                + "fetch groups");
-        }
-    }
-
-    protected void checkObject(OpenJPAEntityManager pm,
-        FetchGroupTestObject o, boolean a, boolean b,
-        boolean c, boolean d, boolean e, boolean f) {
-        OpenJPAStateManager sm = getStateManager(o, pm);
-        BitSet loaded = sm.getLoaded();
-
-        FieldMetaData[] fmds = sm.getMetaData().getFields();
-        int i = 0;
-        for (; i < fmds.length; i++) {
-            if (fmds[i].getName().equals("a"))
-                assertEquals(a, loaded.get(i));
-            else if (fmds[i].getName().equals("b"))
-                assertEquals(b, loaded.get(i));
-            else if (fmds[i].getName().equals("c"))
-                assertEquals(c, loaded.get(i));
-            else if (fmds[i].getName().equals("d"))
-                assertEquals(d, loaded.get(i));
-            else if (fmds[i].getName().equals("e"))
-                assertEquals(e, loaded.get(i));
-            else if (fmds[i].getName().equals("f"))
-                assertEquals(f, loaded.get(i));
-        }
-    }
-
-    protected void checkChildObject(OpenJPAEntityManager pm,
-        FetchGroupTestObjectChild o, boolean a, boolean b,
-        boolean c, boolean d, boolean e, boolean f, boolean childA,
-        boolean childB, boolean childC, boolean childD) {
-        checkObject(pm, o, a, b, c, d, e, f);
-
-        OpenJPAStateManager sm = getStateManager(o, pm);
-        BitSet loaded = sm.getLoaded();
-
-        FieldMetaData[] fmds = sm.getMetaData().getFields();
-        int i = 0;
-        for (; i < fmds.length; i++) {
-            if (fmds[i].getName().equals("childA"))
-                assertEquals(childA, loaded.get(i));
-            else if (fmds[i].getName().equals("childB"))
-                assertEquals(childB, loaded.get(i));
-            else if (fmds[i].getName().equals("childC"))
-                assertEquals(childC, loaded.get(i));
-            else if (fmds[i].getName().equals("childD"))
-                assertEquals(childD, loaded.get(i));
-        }
-    }
-
-    protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
-        return pm.find(FetchGroupTestObject.class, oid1);
-    }
-
-    protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
-        return pm.find(FetchGroupTestObject.class, oid2);
-    }
-
-    protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
-        return pm.find(FetchGroupTestObjectChild.class, oidc1);
-    }
-
-    /**
-     * Tests that named fetch groups actually bring in the
-     * managed object.
-     */
-    public void testFetchGroupInstantiated() {
-        deleteAll(AttachA.class);
-        deleteAll(AttachB.class);
-        deleteAll(AttachC.class);
-        deleteAll(AttachD.class);
-        deleteAll(AttachE.class);
-        deleteAll(AttachF.class);
-
-        OpenJPAEntityManager pm;
-
-        pm = getPM();
-        startTx(pm);
-        AttachE e = new AttachE();
-        AttachB b = new AttachB();
-        e.setB(b);
-        pm.persist(e);
-
-        endTx(pm);
-        endEm(pm);
-
-        Object ob;
-
-        pm = getPM();
-        startTx(pm);
-        assertSize(0, pm.getManagedObjects());
-        ob = pm.createExtent(AttachE.class, true).iterator().next();
-        // make sure relation is not loaded
-        assertSize(1, pm.getManagedObjects());
-        rollbackTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        startTx(pm);
-        // now make sure we load relations
-        pm.getFetchPlan().addFetchGroup("all");
-        assertSize(0, pm.getManagedObjects());
-        ob = pm.createExtent(AttachE.class, true).iterator().next();
-        // make sure relation is loaded
-        assertSize(2, pm.getManagedObjects());
-        rollbackTx(pm);
-        endEm(pm);
-    }
-}
+/*
+ * TestFetchGroups.java
+ *
+ * Created on October 10, 2006, 5:46 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AttachA;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachB;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachC;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachD;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachE;
+import org.apache.openjpa.persistence.kernel.common.apps.AttachF;
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.FetchPlan;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestFetchGroups extends BaseKernelTest {
+
+    private int oid1;
+    private int oid2;
+    private int oidc1;
+
+    public TestFetchGroups(String s) {
+        super(s);
+    }
+
+    /**
+     * Creates a new instance of TestFetchGroups
+     */
+    public TestFetchGroups() {
+    }
+
+    public void setUp() {
+        deleteAll(FetchGroupTestObject.class);
+
+        FetchGroupTestObject o1 = new FetchGroupTestObject();
+        // the value that 'a' is set to is important -- TestFetchGroupsExtent
+        // and TestFetchGroupsQuery rely on this
+        o1.setA(5);
+        o1.setB("foo");
+        //o1.setC (new BigInteger (89));
+        o1.setD(new Date());
+        o1.setE("e-foo");
+        o1.setF("f-foo");
+
+        FetchGroupTestObject o2 = new FetchGroupTestObject();
+        // the value that 'a' is set to is important -- TestFetchGroupsExtent
+        // and TestFetchGroupsQuery rely on this
+        o2.setA(3);
+        o2.setB("bar");
+        //o2.setC (new BigInteger (13));
+        o2.setD(new Date());
+        o2.setE("e-bar");
+        o2.setF("f-bar");
+        o2.setG(o1);
+        o2.setH(o1);
+
+        FetchGroupTestObjectChild c1 = new FetchGroupTestObjectChild();
+        // the value that 'a' is set to is important -- TestFetchGroupsExtent
+        // and TestFetchGroupsQuery rely on this
+        c1.setA(4);
+        c1.setB("child");
+        c1.setD(new Date());
+        c1.setE("e-baz");
+        c1.setF("f-baz");
+        c1.setG(o1);
+        c1.setH(o1);
+        c1.setChildA(1);
+        c1.setChildB(2);
+        c1.setChildC(3);
+        c1.setChildD(4);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        pm.persist(o1);
+        pm.persist(o2);
+        pm.persist(c1);
+        endTx(pm);
+
+        oid1 = o1.getId();
+        oid2 = o2.getId();
+        oidc1 = c1.getId();
+
+        endEm(pm);
+    }
+
+    public void testFetchGroupsFromConfiguration() {
+        Map props = new HashMap();
+        props.put("openjpa.FetchGroups", "default,fg1,fg2");
+        OpenJPAEntityManagerFactory factory = getEmf(props);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) factory.createEntityManager();
+        checkGroups(pm, new String[]{ "fg1", "fg2" });
+        factory.close();
+    }
+
+    public void testFetchGroupsNoConfiguration() {
+        OpenJPAEntityManager pm = getPM();
+
+        FetchGroupTestObject o1 = getO1(pm);
+        FetchGroupTestObject o2 = getO2(pm);
+
+        // only field a should be loaded.
+        checkObject(pm, o1, true, false, false, false, false, false);
+
+        // upon loading field b, fields c and d should also be loaded,
+        // but e and f should not.
+        o1.getB();
+        checkObject(pm, o1, true, true, true, true, false, false);
+
+        // loading field h should not cause any of the others to be loaded.
+        assertEquals(o1, o2.getH());
+        checkObject(pm, o2, true, false, false, false, false, false);
+
+        // loading field g should cause e and f to be loaded.
+        assertEquals(o1, o2.getG());
+        checkObject(pm, o2, true, false, false, false, true, true);
+    }
+
+    public void testRetrieveAll() {
+        OpenJPAEntityManager pm = getPM();
+
+        FetchGroupTestObject o1 = getO1(pm);
+        FetchGroupTestObject o2 = getO2(pm);
+
+        // only field a should be loaded.
+        checkObject(pm, o1, true, false, false, false, false, false);
+        checkObject(pm, o2, true, false, false, false, false, false);
+
+        // only field a should be loaded.
+        pm.retrieve(o1);
+        checkObject(pm, o1, true, false, false, false, false, false);
+
+        // Add groups 1 and 3 to the default fetch configuration.
+        pm.getFetchPlan().addFetchGroup("g1");
+        pm.getFetchPlan().addFetchGroup("g3");
+
+        // Retrieve o1's "DFG" which will actually do all configured
+        // fetch groups.
+        // DFG fields and fields in groups 1 and 3 should be loaded
+        pm.retrieve(o1);
+        checkObject(pm, o1, true, true, true, true, false, false);
+    }
+
+    public void testFetchGroupConfiguration() {
+        OpenJPAEntityManager pm = getPM();
+        FetchPlan fetch = pm.getFetchPlan();
+
+        checkGroups(pm, new String[0]);
+
+        fetch.addFetchGroup("foo");
+        checkGroups(pm, new String[]{ "foo" });
+
+        fetch.addFetchGroup("bar");
+        fetch.addFetchGroup("baz");
+        checkGroups(pm, new String[]{ "foo", "bar", "baz" });
+
+        fetch.addFetchGroup("a");
+        fetch.addFetchGroup("b");
+        fetch.addFetchGroup("c");
+        fetch.addFetchGroup("d");
+        checkGroups(pm, new String[]
+            { "foo", "bar", "baz", "a", "b", "c", "d" });
+
+        fetch.removeFetchGroup("bar");
+        checkGroups(pm, new String[]{ "foo", "baz", "a", "b", "c", "d" });
+
+        fetch.removeFetchGroup("baz");
+        fetch.removeFetchGroup("c");
+        checkGroups(pm, new String[]{ "foo", "a", "b", "d" });
+
+        fetch.clearFetchGroups().addFetchGroup(FetchPlan.GROUP_DEFAULT);
+        checkGroups(pm, new String[0]);
+    }
+
+    private void checkGroups(OpenJPAEntityManager pm, String[] groups) {
+        HashSet groupSet = new HashSet(Arrays.asList(groups));
+        groupSet.add(FetchPlan.GROUP_DEFAULT);
+        assertEquals("groupSet dont match", groupSet,
+            new HashSet(pm.getFetchPlan().getFetchGroups()));
+    }
+
+    public void testFetchGroupsChildWithConfiguration() {
+        OpenJPAEntityManager pm = getPM();
+        pm.getFetchPlan().addFetchGroup("g1");
+        pm.getFetchPlan().addFetchGroup("g3");
+
+        // get this so that h's value is loaded into cache.
+        FetchGroupTestObject o1 = getO1(pm);
+
+        FetchGroupTestObjectChild c1 = getC1(pm);
+
+        // DFG fields and fields in groups 1 and 3 should be loaded
+        checkChildObject(pm, c1, true, true, true, true, false, false,
+            true, true, false, true);
+
+        // upon accessing field b, nothing should change.
+        c1.getB();
+        checkChildObject(pm, c1, true, true, true, true, false, false,
+            true, true, false, true);
+
+        c1.getH();
+    }
+
+    public void testFetchGroupsWithConfiguration() {
+        OpenJPAEntityManager pm = getPM();
+
+        pm.getFetchPlan().addFetchGroup("g1");
+        pm.getFetchPlan().addFetchGroup("g3");
+
+        FetchGroupTestObject o1 = getO1(pm);
+        FetchGroupTestObject o2 = getO2(pm);
+
+        // DFG fields and fields in groups 1 and 3 should be loaded
+        checkObject(pm, o1, true, true, true, true, false, false);
+
+        // upon accessing field b, nothing should change.
+        o1.getB();
+        checkObject(pm, o1, true, true, true, true, false, false);
+
+        // loading field h should not cause any of the others to be loaded.
+        assertEquals(o1, o2.getH());
+        checkObject(pm, o2, true, true, true, true, false, false);
+
+        // loading field g should cause e and f to be loaded.
+        assertEquals(o1, o2.getG());
+        checkObject(pm, o2, true, true, true, true, true, true);
+    }
+
+    /**
+     * Tests that relation fields are loaded immediately when
+     * they are in one of the PM's configured fetch groups.
+     */
+    public void testRelationsLoaded() {
+        OpenJPAEntityManager pm = getPM();
+        pm.getFetchPlan().addFetchGroup("g2");
+
+        // note: important the o1 is *not* in pm's cache at this point, so that
+        // we know it takes another datastore trip to get o1
+
+        // load o2 and retrieve its state manager
+        OpenJPAStateManager sm = getStateManager(getO2(pm), pm);
+        assertNotNull("SM is NULL", sm);
+
+        // 'g' is the name of a 1-1 relation field to o1 in configured
+        // fetch group 'g2'; make sure it is loaded
+        int field = sm.getMetaData().getField("g").getIndex();
+        try {
+            assertTrue(sm.getLoaded().get(field));
+            assertEquals(oid1,
+                ((FetchGroupTestObject) sm.fetchObjectField(field)).getId());
+        } catch (junit.framework.AssertionFailedError afe) {
+            bug(623, afe, "One to one mappings do not work with custom "
+                + "fetch groups");
+        }
+    }
+
+    protected void checkObject(OpenJPAEntityManager pm,
+        FetchGroupTestObject o, boolean a, boolean b,
+        boolean c, boolean d, boolean e, boolean f) {
+        OpenJPAStateManager sm = getStateManager(o, pm);
+        BitSet loaded = sm.getLoaded();
+
+        FieldMetaData[] fmds = sm.getMetaData().getFields();
+        int i = 0;
+        for (; i < fmds.length; i++) {
+            if (fmds[i].getName().equals("a"))
+                assertEquals(a, loaded.get(i));
+            else if (fmds[i].getName().equals("b"))
+                assertEquals(b, loaded.get(i));
+            else if (fmds[i].getName().equals("c"))
+                assertEquals(c, loaded.get(i));
+            else if (fmds[i].getName().equals("d"))
+                assertEquals(d, loaded.get(i));
+            else if (fmds[i].getName().equals("e"))
+                assertEquals(e, loaded.get(i));
+            else if (fmds[i].getName().equals("f"))
+                assertEquals(f, loaded.get(i));
+        }
+    }
+
+    protected void checkChildObject(OpenJPAEntityManager pm,
+        FetchGroupTestObjectChild o, boolean a, boolean b,
+        boolean c, boolean d, boolean e, boolean f, boolean childA,
+        boolean childB, boolean childC, boolean childD) {
+        checkObject(pm, o, a, b, c, d, e, f);
+
+        OpenJPAStateManager sm = getStateManager(o, pm);
+        BitSet loaded = sm.getLoaded();
+
+        FieldMetaData[] fmds = sm.getMetaData().getFields();
+        int i = 0;
+        for (; i < fmds.length; i++) {
+            if (fmds[i].getName().equals("childA"))
+                assertEquals(childA, loaded.get(i));
+            else if (fmds[i].getName().equals("childB"))
+                assertEquals(childB, loaded.get(i));
+            else if (fmds[i].getName().equals("childC"))
+                assertEquals(childC, loaded.get(i));
+            else if (fmds[i].getName().equals("childD"))
+                assertEquals(childD, loaded.get(i));
+        }
+    }
+
+    protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
+        return pm.find(FetchGroupTestObject.class, oid1);
+    }
+
+    protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
+        return pm.find(FetchGroupTestObject.class, oid2);
+    }
+
+    protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
+        return pm.find(FetchGroupTestObjectChild.class, oidc1);
+    }
+
+    /**
+     * Tests that named fetch groups actually bring in the
+     * managed object.
+     */
+    public void testFetchGroupInstantiated() {
+        deleteAll(AttachA.class);
+        deleteAll(AttachB.class);
+        deleteAll(AttachC.class);
+        deleteAll(AttachD.class);
+        deleteAll(AttachE.class);
+        deleteAll(AttachF.class);
+
+        OpenJPAEntityManager pm;
+
+        pm = getPM();
+        startTx(pm);
+        AttachE e = new AttachE();
+        AttachB b = new AttachB();
+        e.setB(b);
+        pm.persist(e);
+
+        endTx(pm);
+        endEm(pm);
+
+        Object ob;
+
+        pm = getPM();
+        startTx(pm);
+        assertSize(0, pm.getManagedObjects());
+        ob = pm.createExtent(AttachE.class, true).iterator().next();
+        // make sure relation is not loaded
+        assertSize(1, pm.getManagedObjects());
+        rollbackTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        startTx(pm);
+        // now make sure we load relations
+        pm.getFetchPlan().addFetchGroup("all");
+        assertSize(0, pm.getManagedObjects());
+        ob = pm.createExtent(AttachE.class, true).iterator().next();
+        // make sure relation is loaded
+        assertSize(2, pm.getManagedObjects());
+        rollbackTx(pm);
+        endEm(pm);
+    }
+}
  
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsExtent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsExtent.java
index b3694d4..9823033 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsExtent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsExtent.java
@@ -1,91 +1,91 @@
-/*
- * TestFetchGroupsExtent.java
- *
- * Created on October 12, 2006, 9:54 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.List;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
-
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestFetchGroupsExtent extends TestFetchGroups {
-
-    /**
-     * Creates a new instance of TestFetchGroupsExtent
-     */
-    public TestFetchGroupsExtent() {
-    }
-
-    public TestFetchGroupsExtent(String s) {
-        super(s);
-    }
-
-    protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
-        Extent e = (Extent) pm.createExtent(FetchGroupTestObject.class,
-            true);
-        List l = e.list();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 5");
-        q.setCandidateCollection(l);
-
-        return (FetchGroupTestObject)
-            ((Collection) q.getResultList()).iterator().next();
-    }
-
-    protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
-        Extent e = (Extent) pm.createExtent(FetchGroupTestObject.class,
-            true);
-        List l = e.list();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 3");
-        q.setCandidateCollection(l);
-
-        return (FetchGroupTestObject)
-            ((Collection) q.getResultList()).iterator().next();
-    }
-
-    protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
-        Extent e = (Extent) pm.createExtent(FetchGroupTestObject.class,
-            true);
-        List l = e.list();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM FetchGroupTestObjectChild o WHERE o.a = 4");
-        q.setCandidateCollection(l);
-
-        return (FetchGroupTestObjectChild)
-            ((Collection) q.getResultList()).iterator().next();
-    }
-}
+/*
+ * TestFetchGroupsExtent.java
+ *
+ * Created on October 12, 2006, 9:54 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.List;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
+
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestFetchGroupsExtent extends TestFetchGroups {
+
+    /**
+     * Creates a new instance of TestFetchGroupsExtent
+     */
+    public TestFetchGroupsExtent() {
+    }
+
+    public TestFetchGroupsExtent(String s) {
+        super(s);
+    }
+
+    protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
+        Extent e = (Extent) pm.createExtent(FetchGroupTestObject.class,
+            true);
+        List l = e.list();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 5");
+        q.setCandidateCollection(l);
+
+        return (FetchGroupTestObject)
+            ((Collection) q.getResultList()).iterator().next();
+    }
+
+    protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
+        Extent e = (Extent) pm.createExtent(FetchGroupTestObject.class,
+            true);
+        List l = e.list();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 3");
+        q.setCandidateCollection(l);
+
+        return (FetchGroupTestObject)
+            ((Collection) q.getResultList()).iterator().next();
+    }
+
+    protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
+        Extent e = (Extent) pm.createExtent(FetchGroupTestObject.class,
+            true);
+        List l = e.list();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM FetchGroupTestObjectChild o WHERE o.a = 4");
+        q.setCandidateCollection(l);
+
+        return (FetchGroupTestObjectChild)
+            ((Collection) q.getResultList()).iterator().next();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsQuery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsQuery.java
index ecb0409..8c07d5a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsQuery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchGroupsQuery.java
@@ -1,87 +1,87 @@
-/*
- * TestFetchGroupsQuery.java
- *
- * Created on October 12, 2006, 10:09 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.List;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestFetchGroupsQuery extends TestFetchGroups {
-
-    /**
-     * Creates a new instance of TestFetchGroupsQuery
-     */
-    public TestFetchGroupsQuery() {
-    }
-
-    public TestFetchGroupsQuery(String s) {
-        super(s);
-    }
-
-    protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
-//        OpenJPAQuery q = pm.createNativeQuery("a == 5",FetchGroupTestObject.class);
-//        return (FetchGroupTestObject)
-//        ((Collection) q.getResultList()).iterator().next();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 5");
-        List l = q.getResultList();
-
-        return (FetchGroupTestObject) (l.iterator().next());
-    }
-
-    protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
-//        OpenJPAQuery q = pm.createNativeQuery("a == 3",FetchGroupTestObject.class);
-//        return (FetchGroupTestObject)
-//        ((Collection) q.getResultList()).iterator().next();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 3");
-        List l = q.getResultList();
-
-        return (FetchGroupTestObject) (l.iterator().next());
-    }
-
-    protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
-//        OpenJPAQuery q = pm.createNativeQuery("a == 4",FetchGroupTestObjectChild.class);
-//        return (FetchGroupTestObjectChild)
-//        ((Collection) q.getResultList()).iterator().next();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM FetchGroupTestObjectChild o WHERE o.a = 4");
-        List l = q.getResultList();
-
-        return (FetchGroupTestObjectChild) (l.iterator().next());
-    }
-}
+/*
+ * TestFetchGroupsQuery.java
+ *
+ * Created on October 12, 2006, 10:09 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.List;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestFetchGroupsQuery extends TestFetchGroups {
+
+    /**
+     * Creates a new instance of TestFetchGroupsQuery
+     */
+    public TestFetchGroupsQuery() {
+    }
+
+    public TestFetchGroupsQuery(String s) {
+        super(s);
+    }
+
+    protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
+//        OpenJPAQuery q = pm.createNativeQuery("a == 5",FetchGroupTestObject.class);
+//        return (FetchGroupTestObject)
+//        ((Collection) q.getResultList()).iterator().next();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 5");
+        List l = q.getResultList();
+
+        return (FetchGroupTestObject) (l.iterator().next());
+    }
+
+    protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
+//        OpenJPAQuery q = pm.createNativeQuery("a == 3",FetchGroupTestObject.class);
+//        return (FetchGroupTestObject)
+//        ((Collection) q.getResultList()).iterator().next();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM FetchGroupTestObject o WHERE o.a = 3");
+        List l = q.getResultList();
+
+        return (FetchGroupTestObject) (l.iterator().next());
+    }
+
+    protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
+//        OpenJPAQuery q = pm.createNativeQuery("a == 4",FetchGroupTestObjectChild.class);
+//        return (FetchGroupTestObjectChild)
+//        ((Collection) q.getResultList()).iterator().next();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM FetchGroupTestObjectChild o WHERE o.a = 4");
+        List l = q.getResultList();
+
+        return (FetchGroupTestObjectChild) (l.iterator().next());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchPlan.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchPlan.java
index 84eb02d..207f797 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchPlan.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFetchPlan.java
@@ -1,526 +1,526 @@
-/*
- * TestFetchPlan.java
- *
- * Created on October 16, 2006, 3:02 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.PCAddress;
-import org.apache.openjpa.persistence.kernel.common.apps.PCCompany;
-import org.apache.openjpa.persistence.kernel.common.apps.PCCountry;
-import org.apache.openjpa.persistence.kernel.common.apps.PCDepartment;
-import org.apache.openjpa.persistence.kernel.common.apps.PCDirectory;
-import org.apache.openjpa.persistence.kernel.common.apps.PCEmployee;
-import org.apache.openjpa.persistence.kernel.common.apps.PCFile;
-import org.apache.openjpa.persistence.kernel.common.apps.PCPerson;
-
-import org.apache.openjpa.persistence.FetchPlan;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestFetchPlan extends BaseKernelTest {
-
-    static Object _rootDirId;
-    static Object _rootCompanyId;
-
-    static final int MAX_DEPTH = 5; // Maximum depth of the directories
-    static final int MAX_CHILD = 3; // Maximum number of files/directory
-    static final String quote = "\"";
-    private static boolean firstTime = true;
-
-    /**
-     * Creates a new instance of TestFetchPlan
-     */
-    public TestFetchPlan() {
-    }
-
-    public TestFetchPlan(String name) {
-        super(name);
-    }
-
-    /**
-     * Clears past data and creates new data for test.
-     * Clear test data before and not <em>after</em> such that one can analyze
-     * the database for test failures.
-     */
-    public void setUp() throws Exception {
-        if (firstTime) {
-            firstTime = false;
-            clearTestData();
-            createTestData();
-        }
-    }
-
-    /**
-     * Create a directory tree of MAX_DEPTH with each directory having a single
-     * directory and MAX_CHILD files.
-     * Creates typical Employee-Department-Company-Address instances.
-     *
-     * @return the persitent identifier of the root directory.
-     */
-    void createTestData() {
-        // create a tree of directories with files in them
-        PCDirectory rootDir = new PCDirectory(getDirectoryName(0));
-        PCDirectory parent = rootDir;
-        for (int i = 1; i <= MAX_DEPTH; i++) {
-            PCDirectory dir = new PCDirectory(getDirectoryName(i));
-            parent.add(dir);
-
-            for (int j = 0; j < MAX_CHILD; j++)
-                parent.add(getFileName(j));
-
-            parent = dir;
-        }
-
-        // create a graph
-        //      | ---address-country
-        //      |
-        //  company-dept-employee-address-country
-        //
-        PCCountry country1 = new PCCountry("100", "Employee 1 Country");
-        PCCountry country2 = new PCCountry("200", "Employee 2 Country");
-        PCCountry ccountry = new PCCountry("300", "Company Country");
-
-        PCCompany company = new PCCompany("Company");
-
-        PCDepartment dept1 = new PCDepartment("Department1");
-        PCDepartment dept2 = new PCDepartment("Department2");
-
-        PCEmployee emp1 = new PCEmployee("Employee1");
-        PCEmployee emp2 = new PCEmployee("Employee2");
-
-        PCAddress addr1 = new PCAddress("Street1", "city1", country1);
-        PCAddress addr2 = new PCAddress("Street2", "city2", country2);
-        PCAddress caddr = new PCAddress("Street3", "city3", ccountry);
-
-        dept1.addEmployee(emp1);
-        dept2.addEmployee(emp2);
-
-        company.addDepartment(dept1);
-        company.addDepartment(dept2);
-
-        company.setAddress(caddr);
-
-        emp1.setAddress(addr1);
-        emp2.setAddress(addr2);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(rootDir);
-        pm.persist(company);
-//        _rootDirId     = pm.getObjectId(rootDir);
-        _rootDirId = rootDir.getId();
-        assertNotNull(_rootDirId);
-//        _rootCompanyId = pm.getObjectId(company);
-        _rootCompanyId = company.getId();
-        assertNotNull(_rootCompanyId);
-        endTx(pm);
-        endEm(pm);
-    }
-
-    /**
-     * Test that the single valued field (_parent) is not traversed when the
-     * fecth group selects only the _name field.
-     */
-    public void testZeroRecursionDepthSingleValuedField() {
-        genericTestForSingleValuedRecursiveField("name", 4, 0);
-    }
-
-    /**
-     * Test that the single valued field (_parent) is traversed once and only
-     * once when the fecth group selects the _parent field with recursion depth
-     * of 1 (default).
-     */
-    public void testOneRecursionDepthSingleValuedField() {
-        genericTestForSingleValuedRecursiveField("name+parent", 4, 1);
-    }
-
-    /**
-     * Test that the single valued field (_parent) is traversed twice and only
-     * twice when the fecth group selects the _parent field with recursion depth
-     * of 2.
-     */
-    public void testTwoRecursionDepthSingleValuedField() {
-        genericTestForSingleValuedRecursiveField("name+parent+grandparent",
-            4, 2);
-    }
-
-    public void testThreeRecursionDepthSingleValuedField() {
-        genericTestForSingleValuedRecursiveField
-            ("name+parent+grandparent+greatgrandparent", 4, 3);
-    }
-
-    public void testInfiniteRecursionDepthSingleValuedField() {
-        genericTestForSingleValuedRecursiveField("allparents", 4, -1);
-    }
-
-    /**
-     * Generically tests recursive traversal of single-valued parent field.
-     *
-     * @param plan a plan that fetches L parents and no children
-     * @param rd the recursion depth of directory from the root
-     * @param fd the fetch depth = number of parents fetched
-     */
-    public void genericTestForSingleValuedRecursiveField(String plan, int rd,
-        int fd) {
-        PCDirectory result = queryDirectoryWithPlan(plan, rd, fd);
-
-        checkParents(result, rd, fd);
-
-        Object children = PCDirectory.reflect(result, "_children");
-        assertNull(children);
-    }
-
-    /**
-     * Query to obtain a single directory at the given depth.
-     * The directory name is constructed by the depth it occurs (d0 for root,
-     * d1 for depth 1 and so on).<BR>
-     * Checks the result for for matching name and size of the result (must
-     * be one).
-     *
-     * @param plan name of a fetch plan
-     * @param depth depth of the directory to be queried
-     * @return the selected directory.
-     */
-    PCDirectory queryDirectoryWithPlan(String plan, int rd, int fd) {
-        OpenJPAEntityManager pm = getPM();
-        pm.getFetchPlan().addFetchGroup(plan);
-        if (fd != 0)
-            pm.getFetchPlan().setMaxFetchDepth(fd);
-
-//        String filter = "_name == " + quoted(getDirectoryName(rd));        
-//        OpenJPAQuery query = pm.createNativeQuery(filter,PCDirectory.class);
-//        List result = (List) query.getResultList();
-
-        String query = "SELECT o FROM PCDirectory o WHERE o._name = '" +
-            getDirectoryName(rd) + "'";
-        List fresult = ((OpenJPAQuery) pm.createQuery(query)).getResultList();
-
-        assertEquals(1, fresult.size());
-        PCDirectory dir = (PCDirectory) fresult.get(0);
-
-        return dir;
-    }
-
-    /**
-     * Asserts that
-     * <LI> the given directory name matches the directory name at depth D.
-     * <LI> the parents upto L recursion is not null and beyond is
-     * null.
-     *
-     * @param result a directory to test
-     * @param D depth at which this directory appears
-     * @param L the number of live (fetched) parents. -1 denotes infinite
-     */
-    void checkParents(PCDirectory result, int D, int L) {
-
-        assertEquals("ge", getDirectoryName(D),
-            PCDirectory.reflect(result, "_name"));
-        PCDirectory[] parents = getParents(result, D);
-        int N = (L == -1) ? D : L;
-        for (int i = 0; i < N; i++) {
-            assertNotNull(i + "-th parent at depth " + D + " is null",
-                parents[i]);
-            assertEquals(getDirectoryName(D - i - 1),
-                PCDirectory.reflect(parents[i], "_name"));
-        }
-        for (int i = N; i < D; i++)
-            assertNull(i + "-th parent at depth " + D + " is not null " +
-                parents[i], parents[i]);
-    }
-
-    /**
-     * Gets an array of parents of the given directory. The zeroth element
-     * is the parent of the given directory and (i+1)-th element is the
-     * parent of the i-th element. Uses reflection to ensure that the
-     * side-effect does not cause a database access for the field.
-     *
-     * @param dir a starting directory
-     * @param depth depth to recurse. must be positive.
-     * @return
-     */
-    PCDirectory[] getParents(PCDirectory dir, int depth) {
-        PCDirectory[] result = new PCDirectory[depth];
-        PCDirectory current = dir;
-        for (int i = 0; i < depth; i++) {
-            result[i] = (PCDirectory) PCDirectory.reflect(current, "_parent");
-            current = result[i];
-        }
-        return result;
-    }
-
-    /**
-     * Checks that the first L elements of the given array is non-null and
-     * the rest are null.
-     *
-     * @param depth
-     */
-    void assertNullParent(PCDirectory[] parents, int L) {
-        for (int i = 0; i < L; i++)
-            assertNotNull(parents[i]);
-        for (int i = L; i < parents.length; i++)
-            assertNull(parents[i]);
-    }
-
-    String getDirectoryName(int depth) {
-        return "d" + depth;
-    }
-
-    String getFileName(int depth) {
-        return "f" + depth;
-    }
-
-    String quoted(String s) {
-        return quote + s + quote;
-    }
-
-    /**
-     * Defines a fetch plan that has several fetch groups to traverse a chain
-     * of relationships.
-     * After getting the root by an extent query, checks (by reflection) that
-     * all the relations in the chain are fetched.
-     * The fetch depth is kept infinite, so what would be fetched is essentially
-     * controlled by the fetch groups.
-     */
-    public void testRelationTraversal() {
-        OpenJPAEntityManager pm = getPM();
-        FetchPlan plan = pm.getFetchPlan();
-        pm.getFetchPlan().setMaxFetchDepth(-1);
-        plan.addFetchGroup("employee.department");
-        plan.addFetchGroup("department.company");
-        plan.addFetchGroup("company.address");
-        plan.addFetchGroup("address.country");
-
-        Iterator employees = pm.createExtent(PCEmployee.class, true).iterator();
-        while (employees.hasNext()) {
-            PCEmployee emp = (PCEmployee) employees.next();
-
-            PCDepartment dept = (PCDepartment) PCEmployee.reflect(emp,
-                "department");
-            assertNotNull(dept);
-
-            PCCompany company = (PCCompany) PCDepartment.reflect(dept,
-                "company");
-            assertNotNull(company);
-
-            PCAddress addr = (PCAddress) PCCompany.reflect(company, "address");
-            assertNotNull(addr);
-
-            PCCountry country = (PCCountry) PCAddress.reflect(addr, "country");
-            assertNotNull(country);
-        }
-    }
-
-    /**
-     * Defines a fetch plan that has several fetch groups to traverse a chain
-     * of relationships but truncated at the last relation.
-     * After getting the root by an extent query, checks (by reflection) that
-     * all but the last relation in the chain are fetched.
-     * The fetch depth is kept infinite, so what would be fetched is essentially
-     * controlled by the fetch groups.
-     */
-    public void testRelationTraversalTruncated() {
-        OpenJPAEntityManager pm = getPM();
-        FetchPlan plan = pm.getFetchPlan();
-        pm.getFetchPlan().setMaxFetchDepth(-1);
-        plan.addFetchGroup("employee.department");
-        plan.addFetchGroup("department.company");
-        plan.addFetchGroup("company.address");
-
-        Iterator employees = pm.createExtent(PCEmployee.class, true).iterator();
-        while (employees.hasNext()) {
-            PCEmployee emp = (PCEmployee) employees.next();
-
-            PCDepartment dept = (PCDepartment) PCEmployee.reflect(emp,
-                "department");
-            assertNotNull(dept);
-
-            PCCompany company = (PCCompany) PCDepartment.reflect(dept,
-                "company");
-            assertNotNull(company);
-
-            PCAddress addr = (PCAddress) PCCompany.reflect(company, "address");
-            assertNotNull(addr);
-
-            PCCountry country = (PCCountry) PCAddress.reflect(addr, "country");
-            assertNull(country);
-        }
-    }
-
-    /**
-     * Gets a Compnay object by getObjectById() method as opposed to query.
-     * The active fetch groups should bring in the multi-valued relationships.
-     * The address->country relationship can be reached in two alternate
-     * paths -- one as company->address->country and the other is
-     * company->department->employee->address->country.
-     * Though active fetch groups allow both the paths -- the max fetch depth
-     * is set such that the shorter path is taken but not the longer one.
-     * Hence the company's address->country should be loaded but not the
-     * employee's.
-     */
-    public void testRelationTraversalWithCompanyAsRoot() {
-        OpenJPAEntityManager pm = getPM();
-        FetchPlan plan = pm.getFetchPlan();
-
-        plan.setMaxFetchDepth(2);
-        plan.addFetchGroup("company.departments");
-        plan.addFetchGroup("company.address");
-        plan.addFetchGroup("department.employees");
-        plan.addFetchGroup("person.address");
-        plan.addFetchGroup("address.country");
-
-        PCCompany company =
-            (PCCompany) pm.find(PCCompany.class, _rootCompanyId);
-        Set departments = (Set) PCCompany.reflect(company, "departments");
-        assertNotNull("department is null", departments);
-        assertEquals("exp. depart size is not 2", 2, departments.size());
-        PCDepartment dept = (PCDepartment) departments.iterator().next();
-        assertNotNull("dept is null", dept);
-        Set employees = (Set) PCDepartment.reflect(dept, "employees");
-        assertNotNull("employees is null", employees);
-        assertEquals(1, employees.size());
-        PCEmployee emp = (PCEmployee) employees.iterator().next();
-        assertNotNull("emp is not null", emp);
-        PCAddress eaddr = (PCAddress) PCPerson.reflect(emp, "address");
-        PCAddress caddr = (PCAddress) PCCompany.reflect(company, "address");
-        assertNull("eaddr is not null", eaddr);
-        assertNotNull("caddr is null", caddr);
-        PCCountry country = (PCCountry) PCAddress.reflect(caddr, "country");
-        assertNotNull("country is null", country);
-    }
-
-    /**
-     * Same as above but the root compnay instance is detached.
-     */
-    public void testDetachedRelationTraversalWithCompanyAsRoot() {
-        OpenJPAEntityManager pm = getPM();
-        FetchPlan plan = pm.getFetchPlan();
-        pm.getFetchPlan().setMaxFetchDepth(2);
-        plan.addFetchGroup("company.departments");
-        plan.addFetchGroup("company.address");
-        plan.addFetchGroup("department.employees");
-        plan.addFetchGroup("person.address");
-        plan.addFetchGroup("address.country");
-
-        PCCompany company1 =
-            (PCCompany) pm.find(PCCompany.class, _rootCompanyId);
-
-        PCCompany company = (PCCompany) pm.detach(company1);
-        assertTrue("company is equal company1", company != company1);
-        Set departments = (Set) PCCompany.reflect(company, "departments");
-        assertNotNull("department is null", departments);
-        assertEquals("department size is not 2", 2, departments.size());
-        PCDepartment dept = (PCDepartment) departments.iterator().next();
-        assertNotNull("dept is null", dept);
-        Set employees = (Set) PCDepartment.reflect(dept, "employees");
-        assertNotNull("employee is null", employees);
-        assertEquals("employees size not 1", 1, employees.size());
-        PCEmployee emp = (PCEmployee) employees.iterator().next();
-        assertNotNull("emp is null", emp);
-        PCAddress eaddr = (PCAddress) PCPerson.reflect(emp, "address");
-        PCAddress caddr = (PCAddress) PCCompany.reflect(company, "address");
-        assertNull("eaddr is not null", eaddr);
-        assertNotNull("caddr is null", caddr);
-        PCCountry country = (PCCountry) PCAddress.reflect(caddr, "country");
-        assertNotNull("country is null", country);
-    }
-
-    public void testDefaultFetchGroup() {
-        OpenJPAEntityManager pm = getPM();
-
-        String squery =
-            "SELECT DISTINCT o FROM PCEmployee o WHERE o.name = 'Employee1'";
-        OpenJPAQuery q = pm.createQuery(squery);
-
-        //FIXME jthomas
-        PCEmployee person = (PCEmployee) q.getSingleResult();
-        assertEquals("Exp. String is not employee1", "Employee1",
-            PCPerson.reflect(person, "name"));
-    }
-
-    public void testDefaultFetchGroupExistsByDefault() {
-        OpenJPAEntityManager pm = getPM();
-        assertTrue("pm does not contain default fetchplan",
-            pm.getFetchPlan().getFetchGroups().contains(
-                FetchPlan.GROUP_DEFAULT));
-    }
-
-    public void testDefaultFetchGroupCanBeRemoved() {
-        OpenJPAEntityManager pm = getPM();
-        assertTrue("does not contain default fetchplan",
-            pm.getFetchPlan().getFetchGroups().contains(
-                FetchPlan.GROUP_DEFAULT));
-
-        pm.getFetchPlan().removeFetchGroup(FetchPlan.GROUP_DEFAULT);
-        assertFalse("does contain default fetchplan",
-            pm.getFetchPlan().getFetchGroups().contains(
-                FetchPlan.GROUP_DEFAULT));
-
-        OpenJPAEntityManager pm2 = getPM();
-        assertTrue("pm2 does not contain default fetchplan",
-            pm2.getFetchPlan().getFetchGroups().contains(
-                FetchPlan.GROUP_DEFAULT));
-    }
-
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    private void clearTestData() throws Exception {
-//        OpenJPAEntityManagerFactory pmf =(OpenJPAEntityManagerFactory) getEmf();
-//        OpenJPAConfiguration conf=pmf.getConfiguration();
-//        
-//        Class.forName(pmf.getConfiguration().getConnection2DriverName());
-//        String url=conf.getConnection2URL();
-//        String user=conf.getConnection2UserName();
-//        String pass=conf.getConnection2Password();
-//        
-//        Connection con = DriverManager.getConnection(
-//                url,
-//                user,
-//                pass);
-//        con.setAutoCommit(true);
-//        con.prepareStatement("DELETE FROM PCDIRECTORY").executeUpdate();
-//        con.prepareStatement("DELETE FROM PCFILE").executeUpdate();
-//        con.prepareStatement("DELETE FROM PCPERSON").executeUpdate();
-//        con.prepareStatement("DELETE FROM PCDEPARTMENT").executeUpdate();
-//        con.prepareStatement("DELETE FROM PCCOMPANY").executeUpdate();
-//        con.prepareStatement("DELETE FROM PCADDRESS").executeUpdate();
-//        con.prepareStatement("DELETE FROM PCCOUNTRY").executeUpdate();
-
-        deleteAll(PCDirectory.class);
-        deleteAll(PCFile.class);
-        deleteAll(PCPerson.class);
-        deleteAll(PCDepartment.class);
-        deleteAll(PCCompany.class);
-        deleteAll(PCAddress.class);
-        deleteAll(PCCountry.class);
-        deleteAll(PCEmployee.class);
-    }
-}
+/*
+ * TestFetchPlan.java
+ *
+ * Created on October 16, 2006, 3:02 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.PCAddress;
+import org.apache.openjpa.persistence.kernel.common.apps.PCCompany;
+import org.apache.openjpa.persistence.kernel.common.apps.PCCountry;
+import org.apache.openjpa.persistence.kernel.common.apps.PCDepartment;
+import org.apache.openjpa.persistence.kernel.common.apps.PCDirectory;
+import org.apache.openjpa.persistence.kernel.common.apps.PCEmployee;
+import org.apache.openjpa.persistence.kernel.common.apps.PCFile;
+import org.apache.openjpa.persistence.kernel.common.apps.PCPerson;
+
+import org.apache.openjpa.persistence.FetchPlan;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestFetchPlan extends BaseKernelTest {
+
+    static Object _rootDirId;
+    static Object _rootCompanyId;
+
+    static final int MAX_DEPTH = 5; // Maximum depth of the directories
+    static final int MAX_CHILD = 3; // Maximum number of files/directory
+    static final String quote = "\"";
+    private static boolean firstTime = true;
+
+    /**
+     * Creates a new instance of TestFetchPlan
+     */
+    public TestFetchPlan() {
+    }
+
+    public TestFetchPlan(String name) {
+        super(name);
+    }
+
+    /**
+     * Clears past data and creates new data for test.
+     * Clear test data before and not <em>after</em> such that one can analyze
+     * the database for test failures.
+     */
+    public void setUp() throws Exception {
+        if (firstTime) {
+            firstTime = false;
+            clearTestData();
+            createTestData();
+        }
+    }
+
+    /**
+     * Create a directory tree of MAX_DEPTH with each directory having a single
+     * directory and MAX_CHILD files.
+     * Creates typical Employee-Department-Company-Address instances.
+     *
+     * @return the persitent identifier of the root directory.
+     */
+    void createTestData() {
+        // create a tree of directories with files in them
+        PCDirectory rootDir = new PCDirectory(getDirectoryName(0));
+        PCDirectory parent = rootDir;
+        for (int i = 1; i <= MAX_DEPTH; i++) {
+            PCDirectory dir = new PCDirectory(getDirectoryName(i));
+            parent.add(dir);
+
+            for (int j = 0; j < MAX_CHILD; j++)
+                parent.add(getFileName(j));
+
+            parent = dir;
+        }
+
+        // create a graph
+        //      | ---address-country
+        //      |
+        //  company-dept-employee-address-country
+        //
+        PCCountry country1 = new PCCountry("100", "Employee 1 Country");
+        PCCountry country2 = new PCCountry("200", "Employee 2 Country");
+        PCCountry ccountry = new PCCountry("300", "Company Country");
+
+        PCCompany company = new PCCompany("Company");
+
+        PCDepartment dept1 = new PCDepartment("Department1");
+        PCDepartment dept2 = new PCDepartment("Department2");
+
+        PCEmployee emp1 = new PCEmployee("Employee1");
+        PCEmployee emp2 = new PCEmployee("Employee2");
+
+        PCAddress addr1 = new PCAddress("Street1", "city1", country1);
+        PCAddress addr2 = new PCAddress("Street2", "city2", country2);
+        PCAddress caddr = new PCAddress("Street3", "city3", ccountry);
+
+        dept1.addEmployee(emp1);
+        dept2.addEmployee(emp2);
+
+        company.addDepartment(dept1);
+        company.addDepartment(dept2);
+
+        company.setAddress(caddr);
+
+        emp1.setAddress(addr1);
+        emp2.setAddress(addr2);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(rootDir);
+        pm.persist(company);
+//        _rootDirId     = pm.getObjectId(rootDir);
+        _rootDirId = rootDir.getId();
+        assertNotNull(_rootDirId);
+//        _rootCompanyId = pm.getObjectId(company);
+        _rootCompanyId = company.getId();
+        assertNotNull(_rootCompanyId);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    /**
+     * Test that the single valued field (_parent) is not traversed when the
+     * fecth group selects only the _name field.
+     */
+    public void testZeroRecursionDepthSingleValuedField() {
+        genericTestForSingleValuedRecursiveField("name", 4, 0);
+    }
+
+    /**
+     * Test that the single valued field (_parent) is traversed once and only
+     * once when the fecth group selects the _parent field with recursion depth
+     * of 1 (default).
+     */
+    public void testOneRecursionDepthSingleValuedField() {
+        genericTestForSingleValuedRecursiveField("name+parent", 4, 1);
+    }
+
+    /**
+     * Test that the single valued field (_parent) is traversed twice and only
+     * twice when the fecth group selects the _parent field with recursion depth
+     * of 2.
+     */
+    public void testTwoRecursionDepthSingleValuedField() {
+        genericTestForSingleValuedRecursiveField("name+parent+grandparent",
+            4, 2);
+    }
+
+    public void testThreeRecursionDepthSingleValuedField() {
+        genericTestForSingleValuedRecursiveField
+            ("name+parent+grandparent+greatgrandparent", 4, 3);
+    }
+
+    public void testInfiniteRecursionDepthSingleValuedField() {
+        genericTestForSingleValuedRecursiveField("allparents", 4, -1);
+    }
+
+    /**
+     * Generically tests recursive traversal of single-valued parent field.
+     *
+     * @param plan a plan that fetches L parents and no children
+     * @param rd the recursion depth of directory from the root
+     * @param fd the fetch depth = number of parents fetched
+     */
+    public void genericTestForSingleValuedRecursiveField(String plan, int rd,
+        int fd) {
+        PCDirectory result = queryDirectoryWithPlan(plan, rd, fd);
+
+        checkParents(result, rd, fd);
+
+        Object children = PCDirectory.reflect(result, "_children");
+        assertNull(children);
+    }
+
+    /**
+     * Query to obtain a single directory at the given depth.
+     * The directory name is constructed by the depth it occurs (d0 for root,
+     * d1 for depth 1 and so on).<BR>
+     * Checks the result for for matching name and size of the result (must
+     * be one).
+     *
+     * @param plan name of a fetch plan
+     * @param depth depth of the directory to be queried
+     * @return the selected directory.
+     */
+    PCDirectory queryDirectoryWithPlan(String plan, int rd, int fd) {
+        OpenJPAEntityManager pm = getPM();
+        pm.getFetchPlan().addFetchGroup(plan);
+        if (fd != 0)
+            pm.getFetchPlan().setMaxFetchDepth(fd);
+
+//        String filter = "_name == " + quoted(getDirectoryName(rd));        
+//        OpenJPAQuery query = pm.createNativeQuery(filter,PCDirectory.class);
+//        List result = (List) query.getResultList();
+
+        String query = "SELECT o FROM PCDirectory o WHERE o._name = '" +
+            getDirectoryName(rd) + "'";
+        List fresult = ((OpenJPAQuery) pm.createQuery(query)).getResultList();
+
+        assertEquals(1, fresult.size());
+        PCDirectory dir = (PCDirectory) fresult.get(0);
+
+        return dir;
+    }
+
+    /**
+     * Asserts that
+     * <LI> the given directory name matches the directory name at depth D.
+     * <LI> the parents upto L recursion is not null and beyond is
+     * null.
+     *
+     * @param result a directory to test
+     * @param D depth at which this directory appears
+     * @param L the number of live (fetched) parents. -1 denotes infinite
+     */
+    void checkParents(PCDirectory result, int D, int L) {
+
+        assertEquals("ge", getDirectoryName(D),
+            PCDirectory.reflect(result, "_name"));
+        PCDirectory[] parents = getParents(result, D);
+        int N = (L == -1) ? D : L;
+        for (int i = 0; i < N; i++) {
+            assertNotNull(i + "-th parent at depth " + D + " is null",
+                parents[i]);
+            assertEquals(getDirectoryName(D - i - 1),
+                PCDirectory.reflect(parents[i], "_name"));
+        }
+        for (int i = N; i < D; i++)
+            assertNull(i + "-th parent at depth " + D + " is not null " +
+                parents[i], parents[i]);
+    }
+
+    /**
+     * Gets an array of parents of the given directory. The zeroth element
+     * is the parent of the given directory and (i+1)-th element is the
+     * parent of the i-th element. Uses reflection to ensure that the
+     * side-effect does not cause a database access for the field.
+     *
+     * @param dir a starting directory
+     * @param depth depth to recurse. must be positive.
+     * @return
+     */
+    PCDirectory[] getParents(PCDirectory dir, int depth) {
+        PCDirectory[] result = new PCDirectory[depth];
+        PCDirectory current = dir;
+        for (int i = 0; i < depth; i++) {
+            result[i] = (PCDirectory) PCDirectory.reflect(current, "_parent");
+            current = result[i];
+        }
+        return result;
+    }
+
+    /**
+     * Checks that the first L elements of the given array is non-null and
+     * the rest are null.
+     *
+     * @param depth
+     */
+    void assertNullParent(PCDirectory[] parents, int L) {
+        for (int i = 0; i < L; i++)
+            assertNotNull(parents[i]);
+        for (int i = L; i < parents.length; i++)
+            assertNull(parents[i]);
+    }
+
+    String getDirectoryName(int depth) {
+        return "d" + depth;
+    }
+
+    String getFileName(int depth) {
+        return "f" + depth;
+    }
+
+    String quoted(String s) {
+        return quote + s + quote;
+    }
+
+    /**
+     * Defines a fetch plan that has several fetch groups to traverse a chain
+     * of relationships.
+     * After getting the root by an extent query, checks (by reflection) that
+     * all the relations in the chain are fetched.
+     * The fetch depth is kept infinite, so what would be fetched is essentially
+     * controlled by the fetch groups.
+     */
+    public void testRelationTraversal() {
+        OpenJPAEntityManager pm = getPM();
+        FetchPlan plan = pm.getFetchPlan();
+        pm.getFetchPlan().setMaxFetchDepth(-1);
+        plan.addFetchGroup("employee.department");
+        plan.addFetchGroup("department.company");
+        plan.addFetchGroup("company.address");
+        plan.addFetchGroup("address.country");
+
+        Iterator employees = pm.createExtent(PCEmployee.class, true).iterator();
+        while (employees.hasNext()) {
+            PCEmployee emp = (PCEmployee) employees.next();
+
+            PCDepartment dept = (PCDepartment) PCEmployee.reflect(emp,
+                "department");
+            assertNotNull(dept);
+
+            PCCompany company = (PCCompany) PCDepartment.reflect(dept,
+                "company");
+            assertNotNull(company);
+
+            PCAddress addr = (PCAddress) PCCompany.reflect(company, "address");
+            assertNotNull(addr);
+
+            PCCountry country = (PCCountry) PCAddress.reflect(addr, "country");
+            assertNotNull(country);
+        }
+    }
+
+    /**
+     * Defines a fetch plan that has several fetch groups to traverse a chain
+     * of relationships but truncated at the last relation.
+     * After getting the root by an extent query, checks (by reflection) that
+     * all but the last relation in the chain are fetched.
+     * The fetch depth is kept infinite, so what would be fetched is essentially
+     * controlled by the fetch groups.
+     */
+    public void testRelationTraversalTruncated() {
+        OpenJPAEntityManager pm = getPM();
+        FetchPlan plan = pm.getFetchPlan();
+        pm.getFetchPlan().setMaxFetchDepth(-1);
+        plan.addFetchGroup("employee.department");
+        plan.addFetchGroup("department.company");
+        plan.addFetchGroup("company.address");
+
+        Iterator employees = pm.createExtent(PCEmployee.class, true).iterator();
+        while (employees.hasNext()) {
+            PCEmployee emp = (PCEmployee) employees.next();
+
+            PCDepartment dept = (PCDepartment) PCEmployee.reflect(emp,
+                "department");
+            assertNotNull(dept);
+
+            PCCompany company = (PCCompany) PCDepartment.reflect(dept,
+                "company");
+            assertNotNull(company);
+
+            PCAddress addr = (PCAddress) PCCompany.reflect(company, "address");
+            assertNotNull(addr);
+
+            PCCountry country = (PCCountry) PCAddress.reflect(addr, "country");
+            assertNull(country);
+        }
+    }
+
+    /**
+     * Gets a Compnay object by getObjectById() method as opposed to query.
+     * The active fetch groups should bring in the multi-valued relationships.
+     * The address->country relationship can be reached in two alternate
+     * paths -- one as company->address->country and the other is
+     * company->department->employee->address->country.
+     * Though active fetch groups allow both the paths -- the max fetch depth
+     * is set such that the shorter path is taken but not the longer one.
+     * Hence the company's address->country should be loaded but not the
+     * employee's.
+     */
+    public void testRelationTraversalWithCompanyAsRoot() {
+        OpenJPAEntityManager pm = getPM();
+        FetchPlan plan = pm.getFetchPlan();
+
+        plan.setMaxFetchDepth(2);
+        plan.addFetchGroup("company.departments");
+        plan.addFetchGroup("company.address");
+        plan.addFetchGroup("department.employees");
+        plan.addFetchGroup("person.address");
+        plan.addFetchGroup("address.country");
+
+        PCCompany company =
+            (PCCompany) pm.find(PCCompany.class, _rootCompanyId);
+        Set departments = (Set) PCCompany.reflect(company, "departments");
+        assertNotNull("department is null", departments);
+        assertEquals("exp. depart size is not 2", 2, departments.size());
+        PCDepartment dept = (PCDepartment) departments.iterator().next();
+        assertNotNull("dept is null", dept);
+        Set employees = (Set) PCDepartment.reflect(dept, "employees");
+        assertNotNull("employees is null", employees);
+        assertEquals(1, employees.size());
+        PCEmployee emp = (PCEmployee) employees.iterator().next();
+        assertNotNull("emp is not null", emp);
+        PCAddress eaddr = (PCAddress) PCPerson.reflect(emp, "address");
+        PCAddress caddr = (PCAddress) PCCompany.reflect(company, "address");
+        assertNull("eaddr is not null", eaddr);
+        assertNotNull("caddr is null", caddr);
+        PCCountry country = (PCCountry) PCAddress.reflect(caddr, "country");
+        assertNotNull("country is null", country);
+    }
+
+    /**
+     * Same as above but the root compnay instance is detached.
+     */
+    public void testDetachedRelationTraversalWithCompanyAsRoot() {
+        OpenJPAEntityManager pm = getPM();
+        FetchPlan plan = pm.getFetchPlan();
+        pm.getFetchPlan().setMaxFetchDepth(2);
+        plan.addFetchGroup("company.departments");
+        plan.addFetchGroup("company.address");
+        plan.addFetchGroup("department.employees");
+        plan.addFetchGroup("person.address");
+        plan.addFetchGroup("address.country");
+
+        PCCompany company1 =
+            (PCCompany) pm.find(PCCompany.class, _rootCompanyId);
+
+        PCCompany company = (PCCompany) pm.detach(company1);
+        assertTrue("company is equal company1", company != company1);
+        Set departments = (Set) PCCompany.reflect(company, "departments");
+        assertNotNull("department is null", departments);
+        assertEquals("department size is not 2", 2, departments.size());
+        PCDepartment dept = (PCDepartment) departments.iterator().next();
+        assertNotNull("dept is null", dept);
+        Set employees = (Set) PCDepartment.reflect(dept, "employees");
+        assertNotNull("employee is null", employees);
+        assertEquals("employees size not 1", 1, employees.size());
+        PCEmployee emp = (PCEmployee) employees.iterator().next();
+        assertNotNull("emp is null", emp);
+        PCAddress eaddr = (PCAddress) PCPerson.reflect(emp, "address");
+        PCAddress caddr = (PCAddress) PCCompany.reflect(company, "address");
+        assertNull("eaddr is not null", eaddr);
+        assertNotNull("caddr is null", caddr);
+        PCCountry country = (PCCountry) PCAddress.reflect(caddr, "country");
+        assertNotNull("country is null", country);
+    }
+
+    public void testDefaultFetchGroup() {
+        OpenJPAEntityManager pm = getPM();
+
+        String squery =
+            "SELECT DISTINCT o FROM PCEmployee o WHERE o.name = 'Employee1'";
+        OpenJPAQuery q = pm.createQuery(squery);
+
+        //FIXME jthomas
+        PCEmployee person = (PCEmployee) q.getSingleResult();
+        assertEquals("Exp. String is not employee1", "Employee1",
+            PCPerson.reflect(person, "name"));
+    }
+
+    public void testDefaultFetchGroupExistsByDefault() {
+        OpenJPAEntityManager pm = getPM();
+        assertTrue("pm does not contain default fetchplan",
+            pm.getFetchPlan().getFetchGroups().contains(
+                FetchPlan.GROUP_DEFAULT));
+    }
+
+    public void testDefaultFetchGroupCanBeRemoved() {
+        OpenJPAEntityManager pm = getPM();
+        assertTrue("does not contain default fetchplan",
+            pm.getFetchPlan().getFetchGroups().contains(
+                FetchPlan.GROUP_DEFAULT));
+
+        pm.getFetchPlan().removeFetchGroup(FetchPlan.GROUP_DEFAULT);
+        assertFalse("does contain default fetchplan",
+            pm.getFetchPlan().getFetchGroups().contains(
+                FetchPlan.GROUP_DEFAULT));
+
+        OpenJPAEntityManager pm2 = getPM();
+        assertTrue("pm2 does not contain default fetchplan",
+            pm2.getFetchPlan().getFetchGroups().contains(
+                FetchPlan.GROUP_DEFAULT));
+    }
+
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    private void clearTestData() throws Exception {
+//        OpenJPAEntityManagerFactory pmf =(OpenJPAEntityManagerFactory) getEmf();
+//        OpenJPAConfiguration conf=pmf.getConfiguration();
+//        
+//        Class.forName(pmf.getConfiguration().getConnection2DriverName());
+//        String url=conf.getConnection2URL();
+//        String user=conf.getConnection2UserName();
+//        String pass=conf.getConnection2Password();
+//        
+//        Connection con = DriverManager.getConnection(
+//                url,
+//                user,
+//                pass);
+//        con.setAutoCommit(true);
+//        con.prepareStatement("DELETE FROM PCDIRECTORY").executeUpdate();
+//        con.prepareStatement("DELETE FROM PCFILE").executeUpdate();
+//        con.prepareStatement("DELETE FROM PCPERSON").executeUpdate();
+//        con.prepareStatement("DELETE FROM PCDEPARTMENT").executeUpdate();
+//        con.prepareStatement("DELETE FROM PCCOMPANY").executeUpdate();
+//        con.prepareStatement("DELETE FROM PCADDRESS").executeUpdate();
+//        con.prepareStatement("DELETE FROM PCCOUNTRY").executeUpdate();
+
+        deleteAll(PCDirectory.class);
+        deleteAll(PCFile.class);
+        deleteAll(PCPerson.class);
+        deleteAll(PCDepartment.class);
+        deleteAll(PCCompany.class);
+        deleteAll(PCAddress.class);
+        deleteAll(PCCountry.class);
+        deleteAll(PCEmployee.class);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange.java
index 876936f..6f684b6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange.java
@@ -1,383 +1,383 @@
-/*
- * TestFieldRange.java
- *
- * Created on October 12, 2006, 10:14 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.Assert;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestFieldRange extends BaseKernelTest {
-
-    protected static String RANDOM_STRING =
-        "This is my test String with all "
-            + "kinds of wierd characters: "
-            + "!@@#$\\%^&\"*()-=\\|\"\"\"\"\"+_/?.>,<~`"
-            + "'''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
-            + "''''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
-            + "!@@#$\\%^&\"*()-=\\|+_/?.>,<~`";
-
-    /**
-     * Creates a new instance of TestFieldRange
-     */
-    public TestFieldRange() {
-    }
-
-    public TestFieldRange(String name) {
-        super(name);
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-        deleteAll(AllFieldTypesTest.class);
-    }
-
-    public void testSaveState()
-        throws Exception {
-        allFieldSaveState(
-            (int) 259645,
-            (short) 50849,
-            (long) 2349847982L,
-            (float) 43273423.0234723F,
-            (double) 34678.02384723D,
-            (byte) -120,
-            (boolean) true,
-            (char) '%',
-            (Date) new Date(),
-            (Serializable) new StringBuffer(5000),
-            (String) RANDOM_STRING,
-            randomBigInteger(),
-            randomBigDecimal());
-    }
-
-    /**
-     * Test to make sure all the numeric fields can accept the maximum
-     * values for their data size. Note that we subtract one from
-     * each of the values because some databases (like InstantDB)
-     * may consider them to be equivalent to NULL.
-     * FixMe: Hangs for some mysterious reason. aokeke
-     */
-
-//    public void testLargeNumbers()
-//    throws Exception {
-//        try {
-//            allFieldSaveState(
-//                    (int) (Integer.MAX_VALUE - 1),
-//                    (short) (Short.MAX_VALUE - 1),
-//                    (long) (Long.MAX_VALUE - 1l),
-//                    (float) (Float.MAX_VALUE - 1.0f),
-//                    (double) (Double.MAX_VALUE - 1.0d),
-//                    (byte) (Byte.MAX_VALUE),
-//                    (boolean) true,
-//                    (char) 'q',
-//                    (Date) new Date(),
-//                    (Serializable) new StringBuffer(5000),
-//                    (String) RANDOM_STRING,
-//                    randomBigInteger(),
-//                    randomBigDecimal());
-//        } catch (Throwable e) {
-//            bug(3, e, "doubles and floats");
-//        }
-//    }
-
-    /**
-     * Test to make sure all the numeric fields can be set to
-     * very low values. We add one to the minimim value because
-     * some databases (such as InstantDB) consider the MIN_VALUE
-     * to be equivalent to null. This is arguably a bug, but
-     * not a killer one.
-     */
-    public void testLargeNumbersNegative()
-        throws Exception {
-        allFieldSaveState(
-            (int) (Integer.MIN_VALUE + 1),
-            (short) (Short.MIN_VALUE + 1),
-            (long) (Long.MIN_VALUE + 1l),
-            (float) (Float.MIN_VALUE + 1.0f),
-            (double) (Double.MIN_VALUE + 1.0d),
-            (byte) (Byte.MIN_VALUE + 1),
-            (boolean) true,
-            (char) 'q',
-            (Date) new Date(),
-            (Serializable) new StringBuffer(5000),
-            (String) RANDOM_STRING,
-            randomBigInteger(),
-            randomBigDecimal());
-    }
-
-    public void testDoubleAndFloatPrecision()
-        throws Exception {
-        allFieldSaveState(
-            (int) (0),
-            (short) (0),
-            (long) (0l),
-            (float) (10.0f / 3.0f),
-            (double) (100.0d / 3.0d),
-            (byte) (0),
-            (boolean) true,
-            (char) 'q',
-            (Date) new Date(),
-            (Serializable) new StringBuffer(5000),
-            (String) RANDOM_STRING,
-            randomBigInteger(),
-            randomBigDecimal());
-    }
-
-    public void testZeroNumbers()
-        throws Exception {
-        allFieldSaveState(
-            (int) (0),
-            (short) (0),
-            (long) (0l),
-            (float) (0.0f),
-            (double) (0.0d),
-            (byte) (0),
-            (boolean) true,
-            (char) 'q',
-            (Date) new Date(),
-            (Serializable) new StringBuffer(5000),
-            (String) RANDOM_STRING,
-            new BigInteger("0"),
-            new BigDecimal("0.0"));
-    }
-
-    public void testLowDate()
-        throws Exception {
-        dateTest(0);
-    }
-
-    public void testCurDate()
-        throws Exception {
-        dateTest(System.currentTimeMillis());
-    }
-
-    public void testHighDate()
-        throws Exception {
-        try {
-            // postgres will sometimes store the String "invalid" if the
-            // date is too high, which will prevent us from even reading
-            // the records that contain this corrupt value (thus breaking
-            // any subsequent attempts to read instances of AllFieldTypesTest).
-            // An Example of a date like this is:
-            //   (Timestamp) 2038-02-08 22:20:07.65
-            if (getCurrentPlatform() ==
-                AbstractTestCase.Platform.POSTGRESQL)
-                fail("Postgres can't even try to store a high date");
-
-            dateTest(System.currentTimeMillis() * 2);
-        } catch (AssertionFailedError e) {
-            bug(6, e, "Some data stores cannot deal "
-                + "with very high dates");
-        }
-    }
-
-    /**
-     * Some date instances that have been known to have problems.
-     */
-    public void testProblematicDates()
-        throws Exception {
-        dateTest(1047744639);        // pointbase had probs with this
-    }
-
-    private void dateTest(long l)
-        throws Exception {
-        Date d = new Date(l);
-
-        allFieldSaveState(
-            (int) 10,
-            (short) 10,
-            (long) 10,
-            (float) 0,
-            (double) 0,
-            (byte) 10,
-            (boolean) true,
-            (char) 'x',
-            (Date) d,
-            (Serializable) new StringBuffer(10),
-            (String) RANDOM_STRING,
-            new BigInteger("0"),
-            new BigDecimal("0"));
-    }
-
-    public void allFieldSaveState(int testint, short testshort, long testlong,
-        float testfloat, double testdouble, byte testbyte,
-        boolean testboolean, char testchar, Date testDate,
-        Serializable testObject, String testString,
-        BigInteger testBigInteger, BigDecimal testBigDecimal)
-        throws Exception {
-        try {
-            allFieldSaveStateInternal(testint, testshort, testlong,
-                testfloat, testdouble, testbyte,
-                testboolean, testchar, testDate,
-                testObject, testString, testBigInteger, testBigDecimal);
-        } finally {
-            try {
-                // make *sure* we do not leave a transaction open
-                rollbackTx(getPM(true, false));
-            } catch (Throwable t) {
-
-            }
-        }
-    }
-
-    public void allFieldSaveStateInternal(
-        int testint, short testshort, long testlong,
-        float testfloat, double testdouble, byte testbyte,
-        boolean testboolean, char testchar, Date testDate,
-        Serializable testObject, String testString,
-        BigInteger testBigInteger, BigDecimal testBigDecimal)
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        AllFieldTypesTest test = new AllFieldTypesTest();
-        pm.persist(test);
-        Object testID = pm.getObjectId(test);
-
-        test.setTestint(testint);
-        test.setTestlong(testlong);
-        test.setTestdouble(testdouble);
-        test.setTestshort(testshort);
-        test.setTestfloat(testfloat);
-        test.setTestbyte(testbyte);
-        test.setTestboolean(testboolean);
-        test.setTestchar(testchar);
-        test.setTestString(testString);
-        test.setTestDate(testDate);
-        test.setTestObject(testObject);
-        test.setTestBigInteger(testBigInteger);
-        test.setTestBigDecimal(testBigDecimal);
-
-        try {
-            endTx(pm);
-        } catch (Exception e) {
-            if (e instanceof Exception &&
-                ((Exception) e).getMessage().indexOf
-                    ("Maximum length is 8000") != -1) {
-                bug(AbstractTestCase.Platform.SQLSERVER, 5, e,
-                    "SQLServer cannot deal"
-                        + " with numbers with more than 8000 digits");
-            } else {
-                throw e;
-            }
-        }
-
-        endEm(pm);
-
-        //assertPersistent (test, true, false, false, false);
-
-        pm = getPM(true, false);
-        startTx(pm);
-
-        AllFieldTypesTest retrievedObject =
-            (AllFieldTypesTest) pm.find(AllFieldTypesTest.class, testID);
-
-        assertEquals("Field type int", testint,
-            retrievedObject.getTestint());
-        assertEquals("Field type short", testshort,
-            retrievedObject.getTestshort());
-        assertEquals("Field type boolean", testboolean,
-            retrievedObject.getTestboolean());
-        assertEquals("Field type char", testchar,
-            retrievedObject.getTestchar());
-        assertEquals("Field type long", testlong,
-            retrievedObject.getTestlong());
-
-        assertEquals("Field type byte", testbyte,
-            retrievedObject.getTestbyte());
-        assertEquals("Field type String", testString,
-            retrievedObject.getTestString());
-
-        int i1 = (int) (testDate.getTime() / 1000);
-        int i2 = (int) (retrievedObject.getTestDate().getTime() / 1000);
-
-        int testDateDay = testDate.getDay();
-        int testDateMonth = testDate.getMonth();
-        int testDateYear = testDate.getYear();
-
-        int retrievedObjectDay = retrievedObject.getTestDate().getDay();
-        int retrievedObjectMonth = retrievedObject.getTestDate().getMonth();
-        int retrievedObjectYear = retrievedObject.getTestDate().getYear();
-
-        System.out.println("i1 : " + i1 + "\ni2 : " + i2);
-
-        //CR346162. In this CR, it was stated that @Temporal(DATE) fields will be equal for year, month, day but not for hours, 
-        //minutes, seconds. So, we removed the time check and checked only for the equality of day, month and year
-
-        /* assertEquals("Field type Date: "
-     + testDate.getTime() + "!="
-     + retrievedObject.getTestDate().getTime()
-     + "[" + new Date(testDate.getTime()) + " != "
-     + new Date(retrievedObject.getTestDate().getTime()) + "]",
-     (int) (testDate.getTime() / 1000),
-     (int) (retrievedObject.getTestDate().getTime() / 1000));*/
-
-        if ((testDateDay != retrievedObjectDay) ||
-            (testDateMonth != retrievedObjectMonth) ||
-            (testDateYear != retrievedObjectYear)) {
-            Assert.fail(
-                "Field type Date not stored properly. One or more of the components of the date (day, month or year) do not match. \n" +
-                    " Value that should be stored : " + testDate.toGMTString() +
-                    ". \nValue that is actually" +
-                    "stored : " + retrievedObject.getTestDate().toGMTString());
-        }
-        //assertEquals ("Field type Object", testObject,
-        //retrievedObject.getTestObject ());
-        assertEquals("Field type BigInteger", testBigInteger,
-            retrievedObject.getTestBigInteger());
-
-        try {
-            assertEquals("Field type BigDecimal (BigInteger part)",
-                testBigDecimal.toBigInteger(),
-                retrievedObject.getTestBigDecimal().toBigInteger());
-
-            assertEquals("Field type BigDecimal",
-                testBigDecimal,
-                retrievedObject.getTestBigDecimal());
-
-            assertEquals("Field type float", testfloat,
-                retrievedObject.getTestfloat(), 0.01f);
-            assertEquals("Field type double", testdouble,
-                retrievedObject.getTestdouble(), 0.01d);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe,
-                "Doubles and Floats lose precision in some data stores");
-        }
-
-        rollbackTx(pm);
-    }
-}
+/*
+ * TestFieldRange.java
+ *
+ * Created on October 12, 2006, 10:14 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.Assert;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestFieldRange extends BaseKernelTest {
+
+    protected static String RANDOM_STRING =
+        "This is my test String with all "
+            + "kinds of wierd characters: "
+            + "!@@#$\\%^&\"*()-=\\|\"\"\"\"\"+_/?.>,<~`"
+            + "'''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+            + "''''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+            + "!@@#$\\%^&\"*()-=\\|+_/?.>,<~`";
+
+    /**
+     * Creates a new instance of TestFieldRange
+     */
+    public TestFieldRange() {
+    }
+
+    public TestFieldRange(String name) {
+        super(name);
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+        deleteAll(AllFieldTypesTest.class);
+    }
+
+    public void testSaveState()
+        throws Exception {
+        allFieldSaveState(
+            (int) 259645,
+            (short) 50849,
+            (long) 2349847982L,
+            (float) 43273423.0234723F,
+            (double) 34678.02384723D,
+            (byte) -120,
+            (boolean) true,
+            (char) '%',
+            (Date) new Date(),
+            (Serializable) new StringBuffer(5000),
+            (String) RANDOM_STRING,
+            randomBigInteger(),
+            randomBigDecimal());
+    }
+
+    /**
+     * Test to make sure all the numeric fields can accept the maximum
+     * values for their data size. Note that we subtract one from
+     * each of the values because some databases (like InstantDB)
+     * may consider them to be equivalent to NULL.
+     * FixMe: Hangs for some mysterious reason. aokeke
+     */
+
+//    public void testLargeNumbers()
+//    throws Exception {
+//        try {
+//            allFieldSaveState(
+//                    (int) (Integer.MAX_VALUE - 1),
+//                    (short) (Short.MAX_VALUE - 1),
+//                    (long) (Long.MAX_VALUE - 1l),
+//                    (float) (Float.MAX_VALUE - 1.0f),
+//                    (double) (Double.MAX_VALUE - 1.0d),
+//                    (byte) (Byte.MAX_VALUE),
+//                    (boolean) true,
+//                    (char) 'q',
+//                    (Date) new Date(),
+//                    (Serializable) new StringBuffer(5000),
+//                    (String) RANDOM_STRING,
+//                    randomBigInteger(),
+//                    randomBigDecimal());
+//        } catch (Throwable e) {
+//            bug(3, e, "doubles and floats");
+//        }
+//    }
+
+    /**
+     * Test to make sure all the numeric fields can be set to
+     * very low values. We add one to the minimim value because
+     * some databases (such as InstantDB) consider the MIN_VALUE
+     * to be equivalent to null. This is arguably a bug, but
+     * not a killer one.
+     */
+    public void testLargeNumbersNegative()
+        throws Exception {
+        allFieldSaveState(
+            (int) (Integer.MIN_VALUE + 1),
+            (short) (Short.MIN_VALUE + 1),
+            (long) (Long.MIN_VALUE + 1l),
+            (float) (Float.MIN_VALUE + 1.0f),
+            (double) (Double.MIN_VALUE + 1.0d),
+            (byte) (Byte.MIN_VALUE + 1),
+            (boolean) true,
+            (char) 'q',
+            (Date) new Date(),
+            (Serializable) new StringBuffer(5000),
+            (String) RANDOM_STRING,
+            randomBigInteger(),
+            randomBigDecimal());
+    }
+
+    public void testDoubleAndFloatPrecision()
+        throws Exception {
+        allFieldSaveState(
+            (int) (0),
+            (short) (0),
+            (long) (0l),
+            (float) (10.0f / 3.0f),
+            (double) (100.0d / 3.0d),
+            (byte) (0),
+            (boolean) true,
+            (char) 'q',
+            (Date) new Date(),
+            (Serializable) new StringBuffer(5000),
+            (String) RANDOM_STRING,
+            randomBigInteger(),
+            randomBigDecimal());
+    }
+
+    public void testZeroNumbers()
+        throws Exception {
+        allFieldSaveState(
+            (int) (0),
+            (short) (0),
+            (long) (0l),
+            (float) (0.0f),
+            (double) (0.0d),
+            (byte) (0),
+            (boolean) true,
+            (char) 'q',
+            (Date) new Date(),
+            (Serializable) new StringBuffer(5000),
+            (String) RANDOM_STRING,
+            new BigInteger("0"),
+            new BigDecimal("0.0"));
+    }
+
+    public void testLowDate()
+        throws Exception {
+        dateTest(0);
+    }
+
+    public void testCurDate()
+        throws Exception {
+        dateTest(System.currentTimeMillis());
+    }
+
+    public void testHighDate()
+        throws Exception {
+        try {
+            // postgres will sometimes store the String "invalid" if the
+            // date is too high, which will prevent us from even reading
+            // the records that contain this corrupt value (thus breaking
+            // any subsequent attempts to read instances of AllFieldTypesTest).
+            // An Example of a date like this is:
+            //   (Timestamp) 2038-02-08 22:20:07.65
+            if (getCurrentPlatform() ==
+                AbstractTestCase.Platform.POSTGRESQL)
+                fail("Postgres can't even try to store a high date");
+
+            dateTest(System.currentTimeMillis() * 2);
+        } catch (AssertionFailedError e) {
+            bug(6, e, "Some data stores cannot deal "
+                + "with very high dates");
+        }
+    }
+
+    /**
+     * Some date instances that have been known to have problems.
+     */
+    public void testProblematicDates()
+        throws Exception {
+        dateTest(1047744639);        // pointbase had probs with this
+    }
+
+    private void dateTest(long l)
+        throws Exception {
+        Date d = new Date(l);
+
+        allFieldSaveState(
+            (int) 10,
+            (short) 10,
+            (long) 10,
+            (float) 0,
+            (double) 0,
+            (byte) 10,
+            (boolean) true,
+            (char) 'x',
+            (Date) d,
+            (Serializable) new StringBuffer(10),
+            (String) RANDOM_STRING,
+            new BigInteger("0"),
+            new BigDecimal("0"));
+    }
+
+    public void allFieldSaveState(int testint, short testshort, long testlong,
+        float testfloat, double testdouble, byte testbyte,
+        boolean testboolean, char testchar, Date testDate,
+        Serializable testObject, String testString,
+        BigInteger testBigInteger, BigDecimal testBigDecimal)
+        throws Exception {
+        try {
+            allFieldSaveStateInternal(testint, testshort, testlong,
+                testfloat, testdouble, testbyte,
+                testboolean, testchar, testDate,
+                testObject, testString, testBigInteger, testBigDecimal);
+        } finally {
+            try {
+                // make *sure* we do not leave a transaction open
+                rollbackTx(getPM(true, false));
+            } catch (Throwable t) {
+
+            }
+        }
+    }
+
+    public void allFieldSaveStateInternal(
+        int testint, short testshort, long testlong,
+        float testfloat, double testdouble, byte testbyte,
+        boolean testboolean, char testchar, Date testDate,
+        Serializable testObject, String testString,
+        BigInteger testBigInteger, BigDecimal testBigDecimal)
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        AllFieldTypesTest test = new AllFieldTypesTest();
+        pm.persist(test);
+        Object testID = pm.getObjectId(test);
+
+        test.setTestint(testint);
+        test.setTestlong(testlong);
+        test.setTestdouble(testdouble);
+        test.setTestshort(testshort);
+        test.setTestfloat(testfloat);
+        test.setTestbyte(testbyte);
+        test.setTestboolean(testboolean);
+        test.setTestchar(testchar);
+        test.setTestString(testString);
+        test.setTestDate(testDate);
+        test.setTestObject(testObject);
+        test.setTestBigInteger(testBigInteger);
+        test.setTestBigDecimal(testBigDecimal);
+
+        try {
+            endTx(pm);
+        } catch (Exception e) {
+            if (e instanceof Exception &&
+                ((Exception) e).getMessage().indexOf
+                    ("Maximum length is 8000") != -1) {
+                bug(AbstractTestCase.Platform.SQLSERVER, 5, e,
+                    "SQLServer cannot deal"
+                        + " with numbers with more than 8000 digits");
+            } else {
+                throw e;
+            }
+        }
+
+        endEm(pm);
+
+        //assertPersistent (test, true, false, false, false);
+
+        pm = getPM(true, false);
+        startTx(pm);
+
+        AllFieldTypesTest retrievedObject =
+            (AllFieldTypesTest) pm.find(AllFieldTypesTest.class, testID);
+
+        assertEquals("Field type int", testint,
+            retrievedObject.getTestint());
+        assertEquals("Field type short", testshort,
+            retrievedObject.getTestshort());
+        assertEquals("Field type boolean", testboolean,
+            retrievedObject.getTestboolean());
+        assertEquals("Field type char", testchar,
+            retrievedObject.getTestchar());
+        assertEquals("Field type long", testlong,
+            retrievedObject.getTestlong());
+
+        assertEquals("Field type byte", testbyte,
+            retrievedObject.getTestbyte());
+        assertEquals("Field type String", testString,
+            retrievedObject.getTestString());
+
+        int i1 = (int) (testDate.getTime() / 1000);
+        int i2 = (int) (retrievedObject.getTestDate().getTime() / 1000);
+
+        int testDateDay = testDate.getDay();
+        int testDateMonth = testDate.getMonth();
+        int testDateYear = testDate.getYear();
+
+        int retrievedObjectDay = retrievedObject.getTestDate().getDay();
+        int retrievedObjectMonth = retrievedObject.getTestDate().getMonth();
+        int retrievedObjectYear = retrievedObject.getTestDate().getYear();
+
+        System.out.println("i1 : " + i1 + "\ni2 : " + i2);
+
+        //CR346162. In this CR, it was stated that @Temporal(DATE) fields will be equal for year, month, day but not for hours, 
+        //minutes, seconds. So, we removed the time check and checked only for the equality of day, month and year
+
+        /* assertEquals("Field type Date: "
+     + testDate.getTime() + "!="
+     + retrievedObject.getTestDate().getTime()
+     + "[" + new Date(testDate.getTime()) + " != "
+     + new Date(retrievedObject.getTestDate().getTime()) + "]",
+     (int) (testDate.getTime() / 1000),
+     (int) (retrievedObject.getTestDate().getTime() / 1000));*/
+
+        if ((testDateDay != retrievedObjectDay) ||
+            (testDateMonth != retrievedObjectMonth) ||
+            (testDateYear != retrievedObjectYear)) {
+            Assert.fail(
+                "Field type Date not stored properly. One or more of the components of the date (day, month or year) do not match. \n" +
+                    " Value that should be stored : " + testDate.toGMTString() +
+                    ". \nValue that is actually" +
+                    "stored : " + retrievedObject.getTestDate().toGMTString());
+        }
+        //assertEquals ("Field type Object", testObject,
+        //retrievedObject.getTestObject ());
+        assertEquals("Field type BigInteger", testBigInteger,
+            retrievedObject.getTestBigInteger());
+
+        try {
+            assertEquals("Field type BigDecimal (BigInteger part)",
+                testBigDecimal.toBigInteger(),
+                retrievedObject.getTestBigDecimal().toBigInteger());
+
+            assertEquals("Field type BigDecimal",
+                testBigDecimal,
+                retrievedObject.getTestBigDecimal());
+
+            assertEquals("Field type float", testfloat,
+                retrievedObject.getTestfloat(), 0.01f);
+            assertEquals("Field type double", testdouble,
+                retrievedObject.getTestdouble(), 0.01d);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe,
+                "Doubles and Floats lose precision in some data stores");
+        }
+
+        rollbackTx(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange2.java
index 45a2f57..9103fbf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldRange2.java
@@ -1,232 +1,232 @@
-/*
- * TestFieldRange.java
- *
- * Created on October 12, 2006, 10:14 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestFieldRange2 extends BaseKernelTest {
-
-    protected static String RANDOM_STRING =
-        "This is my test String with all "
-            + "kinds of wierd characters: "
-            + "!@@#$\\%^&\"*()-=\\|\"\"\"\"\"+_/?.>,<~`"
-            + "'''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
-            + "''''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
-            + "!@@#$\\%^&\"*()-=\\|+_/?.>,<~`";
-
-    /**
-     * Creates a new instance of TestFieldRange
-     */
-    public TestFieldRange2() {
-    }
-
-    public TestFieldRange2(String name) {
-        super(name);
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-        deleteAll(AllFieldTypesTest.class);
-    }
-
-    public void testSaveState()
-        throws Exception {
-        allFieldSaveState(
-            (int) 259645,
-            (short) 50849,
-            (long) 2349847982L,
-            (float) 43273423.0234723F,
-            (double) 34678.02384723D,
-            (byte) -120,
-            (boolean) true,
-            (char) '%',
-            (Date) new Date(),
-            (Serializable) new StringBuffer(5000),
-            (String) RANDOM_STRING,
-            randomBigInteger(),
-            randomBigDecimal());
-    }
-
-    private void dateTest(long l)
-        throws Exception {
-        Date d = new Date(l);
-
-        allFieldSaveState(
-            (int) 10,
-            (short) 10,
-            (long) 10,
-            (float) 0,
-            (double) 0,
-            (byte) 10,
-            (boolean) true,
-            (char) 'x',
-            (Date) d,
-            (Serializable) new StringBuffer(10),
-            (String) RANDOM_STRING,
-            new BigInteger("0"),
-            new BigDecimal("0"));
-    }
-
-    public void allFieldSaveState(int testint, short testshort, long testlong,
-        float testfloat, double testdouble, byte testbyte,
-        boolean testboolean, char testchar, Date testDate,
-        Serializable testObject, String testString,
-        BigInteger testBigInteger, BigDecimal testBigDecimal)
-        throws Exception {
-        try {
-            allFieldSaveStateInternal(testint, testshort, testlong,
-                testfloat, testdouble, testbyte,
-                testboolean, testchar, testDate,
-                testObject, testString, testBigInteger, testBigDecimal);
-        } finally {
-            try {
-                // make *sure* we do not leave a transaction open
-                rollbackTx(getPM(true, false));
-            } catch (Throwable t) {
-
-            }
-        }
-    }
-
-    public void allFieldSaveStateInternal(
-        int testint, short testshort, long testlong,
-        float testfloat, double testdouble, byte testbyte,
-        boolean testboolean, char testchar, Date testDate,
-        Serializable testObject, String testString,
-        BigInteger testBigInteger, BigDecimal testBigDecimal)
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        AllFieldTypesTest test = new AllFieldTypesTest();
-        //pm.persist(test);
-        //Object testID = pm.getObjectId(test);
-
-        test.setTestint(testint);
-        test.setTestlong(testlong);
-        test.setTestdouble(testdouble);
-        test.setTestshort(testshort);
-        test.setTestfloat(testfloat);
-        test.setTestbyte(testbyte);
-        test.setTestboolean(testboolean);
-        test.setTestchar(testchar);
-        test.setTestString(testString);
-        test.setTestDate(testDate);
-        test.setTestObject(testObject);
-        test.setTestBigInteger(testBigInteger);
-        test.setTestBigDecimal(testBigDecimal);
-
-        pm.persist(test);
-        Object testID = pm.getObjectId(test);
-
-        try {
-            endTx(pm);
-        } catch (Exception e) {
-            if (e instanceof Exception &&
-                ((Exception) e).getMessage().indexOf
-                    ("Maximum length is 8000") != -1) {
-                bug(5, e, "SQLServer cannot deal"
-                        + " with numbers with more than 8000 digits");
-            } else {
-                throw e;
-            }
-        }
-
-        endEm(pm);
-
-        //assertPersistent (test, true, false, false, false);
-
-        pm = getPM(true, false);
-        startTx(pm);
-
-        AllFieldTypesTest retrievedObject =
-            (AllFieldTypesTest) pm.find(AllFieldTypesTest.class, testID);
-
-        assertEquals("Field type int", testint,
-            retrievedObject.getTestint());
-        assertEquals("Field type short", testshort,
-            retrievedObject.getTestshort());
-        assertEquals("Field type boolean", testboolean,
-            retrievedObject.getTestboolean());
-        assertEquals("Field type char", testchar,
-            retrievedObject.getTestchar());
-        assertEquals("Field type long", testlong,
-            retrievedObject.getTestlong());
-
-        assertEquals("Field type byte", testbyte,
-            retrievedObject.getTestbyte());
-        assertEquals("Field type String", testString,
-            retrievedObject.getTestString());
-
-        int i1 = (int) (testDate.getTime() / 1000);
-        int i2 = (int) (retrievedObject.getTestDate().getTime() / 1000);
-
-        System.out.println("i1 : " + i1 + "\ni2 : " + i2);
-        assertEquals("Field type Date: "
-            + testDate.getTime() + "!="
-            + retrievedObject.getTestDate().getTime()
-            + "[" + new Date(testDate.getTime()) + " != "
-            + new Date(retrievedObject.getTestDate().getTime()) + "]",
-            (int) (testDate.getTime() / 1000),
-            (int) (retrievedObject.getTestDate().getTime() / 1000));
-        //assertEquals ("Field type Object", testObject,
-        //retrievedObject.getTestObject ());
-        assertEquals("Field type BigInteger", testBigInteger,
-            retrievedObject.getTestBigInteger());
-
-        try {
-            assertEquals("Field type BigDecimal (BigInteger part)",
-                testBigDecimal.toBigInteger(),
-                retrievedObject.getTestBigDecimal().toBigInteger());
-
-            assertEquals("Field type BigDecimal",
-                testBigDecimal,
-                retrievedObject.getTestBigDecimal());
-
-            assertEquals("Field type float", testfloat,
-                retrievedObject.getTestfloat(), 0.01f);
-            assertEquals("Field type double", testdouble,
-                retrievedObject.getTestdouble(), 0.01d);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe,
-                "Doubles and Floats lose precision in some data stores");
-        }
-
-        rollbackTx(pm);
-    }
-}
+/*
+ * TestFieldRange.java
+ *
+ * Created on October 12, 2006, 10:14 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestFieldRange2 extends BaseKernelTest {
+
+    protected static String RANDOM_STRING =
+        "This is my test String with all "
+            + "kinds of wierd characters: "
+            + "!@@#$\\%^&\"*()-=\\|\"\"\"\"\"+_/?.>,<~`"
+            + "'''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+            + "''''''''''''\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+            + "!@@#$\\%^&\"*()-=\\|+_/?.>,<~`";
+
+    /**
+     * Creates a new instance of TestFieldRange
+     */
+    public TestFieldRange2() {
+    }
+
+    public TestFieldRange2(String name) {
+        super(name);
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+        deleteAll(AllFieldTypesTest.class);
+    }
+
+    public void testSaveState()
+        throws Exception {
+        allFieldSaveState(
+            (int) 259645,
+            (short) 50849,
+            (long) 2349847982L,
+            (float) 43273423.0234723F,
+            (double) 34678.02384723D,
+            (byte) -120,
+            (boolean) true,
+            (char) '%',
+            (Date) new Date(),
+            (Serializable) new StringBuffer(5000),
+            (String) RANDOM_STRING,
+            randomBigInteger(),
+            randomBigDecimal());
+    }
+
+    private void dateTest(long l)
+        throws Exception {
+        Date d = new Date(l);
+
+        allFieldSaveState(
+            (int) 10,
+            (short) 10,
+            (long) 10,
+            (float) 0,
+            (double) 0,
+            (byte) 10,
+            (boolean) true,
+            (char) 'x',
+            (Date) d,
+            (Serializable) new StringBuffer(10),
+            (String) RANDOM_STRING,
+            new BigInteger("0"),
+            new BigDecimal("0"));
+    }
+
+    public void allFieldSaveState(int testint, short testshort, long testlong,
+        float testfloat, double testdouble, byte testbyte,
+        boolean testboolean, char testchar, Date testDate,
+        Serializable testObject, String testString,
+        BigInteger testBigInteger, BigDecimal testBigDecimal)
+        throws Exception {
+        try {
+            allFieldSaveStateInternal(testint, testshort, testlong,
+                testfloat, testdouble, testbyte,
+                testboolean, testchar, testDate,
+                testObject, testString, testBigInteger, testBigDecimal);
+        } finally {
+            try {
+                // make *sure* we do not leave a transaction open
+                rollbackTx(getPM(true, false));
+            } catch (Throwable t) {
+
+            }
+        }
+    }
+
+    public void allFieldSaveStateInternal(
+        int testint, short testshort, long testlong,
+        float testfloat, double testdouble, byte testbyte,
+        boolean testboolean, char testchar, Date testDate,
+        Serializable testObject, String testString,
+        BigInteger testBigInteger, BigDecimal testBigDecimal)
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        AllFieldTypesTest test = new AllFieldTypesTest();
+        //pm.persist(test);
+        //Object testID = pm.getObjectId(test);
+
+        test.setTestint(testint);
+        test.setTestlong(testlong);
+        test.setTestdouble(testdouble);
+        test.setTestshort(testshort);
+        test.setTestfloat(testfloat);
+        test.setTestbyte(testbyte);
+        test.setTestboolean(testboolean);
+        test.setTestchar(testchar);
+        test.setTestString(testString);
+        test.setTestDate(testDate);
+        test.setTestObject(testObject);
+        test.setTestBigInteger(testBigInteger);
+        test.setTestBigDecimal(testBigDecimal);
+
+        pm.persist(test);
+        Object testID = pm.getObjectId(test);
+
+        try {
+            endTx(pm);
+        } catch (Exception e) {
+            if (e instanceof Exception &&
+                ((Exception) e).getMessage().indexOf
+                    ("Maximum length is 8000") != -1) {
+                bug(5, e, "SQLServer cannot deal"
+                        + " with numbers with more than 8000 digits");
+            } else {
+                throw e;
+            }
+        }
+
+        endEm(pm);
+
+        //assertPersistent (test, true, false, false, false);
+
+        pm = getPM(true, false);
+        startTx(pm);
+
+        AllFieldTypesTest retrievedObject =
+            (AllFieldTypesTest) pm.find(AllFieldTypesTest.class, testID);
+
+        assertEquals("Field type int", testint,
+            retrievedObject.getTestint());
+        assertEquals("Field type short", testshort,
+            retrievedObject.getTestshort());
+        assertEquals("Field type boolean", testboolean,
+            retrievedObject.getTestboolean());
+        assertEquals("Field type char", testchar,
+            retrievedObject.getTestchar());
+        assertEquals("Field type long", testlong,
+            retrievedObject.getTestlong());
+
+        assertEquals("Field type byte", testbyte,
+            retrievedObject.getTestbyte());
+        assertEquals("Field type String", testString,
+            retrievedObject.getTestString());
+
+        int i1 = (int) (testDate.getTime() / 1000);
+        int i2 = (int) (retrievedObject.getTestDate().getTime() / 1000);
+
+        System.out.println("i1 : " + i1 + "\ni2 : " + i2);
+        assertEquals("Field type Date: "
+            + testDate.getTime() + "!="
+            + retrievedObject.getTestDate().getTime()
+            + "[" + new Date(testDate.getTime()) + " != "
+            + new Date(retrievedObject.getTestDate().getTime()) + "]",
+            (int) (testDate.getTime() / 1000),
+            (int) (retrievedObject.getTestDate().getTime() / 1000));
+        //assertEquals ("Field type Object", testObject,
+        //retrievedObject.getTestObject ());
+        assertEquals("Field type BigInteger", testBigInteger,
+            retrievedObject.getTestBigInteger());
+
+        try {
+            assertEquals("Field type BigDecimal (BigInteger part)",
+                testBigDecimal.toBigInteger(),
+                retrievedObject.getTestBigDecimal().toBigInteger());
+
+            assertEquals("Field type BigDecimal",
+                testBigDecimal,
+                retrievedObject.getTestBigDecimal());
+
+            assertEquals("Field type float", testfloat,
+                retrievedObject.getTestfloat(), 0.01f);
+            assertEquals("Field type double", testdouble,
+                retrievedObject.getTestdouble(), 0.01d);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe,
+                "Doubles and Floats lose precision in some data stores");
+        }
+
+        rollbackTx(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldState.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldState.java
index 6c34c14..095be96 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldState.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestFieldState.java
@@ -1,81 +1,81 @@
-/*
- * TestFieldState.java
- *
- * Created on October 12, 2006, 10:22 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestFieldState extends BaseKernelTest {
-
-    private Object oid;
-
-    /**
-     * Creates a new instance of TestFieldState
-     */
-    public TestFieldState() {
-    }
-
-    public TestFieldState(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        // create a test object
-        RuntimeTest1 a = new RuntimeTest1("foo", 3);
-        pm.persist(a);
-
-        endTx(pm);
-
-        oid = pm.getObjectId(a);
-        endEm(pm);
-    }
-
-    public void testNotDirtyAfterSameChange() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        RuntimeTest1 a = (RuntimeTest1) pm.find(RuntimeTest1.class, oid);
-        a.setStringField(a.getStringField());
-        OpenJPAStateManager sm = getStateManager(a, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("stringField");
-        assertTrue(sm.getDirty().get(fmd.getIndex()) == false);
-
-        endTx(pm);
-        endEm(pm);
-    }
-}
+/*
+ * TestFieldState.java
+ *
+ * Created on October 12, 2006, 10:22 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestFieldState extends BaseKernelTest {
+
+    private Object oid;
+
+    /**
+     * Creates a new instance of TestFieldState
+     */
+    public TestFieldState() {
+    }
+
+    public TestFieldState(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        // create a test object
+        RuntimeTest1 a = new RuntimeTest1("foo", 3);
+        pm.persist(a);
+
+        endTx(pm);
+
+        oid = pm.getObjectId(a);
+        endEm(pm);
+    }
+
+    public void testNotDirtyAfterSameChange() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        RuntimeTest1 a = (RuntimeTest1) pm.find(RuntimeTest1.class, oid);
+        a.setStringField(a.getStringField());
+        OpenJPAStateManager sm = getStateManager(a, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("stringField");
+        assertTrue(sm.getDirty().get(fmd.getIndex()) == false);
+
+        endTx(pm);
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestGetObjectsById.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestGetObjectsById.java
index 3cccc5a..b6c7863 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestGetObjectsById.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestGetObjectsById.java
@@ -1,88 +1,88 @@
-/*
- * TestGetObjectsById.java
- *
- * Created on October 12, 2006, 10:49 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest5;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestGetObjectsById extends BaseKernelTest {
-
-    private Object[] oids;
-
-    /**
-     * Creates a new instance of TestGetObjectsById
-     */
-    public TestGetObjectsById(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest5.class);
-        deleteAll(RuntimeTest4.class);
-
-        RuntimeTest4 rt4 = new RuntimeTest4("foo");
-
-        RuntimeTest5 related0 = new RuntimeTest5("bar");
-        related0.setRuntimeTest4(rt4);
-        rt4.getRuntimeTest5s().add(related0);
-
-        RuntimeTest5 related1 = new RuntimeTest5("baz");
-        related1.setRuntimeTest4(rt4);
-        rt4.getRuntimeTest5s().add(related1);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(rt4);
-        endTx(pm);
-        oids = new Object[]
-            {
-                pm.getObjectId(rt4),
-                pm.getObjectId(related0),
-                pm.getObjectId(related1),
-            };
-        endEm(pm);
-    }
-
-    public void testGetObjectsByIdInvocation() {
-        OpenJPAEntityManager pm = getPM();
-        try {
-            Object[] pcs = pm.findAll(Object.class, oids);
-            assertEquals(oids.length, pcs.length);
-            for (int i = 0; i < oids.length; i++)
-                assertEquals(oids[i], pm.getObjectId(pcs[i]));
-        } catch (Exception e) {
-            bug(1017, e, "getObjectsById() bug");
-        } finally {
-            endEm(pm);
-        }
-    }
-}
+/*
+ * TestGetObjectsById.java
+ *
+ * Created on October 12, 2006, 10:49 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest5;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestGetObjectsById extends BaseKernelTest {
+
+    private Object[] oids;
+
+    /**
+     * Creates a new instance of TestGetObjectsById
+     */
+    public TestGetObjectsById(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest5.class);
+        deleteAll(RuntimeTest4.class);
+
+        RuntimeTest4 rt4 = new RuntimeTest4("foo");
+
+        RuntimeTest5 related0 = new RuntimeTest5("bar");
+        related0.setRuntimeTest4(rt4);
+        rt4.getRuntimeTest5s().add(related0);
+
+        RuntimeTest5 related1 = new RuntimeTest5("baz");
+        related1.setRuntimeTest4(rt4);
+        rt4.getRuntimeTest5s().add(related1);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(rt4);
+        endTx(pm);
+        oids = new Object[]
+            {
+                pm.getObjectId(rt4),
+                pm.getObjectId(related0),
+                pm.getObjectId(related1),
+            };
+        endEm(pm);
+    }
+
+    public void testGetObjectsByIdInvocation() {
+        OpenJPAEntityManager pm = getPM();
+        try {
+            Object[] pcs = pm.findAll(Object.class, oids);
+            assertEquals(oids.length, pcs.length);
+            for (int i = 0; i < oids.length; i++)
+                assertEquals(oids[i], pm.getObjectId(pcs[i]));
+        } catch (Exception e) {
+            bug(1017, e, "getObjectsById() bug");
+        } finally {
+            endEm(pm);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushes.java
index 1dd3913..84816f3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushes.java
@@ -1,448 +1,448 @@
-/*
- * TestIncrementalFlushes.java
- *
- * Created on October 12, 2006, 11:24 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ModInstanceCallbackTests;
-import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
-
-import org.apache.openjpa.event.AbstractTransactionListener;
-import org.apache.openjpa.event.TransactionEvent;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-
-public class TestIncrementalFlushes extends BaseKernelTest {
-
-    public TestIncrementalFlushes(String str) {
-        super(str);
-    }
-
-    /**
-     * Creates a new instance of TestIncrementalFlushes
-     */
-    public TestIncrementalFlushes() {
-    }
-
-    public void setUp() {
-        deleteAll(ModRuntimeTest1.class);
-//        deleteAll(ModInstanceCallbackTests.class);
-    }
-
-    public void testBasicJdoPreStore() {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
-        pm.persist(a);
-        pm.flush();
-        assertTrue(a.preStoreCalled);
-        endTx(pm);
-    }
-
-    public void testNoFlush() {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
-        pm.persist(a);
-        endTx(pm);
-        assertTrue(a.preStoreCalled);
-    }
-
-    public void testFlushNoChange() {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
-        pm.persist(a);
-        pm.flush();
-        endTx(pm);
-        assertTrue(a.preStoreCalled);
-        assertEquals(10, a.getIntField());
-    }
-
-    /**
-     * Helper method for some common test cases. See utilizations of
-     * this below.
-     */
-    private void basicHelper(boolean update, boolean multi, boolean dfg,
-        boolean nonDFG) {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
-        pm.persist(a);
-        if (update) {
-            endTx(pm);
-            Object oid = pm.getObjectId(a);
-            endEm(pm);
-            pm = getPM(true, false);
-            startTx(pm);
-            a = (ModInstanceCallbackTests) pm
-                .find(ModInstanceCallbackTests.class, oid);
-        } else {
-            pm.flush();
-        }
-
-        if (dfg)
-            a.setIntField(11);
-        if (nonDFG)
-            a.setNonDFGField(11);
-
-        if (multi) {
-            pm.flush();
-
-            if (dfg)
-                a.setIntField(12);
-            if (nonDFG)
-                a.setNonDFGField(12);
-        }
-
-        endTx(pm);
-
-        // if no changes were made and we're in update mode, then this
-        // object won't have had jdoPreStore() called.
-//        if (!(update && (!dfg && !nonDFG)))
-//            assertTrue("a.prestoreCalled is false", a.preStoreCalled);
-
-        if (multi) {
-            if (dfg)
-                assertEquals("a.getIntField is not 12", 12, a.getIntField());
-            if (nonDFG)
-                assertEquals("a.getNonDFGField is not 12", 12,
-                    a.getNonDFGField());
-        } else {
-            if (dfg)
-                assertEquals("a.getIntField is not 12", 11, a.getIntField());
-            if (nonDFG)
-                assertEquals("a.getNonDFGField is not 12", 11,
-                    a.getNonDFGField());
-        }
-    }
-
-    public void testFlushStorePrimaryDFGChange() {
-        basicHelper(false, false, true, false);
-        basicHelper(false, true, true, false);
-        basicHelper(true, false, true, false);
-        basicHelper(true, true, true, false);
-    }
-
-    public void testFlushStorePrimaryNonDFGChange() {
-        basicHelper(false, false, false, true);
-        basicHelper(false, true, false, true);
-        basicHelper(true, false, false, true);
-        basicHelper(true, true, false, true);
-    }
-
-    public void testFlushStorePrimaryNonDFGAndDFGChange() {
-        basicHelper(false, false, true, true);
-        basicHelper(false, true, true, true);
-        basicHelper(true, false, true, true);
-        basicHelper(true, true, true, true);
-    }
-
-    public void testFlushStorePrimaryNoChanges() {
-        basicHelper(false, false, false, false);
-        basicHelper(false, true, false, false);
-        basicHelper(true, false, false, false);
-        basicHelper(true, true, false, false);
-    }
-
-    public void testJdoPreStoreWithModificationBeforeFlush() {
-        tjpswmHelper(true);
-    }
-
-    public void testJdoPreStoreWithModificationAfterFlush() {
-        tjpswmHelper(false);
-    }
-
-    private void tjpswmHelper(boolean before) {
-        // set retainvalues to false so that we can ensure that the
-        // data in the database is correct, and that we're not just
-        // testing that the JVM data is correct.
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
-        pm.persist(a);
-
-        // by setting the name to 'bar', the jdoPreStore() invocation
-        // will set the parent to a new object. This ensures that new
-        // objects created in jdoPreStore() make their way into the DB
-        // during commit.
-        if (before) {
-            a.setStringField("bar");
-            pm.flush();
-        } else {
-            pm.flush();
-            a.setStringField("bar");
-        }
-        endTx(pm);
-        assertTrue("a.preStoreCalled is false", a.preStoreCalled);
-        assertNotNull("a.getOneOne is null", a.getOneOne());
-        assertTrue("getOneOne().getstrngfld.equals(jdoPrestore) is false",
-            a.getOneOne().getStringField().equals("jdoPreStore"));
-    }
-
-    public void testOneToOneBefore() {
-        totoHelper(true, true, false);
-        totoHelper(true, false, false);
-        totoHelper(true, true, true);
-        totoHelper(true, false, true);
-    }
-
-    public void testOneToOneAfter() {
-        totoHelper(false, true, false);
-        totoHelper(false, false, false);
-        totoHelper(false, true, true);
-        totoHelper(false, false, true);
-    }
-
-    private void totoHelper(boolean before, boolean persist,
-        boolean multi) {
-        // set retainvalues to false so that we can ensure that the
-        // data in the database is correct, and that we're not just
-        // testing that the JVM data is correct.
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
-        pm.persist(a);
-
-        ModRuntimeTest1 parent = new ModRuntimeTest1("baz", 11);
-        if (!before)
-            pm.flush();
-
-        if (persist)
-            pm.persist(parent);
-
-        a.setOneOne(parent);
-
-        if (before)
-            pm.flush();
-
-        ModRuntimeTest1 oldParent = null;
-        if (multi) {
-            oldParent = parent;
-            parent = new ModRuntimeTest1("newParent", 12);
-
-            if (!before)
-                pm.flush();
-
-            if (persist)
-                pm.persist(parent);
-
-            a.setOneOne(parent);
-
-            if (before)
-                pm.flush();
-        }
-
-        endTx(pm);
-        assertTrue("a.preStoreCalled is false", a.preStoreCalled);
-        assertNotNull("a.getOneOne is null", a.getOneOne());
-        if (!multi)
-            assertTrue("a.getOneOne().getStringField().equals(baz) is false",
-                a.getOneOne().getStringField().equals("baz"));
-        else {
-            assertTrue(
-                "a.getOneOne().getStringField().equals(newParent) is false",
-                a.getOneOne().getStringField().equals("newParent"));
-
-            // if multi, then we really should delete the baz
-            // parent. This isn't happening right now.
-            // ### should be a bug
-            //assertTrue (JDOHelper.isDeleted (oldParent));
-        }
-    }
-
-    private void assertState(Object o, PCState state, OpenJPAEntityManager pm) {
-        assertEquals(state, getStateManager(o, pm).getPCState());
-    }
-
-    private void commitAndTestDelete(OpenJPAEntityManager pm, Object o) {
-        Object oid = pm.getObjectId(o);
-        endTx(pm);
-
-        pm = getPM();
-        try {
-            pm.find(Object.class, oid);
-            fail("should not be able to load deleted object");
-        } catch (Exception e) {
-            // expected case
-        }
-    }
-
-    public void testDeleteNew() {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-        ModRuntimeTest1 a = new ModRuntimeTest1("foo", 10);
-        pm.persist(a);
-        pm.remove(a);
-        assertState(a, PCState.PNEWDELETED, pm);
-    }
-
-    public void testOptimisticLockGivesCorrectError() {
-        OpenJPAEntityManager pm1 = getPM(true, false);
-        OpenJPAEntityManager pm2 = getPM(true, false);
-
-        ModRuntimeTest1 a1 = new ModRuntimeTest1("foo", 10);
-        startTx(pm1);
-        pm1.persist(a1);
-        endTx(pm1);
-
-        ModRuntimeTest1 a2 = (ModRuntimeTest1)
-            pm2.find(ModRuntimeTest1.class, pm2.getObjectId(a1));
-        startTx(pm2);
-        a2.setStringField("foobar");
-        endTx(pm2);
-
-        startTx(pm1);
-        a1.setStringField("foobarbaz");
-        try {
-            endTx(pm1);
-        } catch (Exception ole) {
-            // expected case
-        } finally {
-            rollbackTx(pm1);
-
-            pm1.close();
-            pm2.close();
-        }
-    }
-
-    /**
-     * Verify that flushes to the datastore are isolated from other
-     * PersistenceManagers. This is mostly a test of the underlying
-     * datastore's transactional isolation capabilities.
-     * <p/>
-     * Disabled: this hangs on Sybase.
-     */
-    public void XXXtestFlushesAreIsolated() {
-        final String name = "testFlushesAreIsolated";
-
-        deleteAll(ModRuntimeTest1.class);
-
-        OpenJPAEntityManager flushPM = getPM(true, false);
-        startTx(flushPM);
-
-        OpenJPAEntityManager readPM = getPM(true, false);
-        startTx(readPM);
-
-        assertSize(0, flushPM.createNativeQuery("stringField == '" + name + "'",
-            ModRuntimeTest1.class));
-        assertSize(0, readPM.createNativeQuery("stringField == '" + name + "'",
-            ModRuntimeTest1.class));
-
-        ModRuntimeTest1 a = new ModRuntimeTest1(name, randomInt().intValue());
-
-        flushPM.persist(a);
-
-        assertSize(0, readPM.createNativeQuery("name == '" + name + "'",
-            ModRuntimeTest1.class));
-
-        flushPM.flush();
-
-        // make sure the other pm doesn't see the flushed object
-        assertSize(0, readPM.createNativeQuery("name == '" + name + "'",
-            ModRuntimeTest1.class));
-
-        flushPM.remove(a);
-
-        assertSize(0, flushPM.createNativeQuery("name == '" + name + "'",
-            ModRuntimeTest1.class));
-        assertSize(0, readPM.createNativeQuery("name == '" + name + "'",
-            ModRuntimeTest1.class));
-
-        endTx(flushPM);
-        endEm(flushPM);
-
-        endTx(readPM);
-        endEm(readPM);
-    }
-
-    public void testEmptyFlush() {
-        OpenJPAEntityManager pm = getPM();
-        TListener listener = new TListener();
-        ((OpenJPAEntityManagerSPI) pm).addTransactionListener(listener);
-        startTx(pm);
-        ModRuntimeTest1 pc = new ModRuntimeTest1();
-        pm.persist(pc);
-        pm.flush();
-        assertEquals(1, listener.flushes);
-        assertEquals(0, listener.commits);
-
-        pm.flush();
-        assertEquals(1, listener.flushes);
-        assertEquals(0, listener.commits);
-
-        pc.setIntField(3);
-        pm.flush();
-        assertEquals(2, listener.flushes);
-        assertEquals(0, listener.commits);
-
-        endTx(pm);
-        assertEquals(2, listener.flushes);
-        assertEquals(1, listener.commits);
-
-        endEm(pm);
-    }
-
-    public void testEmptyRollback() {
-        OpenJPAEntityManager pm = getPM();
-        TListener listener = new TListener();
-        ((OpenJPAEntityManagerSPI) pm).addTransactionListener(listener);
-        startTx(pm);
-        pm.flush();
-        rollbackTx(pm);
-        assertEquals(0, listener.flushes);
-        assertEquals(0, listener.commits);
-        endEm(pm);
-    }
-
-    public void testEmptyCommit() {
-        OpenJPAEntityManager pm = getPM();
-        TListener listener = new TListener();
-        ((OpenJPAEntityManagerSPI) pm).addTransactionListener(listener);
-        startTx(pm);
-        endTx(pm);
-        assertEquals(0, listener.flushes);
-        assertEquals(1, listener.commits);
-        endEm(pm);
-    }
-
-    private static class TListener
-        extends AbstractTransactionListener {
-
-        public int flushes = 0;
-        public int commits = 0;
-
-        protected void eventOccurred(TransactionEvent event) {
-            if (event.getType() == event.BEFORE_FLUSH)
-                flushes++;
-            else if (event.getType() == event.BEFORE_COMMIT)
-                commits++;
-        }
-    }
-}
+/*
+ * TestIncrementalFlushes.java
+ *
+ * Created on October 12, 2006, 11:24 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ModInstanceCallbackTests;
+import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
+
+import org.apache.openjpa.event.AbstractTransactionListener;
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+
+public class TestIncrementalFlushes extends BaseKernelTest {
+
+    public TestIncrementalFlushes(String str) {
+        super(str);
+    }
+
+    /**
+     * Creates a new instance of TestIncrementalFlushes
+     */
+    public TestIncrementalFlushes() {
+    }
+
+    public void setUp() {
+        deleteAll(ModRuntimeTest1.class);
+//        deleteAll(ModInstanceCallbackTests.class);
+    }
+
+    public void testBasicJdoPreStore() {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
+        pm.persist(a);
+        pm.flush();
+        assertTrue(a.preStoreCalled);
+        endTx(pm);
+    }
+
+    public void testNoFlush() {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
+        pm.persist(a);
+        endTx(pm);
+        assertTrue(a.preStoreCalled);
+    }
+
+    public void testFlushNoChange() {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
+        pm.persist(a);
+        pm.flush();
+        endTx(pm);
+        assertTrue(a.preStoreCalled);
+        assertEquals(10, a.getIntField());
+    }
+
+    /**
+     * Helper method for some common test cases. See utilizations of
+     * this below.
+     */
+    private void basicHelper(boolean update, boolean multi, boolean dfg,
+        boolean nonDFG) {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
+        pm.persist(a);
+        if (update) {
+            endTx(pm);
+            Object oid = pm.getObjectId(a);
+            endEm(pm);
+            pm = getPM(true, false);
+            startTx(pm);
+            a = (ModInstanceCallbackTests) pm
+                .find(ModInstanceCallbackTests.class, oid);
+        } else {
+            pm.flush();
+        }
+
+        if (dfg)
+            a.setIntField(11);
+        if (nonDFG)
+            a.setNonDFGField(11);
+
+        if (multi) {
+            pm.flush();
+
+            if (dfg)
+                a.setIntField(12);
+            if (nonDFG)
+                a.setNonDFGField(12);
+        }
+
+        endTx(pm);
+
+        // if no changes were made and we're in update mode, then this
+        // object won't have had jdoPreStore() called.
+//        if (!(update && (!dfg && !nonDFG)))
+//            assertTrue("a.prestoreCalled is false", a.preStoreCalled);
+
+        if (multi) {
+            if (dfg)
+                assertEquals("a.getIntField is not 12", 12, a.getIntField());
+            if (nonDFG)
+                assertEquals("a.getNonDFGField is not 12", 12,
+                    a.getNonDFGField());
+        } else {
+            if (dfg)
+                assertEquals("a.getIntField is not 12", 11, a.getIntField());
+            if (nonDFG)
+                assertEquals("a.getNonDFGField is not 12", 11,
+                    a.getNonDFGField());
+        }
+    }
+
+    public void testFlushStorePrimaryDFGChange() {
+        basicHelper(false, false, true, false);
+        basicHelper(false, true, true, false);
+        basicHelper(true, false, true, false);
+        basicHelper(true, true, true, false);
+    }
+
+    public void testFlushStorePrimaryNonDFGChange() {
+        basicHelper(false, false, false, true);
+        basicHelper(false, true, false, true);
+        basicHelper(true, false, false, true);
+        basicHelper(true, true, false, true);
+    }
+
+    public void testFlushStorePrimaryNonDFGAndDFGChange() {
+        basicHelper(false, false, true, true);
+        basicHelper(false, true, true, true);
+        basicHelper(true, false, true, true);
+        basicHelper(true, true, true, true);
+    }
+
+    public void testFlushStorePrimaryNoChanges() {
+        basicHelper(false, false, false, false);
+        basicHelper(false, true, false, false);
+        basicHelper(true, false, false, false);
+        basicHelper(true, true, false, false);
+    }
+
+    public void testJdoPreStoreWithModificationBeforeFlush() {
+        tjpswmHelper(true);
+    }
+
+    public void testJdoPreStoreWithModificationAfterFlush() {
+        tjpswmHelper(false);
+    }
+
+    private void tjpswmHelper(boolean before) {
+        // set retainvalues to false so that we can ensure that the
+        // data in the database is correct, and that we're not just
+        // testing that the JVM data is correct.
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
+        pm.persist(a);
+
+        // by setting the name to 'bar', the jdoPreStore() invocation
+        // will set the parent to a new object. This ensures that new
+        // objects created in jdoPreStore() make their way into the DB
+        // during commit.
+        if (before) {
+            a.setStringField("bar");
+            pm.flush();
+        } else {
+            pm.flush();
+            a.setStringField("bar");
+        }
+        endTx(pm);
+        assertTrue("a.preStoreCalled is false", a.preStoreCalled);
+        assertNotNull("a.getOneOne is null", a.getOneOne());
+        assertTrue("getOneOne().getstrngfld.equals(jdoPrestore) is false",
+            a.getOneOne().getStringField().equals("jdoPreStore"));
+    }
+
+    public void testOneToOneBefore() {
+        totoHelper(true, true, false);
+        totoHelper(true, false, false);
+        totoHelper(true, true, true);
+        totoHelper(true, false, true);
+    }
+
+    public void testOneToOneAfter() {
+        totoHelper(false, true, false);
+        totoHelper(false, false, false);
+        totoHelper(false, true, true);
+        totoHelper(false, false, true);
+    }
+
+    private void totoHelper(boolean before, boolean persist,
+        boolean multi) {
+        // set retainvalues to false so that we can ensure that the
+        // data in the database is correct, and that we're not just
+        // testing that the JVM data is correct.
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+        ModInstanceCallbackTests a = new ModInstanceCallbackTests("foo", 10);
+        pm.persist(a);
+
+        ModRuntimeTest1 parent = new ModRuntimeTest1("baz", 11);
+        if (!before)
+            pm.flush();
+
+        if (persist)
+            pm.persist(parent);
+
+        a.setOneOne(parent);
+
+        if (before)
+            pm.flush();
+
+        ModRuntimeTest1 oldParent = null;
+        if (multi) {
+            oldParent = parent;
+            parent = new ModRuntimeTest1("newParent", 12);
+
+            if (!before)
+                pm.flush();
+
+            if (persist)
+                pm.persist(parent);
+
+            a.setOneOne(parent);
+
+            if (before)
+                pm.flush();
+        }
+
+        endTx(pm);
+        assertTrue("a.preStoreCalled is false", a.preStoreCalled);
+        assertNotNull("a.getOneOne is null", a.getOneOne());
+        if (!multi)
+            assertTrue("a.getOneOne().getStringField().equals(baz) is false",
+                a.getOneOne().getStringField().equals("baz"));
+        else {
+            assertTrue(
+                "a.getOneOne().getStringField().equals(newParent) is false",
+                a.getOneOne().getStringField().equals("newParent"));
+
+            // if multi, then we really should delete the baz
+            // parent. This isn't happening right now.
+            // ### should be a bug
+            //assertTrue (JDOHelper.isDeleted (oldParent));
+        }
+    }
+
+    private void assertState(Object o, PCState state, OpenJPAEntityManager pm) {
+        assertEquals(state, getStateManager(o, pm).getPCState());
+    }
+
+    private void commitAndTestDelete(OpenJPAEntityManager pm, Object o) {
+        Object oid = pm.getObjectId(o);
+        endTx(pm);
+
+        pm = getPM();
+        try {
+            pm.find(Object.class, oid);
+            fail("should not be able to load deleted object");
+        } catch (Exception e) {
+            // expected case
+        }
+    }
+
+    public void testDeleteNew() {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+        ModRuntimeTest1 a = new ModRuntimeTest1("foo", 10);
+        pm.persist(a);
+        pm.remove(a);
+        assertState(a, PCState.PNEWDELETED, pm);
+    }
+
+    public void testOptimisticLockGivesCorrectError() {
+        OpenJPAEntityManager pm1 = getPM(true, false);
+        OpenJPAEntityManager pm2 = getPM(true, false);
+
+        ModRuntimeTest1 a1 = new ModRuntimeTest1("foo", 10);
+        startTx(pm1);
+        pm1.persist(a1);
+        endTx(pm1);
+
+        ModRuntimeTest1 a2 = (ModRuntimeTest1)
+            pm2.find(ModRuntimeTest1.class, pm2.getObjectId(a1));
+        startTx(pm2);
+        a2.setStringField("foobar");
+        endTx(pm2);
+
+        startTx(pm1);
+        a1.setStringField("foobarbaz");
+        try {
+            endTx(pm1);
+        } catch (Exception ole) {
+            // expected case
+        } finally {
+            rollbackTx(pm1);
+
+            pm1.close();
+            pm2.close();
+        }
+    }
+
+    /**
+     * Verify that flushes to the datastore are isolated from other
+     * PersistenceManagers. This is mostly a test of the underlying
+     * datastore's transactional isolation capabilities.
+     * <p/>
+     * Disabled: this hangs on Sybase.
+     */
+    public void XXXtestFlushesAreIsolated() {
+        final String name = "testFlushesAreIsolated";
+
+        deleteAll(ModRuntimeTest1.class);
+
+        OpenJPAEntityManager flushPM = getPM(true, false);
+        startTx(flushPM);
+
+        OpenJPAEntityManager readPM = getPM(true, false);
+        startTx(readPM);
+
+        assertSize(0, flushPM.createNativeQuery("stringField == '" + name + "'",
+            ModRuntimeTest1.class));
+        assertSize(0, readPM.createNativeQuery("stringField == '" + name + "'",
+            ModRuntimeTest1.class));
+
+        ModRuntimeTest1 a = new ModRuntimeTest1(name, randomInt().intValue());
+
+        flushPM.persist(a);
+
+        assertSize(0, readPM.createNativeQuery("name == '" + name + "'",
+            ModRuntimeTest1.class));
+
+        flushPM.flush();
+
+        // make sure the other pm doesn't see the flushed object
+        assertSize(0, readPM.createNativeQuery("name == '" + name + "'",
+            ModRuntimeTest1.class));
+
+        flushPM.remove(a);
+
+        assertSize(0, flushPM.createNativeQuery("name == '" + name + "'",
+            ModRuntimeTest1.class));
+        assertSize(0, readPM.createNativeQuery("name == '" + name + "'",
+            ModRuntimeTest1.class));
+
+        endTx(flushPM);
+        endEm(flushPM);
+
+        endTx(readPM);
+        endEm(readPM);
+    }
+
+    public void testEmptyFlush() {
+        OpenJPAEntityManager pm = getPM();
+        TListener listener = new TListener();
+        ((OpenJPAEntityManagerSPI) pm).addTransactionListener(listener);
+        startTx(pm);
+        ModRuntimeTest1 pc = new ModRuntimeTest1();
+        pm.persist(pc);
+        pm.flush();
+        assertEquals(1, listener.flushes);
+        assertEquals(0, listener.commits);
+
+        pm.flush();
+        assertEquals(1, listener.flushes);
+        assertEquals(0, listener.commits);
+
+        pc.setIntField(3);
+        pm.flush();
+        assertEquals(2, listener.flushes);
+        assertEquals(0, listener.commits);
+
+        endTx(pm);
+        assertEquals(2, listener.flushes);
+        assertEquals(1, listener.commits);
+
+        endEm(pm);
+    }
+
+    public void testEmptyRollback() {
+        OpenJPAEntityManager pm = getPM();
+        TListener listener = new TListener();
+        ((OpenJPAEntityManagerSPI) pm).addTransactionListener(listener);
+        startTx(pm);
+        pm.flush();
+        rollbackTx(pm);
+        assertEquals(0, listener.flushes);
+        assertEquals(0, listener.commits);
+        endEm(pm);
+    }
+
+    public void testEmptyCommit() {
+        OpenJPAEntityManager pm = getPM();
+        TListener listener = new TListener();
+        ((OpenJPAEntityManagerSPI) pm).addTransactionListener(listener);
+        startTx(pm);
+        endTx(pm);
+        assertEquals(0, listener.flushes);
+        assertEquals(1, listener.commits);
+        endEm(pm);
+    }
+
+    private static class TListener
+        extends AbstractTransactionListener {
+
+        public int flushes = 0;
+        public int commits = 0;
+
+        protected void eventOccurred(TransactionEvent event) {
+            if (event.getType() == event.BEFORE_FLUSH)
+                flushes++;
+            else if (event.getType() == event.BEFORE_COMMIT)
+                commits++;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushesDeletes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushesDeletes.java
index 973f1c6..5386458 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushesDeletes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestIncrementalFlushesDeletes.java
@@ -1,137 +1,137 @@
-/*
- * TestIncrementalFlushesDeletes.java
- *
- * Created on October 12, 2006, 11:38 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestIncrementalFlushesDeletes extends BaseKernelTest {
-
-    private OpenJPAEntityManager pm;
-    private Object oid;
-    private RuntimeTest1 a;
-
-    public TestIncrementalFlushesDeletes(String str) {
-        super(str);
-    }
-
-    /**
-     * Creates a new instance of TestIncrementalFlushesDeletes
-     */
-    public TestIncrementalFlushesDeletes() {
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        pm = getPM(true, false);
-        startTx(pm);
-        a = new RuntimeTest1("foo", 10);
-        pm.persist(a);
-        oid = pm.getObjectId(a);
-    }
-
-    public void tearDown() throws Exception {
-        endTx(pm);
-
-        OpenJPAEntityManager newPm = getPM();
-        try {
-            Object o = newPm.find(RuntimeTest1.class, oid);
-            if (o != null) {
-                fail("should not be able to load deleted object");
-            }
-        } catch (Exception e) {
-            // expected case
-        }
-
-        endEm(newPm);
-        endEm(pm);
-
-        super.tearDown();
-    }
-
-    private void assertState(PCState state, boolean flushed) {
-        OpenJPAStateManager sm = getStateManager(a, pm);
-        assertNotNull(sm);
-        assertEquals(flushed, sm.isFlushed());
-        assertEquals(state, sm.getPCState());
-    }
-
-    /**
-     * PNew => PNewDeleted
-     */
-    public void testNewDeleted() {
-        pm.remove(a);
-        assertState(PCState.PNEWDELETED, false);
-    }
-
-    /**
-     * PNew => PNewDeleted => PNewDeletedFlushed
-     */
-    public void testNewDeletedFlushed() {
-        pm.remove(a);
-        assertState(PCState.PNEWDELETED, false);
-        pm.flush();
-        assertState(PCState.PNEWDELETED, true);
-    }
-
-    /**
-     * PNew => PNewFlushed => PNewFlushedDeleted
-     */
-    public void testNewFlushedDeleted() {
-        pm.flush();
-        assertState(PCState.PNEW, true);
-        pm.remove(a);
-        assertState(PCState.PNEWFLUSHEDDELETED, true);
-    }
-
-    /**
-     * PNew => PNewFlushed => PNewFlushedDeleted => PNewFlushedDeletedFlushed
-     */
-    public void testNewFlushedDeletedFlushed() {
-        pm.flush();
-        assertState(PCState.PNEW, true);
-        pm.remove(a);
-        assertState(PCState.PNEWFLUSHEDDELETED, true);
-        pm.flush();
-        assertState(PCState.PNEWFLUSHEDDELETEDFLUSHED, true);
-    }
-
-/*
-* 	### some remaining test deletes:
-*		PDirty => PDeleted => PDeletedFlushed
-*		PDirty => (change and flush) PDirty => PDeleted => PDeletedFlushed
-*		PClean => PDeleted => PDeletedFlushed
-*		Hollow => PDeleted => PDeletedFlushed
-*/
-}
+/*
+ * TestIncrementalFlushesDeletes.java
+ *
+ * Created on October 12, 2006, 11:38 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestIncrementalFlushesDeletes extends BaseKernelTest {
+
+    private OpenJPAEntityManager pm;
+    private Object oid;
+    private RuntimeTest1 a;
+
+    public TestIncrementalFlushesDeletes(String str) {
+        super(str);
+    }
+
+    /**
+     * Creates a new instance of TestIncrementalFlushesDeletes
+     */
+    public TestIncrementalFlushesDeletes() {
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        pm = getPM(true, false);
+        startTx(pm);
+        a = new RuntimeTest1("foo", 10);
+        pm.persist(a);
+        oid = pm.getObjectId(a);
+    }
+
+    public void tearDown() throws Exception {
+        endTx(pm);
+
+        OpenJPAEntityManager newPm = getPM();
+        try {
+            Object o = newPm.find(RuntimeTest1.class, oid);
+            if (o != null) {
+                fail("should not be able to load deleted object");
+            }
+        } catch (Exception e) {
+            // expected case
+        }
+
+        endEm(newPm);
+        endEm(pm);
+
+        super.tearDown();
+    }
+
+    private void assertState(PCState state, boolean flushed) {
+        OpenJPAStateManager sm = getStateManager(a, pm);
+        assertNotNull(sm);
+        assertEquals(flushed, sm.isFlushed());
+        assertEquals(state, sm.getPCState());
+    }
+
+    /**
+     * PNew => PNewDeleted
+     */
+    public void testNewDeleted() {
+        pm.remove(a);
+        assertState(PCState.PNEWDELETED, false);
+    }
+
+    /**
+     * PNew => PNewDeleted => PNewDeletedFlushed
+     */
+    public void testNewDeletedFlushed() {
+        pm.remove(a);
+        assertState(PCState.PNEWDELETED, false);
+        pm.flush();
+        assertState(PCState.PNEWDELETED, true);
+    }
+
+    /**
+     * PNew => PNewFlushed => PNewFlushedDeleted
+     */
+    public void testNewFlushedDeleted() {
+        pm.flush();
+        assertState(PCState.PNEW, true);
+        pm.remove(a);
+        assertState(PCState.PNEWFLUSHEDDELETED, true);
+    }
+
+    /**
+     * PNew => PNewFlushed => PNewFlushedDeleted => PNewFlushedDeletedFlushed
+     */
+    public void testNewFlushedDeletedFlushed() {
+        pm.flush();
+        assertState(PCState.PNEW, true);
+        pm.remove(a);
+        assertState(PCState.PNEWFLUSHEDDELETED, true);
+        pm.flush();
+        assertState(PCState.PNEWFLUSHEDDELETEDFLUSHED, true);
+    }
+
+/*
+* 	### some remaining test deletes:
+*		PDirty => PDeleted => PDeletedFlushed
+*		PDirty => (change and flush) PDirty => PDeleted => PDeletedFlushed
+*		PClean => PDeleted => PDeletedFlushed
+*		Hollow => PDeleted => PDeletedFlushed
+*/
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInheritance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInheritance.java
index 7bf2c0c..485d077 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInheritance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInheritance.java
@@ -1,148 +1,148 @@
-/*
- * TestInheritance.java
- *
- * Created on October 12, 2006, 11:46 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest3;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestInheritance extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestInheritance
-     */
-    public TestInheritance() {
-    }
-
-    public TestInheritance(String name) {
-        super(name);
-    }
-
-    public void setUp()
-        throws Exception {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-        deleteAll(RuntimeTest3.class);
-
-        // create some instances to query on
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(new RuntimeTest1("RuntimeTest1-instance", 2));
-        pm.persist(new RuntimeTest2("RuntimeTest2-instance", 3));
-        pm.persist(new RuntimeTest3("RuntimeTest3-instance", 4));
-        endTx(pm);
-        endEm(pm);
-    }
-
-    /**
-     * Tests that we can get all three objects via an extent.
-     */
-    public void testGetAllRuntimeTest1s() {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest1 o");
-        Collection c = (Collection) q.getResultList();
-        assertEquals(3, c.size());
-        endEm(pm);
-    }
-
-    /**
-     * Tests that we can get all RuntimeTest2 objects via an extent.
-     */
-    public void testGetAllRuntimeTest2s() {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest2 o");
-        Collection c = (Collection) q.getResultList();
-        assertEquals(2, c.size());
-        endEm(pm);
-    }
-
-    /**
-     * Tests that we can get all RuntimeTest3 objects via an extent.
-     */
-    public void testGetAllRuntimeTest3s() {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest3 o");
-        Collection c = (Collection) q.getResultList();
-        assertEquals(1, c.size());
-        endEm(pm);
-    }
-
-    /**
-     * Tests that we can get just RuntimeTest1s via an extent.
-     */
-    public void testGetJustRuntimeTest1s() {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest1 o");
-        q.setSubclasses(false);
-
-//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest1.class);
-//        FIXME jthomas
-//        q.setCandidates(pm.getExtent(RuntimeTest1.class, false));
-        Collection c = (Collection) q.getResultList();
-        assertEquals(1, c.size());
-        endEm(pm);
-    }
-
-    /**
-     * Tests that we can get just RuntimeTest2s via an extent.
-     */
-    public void testGetJustRuntimeTest2s() {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest2 o");
-        q.setSubclasses(false);
-
-//        FIXME jthomas        
-//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest2.class);
-//        q.setCandidates(pm.createExtent(RuntimeTest2.class, false));
-        Collection c = (Collection) q.getResultList();
-        assertEquals(1, c.size());
-        endEm(pm);
-    }
-
-    /**
-     * Tests that we can get just RuntimeTest3s via an extent.
-     */
-    public void testGetJustRuntimeTest3() {
-        OpenJPAEntityManager pm = getPM();
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest3 o");
-        q.setSubclasses(false);
-
-//      FIXME jthomas
-//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest3.class);
-//        q.setCandidates(pm.getExtent(RuntimeTest3.class, false));
-        Collection c = (Collection) q.getResultList();
-        assertEquals(1, c.size());
-        endEm(pm);
-    }
-}
+/*
+ * TestInheritance.java
+ *
+ * Created on October 12, 2006, 11:46 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest3;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestInheritance extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestInheritance
+     */
+    public TestInheritance() {
+    }
+
+    public TestInheritance(String name) {
+        super(name);
+    }
+
+    public void setUp()
+        throws Exception {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+        deleteAll(RuntimeTest3.class);
+
+        // create some instances to query on
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(new RuntimeTest1("RuntimeTest1-instance", 2));
+        pm.persist(new RuntimeTest2("RuntimeTest2-instance", 3));
+        pm.persist(new RuntimeTest3("RuntimeTest3-instance", 4));
+        endTx(pm);
+        endEm(pm);
+    }
+
+    /**
+     * Tests that we can get all three objects via an extent.
+     */
+    public void testGetAllRuntimeTest1s() {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest1 o");
+        Collection c = (Collection) q.getResultList();
+        assertEquals(3, c.size());
+        endEm(pm);
+    }
+
+    /**
+     * Tests that we can get all RuntimeTest2 objects via an extent.
+     */
+    public void testGetAllRuntimeTest2s() {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest2 o");
+        Collection c = (Collection) q.getResultList();
+        assertEquals(2, c.size());
+        endEm(pm);
+    }
+
+    /**
+     * Tests that we can get all RuntimeTest3 objects via an extent.
+     */
+    public void testGetAllRuntimeTest3s() {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest3 o");
+        Collection c = (Collection) q.getResultList();
+        assertEquals(1, c.size());
+        endEm(pm);
+    }
+
+    /**
+     * Tests that we can get just RuntimeTest1s via an extent.
+     */
+    public void testGetJustRuntimeTest1s() {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest1 o");
+        q.setSubclasses(false);
+
+//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest1.class);
+//        FIXME jthomas
+//        q.setCandidates(pm.getExtent(RuntimeTest1.class, false));
+        Collection c = (Collection) q.getResultList();
+        assertEquals(1, c.size());
+        endEm(pm);
+    }
+
+    /**
+     * Tests that we can get just RuntimeTest2s via an extent.
+     */
+    public void testGetJustRuntimeTest2s() {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest2 o");
+        q.setSubclasses(false);
+
+//        FIXME jthomas        
+//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest2.class);
+//        q.setCandidates(pm.createExtent(RuntimeTest2.class, false));
+        Collection c = (Collection) q.getResultList();
+        assertEquals(1, c.size());
+        endEm(pm);
+    }
+
+    /**
+     * Tests that we can get just RuntimeTest3s via an extent.
+     */
+    public void testGetJustRuntimeTest3() {
+        OpenJPAEntityManager pm = getPM();
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest3 o");
+        q.setSubclasses(false);
+
+//      FIXME jthomas
+//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest3.class);
+//        q.setCandidates(pm.getExtent(RuntimeTest3.class, false));
+        Collection c = (Collection) q.getResultList();
+        assertEquals(1, c.size());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInitialValueFetching.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInitialValueFetching.java
index 1c1bc63..86a31b2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInitialValueFetching.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInitialValueFetching.java
@@ -1,181 +1,181 @@
-/*
- * TestInitialValueFetching.java
- *
- * Created on October 12, 2006, 11:58 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.RestoreStateType;
-
-public class TestInitialValueFetching extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestInitialValueFetching
-     */
-    public TestInitialValueFetching(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        RuntimeTest1 rt1 = new RuntimeTest1("TestInitialValueFetching", 10);
-        pm.persist(rt1);
-
-        rt1.setDateField(new Date());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testInitialValueString() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        RuntimeTest1 rt1 = getObject(pm);
-        OpenJPAStateManager sm = getStateManager(rt1, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("stringField");
-        assertEquals("TestInitialValueFetching",
-            sm.fetchInitialField(fmd.getIndex()));
-        rt1.setStringField("TestInitialValueFetching-2");
-        assertEquals("TestInitialValueFetching",
-            sm.fetchInitialField(fmd.getIndex()));
-        endTx(pm);
-        assertEquals("TestInitialValueFetching-2",
-            sm.fetchInitialField(fmd.getIndex()));
-        endEm(pm);
-    }
-
-    public void testInitialValueInt() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        RuntimeTest1 rt1 = getObject(pm);
-        OpenJPAStateManager sm = getStateManager(rt1, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("intField1");
-        assertEquals(10,
-            ((Integer) sm.fetchInitialField(fmd.getIndex())).intValue());
-        rt1.setIntField1(11);
-        assertEquals(10,
-            ((Integer) sm.fetchInitialField(fmd.getIndex())).intValue());
-        endTx(pm);
-        assertEquals(11,
-            ((Integer) sm.fetchInitialField(fmd.getIndex())).intValue());
-        endEm(pm);
-    }
-
-    public void testInitialValueMutableValueFailures() {
-        Map props = new HashMap();
-        props.put("openjpa.RestoreMutableValues", "false");
-        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
-            getEmf(props);
-
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)
-            pmf.createEntityManager();
-        RuntimeTest1 rt1 = getObject(pm);
-
-        Date d = rt1.getDateField();
-        OpenJPAStateManager sm = getStateManager(rt1, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("dateField");
-        try {
-            sm.fetchInitialField(fmd.getIndex());
-            fail("should get an exception if RestoreMutableValues is false");
-        } catch (org.apache.openjpa.util.UserException e) {
-            // expected
-        }
-        endEm(pm);
-        pmf.close();
-    }
-
-    public void testInitialValueDate() {
-        Map props = new HashMap();
-        props.put("openjpa.RestoreState", "all");
-        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
-            getEmf(props);
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)
-            pmf.createEntityManager();
-        startTx(pm);
-        RuntimeTest1 rt1 = getObject(pm);
-
-        Date d = rt1.getDateField();
-
-        OpenJPAStateManager sm = getStateManager(rt1, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("dateField");
-        assertEquals(d, sm.fetchInitialField(fmd.getIndex()));
-
-        // == should pass here since we haven't made any modifications.
-        assertTrue("mutable object fails == test; should not",
-            d == sm.fetchInitialField(fmd.getIndex()));
-
-        Date d2 = new Date();
-        rt1.setDateField(d2);
-        assertEquals(d, sm.fetchInitialField(fmd.getIndex()));
-        endTx(pm);
-        assertEquals(d2, sm.fetchInitialField(fmd.getIndex()));
-        assertTrue("mutable object passes == test; should not",
-            d2 != sm.fetchInitialField(fmd.getIndex()));
-        endEm(pm);
-    }
-
-    public void testInitialValueExceptions() {
-        OpenJPAEntityManager pm = getPM();
-        pm.setRestoreState(RestoreStateType.NONE);
-        startTx(pm);
-        RuntimeTest1 rt1 = getObject(pm);
-        OpenJPAStateManager sm = getStateManager(rt1, pm);
-        FieldMetaData fmd = sm.getMetaData().getField("stringField");
-        try {
-            sm.fetchInitialField(fmd.getIndex());
-            fail("exception should be thrown by KodoSM.fetchInitialField");
-        } catch (org.apache.openjpa.util.UserException e) {
-            // expected case
-        }
-        endTx(pm);
-        endEm(pm);
-    }
-
-    private RuntimeTest1 getObject(OpenJPAEntityManager pm) {
-//        return (RuntimeTest1) ((Collection) 
-//        		pm.createNativeQuery( "stringField == \"TestInitialValueFetching\"",RuntimeTest1.class)
-//        .getResultList()).iterator().next();
-
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT o FROM RuntimeTest1 o WHERE o.stringField = \'TestInitialValueFetching\'");
-        List l = q.getResultList();
-
-        return (RuntimeTest1) l.iterator().next();
-    }
-}
+/*
+ * TestInitialValueFetching.java
+ *
+ * Created on October 12, 2006, 11:58 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.RestoreStateType;
+
+public class TestInitialValueFetching extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestInitialValueFetching
+     */
+    public TestInitialValueFetching(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        RuntimeTest1 rt1 = new RuntimeTest1("TestInitialValueFetching", 10);
+        pm.persist(rt1);
+
+        rt1.setDateField(new Date());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testInitialValueString() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        RuntimeTest1 rt1 = getObject(pm);
+        OpenJPAStateManager sm = getStateManager(rt1, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("stringField");
+        assertEquals("TestInitialValueFetching",
+            sm.fetchInitialField(fmd.getIndex()));
+        rt1.setStringField("TestInitialValueFetching-2");
+        assertEquals("TestInitialValueFetching",
+            sm.fetchInitialField(fmd.getIndex()));
+        endTx(pm);
+        assertEquals("TestInitialValueFetching-2",
+            sm.fetchInitialField(fmd.getIndex()));
+        endEm(pm);
+    }
+
+    public void testInitialValueInt() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        RuntimeTest1 rt1 = getObject(pm);
+        OpenJPAStateManager sm = getStateManager(rt1, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("intField1");
+        assertEquals(10,
+            ((Integer) sm.fetchInitialField(fmd.getIndex())).intValue());
+        rt1.setIntField1(11);
+        assertEquals(10,
+            ((Integer) sm.fetchInitialField(fmd.getIndex())).intValue());
+        endTx(pm);
+        assertEquals(11,
+            ((Integer) sm.fetchInitialField(fmd.getIndex())).intValue());
+        endEm(pm);
+    }
+
+    public void testInitialValueMutableValueFailures() {
+        Map props = new HashMap();
+        props.put("openjpa.RestoreMutableValues", "false");
+        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
+            getEmf(props);
+
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)
+            pmf.createEntityManager();
+        RuntimeTest1 rt1 = getObject(pm);
+
+        Date d = rt1.getDateField();
+        OpenJPAStateManager sm = getStateManager(rt1, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("dateField");
+        try {
+            sm.fetchInitialField(fmd.getIndex());
+            fail("should get an exception if RestoreMutableValues is false");
+        } catch (org.apache.openjpa.util.UserException e) {
+            // expected
+        }
+        endEm(pm);
+        pmf.close();
+    }
+
+    public void testInitialValueDate() {
+        Map props = new HashMap();
+        props.put("openjpa.RestoreState", "all");
+        OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory)
+            getEmf(props);
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)
+            pmf.createEntityManager();
+        startTx(pm);
+        RuntimeTest1 rt1 = getObject(pm);
+
+        Date d = rt1.getDateField();
+
+        OpenJPAStateManager sm = getStateManager(rt1, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("dateField");
+        assertEquals(d, sm.fetchInitialField(fmd.getIndex()));
+
+        // == should pass here since we haven't made any modifications.
+        assertTrue("mutable object fails == test; should not",
+            d == sm.fetchInitialField(fmd.getIndex()));
+
+        Date d2 = new Date();
+        rt1.setDateField(d2);
+        assertEquals(d, sm.fetchInitialField(fmd.getIndex()));
+        endTx(pm);
+        assertEquals(d2, sm.fetchInitialField(fmd.getIndex()));
+        assertTrue("mutable object passes == test; should not",
+            d2 != sm.fetchInitialField(fmd.getIndex()));
+        endEm(pm);
+    }
+
+    public void testInitialValueExceptions() {
+        OpenJPAEntityManager pm = getPM();
+        pm.setRestoreState(RestoreStateType.NONE);
+        startTx(pm);
+        RuntimeTest1 rt1 = getObject(pm);
+        OpenJPAStateManager sm = getStateManager(rt1, pm);
+        FieldMetaData fmd = sm.getMetaData().getField("stringField");
+        try {
+            sm.fetchInitialField(fmd.getIndex());
+            fail("exception should be thrown by KodoSM.fetchInitialField");
+        } catch (org.apache.openjpa.util.UserException e) {
+            // expected case
+        }
+        endTx(pm);
+        endEm(pm);
+    }
+
+    private RuntimeTest1 getObject(OpenJPAEntityManager pm) {
+//        return (RuntimeTest1) ((Collection) 
+//        		pm.createNativeQuery( "stringField == \"TestInitialValueFetching\"",RuntimeTest1.class)
+//        .getResultList()).iterator().next();
+
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT o FROM RuntimeTest1 o WHERE o.stringField = \'TestInitialValueFetching\'");
+        List l = q.getResultList();
+
+        return (RuntimeTest1) l.iterator().next();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInstanceCallbacks.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInstanceCallbacks.java
index fc8ec1b..888d156 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInstanceCallbacks.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestInstanceCallbacks.java
@@ -1,291 +1,291 @@
-/*
- * TestInstanceCallbacks.java
- *
- * Created on October 12, 2006, 1:19 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.InstanceCallbacksTest;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestInstanceCallbacks extends BaseKernelTest {
-
-    private static final int COMMIT = 0;
-    private static final int FLUSH = 1;
-    private static final int PRESTORE = 2;
-
-    private OpenJPAEntityManager _pm = null;
-    private InstanceCallbacksTest _callbacks = null;
-
-    public TestInstanceCallbacks(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates a new instance of TestInstanceCallbacks
-     */
-    public TestInstanceCallbacks() {
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(InstanceCallbacksTest.class);
-        deleteAll(RuntimeTest1.class);
-        _pm = getPM(true, true);
-        startTx(_pm);
-        _callbacks = new InstanceCallbacksTest();
-        _callbacks.setStringField("foo");
-        _pm.persist(_callbacks);
-        Object id = _pm.getObjectId(_callbacks);
-        endTx(_pm);
-        endEm(_pm);
-
-        // re-find with different PM
-        _pm = getPM();
-        _callbacks =
-            (InstanceCallbacksTest) _pm.find(InstanceCallbacksTest.class, id);
-    }
-
-    public void tearDown() throws Exception {
-        rollbackTx(_pm);
-        endEm(_pm);
-        super.tearDown();
-    }
-
-    public void testPostLoad() {
-        _callbacks.getStringField();
-        assertTrue(_callbacks.postLoadCalled);
-    }
-
-    public void testPreStore() {
-        preStoreTest(COMMIT);
-    }
-
-    public void testPreStoreWithFlush() {
-        preStoreTest(FLUSH);
-    }
-
-    public void testPreStoreWithPreStore() {
-        preStoreTest(PRESTORE);
-    }
-
-    private void preStoreTest(int action) {
-        assertNoCallbacksInvoked(_callbacks);
-//        _pm.begin();
-        startTx(_pm);
-
-        _callbacks.setStringField("bar");
-        Object oid = _pm.getObjectId(_callbacks);
-        if (action == COMMIT) {
-            _pm.flush();
-            endTx(_pm);
-        } else if (action == FLUSH)
-            _pm.flush();
-        else if (action == PRESTORE)
-            _pm.preFlush();
-        assertTrue("prestore wasnt called", _callbacks.preStoreCalled);
-        if (action != COMMIT) {
-//            _pm.commit();
-            if (action != FLUSH)
-                _pm.flush();
-            endTx(_pm);
-        }
-
-        OpenJPAEntityManager pm = getPM();
-        InstanceCallbacksTest callbacks = (InstanceCallbacksTest)
-            pm.find(InstanceCallbacksTest.class, oid);
-        assertNoCallbacksInvoked(callbacks);
-        assertEquals("getonetoone strng is not jdoprestore", "jdoPreStore",
-            callbacks.getOneOne().getStringField());
-        endEm(pm);
-    }
-
-    public void testPreDelete() {
-        assertNoCallbacksInvoked(_callbacks);
-        startTx(_pm);
-        _pm.remove(_callbacks);
-        assertTrue(_callbacks.preDeleteCalled);
-        endTx(_pm);
-    }
-
-    public void testPreDeleteRecursion() {
-        assertNoCallbacksInvoked(_callbacks);
-        startTx(_pm);
-        _callbacks.preDeleteCycle = 0;
-        _pm.remove(_callbacks);
-        assertEquals(1, _callbacks.preDeleteCycle);
-        endTx(_pm);
-    }
-
-    public void testSetRelatedReferenceInPreStore() {
-        assertNull(_callbacks.getRelId());
-        InstanceCallbacksTest callbacks2 = new InstanceCallbacksTest();
-        callbacks2.setRelId(_pm.getObjectId(_callbacks));
-        startTx(_pm);
-        _pm.persist(callbacks2);
-        _pm.flush();
-        endTx(_pm);
-        assertEquals(8888, _callbacks.getIntField());
-        try {
-            assertEquals(callbacks2, _callbacks.getRel());
-        } catch (AssertionFailedError afe) {
-            bug(1162, afe, "Setting a related object reference in "
-                + "preStore fails");
-        }
-    }
-
-    public void testFlushCausesFlush() {
-        //### JDO2MIG : this is failing because we're consuming exceptions
-        // throws from callbacks; need to decide what to do with them
-        causeFlushTest(FLUSH);
-    }
-
-    public void testPreStoreCausesFlush() {
-        //### JDO2MIG : this is failing because we're consuming exceptions
-        // throws from callbacks; need to decide what to do with them
-        causeFlushTest(PRESTORE);
-    }
-
-    private void causeFlushTest(int action) {
-        startTx(_pm);
-        _callbacks.setStringField("sss");
-        _callbacks.flushInPreStore = true;
-        try {
-            if (action == FLUSH)
-                _pm.flush();
-            else
-                _pm.preFlush();
-
-            bug(1139, "Recursive flush allowed because exception swallowed");
-        } catch (Exception je) {
-        }
-        rollbackTx(_pm);
-    }
-
-    private void assertNoCallbacksInvoked(InstanceCallbacksTest pc) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-
-        assertFalse("Expected preDelete to not have been called for object ID "
-            + pm.getObjectId(pc), pc.preDeleteCalled);
-        assertFalse("Expected preClear to not have been called for object ID "
-            + pm.getObjectId(pc), pc.preClearCalled);
-        assertFalse("Expected preStore to not have been called for object ID "
-            + pm.getObjectId(pc), pc.preStoreCalled);
-    }
-
-    /* 
-    // no JPA equivalent
-
-    public void testDetachAttach()
-    throws Exception {
-        OpenJPAEntityManager pm = getPM();
-        DetachAttachEvent pc = (DetachAttachEvent) pm.find
-                (DetachAttachEvent.class,createDetachableId(4));
-        DetachAttachEvent.EVENTS.clear();
-        pc = (DetachAttachEvent) pm.detach(pc);
-        assertDetachEvents(new String[]{ "PRED4", "POSTD4" });
-        endEm(pm,());
-        
-        assertTrue(pm.isDetached(pc));
-        
-        pm = getPM();
-        startTx(pm,());
-        //FIXME jthomas
-        
-//        pm.addInstanceLifecycleListener(new CreateLifecycleListener() {
-//            public void postCreate(InstanceLifecycleEvent ev) {
-//                fail("No post create necessary");
-//            }
-//        }, null);
-        pm.persist(pc);
-        assertDetachEvents(new String[]{ "PREA4", "POSTA4" });
-        endTx(pm,());
-        endEm(pm,());
-    }
-    
-    public void testDetachAttachRelations() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm,());
-        DetachAttachEvent pc = (DetachAttachEvent) pm.find
-                (DetachAttachEvent.class,createDetachableId(2));
-        pc.setOneOne((DetachAttachEvent) pm.find
-                (DetachAttachEvent.class,createDetachableId(4)));
-        endTx(pm,());
-        DetachAttachEvent.EVENTS.clear();
-        pc = (DetachAttachEvent) pm.detach(pc);
-        endEm(pm,());
-        assertDetachEvents(
-                new String[]{ "PRED2", "PRED4", "POSTD2", "POSTD4" });
-        
-        pm = getPM();
-        startTx(pm,());
-        pm.persist(pc);
-        assertDetachEvents(
-                new String[]{ "PREA2", "PREA4", "POSTA2", "POSTA4" });
-        rollbackTx(pm,());
-        endEm(pm,());
-    }
-    
-    private void assertDetachEvents(String[] expected) {
-        Collection events = DetachAttachEvent.EVENTS;
-        if (expected.length != events.size()) {
-            StringBuffer buf = new StringBuffer();
-            for (int i = 0; i < expected.length; i++)
-                buf.append(expected[i]).append(",");
-            buf.append("!=");
-            for (Iterator it = events.iterator(); it.hasNext();)
-                buf.append(it.next()).append(",");
-            fail("mismatch event count:" + buf);
-        }
-        String event;
-        for (int i = 0; i < expected.length; i++) {
-            if (!events.remove(expected[i]))
-                fail("Event not fired:" + expected[i]);
-            if (events.contains(expected[i]))
-                fail("Event fired twice:" + expected[i]);
-        }
-        if (!events.isEmpty())
-            fail("Excess events fired:" + events);
-        DetachAttachEvent.EVENTS.clear();
-    }
-    
-    private Object createDetachableId(int field) {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm,());
-        DetachAttachEvent pc = new DetachAttachEvent();
-        pc.setIntField(field);
-        pm.persist(pc);
-        endTx(pm,());
-        endEm(pm,());
-//        return pm.getObjectId(pc);
-        return pc.getId();
-    }
-    */
-}
+/*
+ * TestInstanceCallbacks.java
+ *
+ * Created on October 12, 2006, 1:19 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.InstanceCallbacksTest;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestInstanceCallbacks extends BaseKernelTest {
+
+    private static final int COMMIT = 0;
+    private static final int FLUSH = 1;
+    private static final int PRESTORE = 2;
+
+    private OpenJPAEntityManager _pm = null;
+    private InstanceCallbacksTest _callbacks = null;
+
+    public TestInstanceCallbacks(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates a new instance of TestInstanceCallbacks
+     */
+    public TestInstanceCallbacks() {
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(InstanceCallbacksTest.class);
+        deleteAll(RuntimeTest1.class);
+        _pm = getPM(true, true);
+        startTx(_pm);
+        _callbacks = new InstanceCallbacksTest();
+        _callbacks.setStringField("foo");
+        _pm.persist(_callbacks);
+        Object id = _pm.getObjectId(_callbacks);
+        endTx(_pm);
+        endEm(_pm);
+
+        // re-find with different PM
+        _pm = getPM();
+        _callbacks =
+            (InstanceCallbacksTest) _pm.find(InstanceCallbacksTest.class, id);
+    }
+
+    public void tearDown() throws Exception {
+        rollbackTx(_pm);
+        endEm(_pm);
+        super.tearDown();
+    }
+
+    public void testPostLoad() {
+        _callbacks.getStringField();
+        assertTrue(_callbacks.postLoadCalled);
+    }
+
+    public void testPreStore() {
+        preStoreTest(COMMIT);
+    }
+
+    public void testPreStoreWithFlush() {
+        preStoreTest(FLUSH);
+    }
+
+    public void testPreStoreWithPreStore() {
+        preStoreTest(PRESTORE);
+    }
+
+    private void preStoreTest(int action) {
+        assertNoCallbacksInvoked(_callbacks);
+//        _pm.begin();
+        startTx(_pm);
+
+        _callbacks.setStringField("bar");
+        Object oid = _pm.getObjectId(_callbacks);
+        if (action == COMMIT) {
+            _pm.flush();
+            endTx(_pm);
+        } else if (action == FLUSH)
+            _pm.flush();
+        else if (action == PRESTORE)
+            _pm.preFlush();
+        assertTrue("prestore wasnt called", _callbacks.preStoreCalled);
+        if (action != COMMIT) {
+//            _pm.commit();
+            if (action != FLUSH)
+                _pm.flush();
+            endTx(_pm);
+        }
+
+        OpenJPAEntityManager pm = getPM();
+        InstanceCallbacksTest callbacks = (InstanceCallbacksTest)
+            pm.find(InstanceCallbacksTest.class, oid);
+        assertNoCallbacksInvoked(callbacks);
+        assertEquals("getonetoone strng is not jdoprestore", "jdoPreStore",
+            callbacks.getOneOne().getStringField());
+        endEm(pm);
+    }
+
+    public void testPreDelete() {
+        assertNoCallbacksInvoked(_callbacks);
+        startTx(_pm);
+        _pm.remove(_callbacks);
+        assertTrue(_callbacks.preDeleteCalled);
+        endTx(_pm);
+    }
+
+    public void testPreDeleteRecursion() {
+        assertNoCallbacksInvoked(_callbacks);
+        startTx(_pm);
+        _callbacks.preDeleteCycle = 0;
+        _pm.remove(_callbacks);
+        assertEquals(1, _callbacks.preDeleteCycle);
+        endTx(_pm);
+    }
+
+    public void testSetRelatedReferenceInPreStore() {
+        assertNull(_callbacks.getRelId());
+        InstanceCallbacksTest callbacks2 = new InstanceCallbacksTest();
+        callbacks2.setRelId(_pm.getObjectId(_callbacks));
+        startTx(_pm);
+        _pm.persist(callbacks2);
+        _pm.flush();
+        endTx(_pm);
+        assertEquals(8888, _callbacks.getIntField());
+        try {
+            assertEquals(callbacks2, _callbacks.getRel());
+        } catch (AssertionFailedError afe) {
+            bug(1162, afe, "Setting a related object reference in "
+                + "preStore fails");
+        }
+    }
+
+    public void testFlushCausesFlush() {
+        //### JDO2MIG : this is failing because we're consuming exceptions
+        // throws from callbacks; need to decide what to do with them
+        causeFlushTest(FLUSH);
+    }
+
+    public void testPreStoreCausesFlush() {
+        //### JDO2MIG : this is failing because we're consuming exceptions
+        // throws from callbacks; need to decide what to do with them
+        causeFlushTest(PRESTORE);
+    }
+
+    private void causeFlushTest(int action) {
+        startTx(_pm);
+        _callbacks.setStringField("sss");
+        _callbacks.flushInPreStore = true;
+        try {
+            if (action == FLUSH)
+                _pm.flush();
+            else
+                _pm.preFlush();
+
+            bug(1139, "Recursive flush allowed because exception swallowed");
+        } catch (Exception je) {
+        }
+        rollbackTx(_pm);
+    }
+
+    private void assertNoCallbacksInvoked(InstanceCallbacksTest pc) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+
+        assertFalse("Expected preDelete to not have been called for object ID "
+            + pm.getObjectId(pc), pc.preDeleteCalled);
+        assertFalse("Expected preClear to not have been called for object ID "
+            + pm.getObjectId(pc), pc.preClearCalled);
+        assertFalse("Expected preStore to not have been called for object ID "
+            + pm.getObjectId(pc), pc.preStoreCalled);
+    }
+
+    /* 
+    // no JPA equivalent
+
+    public void testDetachAttach()
+    throws Exception {
+        OpenJPAEntityManager pm = getPM();
+        DetachAttachEvent pc = (DetachAttachEvent) pm.find
+                (DetachAttachEvent.class,createDetachableId(4));
+        DetachAttachEvent.EVENTS.clear();
+        pc = (DetachAttachEvent) pm.detach(pc);
+        assertDetachEvents(new String[]{ "PRED4", "POSTD4" });
+        endEm(pm,());
+        
+        assertTrue(pm.isDetached(pc));
+        
+        pm = getPM();
+        startTx(pm,());
+        //FIXME jthomas
+        
+//        pm.addInstanceLifecycleListener(new CreateLifecycleListener() {
+//            public void postCreate(InstanceLifecycleEvent ev) {
+//                fail("No post create necessary");
+//            }
+//        }, null);
+        pm.persist(pc);
+        assertDetachEvents(new String[]{ "PREA4", "POSTA4" });
+        endTx(pm,());
+        endEm(pm,());
+    }
+    
+    public void testDetachAttachRelations() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm,());
+        DetachAttachEvent pc = (DetachAttachEvent) pm.find
+                (DetachAttachEvent.class,createDetachableId(2));
+        pc.setOneOne((DetachAttachEvent) pm.find
+                (DetachAttachEvent.class,createDetachableId(4)));
+        endTx(pm,());
+        DetachAttachEvent.EVENTS.clear();
+        pc = (DetachAttachEvent) pm.detach(pc);
+        endEm(pm,());
+        assertDetachEvents(
+                new String[]{ "PRED2", "PRED4", "POSTD2", "POSTD4" });
+        
+        pm = getPM();
+        startTx(pm,());
+        pm.persist(pc);
+        assertDetachEvents(
+                new String[]{ "PREA2", "PREA4", "POSTA2", "POSTA4" });
+        rollbackTx(pm,());
+        endEm(pm,());
+    }
+    
+    private void assertDetachEvents(String[] expected) {
+        Collection events = DetachAttachEvent.EVENTS;
+        if (expected.length != events.size()) {
+            StringBuffer buf = new StringBuffer();
+            for (int i = 0; i < expected.length; i++)
+                buf.append(expected[i]).append(",");
+            buf.append("!=");
+            for (Iterator it = events.iterator(); it.hasNext();)
+                buf.append(it.next()).append(",");
+            fail("mismatch event count:" + buf);
+        }
+        String event;
+        for (int i = 0; i < expected.length; i++) {
+            if (!events.remove(expected[i]))
+                fail("Event not fired:" + expected[i]);
+            if (events.contains(expected[i]))
+                fail("Event fired twice:" + expected[i]);
+        }
+        if (!events.isEmpty())
+            fail("Excess events fired:" + events);
+        DetachAttachEvent.EVENTS.clear();
+    }
+    
+    private Object createDetachableId(int field) {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm,());
+        DetachAttachEvent pc = new DetachAttachEvent();
+        pc.setIntField(field);
+        pm.persist(pc);
+        endTx(pm,());
+        endEm(pm,());
+//        return pm.getObjectId(pc);
+        return pc.getId();
+    }
+    */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultiThreaded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultiThreaded.java
index 1081310..9e57ee8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultiThreaded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultiThreaded.java
@@ -1,148 +1,148 @@
-/*
- * TestMultiThreaded.java
- *
- * Created on October 12, 2006, 2:21 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestMultiThreaded extends BaseKernelTest {
-
-    static int serial = 5;
-    static int threads = 5;
-    static int iterations = 5;
-
-    private OpenJPAEntityManager pm;
-    private Object id;
-    private String name;
-
-    /**
-     * Creates a new instance of TestMultiThreaded
-     */
-    public TestMultiThreaded() {
-    }
-
-    public TestMultiThreaded(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager pm2 = getPM();
-        startTx(pm2);
-        name = "testMultiThreaded" + Math.random();
-        RuntimeTest1 a = new RuntimeTest1(name,
-            (int) (Math.random() * Integer.MAX_VALUE));
-        pm2.persist(a);
-        id = pm2.getObjectId(a);
-        endTx(pm2);
-
-        Map props = new HashMap();
-        props.put("openjpa.Multithreaded", "true");
-        OpenJPAEntityManagerFactory pmf =
-            (OpenJPAEntityManagerFactory) getEmf(props);
-        pm = pmf.createEntityManager();
-        startTx(pm);
-    }
-
-    public void tearDown()
-        throws Exception {
-        try {
-            rollbackTx(pm);
-            endEm(pm);
-        } catch (Exception e) {
-            // this is not what we are testing
-        }
-        super.tearDown();
-    }
-
-    public void testgetTransaction() {
-        mttest(serial, threads, iterations);
-        pm.getTransaction();
-    }
-
-    public void testGetObjectById() {
-        mttest(serial, threads, iterations);
-        assertNotNull(pm.find(RuntimeTest1.class, id));
-    }
-
-    public void testQueryExecution() {
-        mttest(serial, threads, iterations);
-        OpenJPAQuery q = pm.createQuery("select o from RuntimeTest1 o "
-            + "where o.stringField = '" + name + "'");
-        assertEquals(1, q.getResultList().size());
-    }
-
-    public void testDeletePersistent() {
-        mttest(serial, threads, iterations);
-        pm.removeAll(pm.createQuery("select o from RuntimeTest1 o "
-            + "where o.stringField = '" + name + "'").getResultList());
-    }
-
-    public void testRefreshAll() {
-        mttest(serial, threads, iterations);
-        pm.refreshAll();
-    }
-
-    public void testEvictAll() {
-        mttest(serial, threads, iterations);
-        pm.evictAll();
-    }
-
-    public void testIterateExtent()
-        throws Throwable {
-        if (timeout(120 * 1000)) return;
-
-        mttest(serial, threads, iterations);
-
-        assertTrue("Transaction should have been active",
-            pm.getTransaction().isActive());
-
-        for (int i = 0; i < 3; i++) {
-            pm.persist(new RuntimeTest1("testIterateExtent" + Math.random(),
-                (int) (Math.random() * Integer.MAX_VALUE)));
-        }
-
-        assertTrue("Transaction should have been active",
-            pm.getTransaction().isActive());
-
-        for (Iterator i = pm.createExtent(RuntimeTest1.class, true).iterator();
-            i.hasNext(); i.next())
-            ;
-
-        assertTrue("Transaction should have been active",
-            pm.getTransaction().isActive());
-    }
-}
+/*
+ * TestMultiThreaded.java
+ *
+ * Created on October 12, 2006, 2:21 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestMultiThreaded extends BaseKernelTest {
+
+    static int serial = 5;
+    static int threads = 5;
+    static int iterations = 5;
+
+    private OpenJPAEntityManager pm;
+    private Object id;
+    private String name;
+
+    /**
+     * Creates a new instance of TestMultiThreaded
+     */
+    public TestMultiThreaded() {
+    }
+
+    public TestMultiThreaded(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager pm2 = getPM();
+        startTx(pm2);
+        name = "testMultiThreaded" + Math.random();
+        RuntimeTest1 a = new RuntimeTest1(name,
+            (int) (Math.random() * Integer.MAX_VALUE));
+        pm2.persist(a);
+        id = pm2.getObjectId(a);
+        endTx(pm2);
+
+        Map props = new HashMap();
+        props.put("openjpa.Multithreaded", "true");
+        OpenJPAEntityManagerFactory pmf =
+            (OpenJPAEntityManagerFactory) getEmf(props);
+        pm = pmf.createEntityManager();
+        startTx(pm);
+    }
+
+    public void tearDown()
+        throws Exception {
+        try {
+            rollbackTx(pm);
+            endEm(pm);
+        } catch (Exception e) {
+            // this is not what we are testing
+        }
+        super.tearDown();
+    }
+
+    public void testgetTransaction() {
+        mttest(serial, threads, iterations);
+        pm.getTransaction();
+    }
+
+    public void testGetObjectById() {
+        mttest(serial, threads, iterations);
+        assertNotNull(pm.find(RuntimeTest1.class, id));
+    }
+
+    public void testQueryExecution() {
+        mttest(serial, threads, iterations);
+        OpenJPAQuery q = pm.createQuery("select o from RuntimeTest1 o "
+            + "where o.stringField = '" + name + "'");
+        assertEquals(1, q.getResultList().size());
+    }
+
+    public void testDeletePersistent() {
+        mttest(serial, threads, iterations);
+        pm.removeAll(pm.createQuery("select o from RuntimeTest1 o "
+            + "where o.stringField = '" + name + "'").getResultList());
+    }
+
+    public void testRefreshAll() {
+        mttest(serial, threads, iterations);
+        pm.refreshAll();
+    }
+
+    public void testEvictAll() {
+        mttest(serial, threads, iterations);
+        pm.evictAll();
+    }
+
+    public void testIterateExtent()
+        throws Throwable {
+        if (timeout(120 * 1000)) return;
+
+        mttest(serial, threads, iterations);
+
+        assertTrue("Transaction should have been active",
+            pm.getTransaction().isActive());
+
+        for (int i = 0; i < 3; i++) {
+            pm.persist(new RuntimeTest1("testIterateExtent" + Math.random(),
+                (int) (Math.random() * Integer.MAX_VALUE)));
+        }
+
+        assertTrue("Transaction should have been active",
+            pm.getTransaction().isActive());
+
+        for (Iterator i = pm.createExtent(RuntimeTest1.class, true).iterator();
+            i.hasNext(); i.next())
+            ;
+
+        assertTrue("Transaction should have been active",
+            pm.getTransaction().isActive());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultipleInsertDeleteSameId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultipleInsertDeleteSameId.java
index ad3ac29..e107596 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultipleInsertDeleteSameId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestMultipleInsertDeleteSameId.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestMultipleInsertDeleteSameId
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(RuntimeTest1.class, CLEAR_TABLES);
-    }
-
-    public void testMultipleInsertDelete() {
-        em.getTransaction().begin();
-
-        RuntimeTest1 o = new RuntimeTest1("one", 99);
-        em.persist(o);
-        Query q = em.createQuery("select o from RuntimeTest1 o "
-          + " where o.stringField = 'one'"); 
-        assertEquals(o, q.getSingleResult());
-
-        em.remove(o);
-        assertEquals(0, q.getResultList().size());
-      
-        RuntimeTest1 o2 = new RuntimeTest1("two", 99);
-        em.persist(o2);
-        q = em.createQuery("select o from RuntimeTest1 o "
-          + " where o.stringField = 'two'"); 
-        assertEquals(o2, q.getSingleResult());
-
-        em.remove(o2);
-        assertEquals(0, q.getResultList().size());
-
-        em.getTransaction().commit();
-        assertNull(em.find(RuntimeTest1.class, 99));
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestMultipleInsertDeleteSameId
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(RuntimeTest1.class, CLEAR_TABLES);
+    }
+
+    public void testMultipleInsertDelete() {
+        em.getTransaction().begin();
+
+        RuntimeTest1 o = new RuntimeTest1("one", 99);
+        em.persist(o);
+        Query q = em.createQuery("select o from RuntimeTest1 o "
+          + " where o.stringField = 'one'"); 
+        assertEquals(o, q.getSingleResult());
+
+        em.remove(o);
+        assertEquals(0, q.getResultList().size());
+      
+        RuntimeTest1 o2 = new RuntimeTest1("two", 99);
+        em.persist(o2);
+        q = em.createQuery("select o from RuntimeTest1 o "
+          + " where o.stringField = 'two'"); 
+        assertEquals(o2, q.getSingleResult());
+
+        em.remove(o2);
+        assertEquals(0, q.getResultList().size());
+
+        em.getTransaction().commit();
+        assertNull(em.find(RuntimeTest1.class, 99));
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestNTW.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestNTW.java
index fa8cf90..189b2dd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestNTW.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestNTW.java
@@ -1,110 +1,110 @@
-/*
- * TestNTW.java
- *
- * Created on October 12, 2006, 2:33 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestNTW extends BaseKernelTest {
-
-    private OpenJPAEntityManagerFactory factory;
-
-    /**
-     * Creates a new instance of TestNTW
-     */
-    public TestNTW() {
-    }
-
-    public TestNTW(String name) {
-        super(name);
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager em = getPM();
-        startTx(em);
-        em.persist(new RuntimeTest1("ntw0", 0));
-        em.persist(new RuntimeTest1("ntw1", 1));
-        em.persist(new RuntimeTest1("ntw2", 2));
-        em.persist(new RuntimeTest1("ntw3", 3));
-        em.persist(new RuntimeTest1("ntw4", 4));
-        endTx(em);
-        endEm(em);
-
-        em = getPM();
-        startTx(em);
-    }
-
-    public void testNonTransactionalWrite() throws Exception {
-        OpenJPAEntityManagerFactory factory = broker();
-        OpenJPAEntityManager em = factory.createEntityManager();
-        OpenJPAQuery q = em.createQuery(
-            "SELECT o FROM RuntimeTest1 o ORDER BY o.stringField ASC");
-        q.setSubclasses(false);
-        Collection c = (Collection) q.getResultList();
-
-        Iterator iter = c.iterator();
-        RuntimeTest1 o;
-        while (iter.hasNext()) {
-            o = (RuntimeTest1) iter.next();
-            o.setStringField(o.getStringField() + " modified");
-        }
-
-        startTx(em);
-        endTx(em);
-
-        q = em.createQuery(
-            "SELECT o FROM RuntimeTest1 o ORDER BY o.stringField ASC");
-        q.setSubclasses(false);
-        Collection results = (Collection) q.getResultList();
-        assertEquals(5, results.size());
-        endEm(em);
-    }
-
-    private OpenJPAEntityManagerFactory broker() {
-        Map map = new HashMap();
-        map.put("OpenJPA.Optimistic", "true");
-        map.put("OpenJPA.NontransactionalRead", "true");
-        map.put("OpenJPA.NontransactionalWrite", "true");
-
-        if (factory == null) {
-            factory = OpenJPAPersistence
-                .createEntityManagerFactory("TestConv", null, map);
-        }
-        return factory;
-    }
-}
+/*
+ * TestNTW.java
+ *
+ * Created on October 12, 2006, 2:33 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestNTW extends BaseKernelTest {
+
+    private OpenJPAEntityManagerFactory factory;
+
+    /**
+     * Creates a new instance of TestNTW
+     */
+    public TestNTW() {
+    }
+
+    public TestNTW(String name) {
+        super(name);
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager em = getPM();
+        startTx(em);
+        em.persist(new RuntimeTest1("ntw0", 0));
+        em.persist(new RuntimeTest1("ntw1", 1));
+        em.persist(new RuntimeTest1("ntw2", 2));
+        em.persist(new RuntimeTest1("ntw3", 3));
+        em.persist(new RuntimeTest1("ntw4", 4));
+        endTx(em);
+        endEm(em);
+
+        em = getPM();
+        startTx(em);
+    }
+
+    public void testNonTransactionalWrite() throws Exception {
+        OpenJPAEntityManagerFactory factory = broker();
+        OpenJPAEntityManager em = factory.createEntityManager();
+        OpenJPAQuery q = em.createQuery(
+            "SELECT o FROM RuntimeTest1 o ORDER BY o.stringField ASC");
+        q.setSubclasses(false);
+        Collection c = (Collection) q.getResultList();
+
+        Iterator iter = c.iterator();
+        RuntimeTest1 o;
+        while (iter.hasNext()) {
+            o = (RuntimeTest1) iter.next();
+            o.setStringField(o.getStringField() + " modified");
+        }
+
+        startTx(em);
+        endTx(em);
+
+        q = em.createQuery(
+            "SELECT o FROM RuntimeTest1 o ORDER BY o.stringField ASC");
+        q.setSubclasses(false);
+        Collection results = (Collection) q.getResultList();
+        assertEquals(5, results.size());
+        endEm(em);
+    }
+
+    private OpenJPAEntityManagerFactory broker() {
+        Map map = new HashMap();
+        map.put("OpenJPA.Optimistic", "true");
+        map.put("OpenJPA.NontransactionalRead", "true");
+        map.put("OpenJPA.NontransactionalWrite", "true");
+
+        if (factory == null) {
+            factory = OpenJPAPersistence
+                .createEntityManagerFactory("TestConv", null, map);
+        }
+        return factory;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOpenResultsCommit.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOpenResultsCommit.java
index 7030bf5..36a656a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOpenResultsCommit.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOpenResultsCommit.java
@@ -1,118 +1,118 @@
-/*
- * TestOpenResultsCommit.java
- *
- * Created on October 12, 2006, 2:43 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.EnumSet;
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestOpenResultsCommit extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestOpenResultsCommit
-     */
-    public TestOpenResultsCommit() {
-    }
-
-    public TestOpenResultsCommit(String testName) {
-        super(testName);
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        for (int i = 0; i < 50; i++)
-            pm.persist(new RuntimeTest1("open results #" + i, i));
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testCommitWithModeTransaction() {
-        try {
-            testCommitWithOpenResults("transaction");
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.EMPRESS), 718, e,
-                "Cannot keep results open across commit");
-        }
-    }
-
-    public void testCommitWithModeOpenJPAEntityManager() {
-        try {
-            testCommitWithOpenResults("persistence-manager");
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.EMPRESS), 718, e,
-                "Cannot keep results open across commit");
-        }
-    }
-
-    public void testCommitWithModeOnDemand() {
-        try {
-            testCommitWithOpenResults("on-demand");
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.EMPRESS), 718, e,
-                "Cannot keep results open across commit");
-        }
-    }
-
-    private void testCommitWithOpenResults(String crm) {
-        Map props = new HashMap();
-        props.put("openjpa.DefaultFetchThreshold", 1 + "");
-        props.put("openjpa.ConnectionRetainMode", crm);
-
-        OpenJPAEntityManagerFactory pmf =
-            (OpenJPAEntityManagerFactory) getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        startTx(pm);
-        Iterator results =
-            pm.createExtent(RuntimeTest1.class, false).iterator();
-        results.next();
-        ((RuntimeTest1) results.next()).setStringField("changed name");
-        endTx(pm);
-        while (results.hasNext())
-            results.next();
-        endEm(pm);
-    }
-}
+/*
+ * TestOpenResultsCommit.java
+ *
+ * Created on October 12, 2006, 2:43 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.EnumSet;
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestOpenResultsCommit extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestOpenResultsCommit
+     */
+    public TestOpenResultsCommit() {
+    }
+
+    public TestOpenResultsCommit(String testName) {
+        super(testName);
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        for (int i = 0; i < 50; i++)
+            pm.persist(new RuntimeTest1("open results #" + i, i));
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testCommitWithModeTransaction() {
+        try {
+            testCommitWithOpenResults("transaction");
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.EMPRESS), 718, e,
+                "Cannot keep results open across commit");
+        }
+    }
+
+    public void testCommitWithModeOpenJPAEntityManager() {
+        try {
+            testCommitWithOpenResults("persistence-manager");
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.EMPRESS), 718, e,
+                "Cannot keep results open across commit");
+        }
+    }
+
+    public void testCommitWithModeOnDemand() {
+        try {
+            testCommitWithOpenResults("on-demand");
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.EMPRESS), 718, e,
+                "Cannot keep results open across commit");
+        }
+    }
+
+    private void testCommitWithOpenResults(String crm) {
+        Map props = new HashMap();
+        props.put("openjpa.DefaultFetchThreshold", 1 + "");
+        props.put("openjpa.ConnectionRetainMode", crm);
+
+        OpenJPAEntityManagerFactory pmf =
+            (OpenJPAEntityManagerFactory) getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        startTx(pm);
+        Iterator results =
+            pm.createExtent(RuntimeTest1.class, false).iterator();
+        results.next();
+        ((RuntimeTest1) results.next()).setStringField("changed name");
+        endTx(pm);
+        while (results.hasNext())
+            results.next();
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOptimisticLockGroups.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOptimisticLockGroups.java
index d2a725c..cf4cf11 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOptimisticLockGroups.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestOptimisticLockGroups.java
@@ -1,358 +1,358 @@
-/*
- * TestOptimisticLockGroups.java
- *
- * Created on October 12, 2006, 2:57 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC;
-import org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC2;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestOptimisticLockGroups extends BaseKernelTest {
-
-    private Object oid;
-
-    /**
-     * Creates a new instance of TestOptimisticLockGroups
-     */
-    public TestOptimisticLockGroups() {
-    }
-
-    public TestOptimisticLockGroups(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(LockGroupPC.class);
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        Object o = new LockGroupPC();
-        pm.persist(o);
-        endTx(pm);
-        oid = pm.getObjectId(o);
-        endEm(pm);
-    }
-
-    public void testDefaultLockGroupFailure1() {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        startTx(pm1);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        pc1.setDefaultLockGroupStringField("pm1 value");
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
-        pc2.setDefaultLockGroupStringField("pm2 value");
-
-        endTx(pm1);
-        endEm(pm1);
-
-        try {
-            endTx(pm2);
-            fail("should not be able to commit change to same value");
-        } catch (Exception e) {
-            assertEquals(pc2, getFailedObject(e));
-        }
-        endEm(pm2);
-    }
-
-    public void testDefaultLockGroupFailure2() {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        startTx(pm1);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        pc1.setDefaultLockGroupStringField("pm1 value");
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
-        pc2.setExplicitDefaultLockGroupIntField(2);
-
-        endTx(pm1);
-        endEm(pm1);
-
-        try {
-            endTx(pm2);
-            fail("should not be able to commit change to same value");
-        } catch (Exception e) {
-            assertEquals(pc2, getFailedObject(e));
-        }
-        endEm(pm2);
-    }
-
-    public void testNonDefaultLockGroupFailure1() {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        startTx(pm1);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        pc1.setLockGroup0IntField(1);
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
-        pc2.setLockGroup0IntField(2);
-
-        endTx(pm1);
-        endEm(pm1);
-
-        try {
-            endTx(pm2);
-            fail("should not be able to commit change to same value");
-        } catch (Exception e) {
-            assertEquals(pc2, getFailedObject(e));
-        }
-        endEm(pm2);
-    }
-
-    public void testNonDefaultLockGroupFailure2() {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        startTx(pm1);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        pc1.setLockGroup0IntField(1);
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
-        pc2.setLockGroup0StringField("pm2");
-
-        endTx(pm1);
-        endEm(pm1);
-
-        try {
-            endTx(pm2);
-            fail("should not be able to commit change to same value");
-        } catch (Exception e) {
-            assertEquals(pc2, getFailedObject(e));
-        }
-        endEm(pm2);
-    }
-
-    public void testMultipleLockGroupSuccess1() {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        startTx(pm1);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        pc1.setDefaultLockGroupStringField("pm1 value");
-        pc1.setExplicitDefaultLockGroupIntField(1);
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
-        pc2.setLockGroup0IntField(2);
-
-        OpenJPAEntityManager pm3 = getPM(false, false);
-        startTx(pm3);
-        LockGroupPC pc3 = (LockGroupPC) pm3.find(LockGroupPC.class, oid);
-        pc3.setLockGroup1RelationField(new RuntimeTest1());
-
-        endTx(pm1);
-        endEm(pm1);
-
-        endTx(pm2);
-        endEm(pm2);
-
-        endTx(pm3);
-        endEm(pm3);
-    }
-
-    public void testMultipleLockGroupSuccess2() {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        startTx(pm1);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        pc1.setDefaultLockGroupStringField("pm1 value");
-        pc1.setLockGroup0IntField(1);
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
-        pc2.setLockGroup1RelationField(new RuntimeTest1());
-
-        endTx(pm2);
-        endEm(pm2);
-
-        endTx(pm1);
-        endEm(pm1);
-    }
-
-//        FIX ME: aokeke - test is taking so much resource and causing subsequent test to fail
-//        public void testNoLockGroupSuccess() {
-//        OpenJPAEntityManager pm1 = getPM(false, false);
-//        startTx(pm1,());
-//        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class,oid);
-//        pc1.setDefaultLockGroupStringField("pm1 value");
-//        pc1.setLockGroup0IntField(1);
-//        pc1.setUnlockedStringField("pm1 value");
-//        
-//        OpenJPAEntityManager pm2 = getPM(false, false);
-//        startTx(pm2,());
-//        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class,oid);
-//        pc2.setLockGroup1RelationField(new RuntimeTest1());
-//        pc2.setUnlockedStringField("pm2 value");
-//        
-//        endTx(pm1,());
-//        endEm(pm1);
-//        
-//        endTx(pm2,());
-//        endEm(pm2);
-//    }
-
-    public void testAttachDetachSuccess()
-        throws Exception {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        Object detached = pm1.detach(pc1);
-        startTx(pm1);
-        pc1.setLockGroup0IntField(1);
-        pc1.setUnlockedStringField("pm1 changed value");
-        endTx(pm1);
-        endEm(pm1);
-
-        /*
-         // won't work without non-transient detached state
-         ByteArrayOutputStream baos = new ByteArrayOutputStream ();
-         ObjectOutputStream oos = new ObjectOutputStream (baos);
-         oos.writeObject (detached);
-         oos.close ();
-         baos.close ();
-
-         ByteArrayInputStream bais =
-             new ByteArrayInputStream (baos.toByteArray ());
-         ObjectInputStream ois = new ObjectInputStream (bais);
-         LockGroupPC clone = (LockGroupPC) ois.readObject ();
-        */
-        LockGroupPC clone = (LockGroupPC) detached;
-        clone.setLockGroup1IntField(2);
-        clone.setUnlockedStringField("pm2 value");
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        pm2.merge(clone);
-        endTx(pm2);
-        endEm(pm2);
-    }
-
-    public void testAttachDetachFailure()
-        throws Exception {
-        OpenJPAEntityManager pm1 = getPM(false, false);
-        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
-        Object detached = pm1.detach(pc1);
-        startTx(pm1);
-        pc1.setLockGroup0IntField(1);
-        endTx(pm1);
-        endEm(pm1);
-
-        /*
-         // won't work without non-transient detached state
-         ByteArrayOutputStream baos = new ByteArrayOutputStream ();
-         ObjectOutputStream oos = new ObjectOutputStream (baos);
-         oos.writeObject (detached);
-         oos.close ();
-         baos.close ();
-
-         ByteArrayInputStream bais =
-             new ByteArrayInputStream (baos.toByteArray ());
-         ObjectInputStream ois = new ObjectInputStream (bais);
-         LockGroupPC clone = (LockGroupPC) ois.readObject ();
-        */
-        LockGroupPC clone = (LockGroupPC) detached;
-        clone.setLockGroup0IntField(2);
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        startTx(pm2);
-        boolean failed = false;
-        try {
-            pm2.merge(clone);
-        } catch (Exception e) {
-            failed = true;
-        }
-
-        if (failed)
-            rollbackTx(pm2);
-        else {
-            try {
-                endTx(pm2);
-                fail("Allowed conflicting changes");
-            } catch (Exception jve) {
-            }
-        }
-    }
-
-    public void testLockGroupNone() {
-        OpenJPAEntityManager pm = getPM(false, false);
-//        pm.begin();
-        deleteAll(LockGroupPC2.class, pm);
-        startTx(pm);
-        LockGroupPC2 pc = new LockGroupPC2();
-        pc.setName("pc");
-        pm.persist(pc);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = getPM(false, false);
-        pc = (LockGroupPC2) pm.find(LockGroupPC2.class, oid);
-        startTx(pm);
-        pc.getList().add("foo");
-
-        OpenJPAEntityManager pm2 = getPM(false, false);
-        LockGroupPC2 pc2 = (LockGroupPC2) pm2.find(LockGroupPC2.class, oid);
-        startTx(pm2);
-        pc2.getList().add("bar");
-        endTx(pm2);
-        endEm(pm2);
-
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM(false, false);
-        pc = (LockGroupPC2) pm.find(LockGroupPC2.class, oid);
-        assertEquals(2, pc.getList().size());
-        endEm(pm);
-    }
-
-//    public void testKnownSubclass() {
-//        OpenJPAEntityManager pm = getPM(false, false);
-//        LockGroupPCKnownSubclass pc = new LockGroupPCKnownSubclass();
-//        pc.setDefaultLockGroupStringField("pc");
-//        startTx(pm,());
-//        pm.persist(pc);
-//        endTx(pm,());
-//        
-//        startTx(pm,());
-//        pc.setKnownSubclassStringField("foo");
-//        endTx(pm,());
-//    }
-
-    //FIXME jthomas - what do we need to substitute for JDOException ?
-//    private Object getFailedObject(JDOException e) {
-//        return ((JDOException) e.getNestedExceptions()[0]).getFailedObject();
-//    }
-
-    private Object getFailedObject(Exception e) {
-        return null;
-    }
-}
+/*
+ * TestOptimisticLockGroups.java
+ *
+ * Created on October 12, 2006, 2:57 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC;
+import org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC2;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestOptimisticLockGroups extends BaseKernelTest {
+
+    private Object oid;
+
+    /**
+     * Creates a new instance of TestOptimisticLockGroups
+     */
+    public TestOptimisticLockGroups() {
+    }
+
+    public TestOptimisticLockGroups(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(LockGroupPC.class);
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        Object o = new LockGroupPC();
+        pm.persist(o);
+        endTx(pm);
+        oid = pm.getObjectId(o);
+        endEm(pm);
+    }
+
+    public void testDefaultLockGroupFailure1() {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        startTx(pm1);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        pc1.setDefaultLockGroupStringField("pm1 value");
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
+        pc2.setDefaultLockGroupStringField("pm2 value");
+
+        endTx(pm1);
+        endEm(pm1);
+
+        try {
+            endTx(pm2);
+            fail("should not be able to commit change to same value");
+        } catch (Exception e) {
+            assertEquals(pc2, getFailedObject(e));
+        }
+        endEm(pm2);
+    }
+
+    public void testDefaultLockGroupFailure2() {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        startTx(pm1);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        pc1.setDefaultLockGroupStringField("pm1 value");
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
+        pc2.setExplicitDefaultLockGroupIntField(2);
+
+        endTx(pm1);
+        endEm(pm1);
+
+        try {
+            endTx(pm2);
+            fail("should not be able to commit change to same value");
+        } catch (Exception e) {
+            assertEquals(pc2, getFailedObject(e));
+        }
+        endEm(pm2);
+    }
+
+    public void testNonDefaultLockGroupFailure1() {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        startTx(pm1);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        pc1.setLockGroup0IntField(1);
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
+        pc2.setLockGroup0IntField(2);
+
+        endTx(pm1);
+        endEm(pm1);
+
+        try {
+            endTx(pm2);
+            fail("should not be able to commit change to same value");
+        } catch (Exception e) {
+            assertEquals(pc2, getFailedObject(e));
+        }
+        endEm(pm2);
+    }
+
+    public void testNonDefaultLockGroupFailure2() {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        startTx(pm1);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        pc1.setLockGroup0IntField(1);
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
+        pc2.setLockGroup0StringField("pm2");
+
+        endTx(pm1);
+        endEm(pm1);
+
+        try {
+            endTx(pm2);
+            fail("should not be able to commit change to same value");
+        } catch (Exception e) {
+            assertEquals(pc2, getFailedObject(e));
+        }
+        endEm(pm2);
+    }
+
+    public void testMultipleLockGroupSuccess1() {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        startTx(pm1);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        pc1.setDefaultLockGroupStringField("pm1 value");
+        pc1.setExplicitDefaultLockGroupIntField(1);
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
+        pc2.setLockGroup0IntField(2);
+
+        OpenJPAEntityManager pm3 = getPM(false, false);
+        startTx(pm3);
+        LockGroupPC pc3 = (LockGroupPC) pm3.find(LockGroupPC.class, oid);
+        pc3.setLockGroup1RelationField(new RuntimeTest1());
+
+        endTx(pm1);
+        endEm(pm1);
+
+        endTx(pm2);
+        endEm(pm2);
+
+        endTx(pm3);
+        endEm(pm3);
+    }
+
+    public void testMultipleLockGroupSuccess2() {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        startTx(pm1);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        pc1.setDefaultLockGroupStringField("pm1 value");
+        pc1.setLockGroup0IntField(1);
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class, oid);
+        pc2.setLockGroup1RelationField(new RuntimeTest1());
+
+        endTx(pm2);
+        endEm(pm2);
+
+        endTx(pm1);
+        endEm(pm1);
+    }
+
+//        FIX ME: aokeke - test is taking so much resource and causing subsequent test to fail
+//        public void testNoLockGroupSuccess() {
+//        OpenJPAEntityManager pm1 = getPM(false, false);
+//        startTx(pm1,());
+//        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class,oid);
+//        pc1.setDefaultLockGroupStringField("pm1 value");
+//        pc1.setLockGroup0IntField(1);
+//        pc1.setUnlockedStringField("pm1 value");
+//        
+//        OpenJPAEntityManager pm2 = getPM(false, false);
+//        startTx(pm2,());
+//        LockGroupPC pc2 = (LockGroupPC) pm2.find(LockGroupPC.class,oid);
+//        pc2.setLockGroup1RelationField(new RuntimeTest1());
+//        pc2.setUnlockedStringField("pm2 value");
+//        
+//        endTx(pm1,());
+//        endEm(pm1);
+//        
+//        endTx(pm2,());
+//        endEm(pm2);
+//    }
+
+    public void testAttachDetachSuccess()
+        throws Exception {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        Object detached = pm1.detach(pc1);
+        startTx(pm1);
+        pc1.setLockGroup0IntField(1);
+        pc1.setUnlockedStringField("pm1 changed value");
+        endTx(pm1);
+        endEm(pm1);
+
+        /*
+         // won't work without non-transient detached state
+         ByteArrayOutputStream baos = new ByteArrayOutputStream ();
+         ObjectOutputStream oos = new ObjectOutputStream (baos);
+         oos.writeObject (detached);
+         oos.close ();
+         baos.close ();
+
+         ByteArrayInputStream bais =
+             new ByteArrayInputStream (baos.toByteArray ());
+         ObjectInputStream ois = new ObjectInputStream (bais);
+         LockGroupPC clone = (LockGroupPC) ois.readObject ();
+        */
+        LockGroupPC clone = (LockGroupPC) detached;
+        clone.setLockGroup1IntField(2);
+        clone.setUnlockedStringField("pm2 value");
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        pm2.merge(clone);
+        endTx(pm2);
+        endEm(pm2);
+    }
+
+    public void testAttachDetachFailure()
+        throws Exception {
+        OpenJPAEntityManager pm1 = getPM(false, false);
+        LockGroupPC pc1 = (LockGroupPC) pm1.find(LockGroupPC.class, oid);
+        Object detached = pm1.detach(pc1);
+        startTx(pm1);
+        pc1.setLockGroup0IntField(1);
+        endTx(pm1);
+        endEm(pm1);
+
+        /*
+         // won't work without non-transient detached state
+         ByteArrayOutputStream baos = new ByteArrayOutputStream ();
+         ObjectOutputStream oos = new ObjectOutputStream (baos);
+         oos.writeObject (detached);
+         oos.close ();
+         baos.close ();
+
+         ByteArrayInputStream bais =
+             new ByteArrayInputStream (baos.toByteArray ());
+         ObjectInputStream ois = new ObjectInputStream (bais);
+         LockGroupPC clone = (LockGroupPC) ois.readObject ();
+        */
+        LockGroupPC clone = (LockGroupPC) detached;
+        clone.setLockGroup0IntField(2);
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        startTx(pm2);
+        boolean failed = false;
+        try {
+            pm2.merge(clone);
+        } catch (Exception e) {
+            failed = true;
+        }
+
+        if (failed)
+            rollbackTx(pm2);
+        else {
+            try {
+                endTx(pm2);
+                fail("Allowed conflicting changes");
+            } catch (Exception jve) {
+            }
+        }
+    }
+
+    public void testLockGroupNone() {
+        OpenJPAEntityManager pm = getPM(false, false);
+//        pm.begin();
+        deleteAll(LockGroupPC2.class, pm);
+        startTx(pm);
+        LockGroupPC2 pc = new LockGroupPC2();
+        pc.setName("pc");
+        pm.persist(pc);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = getPM(false, false);
+        pc = (LockGroupPC2) pm.find(LockGroupPC2.class, oid);
+        startTx(pm);
+        pc.getList().add("foo");
+
+        OpenJPAEntityManager pm2 = getPM(false, false);
+        LockGroupPC2 pc2 = (LockGroupPC2) pm2.find(LockGroupPC2.class, oid);
+        startTx(pm2);
+        pc2.getList().add("bar");
+        endTx(pm2);
+        endEm(pm2);
+
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM(false, false);
+        pc = (LockGroupPC2) pm.find(LockGroupPC2.class, oid);
+        assertEquals(2, pc.getList().size());
+        endEm(pm);
+    }
+
+//    public void testKnownSubclass() {
+//        OpenJPAEntityManager pm = getPM(false, false);
+//        LockGroupPCKnownSubclass pc = new LockGroupPCKnownSubclass();
+//        pc.setDefaultLockGroupStringField("pc");
+//        startTx(pm,());
+//        pm.persist(pc);
+//        endTx(pm,());
+//        
+//        startTx(pm,());
+//        pc.setKnownSubclassStringField("foo");
+//        endTx(pm,());
+//    }
+
+    //FIXME jthomas - what do we need to substitute for JDOException ?
+//    private Object getFailedObject(JDOException e) {
+//        return ((JDOException) e.getNestedExceptions()[0]).getFailedObject();
+//    }
+
+    private Object getFailedObject(Exception e) {
+        return null;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPCClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPCClass.java
index 8f0016c..84ec4b4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPCClass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPCClass.java
@@ -1,156 +1,156 @@
-/*
- * TestPCClass.java
- *
- * Created on October 12, 2006, 4:27 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.Serializable;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.PCClassInterface;
-import org.apache.openjpa.persistence.kernel.common.apps.PCClassPC;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestPCClass extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestPCClass
-     */
-    public TestPCClass() {
-    }
-
-    public TestPCClass(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        deleteAll(PCClassPC.class);
-    }
-
-    public void testMetaData() {
-
-        MetaDataRepository repos = getConfiguration()
-            .getMetaDataRepositoryInstance();
-        ClassMetaData meta = repos.getMetaData(PCClassPC.class, null, true);
-
-        FieldMetaData fmd = meta.getField("specificPC");
-        assertNotNull("fmd is nulll", fmd);
-        assertEquals("JavaTypes.PC != fmd.getTypeCode()", JavaTypes.PC,
-            fmd.getTypeCode());
-        assertEquals("PCClassPC.class.getName() != fmd.getType().getName()",
-            PCClassPC.class.getName(), fmd.getType().getName());
-        assertEquals(
-            "Object.class.getName() != fmd.getDeclaredType().getName()",
-            Object.class.getName(), fmd.getDeclaredType().getName());
-
-        fmd = meta.getField("genericPC");
-        assertNotNull("fmd is null", fmd);
-        assertEquals("JavaTypes.PC_UNTYPE != fmd.getTypeCode()",
-            JavaTypes.PC_UNTYPED, fmd.getTypeCode());
-        assertEquals(
-            "PersistenceCapable.class.getName() != fmd.getType().getName()",
-            PersistenceCapable.class.getName(), fmd.getType().getName());
-        assertEquals(Object.class.getName(),
-            fmd.getDeclaredType().getName());
-
-        fmd = meta.getField("genericObject");
-        assertNotNull(fmd);
-        assertEquals(JavaTypes.OBJECT, fmd.getTypeCode());
-        assertEquals(Object.class.getName(), fmd.getType().getName());
-        assertEquals(Object.class.getName(),
-            fmd.getDeclaredType().getName());
-
-        fmd = meta.getField("specificInterface");
-        assertNotNull(fmd);
-        assertEquals(JavaTypes.PC, fmd.getTypeCode());
-        assertEquals(PCClassPC.class.getName(), fmd.getType().getName());
-        assertEquals(PCClassInterface.class.getName(),
-            fmd.getDeclaredType().getName());
-
-        fmd = meta.getField("defaultInterface");
-        assertNotNull(fmd);
-        assertEquals(JavaTypes.PC_UNTYPED, fmd.getTypeCode());
-        assertEquals(PCClassInterface.class.getName(),
-            fmd.getType().getName());
-        assertEquals(PCClassInterface.class.getName(),
-            fmd.getDeclaredType().getName());
-
-        fmd = meta.getField("serializableInterface");
-        assertNotNull(fmd);
-        assertEquals(JavaTypes.OBJECT, fmd.getTypeCode());
-        assertEquals(Serializable.class.getName(), fmd.getType().getName());
-        assertEquals(Serializable.class.getName(),
-            fmd.getDeclaredType().getName());
-
-        fmd = meta.getField("genericInterface");
-        assertNotNull(fmd);
-        assertEquals(JavaTypes.OBJECT, fmd.getTypeCode());
-        assertEquals(Object.class.getName(), fmd.getType().getName());
-        assertEquals(PCClassInterface.class.getName(),
-            fmd.getDeclaredType().getName());
-    }
-
-    public void testPersist() {
-        PCClassPC pc = new PCClassPC();
-        pc.setSpecificPC(pc);
-        pc.setGenericPC(pc);
-        pc.setGenericObject(pc);
-        pc.setSpecificInterface(pc);
-        pc.setDefaultInterface(pc);
-        pc.setGenericInterface(pc);
-        pc.setSerializableInterface(pc);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-
-        pc = (PCClassPC) pm.find(PCClassPC.class, oid);
-
-        assertTrue(pc == pc.getSpecificPC());
-        assertTrue(pc == pc.getGenericPC());
-        assertNotNull(pc.getGenericObject());
-        assertTrue(pc == pc.getGenericObject());
-        assertTrue(pc == pc.getSpecificInterface());
-        assertTrue(pc == pc.getDefaultInterface());
-        assertNotNull(pc.getGenericInterface());
-        assertTrue(pc == pc.getGenericInterface());
-        assertNotNull(pc.getSerializableInterface());
-        assertTrue(pc == pc.getSerializableInterface());
-
-        endEm(pm);
-    }
-}
+/*
+ * TestPCClass.java
+ *
+ * Created on October 12, 2006, 4:27 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.Serializable;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.PCClassInterface;
+import org.apache.openjpa.persistence.kernel.common.apps.PCClassPC;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestPCClass extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestPCClass
+     */
+    public TestPCClass() {
+    }
+
+    public TestPCClass(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        deleteAll(PCClassPC.class);
+    }
+
+    public void testMetaData() {
+
+        MetaDataRepository repos = getConfiguration()
+            .getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(PCClassPC.class, null, true);
+
+        FieldMetaData fmd = meta.getField("specificPC");
+        assertNotNull("fmd is nulll", fmd);
+        assertEquals("JavaTypes.PC != fmd.getTypeCode()", JavaTypes.PC,
+            fmd.getTypeCode());
+        assertEquals("PCClassPC.class.getName() != fmd.getType().getName()",
+            PCClassPC.class.getName(), fmd.getType().getName());
+        assertEquals(
+            "Object.class.getName() != fmd.getDeclaredType().getName()",
+            Object.class.getName(), fmd.getDeclaredType().getName());
+
+        fmd = meta.getField("genericPC");
+        assertNotNull("fmd is null", fmd);
+        assertEquals("JavaTypes.PC_UNTYPE != fmd.getTypeCode()",
+            JavaTypes.PC_UNTYPED, fmd.getTypeCode());
+        assertEquals(
+            "PersistenceCapable.class.getName() != fmd.getType().getName()",
+            PersistenceCapable.class.getName(), fmd.getType().getName());
+        assertEquals(Object.class.getName(),
+            fmd.getDeclaredType().getName());
+
+        fmd = meta.getField("genericObject");
+        assertNotNull(fmd);
+        assertEquals(JavaTypes.OBJECT, fmd.getTypeCode());
+        assertEquals(Object.class.getName(), fmd.getType().getName());
+        assertEquals(Object.class.getName(),
+            fmd.getDeclaredType().getName());
+
+        fmd = meta.getField("specificInterface");
+        assertNotNull(fmd);
+        assertEquals(JavaTypes.PC, fmd.getTypeCode());
+        assertEquals(PCClassPC.class.getName(), fmd.getType().getName());
+        assertEquals(PCClassInterface.class.getName(),
+            fmd.getDeclaredType().getName());
+
+        fmd = meta.getField("defaultInterface");
+        assertNotNull(fmd);
+        assertEquals(JavaTypes.PC_UNTYPED, fmd.getTypeCode());
+        assertEquals(PCClassInterface.class.getName(),
+            fmd.getType().getName());
+        assertEquals(PCClassInterface.class.getName(),
+            fmd.getDeclaredType().getName());
+
+        fmd = meta.getField("serializableInterface");
+        assertNotNull(fmd);
+        assertEquals(JavaTypes.OBJECT, fmd.getTypeCode());
+        assertEquals(Serializable.class.getName(), fmd.getType().getName());
+        assertEquals(Serializable.class.getName(),
+            fmd.getDeclaredType().getName());
+
+        fmd = meta.getField("genericInterface");
+        assertNotNull(fmd);
+        assertEquals(JavaTypes.OBJECT, fmd.getTypeCode());
+        assertEquals(Object.class.getName(), fmd.getType().getName());
+        assertEquals(PCClassInterface.class.getName(),
+            fmd.getDeclaredType().getName());
+    }
+
+    public void testPersist() {
+        PCClassPC pc = new PCClassPC();
+        pc.setSpecificPC(pc);
+        pc.setGenericPC(pc);
+        pc.setGenericObject(pc);
+        pc.setSpecificInterface(pc);
+        pc.setDefaultInterface(pc);
+        pc.setGenericInterface(pc);
+        pc.setSerializableInterface(pc);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+
+        pc = (PCClassPC) pm.find(PCClassPC.class, oid);
+
+        assertTrue(pc == pc.getSpecificPC());
+        assertTrue(pc == pc.getGenericPC());
+        assertNotNull(pc.getGenericObject());
+        assertTrue(pc == pc.getGenericObject());
+        assertTrue(pc == pc.getSpecificInterface());
+        assertTrue(pc == pc.getDefaultInterface());
+        assertNotNull(pc.getGenericInterface());
+        assertTrue(pc == pc.getGenericInterface());
+        assertNotNull(pc.getSerializableInterface());
+        assertTrue(pc == pc.getSerializableInterface());
+
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPMMemory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPMMemory.java
index 52757c3..f820cc0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPMMemory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPMMemory.java
@@ -1,296 +1,296 @@
-/*
- * TestPMMemory.java
- *
- * Created on October 13, 2006, 3:28 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.event.AbstractTransactionListener;
-import org.apache.openjpa.event.TransactionEvent;
-import org.apache.openjpa.event.TransactionListener;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestPMMemory extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestPMMemory
-     */
-    public TestPMMemory() {
-    }
-
-    public TestPMMemory(String s) {
-        super(s);
-    }
-
-    public boolean skipTest() {
-        return true;
-    }
-
-    private static final boolean _doPause = false;
-    private static final int NUM_OBJECTS = 2000;
-    private static final int NUM_FLUSHES = 5;
-
-    // Hack to run stand alone.
-    public static void main(String[] args)
-        throws Exception {
-        TestPMMemory testpm = new TestPMMemory("testPMMemory");
-        testpm.setUp();
-        testpm.testMemoryUse();
-    }
-
-    public void setUp() {
-        System.out.println("About to delete all");
-        deleteAllStaged(getPM(), RuntimeTest1.class);
-        // deleteAll (RuntimeTest1.class);
-        System.out.println("Done delete all");
-    }
-
-    public void deleteAllStaged(OpenJPAEntityManager pmArg, Class classType) {
-        /*
-          // create 64000 objects
-          // now call this, WITH the datacache on,
-          // and despite using a fetchBatch size,
-          //		this _will_ run out of memory
-          // props:
-  kodo.DataCache: true(CacheSize=5, SoftReferenceSize=1)
-  kodo.RemoteCommitProvider: sjvm
-          */
-        int delCount = 0;
-        OpenJPAEntityManager pm;
-
-        boolean needToDelete = true;
-        while (needToDelete) {
-            pm = getPM();
-            startTx(pm);
-            //pm.setLargeTransaction(true);
-            pm.setTrackChangesByType(true);
-            String cstrng = classType.getName();
-            OpenJPAQuery kq = pm.createQuery("SELECT o FROM " + cstrng + " o");
-            kq.getFetchPlan().setFetchBatchSize(100);
-            Collection results = (Collection) kq.getResultList();
-            if (results.size() == 0) {
-                needToDelete = false;
-                break;
-            }
-            System.out.println("We need to delete " + results.size());
-            Iterator iter = results.iterator();
-            while (iter.hasNext()) {
-                pm.remove(iter.next());
-                delCount += 1;
-                if ((delCount % 800) == 0) {
-                    pm.flush();
-                    // is the trans cahce now holding
-                    // all these objects?
-                    break;
-                }
-            }
-            System.out.print("deleted 200");
-            endTx(pm);
-            endEm(pm);
-        }
-        System.out.println("Done deleting");
-    }
-
-    private void reportMemory() {
-        reportMemory("Memory used");
-        /*
-      DataCacheImpl dc;
-      dc = (DataCacheImpl) kpm.getConfiguration ().getDataCacheManager ().
-          getDataCache ()
-      CacheMap cacheMap = dc.getCacheMap ();
-      values/keySet
-      */
-    }
-
-    private void reportMemory(String msg) {
-        System.gc();
-        long memUsed = Runtime.getRuntime().totalMemory();
-        long memFree = Runtime.getRuntime().freeMemory();
-        System.out.println("" + msg + " : " + memUsed + ", " +
-            memFree);
-    }
-
-    private void pause(double seconds) {
-        if (!_doPause)
-            return;
-        try {
-            Thread.currentThread().yield();
-            Thread.currentThread().sleep((int) seconds * 1000);
-        } catch (Exception e) {
-        }
-    }
-
-    public void testMemoryUse() throws Exception {
-
-        System.out.println("Baseline, starting memory for N objects of " +
-            NUM_OBJECTS);
-        OpenJPAEntityManagerFactory kpmf =
-            (OpenJPAEntityManagerFactory) getEmf();
-        OpenJPAEntityManager kpm = (OpenJPAEntityManager)
-            kpmf.createEntityManager();
-
-        startTx(kpm);
-        int runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, 0);
-        endTx(kpm);
-
-        System.out.println("Baseline, starting memory ");
-        reportMemory();
-
-        TransactionListener l = new AbstractTransactionListener() {
-            public void afterCommit(TransactionEvent ev) {
-                System.out.println(
-                    "My Listener in afterCommit");
-                System.out.println(
-                    "Num objects in transaction "
-                        + ev.getTransactionalObjects().size());
-
-                // send out an email confirming that the
-                // transaction was a success
-            }
-        };
-
-        // kpm.registerListener (l);
-
-        // jprobe, jprofiler.
-        // prefer treeview
-
-        // Run a transaction for a whilw and report memory
-        startTx(kpm);
-        int objCount = 0;
-        for (int i = 0; i < NUM_FLUSHES; i++) {
-            System.out.println();
-            System.out.println("Iteration #" + i + " created " +
-                objCount);
-            reportMemory();
-            //kpm.setLargeTransaction(true);
-            kpm.setTrackChangesByType(true);
-            runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, runningId);
-            objCount += NUM_OBJECTS;
-            kpm.flush();
-            grabAllMemory();
-            //    pause(30);
-        }
-
-        System.out.println("Created objects, about to commit ()");
-        pause(90);
-        endTx(kpm);
-        pause(1);
-        System.out.println("Now commit ()");
-        reportMemory();
-        pause(33);
-    }
-
-    protected void grabAllMemory() {
-        // exhaust all memory so that GC is run.
-        int size = 4096;
-        boolean grab = true;
-        int[] glob;
-        while (grab) {
-            try {
-                glob = new int[size];
-                size *= 2;
-            } catch (OutOfMemoryError e) {
-                System.out.println("Mem grabbed " + size);
-                grab = false;
-                glob = null;
-            }
-        }
-        glob = null;
-    }
-
-    protected int performAddsModifiesDeletes(OpenJPAEntityManager pm,
-        int numObjects, int runningId) {
-        // pm should be active. Function does not perform commit.
-
-        // Perform a series of transactions that will trigger adds,
-        // deletes, and udpates
-
-        // create objects
-        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i] = new RuntimeTest1("foo #" + i, runningId + i);
-        }
-        runningId += persistables.length;
-
-        // add them
-        for (int i = 0; i < persistables.length; i++) {
-            pm.persist(persistables[i]);
-        }
-
-        // modify them
-        for (int i = 0; i < persistables.length; i++) {
-            persistables[i].setIntField1(i + 1);
-        }
-
-/*
-		// delete them
-		for (int i = 0; i < persistables.length; i++)
-		{
-			pm.deletePersistent (persistables [i]);
-		}
-*/
-        return runningId + 1;
-    }
-
-    static int _fetchGroupSerial = 0;
-
-    protected OpenJPAEntityManagerFactory createDistinctFactory(
-        Class providerClass, String classProps1) {
-        Map props = null;
-
-        //FIXME jthomas
-        /*
-        if (providerClass != null) {
-            props = new String[]{
-                "openjpa.RemoteCommitProvider", Configurations.getPlugin(
-                providerClass.getNameclassProps1),
-                // use this property to differentiate the factory
-                "openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial,
-            };
-        } else {
-            // No RCP
-            props = new String[]{
-                // use this property to differentiate the factory
-                "openjpa.RemoteCommitProvider", "sjvm",
-                "openjpa.FetchGroups", "differentiatingFetchGroup" +
-                _fetchGroupSerial,
-            };
-        }
-        _fetchGroupSerial += 1;
-         */
-
-        return (OpenJPAEntityManagerFactory) getEmf(props);
-    }
-}
+/*
+ * TestPMMemory.java
+ *
+ * Created on October 13, 2006, 3:28 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.AbstractTransactionListener;
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.event.TransactionListener;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestPMMemory extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestPMMemory
+     */
+    public TestPMMemory() {
+    }
+
+    public TestPMMemory(String s) {
+        super(s);
+    }
+
+    public boolean skipTest() {
+        return true;
+    }
+
+    private static final boolean _doPause = false;
+    private static final int NUM_OBJECTS = 2000;
+    private static final int NUM_FLUSHES = 5;
+
+    // Hack to run stand alone.
+    public static void main(String[] args)
+        throws Exception {
+        TestPMMemory testpm = new TestPMMemory("testPMMemory");
+        testpm.setUp();
+        testpm.testMemoryUse();
+    }
+
+    public void setUp() {
+        System.out.println("About to delete all");
+        deleteAllStaged(getPM(), RuntimeTest1.class);
+        // deleteAll (RuntimeTest1.class);
+        System.out.println("Done delete all");
+    }
+
+    public void deleteAllStaged(OpenJPAEntityManager pmArg, Class classType) {
+        /*
+          // create 64000 objects
+          // now call this, WITH the datacache on,
+          // and despite using a fetchBatch size,
+          //		this _will_ run out of memory
+          // props:
+  kodo.DataCache: true(CacheSize=5, SoftReferenceSize=1)
+  kodo.RemoteCommitProvider: sjvm
+          */
+        int delCount = 0;
+        OpenJPAEntityManager pm;
+
+        boolean needToDelete = true;
+        while (needToDelete) {
+            pm = getPM();
+            startTx(pm);
+            //pm.setLargeTransaction(true);
+            pm.setTrackChangesByType(true);
+            String cstrng = classType.getName();
+            OpenJPAQuery kq = pm.createQuery("SELECT o FROM " + cstrng + " o");
+            kq.getFetchPlan().setFetchBatchSize(100);
+            Collection results = (Collection) kq.getResultList();
+            if (results.size() == 0) {
+                needToDelete = false;
+                break;
+            }
+            System.out.println("We need to delete " + results.size());
+            Iterator iter = results.iterator();
+            while (iter.hasNext()) {
+                pm.remove(iter.next());
+                delCount += 1;
+                if ((delCount % 800) == 0) {
+                    pm.flush();
+                    // is the trans cahce now holding
+                    // all these objects?
+                    break;
+                }
+            }
+            System.out.print("deleted 200");
+            endTx(pm);
+            endEm(pm);
+        }
+        System.out.println("Done deleting");
+    }
+
+    private void reportMemory() {
+        reportMemory("Memory used");
+        /*
+      DataCacheImpl dc;
+      dc = (DataCacheImpl) kpm.getConfiguration ().getDataCacheManager ().
+          getDataCache ()
+      CacheMap cacheMap = dc.getCacheMap ();
+      values/keySet
+      */
+    }
+
+    private void reportMemory(String msg) {
+        System.gc();
+        long memUsed = Runtime.getRuntime().totalMemory();
+        long memFree = Runtime.getRuntime().freeMemory();
+        System.out.println("" + msg + " : " + memUsed + ", " +
+            memFree);
+    }
+
+    private void pause(double seconds) {
+        if (!_doPause)
+            return;
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testMemoryUse() throws Exception {
+
+        System.out.println("Baseline, starting memory for N objects of " +
+            NUM_OBJECTS);
+        OpenJPAEntityManagerFactory kpmf =
+            (OpenJPAEntityManagerFactory) getEmf();
+        OpenJPAEntityManager kpm = (OpenJPAEntityManager)
+            kpmf.createEntityManager();
+
+        startTx(kpm);
+        int runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, 0);
+        endTx(kpm);
+
+        System.out.println("Baseline, starting memory ");
+        reportMemory();
+
+        TransactionListener l = new AbstractTransactionListener() {
+            public void afterCommit(TransactionEvent ev) {
+                System.out.println(
+                    "My Listener in afterCommit");
+                System.out.println(
+                    "Num objects in transaction "
+                        + ev.getTransactionalObjects().size());
+
+                // send out an email confirming that the
+                // transaction was a success
+            }
+        };
+
+        // kpm.registerListener (l);
+
+        // jprobe, jprofiler.
+        // prefer treeview
+
+        // Run a transaction for a whilw and report memory
+        startTx(kpm);
+        int objCount = 0;
+        for (int i = 0; i < NUM_FLUSHES; i++) {
+            System.out.println();
+            System.out.println("Iteration #" + i + " created " +
+                objCount);
+            reportMemory();
+            //kpm.setLargeTransaction(true);
+            kpm.setTrackChangesByType(true);
+            runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, runningId);
+            objCount += NUM_OBJECTS;
+            kpm.flush();
+            grabAllMemory();
+            //    pause(30);
+        }
+
+        System.out.println("Created objects, about to commit ()");
+        pause(90);
+        endTx(kpm);
+        pause(1);
+        System.out.println("Now commit ()");
+        reportMemory();
+        pause(33);
+    }
+
+    protected void grabAllMemory() {
+        // exhaust all memory so that GC is run.
+        int size = 4096;
+        boolean grab = true;
+        int[] glob;
+        while (grab) {
+            try {
+                glob = new int[size];
+                size *= 2;
+            } catch (OutOfMemoryError e) {
+                System.out.println("Mem grabbed " + size);
+                grab = false;
+                glob = null;
+            }
+        }
+        glob = null;
+    }
+
+    protected int performAddsModifiesDeletes(OpenJPAEntityManager pm,
+        int numObjects, int runningId) {
+        // pm should be active. Function does not perform commit.
+
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, runningId + i);
+        }
+        runningId += persistables.length;
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            pm.persist(persistables[i]);
+        }
+
+        // modify them
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setIntField1(i + 1);
+        }
+
+/*
+		// delete them
+		for (int i = 0; i < persistables.length; i++)
+		{
+			pm.deletePersistent (persistables [i]);
+		}
+*/
+        return runningId + 1;
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        Map props = null;
+
+        //FIXME jthomas
+        /*
+        if (providerClass != null) {
+            props = new String[]{
+                "openjpa.RemoteCommitProvider", Configurations.getPlugin(
+                providerClass.getNameclassProps1),
+                // use this property to differentiate the factory
+                "openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial,
+            };
+        } else {
+            // No RCP
+            props = new String[]{
+                // use this property to differentiate the factory
+                "openjpa.RemoteCommitProvider", "sjvm",
+                "openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial,
+            };
+        }
+        _fetchGroupSerial += 1;
+         */
+
+        return (OpenJPAEntityManagerFactory) getEmf(props);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManager.java
index e24fa40..0dde414 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManager.java
@@ -1,431 +1,431 @@
-/*
- * TestOpenJPAEntityManager.java
- *
- * Created on October 12, 2006, 4:40 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.EntityNotFoundException;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.kernel.DelegatingBrokerFactory;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.util.Id;
-
-public class TestPersistenceManager extends BaseKernelTest {
-
-    private int _id = 0;
-    private int _id2 = 0;
-
-    public TestPersistenceManager(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates a new instance of TestOpenJPAEntityManager
-     */
-    public TestPersistenceManager() {
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        RuntimeTest1 a = new RuntimeTest1("STRING", 10);
-        RuntimeTest2 b = new RuntimeTest2("STRING2", 11);
-        pm.persist(a);
-        pm.persist(b);
-        _id = a.getIntField();
-        _id2 = b.getIntField();
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    /**
-     * No-op test that can be run in name to see if the setup is working
-     * properly.
-     */
-    public void testSetup() {
-    }
-
-    /**
-     * Tests that the PM throws Exceptions on usage attempts after it has been
-     * closed.
-     */
-    public void testClosed() {
-        OpenJPAEntityManager pm = getPM();
-        endEm(pm);
-
-        try {
-            // this is the only method that should succeed
-            pm.isOpen();
-        } catch (RuntimeException re) {
-            fail("isClosed");
-        }
-        try {
-            pm.find(RuntimeTest1.class, _id);
-            fail("find");
-        } catch (RuntimeException re) {
-        }
-        try {
-            pm.persist(new RuntimeTest1(20));
-            fail("setUserObject");
-        } catch (RuntimeException re) {
-        }
-        try {
-            pm.setNontransactionalRead(true);
-            fail("setNontransactionalRead");
-        } catch (RuntimeException re) {
-        }
-        try {
-            // this method should fail
-            endEm(pm);
-            bug(65, null, "multiple close should not be allowed");
-            fail("multiple close should not be allowed");
-        } catch (Exception jdoe) {
-            // good: we should get an exception
-        }
-    }
-
-    public void testMultipleCloseThreaded()
-        throws Throwable {
-        final OpenJPAEntityManager pm = getPM();
-        final List result = new ArrayList();
-        startTx(pm);
-
-        endEm(pm);
-
-        new Thread() {
-            public void run() {
-                try {
-                    endEm(pm);
-                    result.add(new Integer(0));
-                } catch (Exception jdoe) {
-                    result.add(jdoe);
-                } catch (Throwable t) {
-                    result.add(t);
-                }
-            }
-        }.start();
-
-        while (result.size() == 0)
-            Thread.currentThread().yield(); // wait for results
-        Object ret = result.get(0);
-
-        if (ret instanceof Exception)
-            return; // good
-
-        if (ret instanceof Throwable)
-            throw (Throwable) ret;
-
-        bug(65, null,
-            "multiple close in different threads should not be allowed");
-    }
-
-    /**
-     * This method tries to perform operations that should lead to
-     * illegal states, such as persisting instances outside of transactions,
-     * etc.
-     */
-    public void testIllegalState() {
-        OpenJPAEntityManager pm = getPM();
-
-        RuntimeTest1 a = new RuntimeTest1("foo", 14);
-        RuntimeTest1 a2 = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
-
-        try {
-            pm.persist(a);
-            fail("persist");
-        }
-        catch (Exception ise) {
-        }
-        try {
-            pm.isTransactional(a2);
-            fail("makeTransactional");
-        }
-        catch (Exception ise) {
-        }
-        try {
-            pm.remove(a2);
-            fail("deletePersistent");
-        }
-        catch (Exception ise) {
-        }
-
-        endEm(pm);
-    }
-
-    public void testOpenJPAEntityManagerFactorySerializable()
-        throws Exception {
-        OpenJPAEntityManagerFactory pmf =
-            (OpenJPAEntityManagerFactory) getEmf();
-        assertNotNull("OpenJPAEntityManagerFactory is null.", pmf);
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(pmf);
-
-        OpenJPAEntityManagerFactory pmf2 = (OpenJPAEntityManagerFactory)
-            new ObjectInputStream(
-                new ByteArrayInputStream(baos.toByteArray())).readObject();
-        assertNotNull("Deserialized OpenJPAEntityManagerFactory is null.",
-            pmf2);
-
-        OpenJPAEntityManager pm = pmf2.createEntityManager();
-        startTx(pm);
-        // go through some objects to make sure our PM is OK
-        for (Iterator i = pm.createExtent(RuntimeTest1.class, true).iterator();
-            i.hasNext(); i.next())
-            ;
-        endTx(pm);
-        endEm(pm);
-    }
-
-    private static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
-        BrokerFactory bf = JPAFacadeHelper.toBrokerFactory(emf);
-        if (bf instanceof DelegatingBrokerFactory)
-            bf = ((DelegatingBrokerFactory) bf).getInnermostDelegate();
-        return bf;
-    }
-
-    /**
-     * Test that a getObjectById() returns the correct instance.
-     */
-    public void testGetObjectById() {
-        // test with valid id
-        OpenJPAEntityManager pm = getPM();
-        RuntimeTest1 b = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
-        assertEquals("STRING", b.getStringField());
-
-        // invalid with possible subclasses should throw immediate exception
-        Object invalidId = new Id(RuntimeTest1.class, -1L);
-        try {
-            pm.find(RuntimeTest1.class, invalidId);
-            fail("Invalid Object");
-        } catch (Exception e) {
-        }
-
-        // invalid without subclasses and without validating should return
-        // hollow
-        invalidId = new Id(RuntimeTest4.class, -1L);
-        try {
-            RuntimeTest4 a = (RuntimeTest4) pm.getReference(RuntimeTest4.class,
-                invalidId);
-            assertNotNull("invalid without subclasses and without validating "
-                + "should return hollow or throw exception", a);
-            a.getName();
-            fail("Allowed access of invalid hollow instance.");
-        }
-        catch (EntityNotFoundException enfe) {
-            // expected
-        }
-
-        invalidId = new Id(RuntimeTest4.class, -3L);
-        assertNull(pm.find(RuntimeTest4.class, invalidId));
-
-        endEm(pm);
-    }
-
-    public void testGetObjectsById() {
-        OpenJPAEntityManager pm = getPM();
-        ArrayList idlist = new ArrayList();
-        idlist.add(_id);
-        idlist.add(_id2);
-        Collection pcs = pm.findAll(RuntimeTest1.class, idlist);
-        assertEquals(2, pcs.size());
-        Iterator iter = pcs.iterator();
-        assertEquals("STRING", ((RuntimeTest1) iter.next()).getStringField());
-        assertEquals("STRING2", ((RuntimeTest2) iter.next()).getStringField());
-        endEm(pm);
-
-        pm = getPM();
-        idlist = new ArrayList();
-        idlist.add(_id);
-        idlist.add(_id);
-        pcs = pm.findAll(RuntimeTest1.class, idlist);
-        iter = pcs.iterator();
-        assertEquals(2, pcs.size());
-        assertEquals("STRING", ((RuntimeTest1) iter.next()).getStringField());
-        iter = pcs.iterator();
-        assertTrue(iter.next() == iter.next());
-        endEm(pm);
-
-        // invalid id causes exception
-        Object invalidId = new Id(RuntimeTest4.class, -1L);
-        pm = getPM();
-        idlist = new ArrayList();
-        idlist.add(_id);
-        idlist.add(invalidId);
-        try {
-            pcs = (ArrayList) pm.findAll(RuntimeTest1.class, idlist);
-            iter = pcs.iterator();
-            assertEquals(2, pcs.size());
-            assertEquals("STRING",
-                ((RuntimeTest1) iter.next()).getStringField());
-            assertNotNull(iter.next());
-            fail("invalid id didnt cause exception");
-        }
-        catch (Exception onfe) {
-            //expected exception. invalid id causes exception
-        }
-
-        try {
-            ((RuntimeTest4) iter.next()).getName();
-            fail("Accessed invalid object.");
-        }
-        catch (Exception onfe) {
-            bug(1138, onfe, "Wrong exception type");
-        }
-
-        pm = getPM();
-        try {
-            pm.findAll(RuntimeTest1.class, idlist);
-            fail("Found invalid object.");
-        } catch (Exception e) {
-        }
-        endEm(pm);
-    }
-
-    public void testEvictAll() {
-        OpenJPAEntityManager pm = getPM();
-
-        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
-        pm.retrieveAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.PNONTRANS, s);
-        }
-        pm.evictAll();
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.HOLLOW, s);
-        }
-    }
-
-    public void testEvictAllCollection() {
-        OpenJPAEntityManager pm = getPM();
-
-        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
-        pm.retrieveAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.PNONTRANS, s);
-        }
-        pm.evictAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.HOLLOW, s);
-        }
-    }
-
-    public void testEvictAllClass() {
-        OpenJPAEntityManager pm = getPM();
-
-        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
-        pm.retrieveAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.PNONTRANS, s);
-        }
-        pm.evictAll(RuntimeTest1.class);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.HOLLOW, s);
-        }
-    }
-
-    public void testEvictAllClassFailure() {
-        OpenJPAEntityManager pm = getPM();
-
-        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
-        pm.retrieveAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.PNONTRANS, s);
-        }
-        pm.evictAll(RuntimeTest2.class);
-        boolean foundPNONTRANS = false;
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            if (s == PCState.PNONTRANS) {
-                foundPNONTRANS = true;
-                break;
-            }
-        }
-        assertTrue("should have found some RuntimeTest1s that were not "
-            + "evicted", foundPNONTRANS);
-    }
-
-    public void testEvictAllExtent() {
-        OpenJPAEntityManager pm = getPM();
-
-        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
-        pm.retrieveAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.PNONTRANS, s);
-        }
-        pm.evictAll(pm.createExtent(RuntimeTest1.class, true));
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.HOLLOW, s);
-        }
-
-        pm.retrieveAll(l);
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            PCState s = getStateManager(iter.next(), pm).getPCState();
-            assertEquals(PCState.PNONTRANS, s);
-        }
-        pm.evictAll(pm.createExtent(RuntimeTest1.class, false));
-        for (Iterator iter = l.iterator(); iter.hasNext();) {
-            Object o = iter.next();
-            if (o.getClass() == RuntimeTest1.class) {
-                PCState s = getStateManager(o, pm).getPCState();
-                assertEquals(PCState.HOLLOW, s);
-            }
-        }
-    }
-}
+/*
+ * TestOpenJPAEntityManager.java
+ *
+ * Created on October 12, 2006, 4:40 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityNotFoundException;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.DelegatingBrokerFactory;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.util.Id;
+
+public class TestPersistenceManager extends BaseKernelTest {
+
+    private int _id = 0;
+    private int _id2 = 0;
+
+    public TestPersistenceManager(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates a new instance of TestOpenJPAEntityManager
+     */
+    public TestPersistenceManager() {
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        RuntimeTest1 a = new RuntimeTest1("STRING", 10);
+        RuntimeTest2 b = new RuntimeTest2("STRING2", 11);
+        pm.persist(a);
+        pm.persist(b);
+        _id = a.getIntField();
+        _id2 = b.getIntField();
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    /**
+     * No-op test that can be run in name to see if the setup is working
+     * properly.
+     */
+    public void testSetup() {
+    }
+
+    /**
+     * Tests that the PM throws Exceptions on usage attempts after it has been
+     * closed.
+     */
+    public void testClosed() {
+        OpenJPAEntityManager pm = getPM();
+        endEm(pm);
+
+        try {
+            // this is the only method that should succeed
+            pm.isOpen();
+        } catch (RuntimeException re) {
+            fail("isClosed");
+        }
+        try {
+            pm.find(RuntimeTest1.class, _id);
+            fail("find");
+        } catch (RuntimeException re) {
+        }
+        try {
+            pm.persist(new RuntimeTest1(20));
+            fail("setUserObject");
+        } catch (RuntimeException re) {
+        }
+        try {
+            pm.setNontransactionalRead(true);
+            fail("setNontransactionalRead");
+        } catch (RuntimeException re) {
+        }
+        try {
+            // this method should fail
+            endEm(pm);
+            bug(65, null, "multiple close should not be allowed");
+            fail("multiple close should not be allowed");
+        } catch (Exception jdoe) {
+            // good: we should get an exception
+        }
+    }
+
+    public void testMultipleCloseThreaded()
+        throws Throwable {
+        final OpenJPAEntityManager pm = getPM();
+        final List result = new ArrayList();
+        startTx(pm);
+
+        endEm(pm);
+
+        new Thread() {
+            public void run() {
+                try {
+                    endEm(pm);
+                    result.add(new Integer(0));
+                } catch (Exception jdoe) {
+                    result.add(jdoe);
+                } catch (Throwable t) {
+                    result.add(t);
+                }
+            }
+        }.start();
+
+        while (result.size() == 0)
+            Thread.currentThread().yield(); // wait for results
+        Object ret = result.get(0);
+
+        if (ret instanceof Exception)
+            return; // good
+
+        if (ret instanceof Throwable)
+            throw (Throwable) ret;
+
+        bug(65, null,
+            "multiple close in different threads should not be allowed");
+    }
+
+    /**
+     * This method tries to perform operations that should lead to
+     * illegal states, such as persisting instances outside of transactions,
+     * etc.
+     */
+    public void testIllegalState() {
+        OpenJPAEntityManager pm = getPM();
+
+        RuntimeTest1 a = new RuntimeTest1("foo", 14);
+        RuntimeTest1 a2 = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
+
+        try {
+            pm.persist(a);
+            fail("persist");
+        }
+        catch (Exception ise) {
+        }
+        try {
+            pm.isTransactional(a2);
+            fail("makeTransactional");
+        }
+        catch (Exception ise) {
+        }
+        try {
+            pm.remove(a2);
+            fail("deletePersistent");
+        }
+        catch (Exception ise) {
+        }
+
+        endEm(pm);
+    }
+
+    public void testOpenJPAEntityManagerFactorySerializable()
+        throws Exception {
+        OpenJPAEntityManagerFactory pmf =
+            (OpenJPAEntityManagerFactory) getEmf();
+        assertNotNull("OpenJPAEntityManagerFactory is null.", pmf);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(pmf);
+
+        OpenJPAEntityManagerFactory pmf2 = (OpenJPAEntityManagerFactory)
+            new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray())).readObject();
+        assertNotNull("Deserialized OpenJPAEntityManagerFactory is null.",
+            pmf2);
+
+        OpenJPAEntityManager pm = pmf2.createEntityManager();
+        startTx(pm);
+        // go through some objects to make sure our PM is OK
+        for (Iterator i = pm.createExtent(RuntimeTest1.class, true).iterator();
+            i.hasNext(); i.next())
+            ;
+        endTx(pm);
+        endEm(pm);
+    }
+
+    private static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
+        BrokerFactory bf = JPAFacadeHelper.toBrokerFactory(emf);
+        if (bf instanceof DelegatingBrokerFactory)
+            bf = ((DelegatingBrokerFactory) bf).getInnermostDelegate();
+        return bf;
+    }
+
+    /**
+     * Test that a getObjectById() returns the correct instance.
+     */
+    public void testGetObjectById() {
+        // test with valid id
+        OpenJPAEntityManager pm = getPM();
+        RuntimeTest1 b = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
+        assertEquals("STRING", b.getStringField());
+
+        // invalid with possible subclasses should throw immediate exception
+        Object invalidId = new Id(RuntimeTest1.class, -1L);
+        try {
+            pm.find(RuntimeTest1.class, invalidId);
+            fail("Invalid Object");
+        } catch (Exception e) {
+        }
+
+        // invalid without subclasses and without validating should return
+        // hollow
+        invalidId = new Id(RuntimeTest4.class, -1L);
+        try {
+            RuntimeTest4 a = (RuntimeTest4) pm.getReference(RuntimeTest4.class,
+                invalidId);
+            assertNotNull("invalid without subclasses and without validating "
+                + "should return hollow or throw exception", a);
+            a.getName();
+            fail("Allowed access of invalid hollow instance.");
+        }
+        catch (EntityNotFoundException enfe) {
+            // expected
+        }
+
+        invalidId = new Id(RuntimeTest4.class, -3L);
+        assertNull(pm.find(RuntimeTest4.class, invalidId));
+
+        endEm(pm);
+    }
+
+    public void testGetObjectsById() {
+        OpenJPAEntityManager pm = getPM();
+        ArrayList idlist = new ArrayList();
+        idlist.add(_id);
+        idlist.add(_id2);
+        Collection pcs = pm.findAll(RuntimeTest1.class, idlist);
+        assertEquals(2, pcs.size());
+        Iterator iter = pcs.iterator();
+        assertEquals("STRING", ((RuntimeTest1) iter.next()).getStringField());
+        assertEquals("STRING2", ((RuntimeTest2) iter.next()).getStringField());
+        endEm(pm);
+
+        pm = getPM();
+        idlist = new ArrayList();
+        idlist.add(_id);
+        idlist.add(_id);
+        pcs = pm.findAll(RuntimeTest1.class, idlist);
+        iter = pcs.iterator();
+        assertEquals(2, pcs.size());
+        assertEquals("STRING", ((RuntimeTest1) iter.next()).getStringField());
+        iter = pcs.iterator();
+        assertTrue(iter.next() == iter.next());
+        endEm(pm);
+
+        // invalid id causes exception
+        Object invalidId = new Id(RuntimeTest4.class, -1L);
+        pm = getPM();
+        idlist = new ArrayList();
+        idlist.add(_id);
+        idlist.add(invalidId);
+        try {
+            pcs = (ArrayList) pm.findAll(RuntimeTest1.class, idlist);
+            iter = pcs.iterator();
+            assertEquals(2, pcs.size());
+            assertEquals("STRING",
+                ((RuntimeTest1) iter.next()).getStringField());
+            assertNotNull(iter.next());
+            fail("invalid id didnt cause exception");
+        }
+        catch (Exception onfe) {
+            //expected exception. invalid id causes exception
+        }
+
+        try {
+            ((RuntimeTest4) iter.next()).getName();
+            fail("Accessed invalid object.");
+        }
+        catch (Exception onfe) {
+            bug(1138, onfe, "Wrong exception type");
+        }
+
+        pm = getPM();
+        try {
+            pm.findAll(RuntimeTest1.class, idlist);
+            fail("Found invalid object.");
+        } catch (Exception e) {
+        }
+        endEm(pm);
+    }
+
+    public void testEvictAll() {
+        OpenJPAEntityManager pm = getPM();
+
+        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
+        pm.retrieveAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.PNONTRANS, s);
+        }
+        pm.evictAll();
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.HOLLOW, s);
+        }
+    }
+
+    public void testEvictAllCollection() {
+        OpenJPAEntityManager pm = getPM();
+
+        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
+        pm.retrieveAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.PNONTRANS, s);
+        }
+        pm.evictAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.HOLLOW, s);
+        }
+    }
+
+    public void testEvictAllClass() {
+        OpenJPAEntityManager pm = getPM();
+
+        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
+        pm.retrieveAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.PNONTRANS, s);
+        }
+        pm.evictAll(RuntimeTest1.class);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.HOLLOW, s);
+        }
+    }
+
+    public void testEvictAllClassFailure() {
+        OpenJPAEntityManager pm = getPM();
+
+        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
+        pm.retrieveAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.PNONTRANS, s);
+        }
+        pm.evictAll(RuntimeTest2.class);
+        boolean foundPNONTRANS = false;
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            if (s == PCState.PNONTRANS) {
+                foundPNONTRANS = true;
+                break;
+            }
+        }
+        assertTrue("should have found some RuntimeTest1s that were not "
+            + "evicted", foundPNONTRANS);
+    }
+
+    public void testEvictAllExtent() {
+        OpenJPAEntityManager pm = getPM();
+
+        List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
+        pm.retrieveAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.PNONTRANS, s);
+        }
+        pm.evictAll(pm.createExtent(RuntimeTest1.class, true));
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.HOLLOW, s);
+        }
+
+        pm.retrieveAll(l);
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            PCState s = getStateManager(iter.next(), pm).getPCState();
+            assertEquals(PCState.PNONTRANS, s);
+        }
+        pm.evictAll(pm.createExtent(RuntimeTest1.class, false));
+        for (Iterator iter = l.iterator(); iter.hasNext();) {
+            Object o = iter.next();
+            if (o.getClass() == RuntimeTest1.class) {
+                PCState s = getStateManager(o, pm).getPCState();
+                assertEquals(PCState.HOLLOW, s);
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManagerFactoryImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManagerFactoryImpl.java
index 42838ef..72cc7da 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManagerFactoryImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistenceManagerFactoryImpl.java
@@ -1,229 +1,229 @@
-/*
- * TestOpenJPAEntityManagerFactoryImpl.java
- *
- * Created on October 13, 2006, 10:54 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Map;
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.event.LoadListener;
-import org.apache.openjpa.kernel.AbstractBrokerFactory;
-import org.apache.openjpa.kernel.BrokerImpl;
-import org.apache.openjpa.kernel.StoreManager;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-public class TestPersistenceManagerFactoryImpl extends BaseKernelTest {
-
-    private OpenJPAConfiguration _conf = null;
-
-    /**
-     * Creates a new instance of TestOpenJPAEntityManagerFactoryImpl
-     */
-    public TestPersistenceManagerFactoryImpl() {
-    }
-
-    public TestPersistenceManagerFactoryImpl(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        _conf = new OpenJPAConfigurationImpl();
-        _conf.setConnection2UserName("user");
-        _conf.setConnection2Password("pass");
-        _conf.setConnection2URL("url");
-    }
-
-    /**
-     * Test that configuration is frozen after retrieving a factory.
-     *
-     * This test case is for kodo persistencemanagerfactories and not openjpaentitymanagers.
-     * therefore its been commented out. 
-     * FIX ME: aokeke
-     */
-/*    public void testConfigurationFreeze() 
-    {
-        OpenJPAEntityManagerFactory pmf = getOpenJPAEntityManagerFactory(_conf.toProperties(false));
-        assertEquals("user", pmf.getConfiguration().getConnection2UserName());
-        assertEquals("url", pmf.getConfiguration().getConnection2URL());
-        try 
-        {
-            pmf.getConfiguration().setConnection2URL("url2");
-            fail("Allowed configuration change.");
-        } 
-        catch (Exception e) 
-        {
-        }
-    }*/
-
-    /**
-     * Test that persistence manager factories are being pooled.
-     *
-     * This test case is for kodo persistencemanagerfactories. It doesnt apply to 
-     * openjpaentitymanagerfactories therefore it will be commented out.
-     * FIX ME: aokeke
-     */
-    /*public void testFactoryPooling() {
-        Properties props = new Properties();
-        props.putAll(_conf.toProperties(false));
-        OpenJPAEntityManagerFactory pmf1 = getOpenJPAEntityManagerFactory(props);
-        
-        props = new Properties();
-        props.putAll(_conf.toProperties(false));
-        OpenJPAEntityManagerFactory pmf2 = getOpenJPAEntityManagerFactory(props);
-        
-        props = new Properties();
-        props.putAll(_conf.toProperties(false));
-        OpenJPAEntityManagerFactory pmf3 = getOpenJPAEntityManagerFactory(props);
-        
-        _conf.setConnectionURL("url2");
-        props = new Properties();
-        props.putAll(_conf.toProperties(false));
-        OpenJPAEntityManagerFactory pmf4 = getOpenJPAEntityManagerFactory
-                (_conf.toProperties(false));
-        
-        props = new Properties();
-        props.putAll(_conf.toProperties(false));
-        OpenJPAEntityManagerFactory pmf5 = getOpenJPAEntityManagerFactory(_conf.toProperties(false));
-        
-        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) == JPAFacadeHelper.toBrokerFactory(pmf2));
-        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) == JPAFacadeHelper.toBrokerFactory(pmf3));
-        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) != JPAFacadeHelper.toBrokerFactory(pmf4));
-        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf4) == JPAFacadeHelper.toBrokerFactory(pmf5));
-    }*/
-
-    /**
-     * Tests that lifecycle listeners are transferred from factory to
-     * persistence managers.
-     */
-    public void testFactoryLifecycleListeners() {
-        OpenJPAEntityManagerFactory pmf =
-            (OpenJPAEntityManagerFactory) getEmf();
-        OpenJPAEntityManagerFactorySPI pmfSPI =
-            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(pmf));
-
-        //FIXME jthomas        
-        LoadListener listener = new LoadListener() {
-            public void afterLoad(LifecycleEvent ev) {
-            }
-
-            public void afterRefresh(LifecycleEvent ev) {
-            }
-        };
-
-        pmfSPI
-            .addLifecycleListener(listener, new Class[]{ RuntimeTest4.class });
-
-        try {
-            BrokerImpl broker = (BrokerImpl) JPAFacadeHelper.toBroker
-                (pmf.createEntityManager());
-            MetaDataRepository repos = broker.getConfiguration().
-                getMetaDataRepositoryInstance();
-            assertTrue("no listeners defined added to Runtimetest4",
-                broker.getLifecycleEventManager().hasLoadListeners(
-                    new RuntimeTest4("foo"),
-                    repos.getMetaData(RuntimeTest4.class, null, true)));
-            assertFalse("there should be listeners def for runtimetest1",
-                broker.getLifecycleEventManager().hasLoadListeners
-                    (new RuntimeTest1(), repos.getMetaData
-                        (RuntimeTest1.class, null, true)));
-            broker.close();
-        } finally {
-            pmfSPI.removeLifecycleListener(listener);
-        }
-    }
-
-    /**
-     * Tests that pooling is maintained on deserialization.
-     * This test case is for kodo persistencemanagerfactories. It doesnt apply to 
-     * openjpaentitymanagerfactories therefore it will be commented out.
-     */
-    /*
-    public void testFactorySerialization()
-    throws Exception {
-        OpenJPAEntityManagerFactory pmf1 = getOpenJPAEntityManagerFactory(_conf.toProperties(false));
-        Object pmf2 = roundtrip(pmf1, true);
-        assertEquals(pmf1, pmf2);
-        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) ==
-                JPAFacadeHelper.toBrokerFactory((OpenJPAEntityManagerFactory) pmf2));
-    }
-    */
-
-    /**
-     * Tests that the <code>Platform</code> property is set by the
-     * concrete PMF implementation.
-     */
-    public void testPlatform() {
-        OpenJPAEntityManagerFactory pmf =
-            (OpenJPAEntityManagerFactory) getEmf();
-        assertNotNull(pmf.getProperties().getProperty("Platform"));
-    }
-
-    protected OpenJPAEntityManagerFactory getEmf(Map props) {
-        props.put("openjpa.BrokerFactory", BrokerFactoryTest.class.getName());
-        return (OpenJPAEntityManagerFactory) super.getEmf(props);
-    }
-
-    public static class BrokerFactoryTest extends AbstractBrokerFactory {
-
-        // standard brokerfactory getter implemented by subclasses
-        public static synchronized BrokerFactoryTest getInstance(
-            ConfigurationProvider cp) {
-            Object key = toPoolKey(cp.getProperties());
-            BrokerFactoryTest factory =
-                (BrokerFactoryTest) getPooledFactoryForKey(key);
-            if (factory != null)
-                return factory;
-
-            factory = newInstance(cp);
-            pool(key, factory);
-            return factory;
-        }
-
-        // standard brokerfactory getter implemented by subclasses
-        public static BrokerFactoryTest newInstance(ConfigurationProvider cp) {
-            OpenJPAConfigurationImpl conf = new OpenJPAConfigurationImpl();
-            cp.setInto(conf);
-            return new BrokerFactoryTest(conf);
-        }
-
-        protected BrokerFactoryTest(OpenJPAConfiguration conf) {
-            super(conf);
-        }
-
-        protected StoreManager newStoreManager() {
-            return null;
-        }
-    }
-}
+/*
+ * TestOpenJPAEntityManagerFactoryImpl.java
+ *
+ * Created on October 13, 2006, 10:54 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Map;
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.LoadListener;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
+import org.apache.openjpa.kernel.BrokerImpl;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+public class TestPersistenceManagerFactoryImpl extends BaseKernelTest {
+
+    private OpenJPAConfiguration _conf = null;
+
+    /**
+     * Creates a new instance of TestOpenJPAEntityManagerFactoryImpl
+     */
+    public TestPersistenceManagerFactoryImpl() {
+    }
+
+    public TestPersistenceManagerFactoryImpl(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        _conf = new OpenJPAConfigurationImpl();
+        _conf.setConnection2UserName("user");
+        _conf.setConnection2Password("pass");
+        _conf.setConnection2URL("url");
+    }
+
+    /**
+     * Test that configuration is frozen after retrieving a factory.
+     *
+     * This test case is for kodo persistencemanagerfactories and not openjpaentitymanagers.
+     * therefore its been commented out. 
+     * FIX ME: aokeke
+     */
+/*    public void testConfigurationFreeze() 
+    {
+        OpenJPAEntityManagerFactory pmf = getOpenJPAEntityManagerFactory(_conf.toProperties(false));
+        assertEquals("user", pmf.getConfiguration().getConnection2UserName());
+        assertEquals("url", pmf.getConfiguration().getConnection2URL());
+        try 
+        {
+            pmf.getConfiguration().setConnection2URL("url2");
+            fail("Allowed configuration change.");
+        } 
+        catch (Exception e) 
+        {
+        }
+    }*/
+
+    /**
+     * Test that persistence manager factories are being pooled.
+     *
+     * This test case is for kodo persistencemanagerfactories. It doesnt apply to 
+     * openjpaentitymanagerfactories therefore it will be commented out.
+     * FIX ME: aokeke
+     */
+    /*public void testFactoryPooling() {
+        Properties props = new Properties();
+        props.putAll(_conf.toProperties(false));
+        OpenJPAEntityManagerFactory pmf1 = getOpenJPAEntityManagerFactory(props);
+        
+        props = new Properties();
+        props.putAll(_conf.toProperties(false));
+        OpenJPAEntityManagerFactory pmf2 = getOpenJPAEntityManagerFactory(props);
+        
+        props = new Properties();
+        props.putAll(_conf.toProperties(false));
+        OpenJPAEntityManagerFactory pmf3 = getOpenJPAEntityManagerFactory(props);
+        
+        _conf.setConnectionURL("url2");
+        props = new Properties();
+        props.putAll(_conf.toProperties(false));
+        OpenJPAEntityManagerFactory pmf4 = getOpenJPAEntityManagerFactory
+                (_conf.toProperties(false));
+        
+        props = new Properties();
+        props.putAll(_conf.toProperties(false));
+        OpenJPAEntityManagerFactory pmf5 = getOpenJPAEntityManagerFactory(_conf.toProperties(false));
+        
+        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) == JPAFacadeHelper.toBrokerFactory(pmf2));
+        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) == JPAFacadeHelper.toBrokerFactory(pmf3));
+        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) != JPAFacadeHelper.toBrokerFactory(pmf4));
+        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf4) == JPAFacadeHelper.toBrokerFactory(pmf5));
+    }*/
+
+    /**
+     * Tests that lifecycle listeners are transferred from factory to
+     * persistence managers.
+     */
+    public void testFactoryLifecycleListeners() {
+        OpenJPAEntityManagerFactory pmf =
+            (OpenJPAEntityManagerFactory) getEmf();
+        OpenJPAEntityManagerFactorySPI pmfSPI =
+            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(pmf));
+
+        //FIXME jthomas        
+        LoadListener listener = new LoadListener() {
+            public void afterLoad(LifecycleEvent ev) {
+            }
+
+            public void afterRefresh(LifecycleEvent ev) {
+            }
+        };
+
+        pmfSPI
+            .addLifecycleListener(listener, new Class[]{ RuntimeTest4.class });
+
+        try {
+            BrokerImpl broker = (BrokerImpl) JPAFacadeHelper.toBroker
+                (pmf.createEntityManager());
+            MetaDataRepository repos = broker.getConfiguration().
+                getMetaDataRepositoryInstance();
+            assertTrue("no listeners defined added to Runtimetest4",
+                broker.getLifecycleEventManager().hasLoadListeners(
+                    new RuntimeTest4("foo"),
+                    repos.getMetaData(RuntimeTest4.class, null, true)));
+            assertFalse("there should be listeners def for runtimetest1",
+                broker.getLifecycleEventManager().hasLoadListeners
+                    (new RuntimeTest1(), repos.getMetaData
+                        (RuntimeTest1.class, null, true)));
+            broker.close();
+        } finally {
+            pmfSPI.removeLifecycleListener(listener);
+        }
+    }
+
+    /**
+     * Tests that pooling is maintained on deserialization.
+     * This test case is for kodo persistencemanagerfactories. It doesnt apply to 
+     * openjpaentitymanagerfactories therefore it will be commented out.
+     */
+    /*
+    public void testFactorySerialization()
+    throws Exception {
+        OpenJPAEntityManagerFactory pmf1 = getOpenJPAEntityManagerFactory(_conf.toProperties(false));
+        Object pmf2 = roundtrip(pmf1, true);
+        assertEquals(pmf1, pmf2);
+        assertTrue(JPAFacadeHelper.toBrokerFactory(pmf1) ==
+                JPAFacadeHelper.toBrokerFactory((OpenJPAEntityManagerFactory) pmf2));
+    }
+    */
+
+    /**
+     * Tests that the <code>Platform</code> property is set by the
+     * concrete PMF implementation.
+     */
+    public void testPlatform() {
+        OpenJPAEntityManagerFactory pmf =
+            (OpenJPAEntityManagerFactory) getEmf();
+        assertNotNull(pmf.getProperties().getProperty("Platform"));
+    }
+
+    protected OpenJPAEntityManagerFactory getEmf(Map props) {
+        props.put("openjpa.BrokerFactory", BrokerFactoryTest.class.getName());
+        return (OpenJPAEntityManagerFactory) super.getEmf(props);
+    }
+
+    public static class BrokerFactoryTest extends AbstractBrokerFactory {
+
+        // standard brokerfactory getter implemented by subclasses
+        public static synchronized BrokerFactoryTest getInstance(
+            ConfigurationProvider cp) {
+            Object key = toPoolKey(cp.getProperties());
+            BrokerFactoryTest factory =
+                (BrokerFactoryTest) getPooledFactoryForKey(key);
+            if (factory != null)
+                return factory;
+
+            factory = newInstance(cp);
+            pool(key, factory);
+            return factory;
+        }
+
+        // standard brokerfactory getter implemented by subclasses
+        public static BrokerFactoryTest newInstance(ConfigurationProvider cp) {
+            OpenJPAConfigurationImpl conf = new OpenJPAConfigurationImpl();
+            cp.setInto(conf);
+            return new BrokerFactoryTest(conf);
+        }
+
+        protected BrokerFactoryTest(OpenJPAConfiguration conf) {
+            super(conf);
+        }
+
+        protected StoreManager newStoreManager() {
+            return null;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistentMaps.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistentMaps.java
index 217ed99..c214830 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistentMaps.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPersistentMaps.java
@@ -1,352 +1,352 @@
-/*
- * TestPersistentMaps.java
- *
- * Created on October 13, 2006, 1:54 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.MapElementPC;
-import org.apache.openjpa.persistence.kernel.common.apps.MapElementPCChild;
-import org.apache.openjpa.persistence.kernel.common.apps.PersistentMapHolder;
-
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestPersistentMaps extends BaseKernelTest {
-
-    private static final String JDOQL = "javax.jdo.query.JDOQL";
-
-    /**
-     * Creates a new instance of TestPersistentMaps
-     */
-    public TestPersistentMaps() {
-    }
-
-    public TestPersistentMaps(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(PersistentMapHolder.class);
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        pm.persist(new PersistentMapHolder());
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    private PersistentMapHolder getHolder(OpenJPAEntityManager pm) {
-        Extent e = pm.createExtent(PersistentMapHolder.class, true);
-        assertSize(1, ((Collection) e.list()));
-        return (PersistentMapHolder) e.iterator().next();
-    }
-
-    private Object keyInstance(Class type) throws Exception {
-        if (type.getName().equals(String.class.getName()))
-            return randomString();
-        else
-            return type.newInstance();
-    }
-
-    private void testMap(int num, String name, Class keyClass, Class valueClass)
-        throws Exception {
-        OpenJPAEntityManager srcpm = getPM(true, true);
-        startTx(srcpm);
-
-        PersistentMapHolder holder = getHolder(srcpm);
-        Map map = holder.getNamedMap(name);
-        Map internalMap = new HashMap();
-
-        for (int i = 0; i < num; i++) {
-            Object key = keyInstance(keyClass);
-            Object value = keyInstance(valueClass);
-            map.put(key, value);
-            internalMap.put(key, value);
-
-            assertEquals(map.get(key), internalMap.get(key));
-        }
-        endTx(srcpm);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-//        holder = getHolder(pm);
-        map = holder.getNamedMap(name);
-        for (Iterator i = internalMap.keySet().iterator(); i.hasNext();) {
-            Object k = i.next();
-            assertEquals(map.get(k), internalMap.get(k));
-        }
-        endTx(pm);
-        endEm(pm);
-
-        String selectWhere =
-            "select from " + PersistentMapHolder.class.getName() + " where ";
-
-        pm = getPM();
-        startTx(pm);
-        for (Iterator i = internalMap.keySet().iterator(); i.hasNext();) {
-
-            Object param = i.next();
-            if (pm.isPersistent(param))
-                param = pm.find(param.getClass(), pm.getObjectId(param));
-
-            Object val = internalMap.get(param);
-            if (pm.isPersistent(val))
-                val = pm.find(val.getClass(), pm.getObjectId(val));
-
-            OpenJPAQuery q;
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + name + ".containsKey(:param)");
-            q.setParameter("param", param);
-            assertSize(1, q.getResultList());
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + name + ".containsValue(:value)");
-            q.setParameter("value", val);
-            assertSize(1, q.getResultList());
-
-            q = pm.createQuery(JDOQL, selectWhere + name + ".containsValue(" +
-                name + ".get(:param))");
-            q.setParameter("param", param);
-            assertSize(1, q.getResultList());
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + name + ".get(:param) != null");
-            q.setParameter("param", param);
-            assertSize(1, q.getResultList());
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + name + ".get(:param) == :value");
-            q.setParameter("param", param);
-            q.setParameter("value", val);
-            assertSize(1, q.getResultList());
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + name + ".get(:param) != :value");
-            q.setParameter("param", param);
-            q.setParameter("value", val);
-            assertSize(0, q.getResultList());
-        }
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        startTx(pm);
-        for (Iterator i = internalMap.keySet().iterator(); i.hasNext();) {
-            Object param = i.next();
-            if (pm.isPersistent(param))
-                param = pm.find(param.getClass(), pm.getObjectId(param));
-
-            List getQueries = new ArrayList(Arrays.asList(new String[]{
-                selectWhere + name + ".get(:param) != null",
-                selectWhere + name + ".get(:param) == " + name + ".get(:param)",
-                selectWhere + "!(" + name + ".get(:param) == null)",
-                selectWhere + "!(" + name + ".get(:param) != " + name +
-                    ".get(:param))",
-            }));
-
-            for (Iterator qi = getQueries.iterator(); qi.hasNext();) {
-                String query = (String) qi.next();
-                if (valueClass == String.class)
-                    query += " order by " + name + ".get(:param) desc";
-                OpenJPAQuery q = pm.createQuery(JDOQL, query);
-                q.setParameter("param", param);
-                assertSize(1, q.getResultList());
-            }
-        }
-        endTx(pm);
-        endEm(pm);
-
-        endEm(srcpm);
-    }
-
-    public void testPCKeyStringValue()
-        throws Exception {
-        testMap(5, "testPCKeyStringValue",
-            MapElementPC.class, String.class);
-    }
-
-    public void testStringKeyPCValue()
-        throws Exception {
-        testMap(6, "testStringKeyPCValue",
-            String.class, MapElementPC.class);
-    }
-
-    public void testPCKeyPCValue()
-        throws Exception {
-        testMap(7, "testPCKeyPCValue",
-            MapElementPC.class, MapElementPC.class);
-    }
-
-    public void testPCSubKeyStringValue()
-        throws Exception {
-        testMap(8, "testPCSubKeyStringValue",
-            MapElementPCChild.class, String.class);
-    }
-
-    public void testStringKeyPCSubValue()
-        throws Exception {
-        testMap(9, "testStringKeyPCSubValue",
-            String.class, MapElementPCChild.class);
-    }
-
-    public void testPCSubKeyPCValue()
-        throws Exception {
-        testMap(10, "testPCSubKeyPCValue",
-            MapElementPCChild.class, MapElementPC.class);
-    }
-
-    public void testPCSubKeyPCSubValue()
-        throws Exception {
-        testMap(11, "testPCSubKeyPCSubValue",
-            MapElementPCChild.class, MapElementPCChild.class);
-    }
-
-    public void testPCKeyPCSubValue()
-        throws Exception {
-        testMap(12, "testPCKeyPCSubValue",
-            MapElementPC.class, MapElementPCChild.class);
-    }
-
-    public void testPCIntfKeyStringValue()
-        throws Exception {
-        testMap(13, "testPCIntfKeyStringValue",
-            MapElementPC.class, String.class);
-    }
-
-    public void testStringKeyPCIntfValue()
-        throws Exception {
-        testMap(14, "testStringKeyPCIntfValue",
-            String.class, MapElementPC.class);
-    }
-
-    public void testPCIntfKeyPCValue()
-        throws Exception {
-        testMap(15, "testPCIntfKeyPCValue",
-            MapElementPC.class, MapElementPC.class);
-    }
-
-    /**
-     * Test querying maps when there are multiple holder instances that
-     * have maps with the same key.
-     */
-    public void testQueryMultipleMaps() throws Exception {
-        deleteAll(PersistentMapHolder.class);
-
-        String mapName = "testStringKeyPCValue";
-
-        String[] mapNames = new String[]{
-            "testPCKeyStringValue",
-            // "testStringKeyPCValue",
-            "testPCKeyPCValue",
-            "testPCSubKeyStringValue",
-            "testStringKeyPCSubValue",
-            "testPCSubKeyPCValue",
-            "testPCSubKeyPCSubValue",
-            "testPCKeyPCSubValue",
-            "testPCIntfKeyStringValue",
-            "testStringKeyPCIntfValue",
-            "testPCIntfKeyPCValue",
-        };
-
-        OpenJPAEntityManager pm;
-
-        pm = getPM();
-        startTx(pm);
-
-        MapElementPC pc = new MapElementPC();
-        pc.setElementData("foo");
-
-        int max = 5;
-
-        for (int i = 0; i < max; i++) {
-            PersistentMapHolder holder = new PersistentMapHolder();
-            for (int j = 0; j < i; j++) {
-                holder.getNamedMap(mapName).put("key" + j, pc);
-            }
-            pm.persist(holder);
-        }
-
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = (MapElementPC) pm.find(MapElementPC.class, pm.getObjectId(pc));
-        for (int i = 0; i < max; i++) {
-            OpenJPAQuery q;
-
-            String key = "key" + i;
-            String selectWhere = "select from " +
-                PersistentMapHolder.class.getName() + " where ";
-            q = pm.createQuery(JDOQL,
-                selectWhere + mapName + ".containsKey(:key)");
-            q.setParameter("key", key);
-            assertSize(max - i - 1, q.getResultList());
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + mapName + ".get(:key) == :val");
-            q.setParameter("key", key);
-            q.setParameter("val", pc);
-            assertSize(max - i - 1, q.getResultList());
-
-            q = pm.createQuery(JDOQL,
-                selectWhere + "testPCKeyStringValue.isEmpty() && "
-                    + mapName + ".get(:key) == :val");
-            q.setParameter("key", key);
-            q.setParameter("val", pc);
-            assertSize(max - i - 1, q.getResultList());
-
-            // now try to execute queries against multiple other
-            // map instances, so we can make sure the joins are robust
-            for (int j = 0; j < mapNames.length; j++) {
-                StringBuffer query = new StringBuffer(selectWhere);
-
-                for (int k = 0; k < j; k++) {
-                    query.append(mapNames[k] + ".isEmpty() && ");
-                }
-
-                q = pm.createQuery(JDOQL,
-                    query + mapName + ".get(:key) == :val");
-                q.setParameter("key", key);
-                q.setParameter("val", pc);
-                assertSize(max - i - 1, q.getResultList());
-            }
-        }
-        endEm(pm);
-    }
-}
+/*
+ * TestPersistentMaps.java
+ *
+ * Created on October 13, 2006, 1:54 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.MapElementPC;
+import org.apache.openjpa.persistence.kernel.common.apps.MapElementPCChild;
+import org.apache.openjpa.persistence.kernel.common.apps.PersistentMapHolder;
+
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestPersistentMaps extends BaseKernelTest {
+
+    private static final String JDOQL = "javax.jdo.query.JDOQL";
+
+    /**
+     * Creates a new instance of TestPersistentMaps
+     */
+    public TestPersistentMaps() {
+    }
+
+    public TestPersistentMaps(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(PersistentMapHolder.class);
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        pm.persist(new PersistentMapHolder());
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    private PersistentMapHolder getHolder(OpenJPAEntityManager pm) {
+        Extent e = pm.createExtent(PersistentMapHolder.class, true);
+        assertSize(1, ((Collection) e.list()));
+        return (PersistentMapHolder) e.iterator().next();
+    }
+
+    private Object keyInstance(Class type) throws Exception {
+        if (type.getName().equals(String.class.getName()))
+            return randomString();
+        else
+            return type.newInstance();
+    }
+
+    private void testMap(int num, String name, Class keyClass, Class valueClass)
+        throws Exception {
+        OpenJPAEntityManager srcpm = getPM(true, true);
+        startTx(srcpm);
+
+        PersistentMapHolder holder = getHolder(srcpm);
+        Map map = holder.getNamedMap(name);
+        Map internalMap = new HashMap();
+
+        for (int i = 0; i < num; i++) {
+            Object key = keyInstance(keyClass);
+            Object value = keyInstance(valueClass);
+            map.put(key, value);
+            internalMap.put(key, value);
+
+            assertEquals(map.get(key), internalMap.get(key));
+        }
+        endTx(srcpm);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+//        holder = getHolder(pm);
+        map = holder.getNamedMap(name);
+        for (Iterator i = internalMap.keySet().iterator(); i.hasNext();) {
+            Object k = i.next();
+            assertEquals(map.get(k), internalMap.get(k));
+        }
+        endTx(pm);
+        endEm(pm);
+
+        String selectWhere =
+            "select from " + PersistentMapHolder.class.getName() + " where ";
+
+        pm = getPM();
+        startTx(pm);
+        for (Iterator i = internalMap.keySet().iterator(); i.hasNext();) {
+
+            Object param = i.next();
+            if (pm.isPersistent(param))
+                param = pm.find(param.getClass(), pm.getObjectId(param));
+
+            Object val = internalMap.get(param);
+            if (pm.isPersistent(val))
+                val = pm.find(val.getClass(), pm.getObjectId(val));
+
+            OpenJPAQuery q;
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + name + ".containsKey(:param)");
+            q.setParameter("param", param);
+            assertSize(1, q.getResultList());
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + name + ".containsValue(:value)");
+            q.setParameter("value", val);
+            assertSize(1, q.getResultList());
+
+            q = pm.createQuery(JDOQL, selectWhere + name + ".containsValue(" +
+                name + ".get(:param))");
+            q.setParameter("param", param);
+            assertSize(1, q.getResultList());
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + name + ".get(:param) != null");
+            q.setParameter("param", param);
+            assertSize(1, q.getResultList());
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + name + ".get(:param) == :value");
+            q.setParameter("param", param);
+            q.setParameter("value", val);
+            assertSize(1, q.getResultList());
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + name + ".get(:param) != :value");
+            q.setParameter("param", param);
+            q.setParameter("value", val);
+            assertSize(0, q.getResultList());
+        }
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        startTx(pm);
+        for (Iterator i = internalMap.keySet().iterator(); i.hasNext();) {
+            Object param = i.next();
+            if (pm.isPersistent(param))
+                param = pm.find(param.getClass(), pm.getObjectId(param));
+
+            List getQueries = new ArrayList(Arrays.asList(new String[]{
+                selectWhere + name + ".get(:param) != null",
+                selectWhere + name + ".get(:param) == " + name + ".get(:param)",
+                selectWhere + "!(" + name + ".get(:param) == null)",
+                selectWhere + "!(" + name + ".get(:param) != " + name +
+                    ".get(:param))",
+            }));
+
+            for (Iterator qi = getQueries.iterator(); qi.hasNext();) {
+                String query = (String) qi.next();
+                if (valueClass == String.class)
+                    query += " order by " + name + ".get(:param) desc";
+                OpenJPAQuery q = pm.createQuery(JDOQL, query);
+                q.setParameter("param", param);
+                assertSize(1, q.getResultList());
+            }
+        }
+        endTx(pm);
+        endEm(pm);
+
+        endEm(srcpm);
+    }
+
+    public void testPCKeyStringValue()
+        throws Exception {
+        testMap(5, "testPCKeyStringValue",
+            MapElementPC.class, String.class);
+    }
+
+    public void testStringKeyPCValue()
+        throws Exception {
+        testMap(6, "testStringKeyPCValue",
+            String.class, MapElementPC.class);
+    }
+
+    public void testPCKeyPCValue()
+        throws Exception {
+        testMap(7, "testPCKeyPCValue",
+            MapElementPC.class, MapElementPC.class);
+    }
+
+    public void testPCSubKeyStringValue()
+        throws Exception {
+        testMap(8, "testPCSubKeyStringValue",
+            MapElementPCChild.class, String.class);
+    }
+
+    public void testStringKeyPCSubValue()
+        throws Exception {
+        testMap(9, "testStringKeyPCSubValue",
+            String.class, MapElementPCChild.class);
+    }
+
+    public void testPCSubKeyPCValue()
+        throws Exception {
+        testMap(10, "testPCSubKeyPCValue",
+            MapElementPCChild.class, MapElementPC.class);
+    }
+
+    public void testPCSubKeyPCSubValue()
+        throws Exception {
+        testMap(11, "testPCSubKeyPCSubValue",
+            MapElementPCChild.class, MapElementPCChild.class);
+    }
+
+    public void testPCKeyPCSubValue()
+        throws Exception {
+        testMap(12, "testPCKeyPCSubValue",
+            MapElementPC.class, MapElementPCChild.class);
+    }
+
+    public void testPCIntfKeyStringValue()
+        throws Exception {
+        testMap(13, "testPCIntfKeyStringValue",
+            MapElementPC.class, String.class);
+    }
+
+    public void testStringKeyPCIntfValue()
+        throws Exception {
+        testMap(14, "testStringKeyPCIntfValue",
+            String.class, MapElementPC.class);
+    }
+
+    public void testPCIntfKeyPCValue()
+        throws Exception {
+        testMap(15, "testPCIntfKeyPCValue",
+            MapElementPC.class, MapElementPC.class);
+    }
+
+    /**
+     * Test querying maps when there are multiple holder instances that
+     * have maps with the same key.
+     */
+    public void testQueryMultipleMaps() throws Exception {
+        deleteAll(PersistentMapHolder.class);
+
+        String mapName = "testStringKeyPCValue";
+
+        String[] mapNames = new String[]{
+            "testPCKeyStringValue",
+            // "testStringKeyPCValue",
+            "testPCKeyPCValue",
+            "testPCSubKeyStringValue",
+            "testStringKeyPCSubValue",
+            "testPCSubKeyPCValue",
+            "testPCSubKeyPCSubValue",
+            "testPCKeyPCSubValue",
+            "testPCIntfKeyStringValue",
+            "testStringKeyPCIntfValue",
+            "testPCIntfKeyPCValue",
+        };
+
+        OpenJPAEntityManager pm;
+
+        pm = getPM();
+        startTx(pm);
+
+        MapElementPC pc = new MapElementPC();
+        pc.setElementData("foo");
+
+        int max = 5;
+
+        for (int i = 0; i < max; i++) {
+            PersistentMapHolder holder = new PersistentMapHolder();
+            for (int j = 0; j < i; j++) {
+                holder.getNamedMap(mapName).put("key" + j, pc);
+            }
+            pm.persist(holder);
+        }
+
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = (MapElementPC) pm.find(MapElementPC.class, pm.getObjectId(pc));
+        for (int i = 0; i < max; i++) {
+            OpenJPAQuery q;
+
+            String key = "key" + i;
+            String selectWhere = "select from " +
+                PersistentMapHolder.class.getName() + " where ";
+            q = pm.createQuery(JDOQL,
+                selectWhere + mapName + ".containsKey(:key)");
+            q.setParameter("key", key);
+            assertSize(max - i - 1, q.getResultList());
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + mapName + ".get(:key) == :val");
+            q.setParameter("key", key);
+            q.setParameter("val", pc);
+            assertSize(max - i - 1, q.getResultList());
+
+            q = pm.createQuery(JDOQL,
+                selectWhere + "testPCKeyStringValue.isEmpty() && "
+                    + mapName + ".get(:key) == :val");
+            q.setParameter("key", key);
+            q.setParameter("val", pc);
+            assertSize(max - i - 1, q.getResultList());
+
+            // now try to execute queries against multiple other
+            // map instances, so we can make sure the joins are robust
+            for (int j = 0; j < mapNames.length; j++) {
+                StringBuffer query = new StringBuffer(selectWhere);
+
+                for (int k = 0; k < j; k++) {
+                    query.append(mapNames[k] + ".isEmpty() && ");
+                }
+
+                q = pm.createQuery(JDOQL,
+                    query + mapName + ".get(:key) == :val");
+                q.setParameter("key", key);
+                q.setParameter("val", pc);
+                assertSize(max - i - 1, q.getResultList());
+            }
+        }
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java
index ab7dcc2..5c24b49 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPessimisticLocking.java
@@ -1,274 +1,274 @@
-/*
- * TestPessimisticLocking.java
- *
- * Created on October 13, 2006, 3:17 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.HashMap;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import java.util.concurrent.locks.ReentrantLock;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.jdbc.FetchMode;
-import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
-
-public class TestPessimisticLocking extends BaseKernelTest {
-
-    private Object _id = null;
-    private int _bugCount = 0;
-    private OpenJPAEntityManagerFactory _factory = null;
-
-    public TestPessimisticLocking(String name) {
-        super(name);
-    }
-
-    /**
-     * Creates a new instance of TestPessimisticLocking
-     */
-    public TestPessimisticLocking() {
-    }
-
-    protected boolean skipTest() {
-        // pointbase doesn't really lock
-        if (getCurrentPlatform() == AbstractTestCase.Platform.POINTBASE)
-            return true;
-
-        if (getConfiguration() instanceof JDBCConfiguration) {
-            JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
-            return !conf.getDBDictionaryInstance().supportsSelectForUpdate;
-        }
-        return false;
-    }
-
-    /**
-     * Use a locking persistence manager with subclass fetch mode to set to
-     * "none" to avoid subclass joins.
-     */
-    protected OpenJPAEntityManager getLockingPM() {
-        OpenJPAEntityManager pm = _factory.createEntityManager();
-        ((JDBCFetchPlan) pm.getFetchPlan())
-            .setSubclassFetchMode(FetchMode.NONE);
-        return pm;
-    }
-
-    public void setUp() throws Exception {
-        deleteAll(RuntimeTest1.class);
-
-        Map propsMap = new HashMap();
-        propsMap.put("openjpa.LockManager", "pessimistic");
-        _factory = (OpenJPAEntityManagerFactory) getEmf(propsMap);
-
-        OpenJPAEntityManager pm = getLockingPM();
-        startTx(pm);
-
-        RuntimeTest1 a = new RuntimeTest1("name", 0);
-        pm.persist(a);
-        _id = pm.getObjectId(a);
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void tearDown() {
-        try {
-            if (_factory != null)
-                _factory.close();
-        } catch (Exception e) {
-        }
-    }
-
-    /**
-     * Test that pessimistic locking is working in the data store.
-     */
-    public void testPessimisticLocking() throws Throwable {
-        pessimisticLockingTest(false);
-    }
-
-    /**
-     * Test that the test case itself is working be using a ReentrantLock. This
-     * test will validate that the test case itself is working correctly, not
-     * that the datastore's pessimistic locking is working.
-     */
-    public void testPessimisticLockingInternal() throws Throwable {
-        pessimisticLockingTest(true);
-    }
-
-    /**
-     * Test that pessimistic locking is working by attempting to update the same
-     * object in the data store.
-     *
-     * @param useReentrantLock true if we want to synchronize on a lock instead of relying on
-     * the data store (used for validating the test case).
-     */
-    public void pessimisticLockingTest(boolean useReentrantLock)
-        throws Throwable {
-        long timeout = System.currentTimeMillis() + (60 * 5 * 1000);
-
-        ReentrantLock lock = null;
-        if (useReentrantLock)
-            lock = new ReentrantLock();
-
-        TestThread t1 = new TestThread(lock);
-        TestThread t2 = new TestThread(lock);
-        t1.start();
-        t2.start();
-
-        getLog().trace("started thread");
-
-        // wait for threads to die or timeout
-        while ((t1.isAlive() || t2.isAlive())
-            && System.currentTimeMillis() < timeout) {
-            Thread.sleep(1000);
-            getLog().trace(
-                "thread waiting for completion ("
-                    + (timeout - System.currentTimeMillis())
-                    + " ms left)");
-        }
-
-        getLog().trace("checking if thread is alive");
-        System.out.flush();
-
-        if (t1.isAlive() || t2.isAlive()) {
-            getLog().trace("thread is still alive");
-            System.out.flush();
-
-            // do out best to clean them up
-            try {
-                t1.interrupt();
-            }
-            catch (Exception e) {
-            }
-            try {
-                t2.interrupt();
-            }
-            catch (Exception e) {
-            }
-
-            throw new Exception("Thread did not complete after timeout ("
-                + timeout + "): possible deadlock");
-        }
-
-        getLog().trace("checking exception for t1");
-        if (t1.exception != null)
-            throw t1.exception;
-
-        getLog().trace("checking exception for t2");
-        if (t2.exception != null)
-            throw t2.exception;
-
-        getLog().trace("verifying pessimistic locking worked...");
-        OpenJPAEntityManager pm = getLockingPM();
-        RuntimeTest1 a = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
-        assertEquals(20 - _bugCount, a.getIntField1());
-        getLog().trace("closing pm");
-        endEm(pm);
-        getLog().trace("done");
-    }
-
-    /**
-     * Update thread that tries to increment an int field.
-     *
-     * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
-     */
-    private class TestThread extends Thread {
-
-        private OpenJPAEntityManager _pm = getLockingPM();
-
-        public Exception exception = null;
-
-        private final ReentrantLock _lock;
-
-        /**
-         * Constructor
-         *
-         * @param lock the ReentrantLock we should use, or null to rely on
-         * pessimistic locking in the data store.
-         */
-        public TestThread(ReentrantLock lock) {
-            this._lock = lock;
-        }
-
-        public synchronized void run() {
-            getLog().trace(
-                Thread.currentThread().getName()
-                    + ": starting update thread");
-            try {
-                for (int i = 0; i < 10; i++) {
-                    if (_lock != null)
-                        _lock.lock();
-
-                    try {
-                        _pm.setOptimistic(false);
-                        startTx(_pm);
-                        RuntimeTest1 a = (RuntimeTest1) _pm.find(
-                            RuntimeTest1.class, _id);
-                        getLog().trace(
-                            Thread.currentThread().getName()
-                                + ": obtained and locked: " + a);
-                        yield();
-                        super.wait(50);
-                        getLog().trace(
-                            Thread.currentThread().getName()
-                                + ": updating age from "
-                                + a.getIntField1());
-                        a.setIntField1(a.getIntField1() + 1);
-                        getLog().trace(
-                            Thread.currentThread().getName()
-                                + ": committed update");
-                        try {
-                            _pm.flush();
-                            endTx(_pm);
-                        }
-                        catch (Exception ex) {
-                            throw new org.apache.openjpa.util.UserException(
-                                "Optimistic lock probably failed after "
-                                    + i + " iterations ("
-                                    + Thread.currentThread().getName()
-                                    + ")", ex);
-                        }
-                        yield();
-                    }
-                    finally {
-                        if (_lock != null)
-                            _lock.unlock();
-                    }
-                }
-            }
-			catch (Exception e)
-			{
-				exception = e;
-			}
-		}
-	}
-
-}
+/*
+ * TestPessimisticLocking.java
+ *
+ * Created on October 13, 2006, 3:17 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.jdbc.FetchMode;
+import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
+
+public class TestPessimisticLocking extends BaseKernelTest {
+
+    private Object _id = null;
+    private int _bugCount = 0;
+    private OpenJPAEntityManagerFactory _factory = null;
+
+    public TestPessimisticLocking(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates a new instance of TestPessimisticLocking
+     */
+    public TestPessimisticLocking() {
+    }
+
+    protected boolean skipTest() {
+        // pointbase doesn't really lock
+        if (getCurrentPlatform() == AbstractTestCase.Platform.POINTBASE)
+            return true;
+
+        if (getConfiguration() instanceof JDBCConfiguration) {
+            JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+            return !conf.getDBDictionaryInstance().supportsSelectForUpdate;
+        }
+        return false;
+    }
+
+    /**
+     * Use a locking persistence manager with subclass fetch mode to set to
+     * "none" to avoid subclass joins.
+     */
+    protected OpenJPAEntityManager getLockingPM() {
+        OpenJPAEntityManager pm = _factory.createEntityManager();
+        ((JDBCFetchPlan) pm.getFetchPlan())
+            .setSubclassFetchMode(FetchMode.NONE);
+        return pm;
+    }
+
+    public void setUp() throws Exception {
+        deleteAll(RuntimeTest1.class);
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.LockManager", "pessimistic");
+        _factory = (OpenJPAEntityManagerFactory) getEmf(propsMap);
+
+        OpenJPAEntityManager pm = getLockingPM();
+        startTx(pm);
+
+        RuntimeTest1 a = new RuntimeTest1("name", 0);
+        pm.persist(a);
+        _id = pm.getObjectId(a);
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void tearDown() {
+        try {
+            if (_factory != null)
+                _factory.close();
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * Test that pessimistic locking is working in the data store.
+     */
+    public void testPessimisticLocking() throws Throwable {
+        pessimisticLockingTest(false);
+    }
+
+    /**
+     * Test that the test case itself is working be using a ReentrantLock. This
+     * test will validate that the test case itself is working correctly, not
+     * that the datastore's pessimistic locking is working.
+     */
+    public void testPessimisticLockingInternal() throws Throwable {
+        pessimisticLockingTest(true);
+    }
+
+    /**
+     * Test that pessimistic locking is working by attempting to update the same
+     * object in the data store.
+     *
+     * @param useReentrantLock true if we want to synchronize on a lock instead of relying on
+     * the data store (used for validating the test case).
+     */
+    public void pessimisticLockingTest(boolean useReentrantLock)
+        throws Throwable {
+        long timeout = System.currentTimeMillis() + (60 * 5 * 1000);
+
+        ReentrantLock lock = null;
+        if (useReentrantLock)
+            lock = new ReentrantLock();
+
+        TestThread t1 = new TestThread(lock);
+        TestThread t2 = new TestThread(lock);
+        t1.start();
+        t2.start();
+
+        getLog().trace("started thread");
+
+        // wait for threads to die or timeout
+        while ((t1.isAlive() || t2.isAlive())
+            && System.currentTimeMillis() < timeout) {
+            Thread.sleep(1000);
+            getLog().trace(
+                "thread waiting for completion ("
+                    + (timeout - System.currentTimeMillis())
+                    + " ms left)");
+        }
+
+        getLog().trace("checking if thread is alive");
+        System.out.flush();
+
+        if (t1.isAlive() || t2.isAlive()) {
+            getLog().trace("thread is still alive");
+            System.out.flush();
+
+            // do out best to clean them up
+            try {
+                t1.interrupt();
+            }
+            catch (Exception e) {
+            }
+            try {
+                t2.interrupt();
+            }
+            catch (Exception e) {
+            }
+
+            throw new Exception("Thread did not complete after timeout ("
+                + timeout + "): possible deadlock");
+        }
+
+        getLog().trace("checking exception for t1");
+        if (t1.exception != null)
+            throw t1.exception;
+
+        getLog().trace("checking exception for t2");
+        if (t2.exception != null)
+            throw t2.exception;
+
+        getLog().trace("verifying pessimistic locking worked...");
+        OpenJPAEntityManager pm = getLockingPM();
+        RuntimeTest1 a = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
+        assertEquals(20 - _bugCount, a.getIntField1());
+        getLog().trace("closing pm");
+        endEm(pm);
+        getLog().trace("done");
+    }
+
+    /**
+     * Update thread that tries to increment an int field.
+     *
+     * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+     */
+    private class TestThread extends Thread {
+
+        private OpenJPAEntityManager _pm = getLockingPM();
+
+        public Exception exception = null;
+
+        private final ReentrantLock _lock;
+
+        /**
+         * Constructor
+         *
+         * @param lock the ReentrantLock we should use, or null to rely on
+         * pessimistic locking in the data store.
+         */
+        public TestThread(ReentrantLock lock) {
+            this._lock = lock;
+        }
+
+        public synchronized void run() {
+            getLog().trace(
+                Thread.currentThread().getName()
+                    + ": starting update thread");
+            try {
+                for (int i = 0; i < 10; i++) {
+                    if (_lock != null)
+                        _lock.lock();
+
+                    try {
+                        _pm.setOptimistic(false);
+                        startTx(_pm);
+                        RuntimeTest1 a = (RuntimeTest1) _pm.find(
+                            RuntimeTest1.class, _id);
+                        getLog().trace(
+                            Thread.currentThread().getName()
+                                + ": obtained and locked: " + a);
+                        yield();
+                        super.wait(50);
+                        getLog().trace(
+                            Thread.currentThread().getName()
+                                + ": updating age from "
+                                + a.getIntField1());
+                        a.setIntField1(a.getIntField1() + 1);
+                        getLog().trace(
+                            Thread.currentThread().getName()
+                                + ": committed update");
+                        try {
+                            _pm.flush();
+                            endTx(_pm);
+                        }
+                        catch (Exception ex) {
+                            throw new org.apache.openjpa.util.UserException(
+                                "Optimistic lock probably failed after "
+                                    + i + " iterations ("
+                                    + Thread.currentThread().getName()
+                                    + ")", ex);
+                        }
+                        yield();
+                    }
+                    finally {
+                        if (_lock != null)
+                            _lock.unlock();
+                    }
+                }
+            }
+			catch (Exception e)
+			{
+				exception = e;
+			}
+		}
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPojoWithoutAnnotationsCannotBePersisted.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPojoWithoutAnnotationsCannotBePersisted.java
index a0d6cfd..1aec2fe 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPojoWithoutAnnotationsCannotBePersisted.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestPojoWithoutAnnotationsCannotBePersisted.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.UnAnnotPojo;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-/*
- * @author Afam Okeke
- * Ensures that pojo that is not persistent capable cannot be persisted.
- */
-
-public class TestPojoWithoutAnnotationsCannotBePersisted
-    extends AbstractTestCase {
-
-    UnAnnotPojo pojo = null;
-
-    public TestPojoWithoutAnnotationsCannotBePersisted(String name) {
-        super(name, "kernelcactusapp");
-    }
-
-    public void setUp() {
-        System.out.println("Running test " + this.getName() + " of " +
-            this.getClass().getSimpleName());
-        pojo = new UnAnnotPojo();
-        pojo.setName("failure");
-        pojo.setNum(0);
-    }
-
-    /*
-      * Try to persist pojo with no metadata
-      */
-    public void testPersistingUnAnnotatedObject() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        try {
-            em.persist(pojo);
-            fail("...Should not persist object without proper metadata...");
-        }
-        catch (Exception e) {
-            //expected
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.UnAnnotPojo;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+/*
+ * @author Afam Okeke
+ * Ensures that pojo that is not persistent capable cannot be persisted.
+ */
+
+public class TestPojoWithoutAnnotationsCannotBePersisted
+    extends AbstractTestCase {
+
+    UnAnnotPojo pojo = null;
+
+    public TestPojoWithoutAnnotationsCannotBePersisted(String name) {
+        super(name, "kernelcactusapp");
+    }
+
+    public void setUp() {
+        System.out.println("Running test " + this.getName() + " of " +
+            this.getClass().getSimpleName());
+        pojo = new UnAnnotPojo();
+        pojo.setName("failure");
+        pojo.setNum(0);
+    }
+
+    /*
+      * Try to persist pojo with no metadata
+      */
+    public void testPersistingUnAnnotatedObject() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        try {
+            em.persist(pojo);
+            fail("...Should not persist object without proper metadata...");
+        }
+        catch (Exception e) {
+            //expected
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestProxies2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestProxies2.java
index 9640b73..933ffaf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestProxies2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestProxies2.java
@@ -1,526 +1,526 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ProxiesPC;
-import org.apache.commons.collections.comparators.ComparableComparator;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.util.Proxy;
-
-public class TestProxies2 extends BaseKernelTest {
-
-    private int _oid = 0;
-    private Date _date = null;
-    private java.sql.Date _sqlDate = null;
-    private java.sql.Timestamp _timestamp = null;
-
-    public TestProxies2(String casename) {
-        super(casename);
-    }
-
-    public void setUp() {
-        deleteAll(ProxiesPC.class);
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        long now = System.currentTimeMillis();
-        _date = new Date(now);
-        _sqlDate = new java.sql.Date(now);
-        _timestamp = new java.sql.Timestamp(now);
-
-        ProxiesPC pc = new ProxiesPC("main");
-        pc.setDate(_date);
-        pc.setSQLDate(_sqlDate);
-        pc.setTimestamp(_timestamp);
-
-        pc.getStringSet().add("val1");
-        pc.getStringSet().add("val2");
-        pc.getStringSet().add("val3");
-        pc.getStringSet().add(null);
-
-        pc.getProxySet().add(new ProxiesPC("set1"));
-        pc.getProxySet().add(new ProxiesPC("set2"));
-        pc.getProxySet().add(new ProxiesPC("set3"));
-
-        pc.getStringMap().put("key1", "1");
-        pc.getStringMap().put("key2", "2");
-        pc.getStringMap().put("key3", "3");
-        pc.getStringMap().put(null, "null");
-        pc.getStringMap().put("null", null);
-
-        pc.getProxyMap().put("key1", new ProxiesPC("map1"));
-        pc.getProxyMap().put("key2", new ProxiesPC("map2"));
-        pc.getProxyMap().put("key3", new ProxiesPC("map3"));
-
-        pc.getList().add("val1");
-        pc.getList().add("val1");
-        pc.getList().add("val2");
-        pc.getList().add("val3");
-        pc.getList().add("val3");
-
-        pm.persist(pc);
-
-        _oid = pc.getId();
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testStringSet() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        Set set = pc.getStringSet();
-        assertEquals(4, set.size());
-        assertTrue(set.contains("val1"));
-        assertTrue(set.contains("val2"));
-        assertTrue(set.contains("val3"));
-        assertTrue(set.contains(null));
-
-        // do some mods to try to confuse the proxy
-        set.remove("val1");
-        set.remove("val1");
-        set.add("val4");
-        set.remove("val4");
-        set.add("val5");
-        set.add("val5");
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and check set
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        set = pc.getStringSet();
-        assertEquals(4, set.size());
-        assertTrue(!set.contains("val1"));
-        assertTrue(set.contains("val2"));
-        assertTrue(set.contains("val3"));
-        assertTrue(!set.contains("val4"));
-        assertTrue(set.contains("val5"));
-        assertTrue(set.contains(null));
-        endEm(pm);
-    }
-
-    public void testStringMap() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        Map map = pc.getStringMap();
-        assertEquals(5, map.size());
-        assertEquals("1", map.get("key1"));
-        assertEquals("2", map.get("key2"));
-        assertEquals("3", map.get("key3"));
-        assertNull(map.get("null"));
-        assertEquals("null", map.get(null));
-
-        // do some mods to try to confuse the proxy
-        map.put("key1", "1a");
-        map.put("key1", "1b");
-        map.put("key4", "4");
-        map.remove("key4");
-        map.remove("foo");
-        map.put("key5", "5");
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and check map
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        map = pc.getStringMap();
-        assertEquals(6, map.size());
-        assertEquals("1b", map.get("key1"));
-        assertEquals("5", map.get("key5"));
-        endEm(pm);
-    }
-
-    public void testProxySet() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        Set set = pc.getProxySet();
-        assertEquals(3, set.size());
-        Iterator itr = set.iterator();
-        ProxiesPC set1 = (ProxiesPC) itr.next();
-        ProxiesPC set2 = (ProxiesPC) itr.next();
-        ProxiesPC set3 = (ProxiesPC) itr.next();
-        assertEquals("set1", set1.getName());
-        assertEquals("set2", set2.getName());
-        assertEquals("set3", set3.getName());
-
-        // do some mods to try to confuse the proxy
-        set.remove(set1);
-        set.remove(set1);
-        ProxiesPC set4 = new ProxiesPC("set4");
-        set.add(set4);
-        set.remove(set4);
-        ProxiesPC set5 = new ProxiesPC("set5");
-        set.add(set5);
-        set.add(set5);
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and check set
-        pm = getPM(true, false);
-        startTx(pm);
-        pc = pm.find(ProxiesPC.class, _oid);
-        pm.refresh(pc);
-
-        set = pc.getProxySet();
-        assertEquals(3, set.size());
-        itr = set.iterator();
-        set1 = (ProxiesPC) itr.next();
-        set2 = (ProxiesPC) itr.next();
-        set3 = (ProxiesPC) itr.next();
-        assertEquals("set2", set1.getName());
-        assertEquals("set3", set2.getName());
-        assertEquals("set5", set3.getName());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testProxyMap() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        Map map = pc.getProxyMap();
-        assertEquals("original map size is correct: 3", 3, map.size());
-        ProxiesPC map1 = (ProxiesPC) map.get("key1");
-        ProxiesPC map2 = (ProxiesPC) map.get("key2");
-        ProxiesPC map3 = (ProxiesPC) map.get("key3");
-        assertEquals("map1", map1.getName());
-        assertEquals("map2", map2.getName());
-        assertEquals("map3", map3.getName());
-
-        // do some mods to try to confuse the proxy
-        ProxiesPC map1a = new ProxiesPC("map1a");
-        map.put("key1", map1a);
-        ProxiesPC map1b = new ProxiesPC("map1b");
-        map.put("key1", map1b);
-        map.put("key4", new ProxiesPC("map4"));
-        map.remove("key4");
-        map.remove("foo");
-        map.put("key5", new ProxiesPC("map5"));
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and check map
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-        startTx(pm);
-        pm.refresh(pc);
-
-        map = pc.getProxyMap();
-
-        assertEquals(4, map.size());
-        assertEquals("map1b", ((ProxiesPC) map.get("key1")).getName());
-        assertEquals("map5", ((ProxiesPC) map.get("key5")).getName());
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testReplace() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // totally replace set
-        Set set = new HashSet();
-        set.add("new");
-        pc.setStringSet(set);
-
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and check set
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        set = pc.getStringSet();
-        assertEquals(1, set.size());
-        assertTrue(set.contains("new"));
-        endEm(pm);
-    }
-
-    public void testComparators() {
-        // make sure the system uses the initial field value to find
-        // comparators
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-        assertNotNull("pc is null", pc);
-        assertTrue("pc.getComp() is not instanceof Proxy",
-            pc.getComp() instanceof Proxy);
-        assertTrue(
-            "(TreeSet) is not pc.getComp()).comparator() instanceof ComparableComparator",
-            ((TreeSet) pc.getComp())
-                .comparator() instanceof ComparableComparator);
-        pm.evict(pc);
-        endTx(pm);
-
-        // see if it still saves comparator after transition to hollow
-        // and back
-        assertTrue("pc.getComp() is not instanceof ProxyTreeSet",
-            pc.getComp() instanceof Proxy);
-        Comparator compart = ((TreeSet) pc.getComp()).comparator();
-        assertNotNull("compart is null", compart);
-        assertTrue(
-            "((TreeSet) is not pc.getComp()).comparator()instanceof ComparableComparator",
-            ((TreeSet) pc.getComp())
-                .comparator() instanceof ComparableComparator);
-
-        endEm(pm);
-    }
-
-    //    FIX ME: Moving fix to essex
-    /*public void testList() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        List list = pc.getList();
-        assertEquals(5, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val2", list.get(2));
-        assertEquals("val3", list.get(3));
-        assertEquals("val3", list.get(4));
-
-        // do some mods to try to confuse the proxy
-        list.remove("val2");
-        list.add("val4");
-        list.remove("val4");
-        list.add("val5");
-        list.add("val6");
-        list.add("val6");
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and modify again to check holes in ordering
-        pm = getPM(false, false);
-        startTx(pm);
-        pc = (ProxiesPC) pm.find(ProxiesPC.class, _oid);
-
-        list = pc.getList();
-        assertEquals(7, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val3", list.get(2));
-        assertEquals("val3", list.get(3));
-        assertEquals("val5", list.get(4));
-        assertEquals("val6", list.get(5));
-        assertEquals("val6", list.get(6));
-
-        list.remove("val5");
-        list.add("val7");
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and check final contents
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        list = pc.getList();
-        assertEquals(7, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val3", list.get(2));
-        assertEquals("val3", list.get(3));
-        assertEquals("val6", list.get(4));
-        assertEquals("val6", list.get(5));
-        assertEquals("val7", list.get(6));
-        endEm(pm);
-    }
-
-    public void testListDisablesChangeTracking() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        List list = pc.getList();
-        assertEquals(5, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val2", list.get(2));
-        assertEquals("val3", list.get(3));
-        assertEquals("val3", list.get(4));
-
-        // removing a copy of val3 should disable tracking
-        list.remove("val2");
-        list.remove("val3");
-        list.add("val5");
-        list.add("val5");
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve and change again to check ordering
-        pm = getPM(false, false);
-        startTx(pm);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        list = pc.getList();
-        assertEquals(5, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val3", list.get(2));
-        assertEquals("val5", list.get(3));
-        assertEquals("val5", list.get(4));
-
-        list.remove("val3");
-        list.add("val6");
-        endTx(pm);
-        endEm(pm);
-
-        // check final contents
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        list = pc.getList();
-        assertEquals(5, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val6", list.get(2));
-        assertEquals("val5", list.get(3));
-        assertEquals("val5", list.get(4));
-        endEm(pm);
-    }
-*/
-    public void testChangeListOrder() {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-
-        // check that orig values are correct
-        List list = pc.getList();
-        assertEquals(5, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val2", list.get(2));
-        assertEquals("val3", list.get(3));
-        assertEquals("val3", list.get(4));
-
-        // reorder val2
-        list.remove("val2");
-        list.add("val2");
-        endTx(pm);
-        endEm(pm);
-
-        // re-retrieve to check ordering
-        pm = getPM(false, false);
-        pc = pm.find(ProxiesPC.class, _oid);
-
-        list = pc.getList();
-        assertEquals(5, list.size());
-        assertEquals("val1", list.get(0));
-        assertEquals("val1", list.get(1));
-        assertEquals("val3", list.get(2));
-        assertEquals("val3", list.get(3));
-        assertEquals("val2", list.get(4));
-        endEm(pm);
-    }
-
-    public void testDate() {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-        Date date = pc.getDate();
-        assertNotNull(date);
-
-        // dates can lose precision, but make sure same day
-        assertEquals(_date.getYear(), date.getYear());
-        assertEquals(_date.getMonth(), date.getMonth());
-        assertEquals(_date.getDate(), date.getDate());
-
-        // make sure proxied
-        assertTrue(!pm.isDirty(pc));
-        date.setTime(System.currentTimeMillis() + 1000 * 60 * 60 * 24);
-        assertTrue(pm.isDirty(pc));
-
-        endTx(pm);
-        assertEquals(date, pc.getDate());
-        endEm(pm);
-    }
-
-    public void testSQLDate() {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-        java.sql.Date date = pc.getSQLDate();
-        assertNotNull(date);
-
-        // dates can lose precision, but make sure same day
-        assertEquals(_sqlDate.getYear(), date.getYear());
-        assertEquals(_sqlDate.getMonth(), date.getMonth());
-        assertEquals(_sqlDate.getDate(), date.getDate());
-
-        // make sure proxied
-        assertTrue(!pm.isDirty(pc));
-        date.setTime(System.currentTimeMillis() + 1000 * 60 * 60 * 24);
-        assertTrue(pm.isDirty(pc));
-
-        endTx(pm);
-        assertEquals(date, pc.getSQLDate());
-        endEm(pm);
-    }
-
-    public void testTimestamp() {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
-        java.sql.Timestamp tstamp = pc.getTimestamp();
-        assertNotNull(tstamp);
-
-        // dates can lose precision, but make sure same day
-        assertEquals(_timestamp.getYear(), tstamp.getYear());
-        assertEquals(_timestamp.getMonth(), tstamp.getMonth());
-        assertEquals(_timestamp.getDate(), tstamp.getDate());
-
-        // make sure proxied
-        assertTrue(!pm.isDirty(pc));
-        tstamp.setNanos(100);
-        assertTrue(pm.isDirty(pc));
-
-        endTx(pm);
-        assertEquals(tstamp, pc.getTimestamp());
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ProxiesPC;
+import org.apache.commons.collections.comparators.ComparableComparator;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.util.Proxy;
+
+public class TestProxies2 extends BaseKernelTest {
+
+    private int _oid = 0;
+    private Date _date = null;
+    private java.sql.Date _sqlDate = null;
+    private java.sql.Timestamp _timestamp = null;
+
+    public TestProxies2(String casename) {
+        super(casename);
+    }
+
+    public void setUp() {
+        deleteAll(ProxiesPC.class);
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        long now = System.currentTimeMillis();
+        _date = new Date(now);
+        _sqlDate = new java.sql.Date(now);
+        _timestamp = new java.sql.Timestamp(now);
+
+        ProxiesPC pc = new ProxiesPC("main");
+        pc.setDate(_date);
+        pc.setSQLDate(_sqlDate);
+        pc.setTimestamp(_timestamp);
+
+        pc.getStringSet().add("val1");
+        pc.getStringSet().add("val2");
+        pc.getStringSet().add("val3");
+        pc.getStringSet().add(null);
+
+        pc.getProxySet().add(new ProxiesPC("set1"));
+        pc.getProxySet().add(new ProxiesPC("set2"));
+        pc.getProxySet().add(new ProxiesPC("set3"));
+
+        pc.getStringMap().put("key1", "1");
+        pc.getStringMap().put("key2", "2");
+        pc.getStringMap().put("key3", "3");
+        pc.getStringMap().put(null, "null");
+        pc.getStringMap().put("null", null);
+
+        pc.getProxyMap().put("key1", new ProxiesPC("map1"));
+        pc.getProxyMap().put("key2", new ProxiesPC("map2"));
+        pc.getProxyMap().put("key3", new ProxiesPC("map3"));
+
+        pc.getList().add("val1");
+        pc.getList().add("val1");
+        pc.getList().add("val2");
+        pc.getList().add("val3");
+        pc.getList().add("val3");
+
+        pm.persist(pc);
+
+        _oid = pc.getId();
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testStringSet() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        Set set = pc.getStringSet();
+        assertEquals(4, set.size());
+        assertTrue(set.contains("val1"));
+        assertTrue(set.contains("val2"));
+        assertTrue(set.contains("val3"));
+        assertTrue(set.contains(null));
+
+        // do some mods to try to confuse the proxy
+        set.remove("val1");
+        set.remove("val1");
+        set.add("val4");
+        set.remove("val4");
+        set.add("val5");
+        set.add("val5");
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and check set
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        set = pc.getStringSet();
+        assertEquals(4, set.size());
+        assertTrue(!set.contains("val1"));
+        assertTrue(set.contains("val2"));
+        assertTrue(set.contains("val3"));
+        assertTrue(!set.contains("val4"));
+        assertTrue(set.contains("val5"));
+        assertTrue(set.contains(null));
+        endEm(pm);
+    }
+
+    public void testStringMap() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        Map map = pc.getStringMap();
+        assertEquals(5, map.size());
+        assertEquals("1", map.get("key1"));
+        assertEquals("2", map.get("key2"));
+        assertEquals("3", map.get("key3"));
+        assertNull(map.get("null"));
+        assertEquals("null", map.get(null));
+
+        // do some mods to try to confuse the proxy
+        map.put("key1", "1a");
+        map.put("key1", "1b");
+        map.put("key4", "4");
+        map.remove("key4");
+        map.remove("foo");
+        map.put("key5", "5");
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and check map
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        map = pc.getStringMap();
+        assertEquals(6, map.size());
+        assertEquals("1b", map.get("key1"));
+        assertEquals("5", map.get("key5"));
+        endEm(pm);
+    }
+
+    public void testProxySet() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        Set set = pc.getProxySet();
+        assertEquals(3, set.size());
+        Iterator itr = set.iterator();
+        ProxiesPC set1 = (ProxiesPC) itr.next();
+        ProxiesPC set2 = (ProxiesPC) itr.next();
+        ProxiesPC set3 = (ProxiesPC) itr.next();
+        assertEquals("set1", set1.getName());
+        assertEquals("set2", set2.getName());
+        assertEquals("set3", set3.getName());
+
+        // do some mods to try to confuse the proxy
+        set.remove(set1);
+        set.remove(set1);
+        ProxiesPC set4 = new ProxiesPC("set4");
+        set.add(set4);
+        set.remove(set4);
+        ProxiesPC set5 = new ProxiesPC("set5");
+        set.add(set5);
+        set.add(set5);
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and check set
+        pm = getPM(true, false);
+        startTx(pm);
+        pc = pm.find(ProxiesPC.class, _oid);
+        pm.refresh(pc);
+
+        set = pc.getProxySet();
+        assertEquals(3, set.size());
+        itr = set.iterator();
+        set1 = (ProxiesPC) itr.next();
+        set2 = (ProxiesPC) itr.next();
+        set3 = (ProxiesPC) itr.next();
+        assertEquals("set2", set1.getName());
+        assertEquals("set3", set2.getName());
+        assertEquals("set5", set3.getName());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testProxyMap() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        Map map = pc.getProxyMap();
+        assertEquals("original map size is correct: 3", 3, map.size());
+        ProxiesPC map1 = (ProxiesPC) map.get("key1");
+        ProxiesPC map2 = (ProxiesPC) map.get("key2");
+        ProxiesPC map3 = (ProxiesPC) map.get("key3");
+        assertEquals("map1", map1.getName());
+        assertEquals("map2", map2.getName());
+        assertEquals("map3", map3.getName());
+
+        // do some mods to try to confuse the proxy
+        ProxiesPC map1a = new ProxiesPC("map1a");
+        map.put("key1", map1a);
+        ProxiesPC map1b = new ProxiesPC("map1b");
+        map.put("key1", map1b);
+        map.put("key4", new ProxiesPC("map4"));
+        map.remove("key4");
+        map.remove("foo");
+        map.put("key5", new ProxiesPC("map5"));
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and check map
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+        startTx(pm);
+        pm.refresh(pc);
+
+        map = pc.getProxyMap();
+
+        assertEquals(4, map.size());
+        assertEquals("map1b", ((ProxiesPC) map.get("key1")).getName());
+        assertEquals("map5", ((ProxiesPC) map.get("key5")).getName());
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testReplace() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // totally replace set
+        Set set = new HashSet();
+        set.add("new");
+        pc.setStringSet(set);
+
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and check set
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        set = pc.getStringSet();
+        assertEquals(1, set.size());
+        assertTrue(set.contains("new"));
+        endEm(pm);
+    }
+
+    public void testComparators() {
+        // make sure the system uses the initial field value to find
+        // comparators
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+        assertNotNull("pc is null", pc);
+        assertTrue("pc.getComp() is not instanceof Proxy",
+            pc.getComp() instanceof Proxy);
+        assertTrue(
+            "(TreeSet) is not pc.getComp()).comparator() instanceof ComparableComparator",
+            ((TreeSet) pc.getComp())
+                .comparator() instanceof ComparableComparator);
+        pm.evict(pc);
+        endTx(pm);
+
+        // see if it still saves comparator after transition to hollow
+        // and back
+        assertTrue("pc.getComp() is not instanceof ProxyTreeSet",
+            pc.getComp() instanceof Proxy);
+        Comparator compart = ((TreeSet) pc.getComp()).comparator();
+        assertNotNull("compart is null", compart);
+        assertTrue(
+            "((TreeSet) is not pc.getComp()).comparator()instanceof ComparableComparator",
+            ((TreeSet) pc.getComp())
+                .comparator() instanceof ComparableComparator);
+
+        endEm(pm);
+    }
+
+    //    FIX ME: Moving fix to essex
+    /*public void testList() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        List list = pc.getList();
+        assertEquals(5, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val2", list.get(2));
+        assertEquals("val3", list.get(3));
+        assertEquals("val3", list.get(4));
+
+        // do some mods to try to confuse the proxy
+        list.remove("val2");
+        list.add("val4");
+        list.remove("val4");
+        list.add("val5");
+        list.add("val6");
+        list.add("val6");
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and modify again to check holes in ordering
+        pm = getPM(false, false);
+        startTx(pm);
+        pc = (ProxiesPC) pm.find(ProxiesPC.class, _oid);
+
+        list = pc.getList();
+        assertEquals(7, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val3", list.get(2));
+        assertEquals("val3", list.get(3));
+        assertEquals("val5", list.get(4));
+        assertEquals("val6", list.get(5));
+        assertEquals("val6", list.get(6));
+
+        list.remove("val5");
+        list.add("val7");
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and check final contents
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        list = pc.getList();
+        assertEquals(7, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val3", list.get(2));
+        assertEquals("val3", list.get(3));
+        assertEquals("val6", list.get(4));
+        assertEquals("val6", list.get(5));
+        assertEquals("val7", list.get(6));
+        endEm(pm);
+    }
+
+    public void testListDisablesChangeTracking() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        List list = pc.getList();
+        assertEquals(5, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val2", list.get(2));
+        assertEquals("val3", list.get(3));
+        assertEquals("val3", list.get(4));
+
+        // removing a copy of val3 should disable tracking
+        list.remove("val2");
+        list.remove("val3");
+        list.add("val5");
+        list.add("val5");
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve and change again to check ordering
+        pm = getPM(false, false);
+        startTx(pm);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        list = pc.getList();
+        assertEquals(5, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val3", list.get(2));
+        assertEquals("val5", list.get(3));
+        assertEquals("val5", list.get(4));
+
+        list.remove("val3");
+        list.add("val6");
+        endTx(pm);
+        endEm(pm);
+
+        // check final contents
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        list = pc.getList();
+        assertEquals(5, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val6", list.get(2));
+        assertEquals("val5", list.get(3));
+        assertEquals("val5", list.get(4));
+        endEm(pm);
+    }
+*/
+    public void testChangeListOrder() {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+
+        // check that orig values are correct
+        List list = pc.getList();
+        assertEquals(5, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val2", list.get(2));
+        assertEquals("val3", list.get(3));
+        assertEquals("val3", list.get(4));
+
+        // reorder val2
+        list.remove("val2");
+        list.add("val2");
+        endTx(pm);
+        endEm(pm);
+
+        // re-retrieve to check ordering
+        pm = getPM(false, false);
+        pc = pm.find(ProxiesPC.class, _oid);
+
+        list = pc.getList();
+        assertEquals(5, list.size());
+        assertEquals("val1", list.get(0));
+        assertEquals("val1", list.get(1));
+        assertEquals("val3", list.get(2));
+        assertEquals("val3", list.get(3));
+        assertEquals("val2", list.get(4));
+        endEm(pm);
+    }
+
+    public void testDate() {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+        Date date = pc.getDate();
+        assertNotNull(date);
+
+        // dates can lose precision, but make sure same day
+        assertEquals(_date.getYear(), date.getYear());
+        assertEquals(_date.getMonth(), date.getMonth());
+        assertEquals(_date.getDate(), date.getDate());
+
+        // make sure proxied
+        assertTrue(!pm.isDirty(pc));
+        date.setTime(System.currentTimeMillis() + 1000 * 60 * 60 * 24);
+        assertTrue(pm.isDirty(pc));
+
+        endTx(pm);
+        assertEquals(date, pc.getDate());
+        endEm(pm);
+    }
+
+    public void testSQLDate() {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+        java.sql.Date date = pc.getSQLDate();
+        assertNotNull(date);
+
+        // dates can lose precision, but make sure same day
+        assertEquals(_sqlDate.getYear(), date.getYear());
+        assertEquals(_sqlDate.getMonth(), date.getMonth());
+        assertEquals(_sqlDate.getDate(), date.getDate());
+
+        // make sure proxied
+        assertTrue(!pm.isDirty(pc));
+        date.setTime(System.currentTimeMillis() + 1000 * 60 * 60 * 24);
+        assertTrue(pm.isDirty(pc));
+
+        endTx(pm);
+        assertEquals(date, pc.getSQLDate());
+        endEm(pm);
+    }
+
+    public void testTimestamp() {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+        ProxiesPC pc = pm.find(ProxiesPC.class, _oid);
+        java.sql.Timestamp tstamp = pc.getTimestamp();
+        assertNotNull(tstamp);
+
+        // dates can lose precision, but make sure same day
+        assertEquals(_timestamp.getYear(), tstamp.getYear());
+        assertEquals(_timestamp.getMonth(), tstamp.getMonth());
+        assertEquals(_timestamp.getDate(), tstamp.getDate());
+
+        // make sure proxied
+        assertTrue(!pm.isDirty(pc));
+        tstamp.setNanos(100);
+        assertTrue(pm.isDirty(pc));
+
+        endTx(pm);
+        assertEquals(tstamp, pc.getTimestamp());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestQueries.java
index f1530ab..1aa5be7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestQueries.java
@@ -1,224 +1,224 @@
-/*
- * TestQueries.java
- *
- * Created on October 13, 2006, 4:27 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
-
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestQueries extends BaseKernelTest {
-
-    private static final int CHILD_COUNT = 3;
-    private int id = 10000;
-
-    public TestQueries(String name) {
-        super(name);
-    }
-
-    public TestQueries() {
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testSimpleQuery() {
-        OpenJPAEntityManager pm = getPM();
-
-        persist(newRuntimeTest1("SimpleQueryA", 50), pm);
-        persist(newRuntimeTest2("SimpleQueryB", 50), pm);
-
-        Collection results = runQuery(RuntimeTest1.class, false,
-            "stringField = \'SimpleQueryA\'", pm);
-        assertEquals(1, results.size());
-
-        results = runQuery(RuntimeTest1.class, true, "intField1 = 50", pm);
-        assertEquals(2, results.size());
-
-        results = runQuery(RuntimeTest2.class, true, "intField1 = 50", pm);
-        assertEquals(1, results.size());
-
-        results = runQuery(RuntimeTest2.class, false, "intField1 = 50", pm);
-        assertEquals(1, results.size());
-
-        endEm(pm);
-    }
-
-    public void testAndQuery() {
-        String query = "intField1 > 10 AND o.intField1 < 50";
-
-        for (int currentCount = 1; currentCount < 15; currentCount++) {
-            OpenJPAEntityManager pm = getPM();
-
-            // make sure that none exist
-            deleteByQuery(RuntimeTest1.class, false, query, pm);
-
-            startTx(pm);
-            for (int i = 1; i <= currentCount; i++)
-                pm.persist(newRuntimeTest1("AndQueryTest", 30 + i));
-            endTx(pm);
-
-            // verify that the query works.
-            Collection results = runQuery(RuntimeTest1.class, false,
-                query, pm);
-            assertEquals(currentCount, results.size());
-            endEm(pm);
-        }
-    }
-
-    public void testRelationQuery() {
-        relationQuery(10, "JOE", 20);
-        relationQuery(99, "BOB", 2);
-        relationQuery(3, "MARTHA", 1);
-        relationQuery(5, "brenda", 43);
-        relationQuery(43, "SarA", 55);
-    }
-
-    public void relationQuery(int intField, String stringField, int count) {
-        OpenJPAEntityManager pm = getPM();
-
-        String query = "selfOneOne.intField1 = " + intField
-            + " AND o.selfOneOne.stringField = '" + stringField + "'";
-        deleteByQuery(RuntimeTest1.class, true, query, pm);
-
-        // we go up the to max count, adding to the people, and validate
-        // with a query each time.
-        for (int currentcount = 0; currentcount <= count; currentcount++) {
-            if (currentcount != 0)
-                persist(newRuntimeTest2(stringField, intField), pm);
-
-            Collection results = runQuery(RuntimeTest1.class, true, query, pm);
-            assertEquals("query (" + query + ") failed to yield "
-                + currentcount + " instances",
-                currentcount * CHILD_COUNT, results.size());
-        }
-
-        endEm(pm);
-    }
-
-    public void testQueryExecuteThrowsExceptionWhenNoNTR() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(newRuntimeTest1("Query", 10));
-        endTx(pm);
-
-        pm.setNontransactionalRead(false);
-//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest1.class);
-        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest1 o");
-        try {
-            Collection c = (Collection) q.getResultList();
-            fail("Query.execute() should have thrown a JDOException when "
-                + "PM is outside a Transaction and NTR==false");
-        } catch (Exception jdoe) {
-            // good
-            startTx(pm);
-            q.getResultList();
-            rollbackTx(pm);
-        }
-    }
-
-    /**
-     * Delete the results of a query, so we can reinsert and test.
-     */
-    private void deleteByQuery(Class type, boolean subs, String filter,
-        OpenJPAEntityManager pm) {
-        startTx(pm);
-        Extent extent = pm.createExtent(type, subs);
-        //FIXME jthomas
-//        OpenJPAQuery query = pm.newQuery(extent, filter);
-//        Collection items = (Collection) query.execute();
-        String cstrng = type.getSimpleName();
-
-        OpenJPAQuery query =
-            pm.createQuery("SELECT o FROM " + cstrng + " o WHERE o." + filter);
-        query.setSubclasses(subs);
-        Collection items = (Collection) query.getResultList();
-        for (Iterator i = items.iterator(); i.hasNext();)
-            pm.remove(i.next());
-
-        //FIXME jthomas
-        //query = pm.newQuery(extent, filter);
-
-        query =
-            pm.createQuery("SELECT o FROM " + cstrng + " o WHERE o." + filter);
-        query.setSubclasses(subs);
-        items = query.getResultList();
-        endTx(pm);
-        assertEquals("after deleting from query (" + query
-            + "), there should have been zero items",
-            0, items.size());
-    }
-
-    private Collection runQuery(Class type, boolean subs, String filter,
-        OpenJPAEntityManager pm) {
-        Extent extent = pm.createExtent(type, subs);
-        //FIXME jthomas
-        //Query query = pm.newQuery(extent, filter);
-        String cstrng = type.getName();
-        OpenJPAQuery query =
-            pm.createQuery("SELECT o FROM " + cstrng + " o WHERE o." + filter);
-        query.setSubclasses(subs);
-        Collection results = (Collection) query.getResultList();
-        return results;
-    }
-
-    private void persist(RuntimeTest1 parent, OpenJPAEntityManager pm) {
-        RuntimeTest1 child;
-        for (int i = 0; i < CHILD_COUNT; i++) {
-            child = newRuntimeTest1("CHILD" + i, i * 10);
-            child.setSelfOneOne(parent);
-            parent.getSelfOneMany().add(child);
-        }
-
-        startTx(pm);
-        pm.persist(parent);
-        endTx(pm);
-    }
-
-    private RuntimeTest1 newRuntimeTest1(String stringField, int intField) {
-        RuntimeTest1 pc = new RuntimeTest1(stringField, intField);
-        pc.setIntField(id++);
-        return pc;
-    }
-
-    private RuntimeTest2 newRuntimeTest2(String stringField, int intField) {
-        RuntimeTest2 pc = new RuntimeTest2(stringField, intField);
-        pc.setIntField(id++);
-        return pc;
-    }
-}
+/*
+ * TestQueries.java
+ *
+ * Created on October 13, 2006, 4:27 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
+
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestQueries extends BaseKernelTest {
+
+    private static final int CHILD_COUNT = 3;
+    private int id = 10000;
+
+    public TestQueries(String name) {
+        super(name);
+    }
+
+    public TestQueries() {
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testSimpleQuery() {
+        OpenJPAEntityManager pm = getPM();
+
+        persist(newRuntimeTest1("SimpleQueryA", 50), pm);
+        persist(newRuntimeTest2("SimpleQueryB", 50), pm);
+
+        Collection results = runQuery(RuntimeTest1.class, false,
+            "stringField = \'SimpleQueryA\'", pm);
+        assertEquals(1, results.size());
+
+        results = runQuery(RuntimeTest1.class, true, "intField1 = 50", pm);
+        assertEquals(2, results.size());
+
+        results = runQuery(RuntimeTest2.class, true, "intField1 = 50", pm);
+        assertEquals(1, results.size());
+
+        results = runQuery(RuntimeTest2.class, false, "intField1 = 50", pm);
+        assertEquals(1, results.size());
+
+        endEm(pm);
+    }
+
+    public void testAndQuery() {
+        String query = "intField1 > 10 AND o.intField1 < 50";
+
+        for (int currentCount = 1; currentCount < 15; currentCount++) {
+            OpenJPAEntityManager pm = getPM();
+
+            // make sure that none exist
+            deleteByQuery(RuntimeTest1.class, false, query, pm);
+
+            startTx(pm);
+            for (int i = 1; i <= currentCount; i++)
+                pm.persist(newRuntimeTest1("AndQueryTest", 30 + i));
+            endTx(pm);
+
+            // verify that the query works.
+            Collection results = runQuery(RuntimeTest1.class, false,
+                query, pm);
+            assertEquals(currentCount, results.size());
+            endEm(pm);
+        }
+    }
+
+    public void testRelationQuery() {
+        relationQuery(10, "JOE", 20);
+        relationQuery(99, "BOB", 2);
+        relationQuery(3, "MARTHA", 1);
+        relationQuery(5, "brenda", 43);
+        relationQuery(43, "SarA", 55);
+    }
+
+    public void relationQuery(int intField, String stringField, int count) {
+        OpenJPAEntityManager pm = getPM();
+
+        String query = "selfOneOne.intField1 = " + intField
+            + " AND o.selfOneOne.stringField = '" + stringField + "'";
+        deleteByQuery(RuntimeTest1.class, true, query, pm);
+
+        // we go up the to max count, adding to the people, and validate
+        // with a query each time.
+        for (int currentcount = 0; currentcount <= count; currentcount++) {
+            if (currentcount != 0)
+                persist(newRuntimeTest2(stringField, intField), pm);
+
+            Collection results = runQuery(RuntimeTest1.class, true, query, pm);
+            assertEquals("query (" + query + ") failed to yield "
+                + currentcount + " instances",
+                currentcount * CHILD_COUNT, results.size());
+        }
+
+        endEm(pm);
+    }
+
+    public void testQueryExecuteThrowsExceptionWhenNoNTR() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(newRuntimeTest1("Query", 10));
+        endTx(pm);
+
+        pm.setNontransactionalRead(false);
+//        OpenJPAQuery q = pm.createNativeQuery("",RuntimeTest1.class);
+        OpenJPAQuery q = pm.createQuery("SELECT o FROM RuntimeTest1 o");
+        try {
+            Collection c = (Collection) q.getResultList();
+            fail("Query.execute() should have thrown a JDOException when "
+                + "PM is outside a Transaction and NTR==false");
+        } catch (Exception jdoe) {
+            // good
+            startTx(pm);
+            q.getResultList();
+            rollbackTx(pm);
+        }
+    }
+
+    /**
+     * Delete the results of a query, so we can reinsert and test.
+     */
+    private void deleteByQuery(Class type, boolean subs, String filter,
+        OpenJPAEntityManager pm) {
+        startTx(pm);
+        Extent extent = pm.createExtent(type, subs);
+        //FIXME jthomas
+//        OpenJPAQuery query = pm.newQuery(extent, filter);
+//        Collection items = (Collection) query.execute();
+        String cstrng = type.getSimpleName();
+
+        OpenJPAQuery query =
+            pm.createQuery("SELECT o FROM " + cstrng + " o WHERE o." + filter);
+        query.setSubclasses(subs);
+        Collection items = (Collection) query.getResultList();
+        for (Iterator i = items.iterator(); i.hasNext();)
+            pm.remove(i.next());
+
+        //FIXME jthomas
+        //query = pm.newQuery(extent, filter);
+
+        query =
+            pm.createQuery("SELECT o FROM " + cstrng + " o WHERE o." + filter);
+        query.setSubclasses(subs);
+        items = query.getResultList();
+        endTx(pm);
+        assertEquals("after deleting from query (" + query
+            + "), there should have been zero items",
+            0, items.size());
+    }
+
+    private Collection runQuery(Class type, boolean subs, String filter,
+        OpenJPAEntityManager pm) {
+        Extent extent = pm.createExtent(type, subs);
+        //FIXME jthomas
+        //Query query = pm.newQuery(extent, filter);
+        String cstrng = type.getName();
+        OpenJPAQuery query =
+            pm.createQuery("SELECT o FROM " + cstrng + " o WHERE o." + filter);
+        query.setSubclasses(subs);
+        Collection results = (Collection) query.getResultList();
+        return results;
+    }
+
+    private void persist(RuntimeTest1 parent, OpenJPAEntityManager pm) {
+        RuntimeTest1 child;
+        for (int i = 0; i < CHILD_COUNT; i++) {
+            child = newRuntimeTest1("CHILD" + i, i * 10);
+            child.setSelfOneOne(parent);
+            parent.getSelfOneMany().add(child);
+        }
+
+        startTx(pm);
+        pm.persist(parent);
+        endTx(pm);
+    }
+
+    private RuntimeTest1 newRuntimeTest1(String stringField, int intField) {
+        RuntimeTest1 pc = new RuntimeTest1(stringField, intField);
+        pc.setIntField(id++);
+        return pc;
+    }
+
+    private RuntimeTest2 newRuntimeTest2(String stringField, int intField) {
+        RuntimeTest2 pc = new RuntimeTest2(stringField, intField);
+        pc.setIntField(id++);
+        return pc;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRestoreValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRestoreValues.java
index eed98c2..913bcf9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRestoreValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRestoreValues.java
@@ -1,142 +1,142 @@
-/*
- * TestRestoreValues.java
- *
- * Created on October 13, 2006, 4:48 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.math.BigInteger;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.RestoreStateType;
-
-public class TestRestoreValues extends BaseKernelTest {
-
-    private Object _oid = null;
-
-    /**
-     * Creates a new instance of TestRestoreValues
-     */
-    public TestRestoreValues(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(FetchGroupTestObject.class);
-
-        FetchGroupTestObject pc = new FetchGroupTestObject();
-        pc.setA(1);
-        pc.setB("2");
-        pc.setC(new BigInteger("100"));
-
-        OpenJPAEntityManager pm = getPM();
-        //pm.getTransaction().begin();
-        startTx(pm);
-        pm.persist(pc);
-        //pm.getTransaction().commit();
-        endTx(pm);
-        _oid = pm.getObjectId(pc);
-        endEm(pm);
-    }
-
-    public OpenJPAEntityManager getPM() {
-        OpenJPAEntityManager pm = super.getPM();
-        pm.setOptimistic(true);
-        //pm.setRestoreValues(true);
-        //pm.setRetainValues(true);
-        pm.setRestoreState(RestoreStateType.ALL);
-        pm.setRetainState(true);
-
-        return pm;
-    }
-
-    public void testUnloadedFieldDirtiedBeforeLoadedField() {
-        OpenJPAEntityManager pm = getPM();
-        FetchGroupTestObject pc = (FetchGroupTestObject) pm.find
-            (FetchGroupTestObject.class, _oid);
-
-        assertNotNull("fetch object is null", pc);
-
-        startTx(pm);
-        pc.setB("3");
-        pc.setA(2);
-        rollbackTx(pm);
-
-        assertEquals(1, pc.getA());
-        assertEquals("2", pc.getB());
-        assertEquals(new BigInteger("100"), pc.getC());
-        endEm(pm);
-    }
-
-    public void testUnloadedFieldDirtiedAfterLoadedField() {
-        OpenJPAEntityManager pm = getPM();
-        FetchGroupTestObject pc = (FetchGroupTestObject) pm.find
-            (FetchGroupTestObject.class, _oid);
-
-        startTx(pm);
-        pc.setA(2);
-        pc.setB("3");
-        rollbackTx(pm);
-
-        assertEquals(1, pc.getA());
-        assertEquals("2", pc.getB());
-        assertEquals(new BigInteger("100"), pc.getC());
-        endEm(pm);
-    }
-
-    public void testLoadedFieldDirtiedAfterLoadedField() {
-        OpenJPAEntityManager pm = getPM();
-        FetchGroupTestObject pc = (FetchGroupTestObject) pm.find
-            (FetchGroupTestObject.class, _oid);
-
-        startTx(pm);
-        pc.setA(2);
-        pc.getB();
-        pc.setB("3");
-        rollbackTx(pm);
-
-        assertEquals(1, pc.getA());
-        assertEquals("2", pc.getB());
-        assertEquals(new BigInteger("100"), pc.getC());
-        endEm(pm);
-    }
-
-    public void testNewInstanceUnmodifiedInTransaction() {
-        FetchGroupTestObject pc = new FetchGroupTestObject();
-        pc.setA(2);
-        pc.setB("3");
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(pc);
-        rollbackTx(pm);
-        assertEquals(2, pc.getA());
-        assertEquals("3", pc.getB());
-        endEm(pm);
-    }
-}
+/*
+ * TestRestoreValues.java
+ *
+ * Created on October 13, 2006, 4:48 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.math.BigInteger;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.RestoreStateType;
+
+public class TestRestoreValues extends BaseKernelTest {
+
+    private Object _oid = null;
+
+    /**
+     * Creates a new instance of TestRestoreValues
+     */
+    public TestRestoreValues(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(FetchGroupTestObject.class);
+
+        FetchGroupTestObject pc = new FetchGroupTestObject();
+        pc.setA(1);
+        pc.setB("2");
+        pc.setC(new BigInteger("100"));
+
+        OpenJPAEntityManager pm = getPM();
+        //pm.getTransaction().begin();
+        startTx(pm);
+        pm.persist(pc);
+        //pm.getTransaction().commit();
+        endTx(pm);
+        _oid = pm.getObjectId(pc);
+        endEm(pm);
+    }
+
+    public OpenJPAEntityManager getPM() {
+        OpenJPAEntityManager pm = super.getPM();
+        pm.setOptimistic(true);
+        //pm.setRestoreValues(true);
+        //pm.setRetainValues(true);
+        pm.setRestoreState(RestoreStateType.ALL);
+        pm.setRetainState(true);
+
+        return pm;
+    }
+
+    public void testUnloadedFieldDirtiedBeforeLoadedField() {
+        OpenJPAEntityManager pm = getPM();
+        FetchGroupTestObject pc = (FetchGroupTestObject) pm.find
+            (FetchGroupTestObject.class, _oid);
+
+        assertNotNull("fetch object is null", pc);
+
+        startTx(pm);
+        pc.setB("3");
+        pc.setA(2);
+        rollbackTx(pm);
+
+        assertEquals(1, pc.getA());
+        assertEquals("2", pc.getB());
+        assertEquals(new BigInteger("100"), pc.getC());
+        endEm(pm);
+    }
+
+    public void testUnloadedFieldDirtiedAfterLoadedField() {
+        OpenJPAEntityManager pm = getPM();
+        FetchGroupTestObject pc = (FetchGroupTestObject) pm.find
+            (FetchGroupTestObject.class, _oid);
+
+        startTx(pm);
+        pc.setA(2);
+        pc.setB("3");
+        rollbackTx(pm);
+
+        assertEquals(1, pc.getA());
+        assertEquals("2", pc.getB());
+        assertEquals(new BigInteger("100"), pc.getC());
+        endEm(pm);
+    }
+
+    public void testLoadedFieldDirtiedAfterLoadedField() {
+        OpenJPAEntityManager pm = getPM();
+        FetchGroupTestObject pc = (FetchGroupTestObject) pm.find
+            (FetchGroupTestObject.class, _oid);
+
+        startTx(pm);
+        pc.setA(2);
+        pc.getB();
+        pc.setB("3");
+        rollbackTx(pm);
+
+        assertEquals(1, pc.getA());
+        assertEquals("2", pc.getB());
+        assertEquals(new BigInteger("100"), pc.getC());
+        endEm(pm);
+    }
+
+    public void testNewInstanceUnmodifiedInTransaction() {
+        FetchGroupTestObject pc = new FetchGroupTestObject();
+        pc.setA(2);
+        pc.setB("3");
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(pc);
+        rollbackTx(pm);
+        assertEquals(2, pc.getA());
+        assertEquals("3", pc.getB());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java
index 0b11839..d8aac1d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestRetainValuesInOptimistic.java
@@ -1,183 +1,183 @@
-/*
- * TestRetainValuesInOptimistic.java
- *
- * Created on October 16, 2006, 10:18 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestRetainValuesInOptimistic extends BaseKernelTest {
-
-    private Object _oid = null;
-
-    /**
-     * Creates a new instance of TestRetainValuesInOptimistic
-     */
-    public TestRetainValuesInOptimistic() {
-    }
-
-    public TestRetainValuesInOptimistic(String test) {
-        super(test);
-    }
-
-    public void setUp()
-        throws Exception {
-        super.setUp();
-
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        RuntimeTest1 pc = new RuntimeTest1("str1", 1);
-        pm.persist(pc);
-        endTx(pm);
-        _oid = pm.getObjectId(pc);
-        endEm(pm);
-    }
-
-    public void testRetain() {
-        clearTest(true);
-        optLockTest(true);
-    }
-
-    public void testNotRetain() {
-        clearTest(false);
-        optLockTest(false);
-    }
-
-    private void clearTest(boolean retain) {
-        OpenJPAEntityManager pm = getPM(retain);
-        OpenJPAEntityManagerFactory pmf = pm.getEntityManagerFactory();
-        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-
-        OpenJPAEntityManager pm2 = getPM();
-        RuntimeTest1 pc2 = (RuntimeTest1) pm2.find(RuntimeTest1.class, _oid);
-        startTx(pm2);
-        pc2.setStringField("str2");
-        pc2.setIntField1(2);
-        endTx(pm2);
-        endEm(pm2);
-
-        startTx(pm);
-        // tickle the object so that it enters the transaction
-        pc.setLocaleField(Locale.CHINA);
-        assertEquals((retain) ? "str1" : "str2", pc.getStringField());
-        assertEquals((retain) ? 1 : 2, pc.getIntField1());
-        try {
-            endTx(pm);
-            if (retain)
-                fail("Should have caused OL violation");
-        }
-        catch (RuntimeException re) {
-            if (!retain)
-                throw re;
-        }
-        catch (Exception e) {
-            //
-        }
-
-        endEm(pm);
-
-        // make sure everything stuck
-        if (!retain) {
-            pm = getPM();
-            pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-            assertEquals("str2", pc.getStringField());
-            assertEquals(2, pc.getIntField1());
-            endEm(pm);
-            try {
-                pmf.close();
-            } catch (Exception e) {
-                // consumme exceptions ... other PMs might be open and
-                // active on this PMF.
-            }
-        }
-    }
-
-    private void optLockTest(boolean retain) {
-        OpenJPAEntityManager pm1 = getPM(retain);
-        OpenJPAEntityManagerFactory pmf = pm1.getEntityManagerFactory();
-
-        startTx(pm1);
-        RuntimeTest1 pc1 = (RuntimeTest1) pm1.find(RuntimeTest1.class, _oid);
-        endTx(pm1);
-
-        OpenJPAEntityManager pm2 = getPM(retain);
-        startTx(pm2);
-        RuntimeTest1 pc2 = (RuntimeTest1) pm2.find(RuntimeTest1.class, _oid);
-        pc2.setStringField("str3");
-        pc2.setIntField1(3);
-        endTx(pm2);
-
-        startTx(pm1);
-        pc1.setStringField("str4");
-        pc1.setIntField1(4);
-        try {
-            endTx(pm1);
-            if (retain)
-                fail("Expected opt lock error.");
-        } catch (Exception jove) {
-            if (!retain)
-                fail("Caught opt lock error.");
-        }
-
-        pm1.close();
-        endEm(pm2);
-        if (retain) {
-            try {
-                pmf.close();
-            } catch (Exception e) {
-                // maybe other PMs are open...
-            }
-        }
-    }
-
-    private OpenJPAEntityManager getPM(boolean retain) {
-        OpenJPAEntityManager pm;
-        Map props = new HashMap();
-        props.put("openjpa.AutoClear", "all");
-
-        if (retain)
-            pm = getPM(true, true);
-        else {
-            OpenJPAEntityManagerFactory pmf = getEmf(props);
-
-            pm = (OpenJPAEntityManager) pmf.createEntityManager();
-            pm.setOptimistic(true);
-            pm.setRetainState(true);
-        }
-        return pm;
-    }
-}
+/*
+ * TestRetainValuesInOptimistic.java
+ *
+ * Created on October 16, 2006, 10:18 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestRetainValuesInOptimistic extends BaseKernelTest {
+
+    private Object _oid = null;
+
+    /**
+     * Creates a new instance of TestRetainValuesInOptimistic
+     */
+    public TestRetainValuesInOptimistic() {
+    }
+
+    public TestRetainValuesInOptimistic(String test) {
+        super(test);
+    }
+
+    public void setUp()
+        throws Exception {
+        super.setUp();
+
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        RuntimeTest1 pc = new RuntimeTest1("str1", 1);
+        pm.persist(pc);
+        endTx(pm);
+        _oid = pm.getObjectId(pc);
+        endEm(pm);
+    }
+
+    public void testRetain() {
+        clearTest(true);
+        optLockTest(true);
+    }
+
+    public void testNotRetain() {
+        clearTest(false);
+        optLockTest(false);
+    }
+
+    private void clearTest(boolean retain) {
+        OpenJPAEntityManager pm = getPM(retain);
+        OpenJPAEntityManagerFactory pmf = pm.getEntityManagerFactory();
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+
+        OpenJPAEntityManager pm2 = getPM();
+        RuntimeTest1 pc2 = (RuntimeTest1) pm2.find(RuntimeTest1.class, _oid);
+        startTx(pm2);
+        pc2.setStringField("str2");
+        pc2.setIntField1(2);
+        endTx(pm2);
+        endEm(pm2);
+
+        startTx(pm);
+        // tickle the object so that it enters the transaction
+        pc.setLocaleField(Locale.CHINA);
+        assertEquals((retain) ? "str1" : "str2", pc.getStringField());
+        assertEquals((retain) ? 1 : 2, pc.getIntField1());
+        try {
+            endTx(pm);
+            if (retain)
+                fail("Should have caused OL violation");
+        }
+        catch (RuntimeException re) {
+            if (!retain)
+                throw re;
+        }
+        catch (Exception e) {
+            //
+        }
+
+        endEm(pm);
+
+        // make sure everything stuck
+        if (!retain) {
+            pm = getPM();
+            pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+            assertEquals("str2", pc.getStringField());
+            assertEquals(2, pc.getIntField1());
+            endEm(pm);
+            try {
+                pmf.close();
+            } catch (Exception e) {
+                // consumme exceptions ... other PMs might be open and
+                // active on this PMF.
+            }
+        }
+    }
+
+    private void optLockTest(boolean retain) {
+        OpenJPAEntityManager pm1 = getPM(retain);
+        OpenJPAEntityManagerFactory pmf = pm1.getEntityManagerFactory();
+
+        startTx(pm1);
+        RuntimeTest1 pc1 = (RuntimeTest1) pm1.find(RuntimeTest1.class, _oid);
+        endTx(pm1);
+
+        OpenJPAEntityManager pm2 = getPM(retain);
+        startTx(pm2);
+        RuntimeTest1 pc2 = (RuntimeTest1) pm2.find(RuntimeTest1.class, _oid);
+        pc2.setStringField("str3");
+        pc2.setIntField1(3);
+        endTx(pm2);
+
+        startTx(pm1);
+        pc1.setStringField("str4");
+        pc1.setIntField1(4);
+        try {
+            endTx(pm1);
+            if (retain)
+                fail("Expected opt lock error.");
+        } catch (Exception jove) {
+            if (!retain)
+                fail("Caught opt lock error.");
+        }
+
+        pm1.close();
+        endEm(pm2);
+        if (retain) {
+            try {
+                pmf.close();
+            } catch (Exception e) {
+                // maybe other PMs are open...
+            }
+        }
+    }
+
+    private OpenJPAEntityManager getPM(boolean retain) {
+        OpenJPAEntityManager pm;
+        Map props = new HashMap();
+        props.put("openjpa.AutoClear", "all");
+
+        if (retain)
+            pm = getPM(true, true);
+        else {
+            OpenJPAEntityManagerFactory pmf = getEmf(props);
+
+            pm = (OpenJPAEntityManager) pmf.createEntityManager();
+            pm.setOptimistic(true);
+            pm.setRetainState(true);
+        }
+        return pm;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbedded.java
index 34ec684..ee3bf89 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbedded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbedded.java
@@ -1,300 +1,300 @@
-/*
- * TestSavepointEmbedded.java
- *
- * Created on October 16, 2006, 10:29 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Properties;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedOwnerPC;
-import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedPC;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestSavepointEmbedded extends BaseKernelTest {
-
-    private int id = 10000;
-
-    /**
-     * Creates a new instance of TestSavepointEmbedded
-     */
-    public TestSavepointEmbedded(String name) {
-        super(name);
-    }
-
-    protected String getSavepointPlugin() {
-        return "in-mem(PreFlush=false)";
-    }
-
-    protected boolean expectNewEmbeddedFailure() {
-        return true;
-    }
-
-    public Properties getProperties(String[] props) {
-        Properties properties = super.getProperties(props);
-        properties.put("openjpa.SavepointManager", getSavepointPlugin());
-        return properties;
-    }
-
-    public void setUp() {
-        deleteAll(EmbeddedOwnerPC.class);
-    }
-
-    private EmbeddedOwnerPC newEmbeddedOwnerPC() {
-        return new EmbeddedOwnerPC(id++, id++);
-    }
-
-    public void testClearNew()
-        throws Exception {
-        doClearNewTest(true, 0, 0);
-        doClearNewTest(true, 2, 0);
-        doClearNewTest(true, 0, 2);
-        doClearNewTest(true, 2, 2);
-        doClearNewTest(false, 0, 0);
-        doClearNewTest(false, 2, 0);
-        doClearNewTest(false, 0, 2);
-        doClearNewTest(false, 2, 2);
-    }
-
-    public void doClearNewTest(boolean newPC, int before, int after)
-        throws Exception {
-        deleteAll(EmbeddedOwnerPC.class);
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
-        pm.persist(pc);
-        pc.setStringField("orig");
-        Object oid = pm.getObjectId(pc);
-        if (!newPC) {
-            endTx(pm);
-            endEm(pm);
-            pm = getPM();
-            startTx(pm);
-            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
-        }
-        for (int i = 0; i < before; i++) {
-            pc.setStringField("b" + i);
-            pm.setSavepoint("b" + i);
-        }
-
-        pc.setStringField("test");
-        pm.setSavepoint("test");
-        EmbeddedPC embed = new EmbeddedPC();
-        embed.setIntField(99);
-        pc.setEmbedded(embed);
-
-        for (int i = 0; i < after; i++) {
-            pc.setStringField("a" + i);
-            pm.setSavepoint("a" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        if (newPC)
-            assertNull(pc.getEmbedded());
-        else
-            assertEquals(0, pc.getEmbedded().getIntField());
-        assertEquals("test", pc.getStringField());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testEmbeddedReassign() {
-        doEmbeddedReassignTest(true, 0, 0);
-        doEmbeddedReassignTest(true, 2, 0);
-        doEmbeddedReassignTest(true, 0, 2);
-        doEmbeddedReassignTest(true, 2, 2);
-        doEmbeddedReassignTest(false, 0, 0);
-        doEmbeddedReassignTest(false, 2, 0);
-        doEmbeddedReassignTest(false, 0, 2);
-        doEmbeddedReassignTest(false, 2, 2);
-    }
-
-    public void doEmbeddedReassignTest(boolean newPC, int before, int after) {
-        deleteAll(EmbeddedOwnerPC.class);
-        deleteAll(EmbeddedPC.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
-        EmbeddedPC embed = new EmbeddedPC();
-        embed.setIntField1(1000);
-        pc.setStringField("orig");
-        pm.persist(pc);
-        pc.setEmbedded(embed);
-
-        Object oid = pm.getObjectId(pc);
-        if (!newPC) {
-            endTx(pm);
-            endEm(pm);
-            pm = getPM();
-            startTx(pm);
-            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
-        }
-        for (int i = 0; i < before; i++) {
-            pc.setStringField("b" + i);
-            pm.setSavepoint("b" + i);
-        }
-
-        pm.setSavepoint("test");
-        embed = new EmbeddedPC();
-        embed.setIntField1(2000);
-        pc.setEmbedded(embed);
-
-        for (int i = 0; i < after; i++) {
-            pc.setStringField("b" + i);
-            pm.setSavepoint("a" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertNotNull(pc.getEmbedded());
-        assertEquals(1000, pc.getEmbedded().getIntField1());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testEmbeddedChange()
-        throws Exception {
-        try {
-            doEmbeddedChangeTest(true, 0, 0);
-            doEmbeddedChangeTest(true, 2, 0);
-            doEmbeddedChangeTest(true, 0, 2);
-            doEmbeddedChangeTest(true, 2, 2);
-        } catch (Throwable t) {
-            if (expectNewEmbeddedFailure())
-                bug(1141, t, "changes to new embedded not detected");
-            else
-                throw (Exception) t;
-        }
-        doEmbeddedChangeTest(false, 0, 0);
-        doEmbeddedChangeTest(false, 2, 0);
-        doEmbeddedChangeTest(false, 0, 2);
-        doEmbeddedChangeTest(false, 2, 2);
-    }
-
-    public void doEmbeddedChangeTest(boolean newPC, int before, int after) {
-        deleteAll(EmbeddedOwnerPC.class);
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
-        EmbeddedPC embed = new EmbeddedPC();
-        embed.setIntField1(1000);
-        pc.setStringField("orig");
-        pm.persist(pc);
-        pc.setEmbedded(embed);
-
-        Object oid = pm.getObjectId(pc);
-        if (!newPC) {
-            endTx(pm);
-            endEm(pm);
-            pm = getPM();
-            startTx(pm);
-            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
-        }
-        for (int i = 0; i < before; i++) {
-            pc.setStringField("b" + i);
-            pm.setSavepoint("b" + i);
-        }
-
-        pm.setSavepoint("test");
-        pc.getEmbedded().setIntField1(2000);
-
-        for (int i = 0; i < after; i++) {
-            pc.setStringField("a" + i);
-            pm.setSavepoint("a" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertNotNull(pc.getEmbedded());
-        assertEquals(1000, pc.getEmbedded().getIntField1());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testEmbeddedChange2()
-        throws Exception {
-        try {
-            doEmbeddedChangeTest2(true, 0, 0);
-            doEmbeddedChangeTest2(true, 2, 0);
-            doEmbeddedChangeTest2(true, 0, 2);
-            doEmbeddedChangeTest2(true, 2, 2);
-        } catch (Throwable t) {
-            if (expectNewEmbeddedFailure())
-                bug(1141, t, "changes to new embedded not detected");
-            else
-                throw (Exception) t;
-        }
-        doEmbeddedChangeTest2(false, 0, 0);
-        doEmbeddedChangeTest2(false, 2, 0);
-        doEmbeddedChangeTest2(false, 0, 2);
-        doEmbeddedChangeTest2(false, 2, 2);
-    }
-
-    // variation with changing embedde fields vs owner field
-    public void doEmbeddedChangeTest2(boolean newPC, int before, int after) {
-        deleteAll(EmbeddedOwnerPC.class);
-        deleteAll(EmbeddedPC.class);
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
-        EmbeddedPC embed = new EmbeddedPC();
-        embed.setIntField1(1000);
-        pc.setStringField("orig");
-        pm.persist(pc);
-        pc.setEmbedded(embed);
-
-        Object oid = pm.getObjectId(pc);
-        if (!newPC) {
-            endTx(pm);
-            endEm(pm);
-            pm = getPM();
-            startTx(pm);
-            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
-        }
-        for (int i = 0; i < before; i++) {
-            pc.getEmbedded().setIntField1(i);
-            pm.setSavepoint("b" + i);
-        }
-
-        pm.setSavepoint("test");
-        pc.getEmbedded().setIntField1(2000);
-
-        for (int i = 0; i < after; i++) {
-            pc.getEmbedded().setIntField1(i * -1);
-            pm.setSavepoint("a" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertNotNull(pc.getEmbedded());
-        if (before == 0)
-            assertEquals(1000, pc.getEmbedded().getIntField1());
-        else
-            assertEquals(before - 1, pc.getEmbedded().getIntField1());
-        endTx(pm);
-        endEm(pm);
-    }
-}
+/*
+ * TestSavepointEmbedded.java
+ *
+ * Created on October 16, 2006, 10:29 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Properties;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedOwnerPC;
+import org.apache.openjpa.persistence.kernel.common.apps.EmbeddedPC;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestSavepointEmbedded extends BaseKernelTest {
+
+    private int id = 10000;
+
+    /**
+     * Creates a new instance of TestSavepointEmbedded
+     */
+    public TestSavepointEmbedded(String name) {
+        super(name);
+    }
+
+    protected String getSavepointPlugin() {
+        return "in-mem(PreFlush=false)";
+    }
+
+    protected boolean expectNewEmbeddedFailure() {
+        return true;
+    }
+
+    public Properties getProperties(String[] props) {
+        Properties properties = super.getProperties(props);
+        properties.put("openjpa.SavepointManager", getSavepointPlugin());
+        return properties;
+    }
+
+    public void setUp() {
+        deleteAll(EmbeddedOwnerPC.class);
+    }
+
+    private EmbeddedOwnerPC newEmbeddedOwnerPC() {
+        return new EmbeddedOwnerPC(id++, id++);
+    }
+
+    public void testClearNew()
+        throws Exception {
+        doClearNewTest(true, 0, 0);
+        doClearNewTest(true, 2, 0);
+        doClearNewTest(true, 0, 2);
+        doClearNewTest(true, 2, 2);
+        doClearNewTest(false, 0, 0);
+        doClearNewTest(false, 2, 0);
+        doClearNewTest(false, 0, 2);
+        doClearNewTest(false, 2, 2);
+    }
+
+    public void doClearNewTest(boolean newPC, int before, int after)
+        throws Exception {
+        deleteAll(EmbeddedOwnerPC.class);
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
+        pm.persist(pc);
+        pc.setStringField("orig");
+        Object oid = pm.getObjectId(pc);
+        if (!newPC) {
+            endTx(pm);
+            endEm(pm);
+            pm = getPM();
+            startTx(pm);
+            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
+        }
+        for (int i = 0; i < before; i++) {
+            pc.setStringField("b" + i);
+            pm.setSavepoint("b" + i);
+        }
+
+        pc.setStringField("test");
+        pm.setSavepoint("test");
+        EmbeddedPC embed = new EmbeddedPC();
+        embed.setIntField(99);
+        pc.setEmbedded(embed);
+
+        for (int i = 0; i < after; i++) {
+            pc.setStringField("a" + i);
+            pm.setSavepoint("a" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        if (newPC)
+            assertNull(pc.getEmbedded());
+        else
+            assertEquals(0, pc.getEmbedded().getIntField());
+        assertEquals("test", pc.getStringField());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testEmbeddedReassign() {
+        doEmbeddedReassignTest(true, 0, 0);
+        doEmbeddedReassignTest(true, 2, 0);
+        doEmbeddedReassignTest(true, 0, 2);
+        doEmbeddedReassignTest(true, 2, 2);
+        doEmbeddedReassignTest(false, 0, 0);
+        doEmbeddedReassignTest(false, 2, 0);
+        doEmbeddedReassignTest(false, 0, 2);
+        doEmbeddedReassignTest(false, 2, 2);
+    }
+
+    public void doEmbeddedReassignTest(boolean newPC, int before, int after) {
+        deleteAll(EmbeddedOwnerPC.class);
+        deleteAll(EmbeddedPC.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
+        EmbeddedPC embed = new EmbeddedPC();
+        embed.setIntField1(1000);
+        pc.setStringField("orig");
+        pm.persist(pc);
+        pc.setEmbedded(embed);
+
+        Object oid = pm.getObjectId(pc);
+        if (!newPC) {
+            endTx(pm);
+            endEm(pm);
+            pm = getPM();
+            startTx(pm);
+            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
+        }
+        for (int i = 0; i < before; i++) {
+            pc.setStringField("b" + i);
+            pm.setSavepoint("b" + i);
+        }
+
+        pm.setSavepoint("test");
+        embed = new EmbeddedPC();
+        embed.setIntField1(2000);
+        pc.setEmbedded(embed);
+
+        for (int i = 0; i < after; i++) {
+            pc.setStringField("b" + i);
+            pm.setSavepoint("a" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertNotNull(pc.getEmbedded());
+        assertEquals(1000, pc.getEmbedded().getIntField1());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testEmbeddedChange()
+        throws Exception {
+        try {
+            doEmbeddedChangeTest(true, 0, 0);
+            doEmbeddedChangeTest(true, 2, 0);
+            doEmbeddedChangeTest(true, 0, 2);
+            doEmbeddedChangeTest(true, 2, 2);
+        } catch (Throwable t) {
+            if (expectNewEmbeddedFailure())
+                bug(1141, t, "changes to new embedded not detected");
+            else
+                throw (Exception) t;
+        }
+        doEmbeddedChangeTest(false, 0, 0);
+        doEmbeddedChangeTest(false, 2, 0);
+        doEmbeddedChangeTest(false, 0, 2);
+        doEmbeddedChangeTest(false, 2, 2);
+    }
+
+    public void doEmbeddedChangeTest(boolean newPC, int before, int after) {
+        deleteAll(EmbeddedOwnerPC.class);
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
+        EmbeddedPC embed = new EmbeddedPC();
+        embed.setIntField1(1000);
+        pc.setStringField("orig");
+        pm.persist(pc);
+        pc.setEmbedded(embed);
+
+        Object oid = pm.getObjectId(pc);
+        if (!newPC) {
+            endTx(pm);
+            endEm(pm);
+            pm = getPM();
+            startTx(pm);
+            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
+        }
+        for (int i = 0; i < before; i++) {
+            pc.setStringField("b" + i);
+            pm.setSavepoint("b" + i);
+        }
+
+        pm.setSavepoint("test");
+        pc.getEmbedded().setIntField1(2000);
+
+        for (int i = 0; i < after; i++) {
+            pc.setStringField("a" + i);
+            pm.setSavepoint("a" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertNotNull(pc.getEmbedded());
+        assertEquals(1000, pc.getEmbedded().getIntField1());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testEmbeddedChange2()
+        throws Exception {
+        try {
+            doEmbeddedChangeTest2(true, 0, 0);
+            doEmbeddedChangeTest2(true, 2, 0);
+            doEmbeddedChangeTest2(true, 0, 2);
+            doEmbeddedChangeTest2(true, 2, 2);
+        } catch (Throwable t) {
+            if (expectNewEmbeddedFailure())
+                bug(1141, t, "changes to new embedded not detected");
+            else
+                throw (Exception) t;
+        }
+        doEmbeddedChangeTest2(false, 0, 0);
+        doEmbeddedChangeTest2(false, 2, 0);
+        doEmbeddedChangeTest2(false, 0, 2);
+        doEmbeddedChangeTest2(false, 2, 2);
+    }
+
+    // variation with changing embedde fields vs owner field
+    public void doEmbeddedChangeTest2(boolean newPC, int before, int after) {
+        deleteAll(EmbeddedOwnerPC.class);
+        deleteAll(EmbeddedPC.class);
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        EmbeddedOwnerPC pc = newEmbeddedOwnerPC();
+        EmbeddedPC embed = new EmbeddedPC();
+        embed.setIntField1(1000);
+        pc.setStringField("orig");
+        pm.persist(pc);
+        pc.setEmbedded(embed);
+
+        Object oid = pm.getObjectId(pc);
+        if (!newPC) {
+            endTx(pm);
+            endEm(pm);
+            pm = getPM();
+            startTx(pm);
+            pc = (EmbeddedOwnerPC) pm.find(EmbeddedOwnerPC.class, oid);
+        }
+        for (int i = 0; i < before; i++) {
+            pc.getEmbedded().setIntField1(i);
+            pm.setSavepoint("b" + i);
+        }
+
+        pm.setSavepoint("test");
+        pc.getEmbedded().setIntField1(2000);
+
+        for (int i = 0; i < after; i++) {
+            pc.getEmbedded().setIntField1(i * -1);
+            pm.setSavepoint("a" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertNotNull(pc.getEmbedded());
+        if (before == 0)
+            assertEquals(1000, pc.getEmbedded().getIntField1());
+        else
+            assertEquals(before - 1, pc.getEmbedded().getIntField1());
+        endTx(pm);
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbeddedPreFlush.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbeddedPreFlush.java
index a75f7b7..bcd51d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbeddedPreFlush.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointEmbeddedPreFlush.java
@@ -1,49 +1,49 @@
-/*
- * TestSavepointEmbeddedPreFlush.java
- *
- * Created on October 16, 2006, 10:43 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-
-
-public class TestSavepointEmbeddedPreFlush extends TestSavepointEmbedded {
-
-    /**
-     * Creates a new instance of TestSavepointEmbeddedPreFlush
-     */
-    public TestSavepointEmbeddedPreFlush(String name) {
-        super(name);
-    }
-
-    protected String getSavepointPlugin() {
-        return "in-mem(PreFlush=true)";
-    }
-
-    protected boolean expectNewEmbeddedFailure() {
-        return false;
-    }
-}
+/*
+ * TestSavepointEmbeddedPreFlush.java
+ *
+ * Created on October 16, 2006, 10:43 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+
+
+public class TestSavepointEmbeddedPreFlush extends TestSavepointEmbedded {
+
+    /**
+     * Creates a new instance of TestSavepointEmbeddedPreFlush
+     */
+    public TestSavepointEmbeddedPreFlush(String name) {
+        super(name);
+    }
+
+    protected String getSavepointPlugin() {
+        return "in-mem(PreFlush=true)";
+    }
+
+    protected boolean expectNewEmbeddedFailure() {
+        return false;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointOrdering.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointOrdering.java
index bebd859..f0d0ab3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointOrdering.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepointOrdering.java
@@ -1,268 +1,268 @@
-/*
- * TestSavepointOrdering.java
- *
- * Created on October 16, 2006, 10:45 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPASavepoint;
-import org.apache.openjpa.kernel.SavepointManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-
-public class TestSavepointOrdering extends BaseKernelTest {
-
-    private static final int USER = 1;
-    private static final int RELEASED = 2;
-    private static final int ROLLBACK = 4;
-
-    static Map _assigned = new HashMap();
-
-    /**
-     * Creates a new instance of TestSavepointOrdering
-     */
-    public TestSavepointOrdering(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        _assigned.clear();
-    }
-
-    public void testCleanUpCommit() {
-        doCleanUpTest(true);
-    }
-
-    public void testCleanUpRollback() {
-        doCleanUpTest(false);
-    }
-
-    public void doCleanUpTest(boolean commit) {
-        Map props = new HashMap();
-        props.put("openjpa.SavepointManager",
-            TrackingSavepointManager.class.getName());
-        OpenJPAEntityManagerFactory pmf = getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-        startTx(pm);
-        pm.setSavepoint("test");
-        pm.setSavepoint("test2");
-        if (commit)
-            endTx(pm);
-        else
-            rollbackTx(pm);
-        assertFlags("test", RELEASED, USER | ROLLBACK);
-        assertFlags("test2", RELEASED, USER | ROLLBACK);
-        endEm(pm);
-    }
-
-    public void testOrderingWithRollback() {
-        doOrderingTest(true);
-    }
-
-    public void testOrderingWithRelease() {
-        doOrderingTest(false);
-    }
-
-    private void doOrderingTest(boolean rollback) {
-        Map props = new HashMap();
-        props.put("openjpa.SavepointManager",
-            TrackingSavepointManager.class.getName());
-        OpenJPAEntityManagerFactory pmf = getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-        startTx(pm);
-        pm.setSavepoint("before");
-        pm.setSavepoint("before2");
-        pm.setSavepoint("test");
-        pm.setSavepoint("test2");
-        pm.setSavepoint("after");
-        pm.setSavepoint("after2");
-        if (rollback)
-            pm.rollbackToSavepoint("test2");
-        else
-            pm.releaseSavepoint("test2");
-
-        assertFlags("before", 0, RELEASED | ROLLBACK);
-        assertFlags("before2", 0, RELEASED | ROLLBACK);
-        assertFlags("test", 0, RELEASED | ROLLBACK);
-        assertFlags("after", RELEASED, USER);
-        assertFlags("after2", RELEASED, USER);
-
-        if (rollback)
-            assertFlags("test2", ROLLBACK, 0);
-        else
-            assertFlags("test2", RELEASED | USER, 0);
-
-        pm.setSavepoint("after3");
-        if (rollback)
-            pm.rollbackToSavepoint("test");
-        else
-            pm.releaseSavepoint("test");
-
-        assertFlags("before", 0, RELEASED | ROLLBACK);
-        assertFlags("before2", 0, RELEASED | ROLLBACK);
-        if (rollback)
-            assertFlags("test", ROLLBACK, 0);
-        else
-            assertFlags("test", RELEASED | USER, 0);
-        assertFlags("after3", RELEASED, USER);
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    public void testDisallowFlush() {
-        Map props = new HashMap();
-        props.put("openjpa.SavepointManager",
-            TrackingSavepointManager.class.getName() + "(AllowFlush=false)");
-        OpenJPAEntityManagerFactory pmf = getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-        startTx(pm);
-        pm.persist(new RuntimeTest1());
-        pm.setSavepoint("a");
-        try {
-            pm.flush();
-            fail("should have failed.");
-        } catch (Exception e) {
-        }
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    public void testDisallowFlush2() {
-        Map props = new HashMap();
-        props.put("openjpa.SavepointManager",
-            TrackingSavepointManager.class.getName() + "(AllowFlush=false)");
-        OpenJPAEntityManagerFactory pmf = getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        startTx(pm);
-        pm.persist(new RuntimeTest1());
-        pm.flush();
-        try {
-            pm.setSavepoint("a");
-            fail("should have failed.");
-        } catch (Exception e) {
-        }
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    public void testAllowFlush() {
-        Map props = new HashMap();
-        props.put("openjpa.SavepointManager",
-            TrackingSavepointManager.class.getName() + "(AllowFlush=true)");
-        OpenJPAEntityManagerFactory pmf = getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        startTx(pm);
-        pm.persist(new RuntimeTest1());
-        pm.setSavepoint("a");
-        try {
-            pm.flush();
-        } catch (Exception e) {
-            fail("allows flush.");
-        }
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    public void testAllowFlush2() {
-        Map props = new HashMap();
-        props.put("openjpa.SavepointManager",
-            TrackingSavepointManager.class.getName() + "(AllowFlush=true)");
-        OpenJPAEntityManagerFactory pmf = getEmf(props);
-        OpenJPAEntityManager pm = pmf.createEntityManager();
-
-        startTx(pm);
-        pm.persist(new RuntimeTest1());
-        pm.flush();
-        try {
-            pm.setSavepoint("a");
-        } catch (Exception e) {
-            fail("allows flush.");
-        }
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    private void assertFlags(String name, int flag, int noflag) {
-        TrackingSavepoint sp = (TrackingSavepoint) _assigned.get(name);
-        assertNotNull(sp);
-        assertEquals(sp.flags & flag, flag);
-        assertTrue((sp.flags & noflag) == 0);
-    }
-
-    public static class TrackingSavepointManager implements SavepointManager {
-
-        public boolean allowFlush = false;
-
-        public boolean supportsIncrementalFlush() {
-            return allowFlush;
-        }
-
-        public OpenJPASavepoint newSavepoint(String name, Broker broker) {
-            TrackingSavepoint sp = new TrackingSavepoint(broker, name);
-            _assigned.put(sp.getName(), sp);
-            return sp;
-        }
-    }
-
-    private static class TrackingSavepoint extends OpenJPASavepoint {
-
-        int flags = 0;
-
-        public TrackingSavepoint(Broker broker, String name) {
-            super(broker, name, false);
-        }
-
-        public Collection rollback(Collection previous) {
-            if ((flags & (ROLLBACK | RELEASED)) != 0)
-                fail("already used");
-            flags |= ROLLBACK;
-            return super.rollback(previous);
-        }
-
-        public void release(boolean user) {
-            if ((flags & (ROLLBACK | RELEASED)) != 0)
-                fail("already used");
-            flags |= RELEASED;
-            if (user) {
-                if ((flags & USER) != 0)
-                    fail("already released");
-                flags |= USER;
-            }
-
-            super.release(user);
-        }
-    }
-}
+/*
+ * TestSavepointOrdering.java
+ *
+ * Created on October 16, 2006, 10:45 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPASavepoint;
+import org.apache.openjpa.kernel.SavepointManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+
+public class TestSavepointOrdering extends BaseKernelTest {
+
+    private static final int USER = 1;
+    private static final int RELEASED = 2;
+    private static final int ROLLBACK = 4;
+
+    static Map _assigned = new HashMap();
+
+    /**
+     * Creates a new instance of TestSavepointOrdering
+     */
+    public TestSavepointOrdering(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        _assigned.clear();
+    }
+
+    public void testCleanUpCommit() {
+        doCleanUpTest(true);
+    }
+
+    public void testCleanUpRollback() {
+        doCleanUpTest(false);
+    }
+
+    public void doCleanUpTest(boolean commit) {
+        Map props = new HashMap();
+        props.put("openjpa.SavepointManager",
+            TrackingSavepointManager.class.getName());
+        OpenJPAEntityManagerFactory pmf = getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+        startTx(pm);
+        pm.setSavepoint("test");
+        pm.setSavepoint("test2");
+        if (commit)
+            endTx(pm);
+        else
+            rollbackTx(pm);
+        assertFlags("test", RELEASED, USER | ROLLBACK);
+        assertFlags("test2", RELEASED, USER | ROLLBACK);
+        endEm(pm);
+    }
+
+    public void testOrderingWithRollback() {
+        doOrderingTest(true);
+    }
+
+    public void testOrderingWithRelease() {
+        doOrderingTest(false);
+    }
+
+    private void doOrderingTest(boolean rollback) {
+        Map props = new HashMap();
+        props.put("openjpa.SavepointManager",
+            TrackingSavepointManager.class.getName());
+        OpenJPAEntityManagerFactory pmf = getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+        startTx(pm);
+        pm.setSavepoint("before");
+        pm.setSavepoint("before2");
+        pm.setSavepoint("test");
+        pm.setSavepoint("test2");
+        pm.setSavepoint("after");
+        pm.setSavepoint("after2");
+        if (rollback)
+            pm.rollbackToSavepoint("test2");
+        else
+            pm.releaseSavepoint("test2");
+
+        assertFlags("before", 0, RELEASED | ROLLBACK);
+        assertFlags("before2", 0, RELEASED | ROLLBACK);
+        assertFlags("test", 0, RELEASED | ROLLBACK);
+        assertFlags("after", RELEASED, USER);
+        assertFlags("after2", RELEASED, USER);
+
+        if (rollback)
+            assertFlags("test2", ROLLBACK, 0);
+        else
+            assertFlags("test2", RELEASED | USER, 0);
+
+        pm.setSavepoint("after3");
+        if (rollback)
+            pm.rollbackToSavepoint("test");
+        else
+            pm.releaseSavepoint("test");
+
+        assertFlags("before", 0, RELEASED | ROLLBACK);
+        assertFlags("before2", 0, RELEASED | ROLLBACK);
+        if (rollback)
+            assertFlags("test", ROLLBACK, 0);
+        else
+            assertFlags("test", RELEASED | USER, 0);
+        assertFlags("after3", RELEASED, USER);
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    public void testDisallowFlush() {
+        Map props = new HashMap();
+        props.put("openjpa.SavepointManager",
+            TrackingSavepointManager.class.getName() + "(AllowFlush=false)");
+        OpenJPAEntityManagerFactory pmf = getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+        startTx(pm);
+        pm.persist(new RuntimeTest1());
+        pm.setSavepoint("a");
+        try {
+            pm.flush();
+            fail("should have failed.");
+        } catch (Exception e) {
+        }
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    public void testDisallowFlush2() {
+        Map props = new HashMap();
+        props.put("openjpa.SavepointManager",
+            TrackingSavepointManager.class.getName() + "(AllowFlush=false)");
+        OpenJPAEntityManagerFactory pmf = getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        startTx(pm);
+        pm.persist(new RuntimeTest1());
+        pm.flush();
+        try {
+            pm.setSavepoint("a");
+            fail("should have failed.");
+        } catch (Exception e) {
+        }
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    public void testAllowFlush() {
+        Map props = new HashMap();
+        props.put("openjpa.SavepointManager",
+            TrackingSavepointManager.class.getName() + "(AllowFlush=true)");
+        OpenJPAEntityManagerFactory pmf = getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        startTx(pm);
+        pm.persist(new RuntimeTest1());
+        pm.setSavepoint("a");
+        try {
+            pm.flush();
+        } catch (Exception e) {
+            fail("allows flush.");
+        }
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    public void testAllowFlush2() {
+        Map props = new HashMap();
+        props.put("openjpa.SavepointManager",
+            TrackingSavepointManager.class.getName() + "(AllowFlush=true)");
+        OpenJPAEntityManagerFactory pmf = getEmf(props);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        startTx(pm);
+        pm.persist(new RuntimeTest1());
+        pm.flush();
+        try {
+            pm.setSavepoint("a");
+        } catch (Exception e) {
+            fail("allows flush.");
+        }
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    private void assertFlags(String name, int flag, int noflag) {
+        TrackingSavepoint sp = (TrackingSavepoint) _assigned.get(name);
+        assertNotNull(sp);
+        assertEquals(sp.flags & flag, flag);
+        assertTrue((sp.flags & noflag) == 0);
+    }
+
+    public static class TrackingSavepointManager implements SavepointManager {
+
+        public boolean allowFlush = false;
+
+        public boolean supportsIncrementalFlush() {
+            return allowFlush;
+        }
+
+        public OpenJPASavepoint newSavepoint(String name, Broker broker) {
+            TrackingSavepoint sp = new TrackingSavepoint(broker, name);
+            _assigned.put(sp.getName(), sp);
+            return sp;
+        }
+    }
+
+    private static class TrackingSavepoint extends OpenJPASavepoint {
+
+        int flags = 0;
+
+        public TrackingSavepoint(Broker broker, String name) {
+            super(broker, name, false);
+        }
+
+        public Collection rollback(Collection previous) {
+            if ((flags & (ROLLBACK | RELEASED)) != 0)
+                fail("already used");
+            flags |= ROLLBACK;
+            return super.rollback(previous);
+        }
+
+        public void release(boolean user) {
+            if ((flags & (ROLLBACK | RELEASED)) != 0)
+                fail("already used");
+            flags |= RELEASED;
+            if (user) {
+                if ((flags & USER) != 0)
+                    fail("already released");
+                flags |= USER;
+            }
+
+            super.release(user);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepoints.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepoints.java
index e8d0bd6..2d0758e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepoints.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSavepoints.java
@@ -1,509 +1,509 @@
-/*
- * TestSavepoints.java
- *
- * Created on October 16, 2006, 11:16 AM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Iterator;
-import java.util.Properties;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest5;
-
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-public class TestSavepoints extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestSavepoints
-     */
-    public TestSavepoints(String name) {
-        super(name);
-    }
-
-    protected String getSavepointPlugin() {
-        return "in-mem";
-    }
-
-    public Properties getProperties(String[] props) {
-        Properties properties = super.getProperties(props);
-        properties.put("openjpa.SavepointManager", getSavepointPlugin());
-        return properties;
-    }
-
-    public void setUp() {
-        deleteAll(ModRuntimeTest1.class);
-        deleteAll(RuntimeTest4.class);
-        deleteAll(RuntimeTest5.class);
-    }
-
-    public void testSimple() {
-        doSimpleTest(true, 0, 0);
-        doSimpleTest(true, 2, 0);
-        doSimpleTest(true, 0, 2);
-        doSimpleTest(false, 0, 0);
-        doSimpleTest(false, 2, 0);
-        doSimpleTest(false, 0, 2);
-    }
-
-    private void doSimpleTest(boolean newPC, int before, int after) {
-        OpenJPAEntityManager pm = getPM();
-        ModRuntimeTest1 pc = new ModRuntimeTest1();
-        startTx(pm);
-        pc.setStringField("orig");
-        pc.setIntField(-11);
-        //FIXME jthomas - setDateField
-        //pc.setDateField(randomDate());
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-
-        if (!newPC) {
-            endTx(pm);
-            pm = getPM();
-            startTx(pm);
-            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        }
-        for (int i = 0; i < before; i++) {
-            pc.setStringField("before" + i);
-            pc.setIntField(i);
-            //FIXME jthomas - setDateField
-            //pc.setDateField(randomDate());
-            pm.setSavepoint("before" + i);
-        }
-
-        pc.setStringField("value");
-        pc.setIntField(333);
-        //FIXME jthomas - setDateField
-        //pc.setDateField(randomDate());
-        //Date date = (Date) pc.getDateField().clone();
-        pm.setSavepoint("test");
-
-        for (int i = 0; i < after; i++) {
-            pc.setStringField("after" + i);
-            pc.setIntField(i * 10);
-            //FIXME jthomas - setDateField
-            //pc.setDateField(randomDate());
-            pm.setSavepoint("after" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertEquals("value", pc.getStringField());
-        assertEquals(333, pc.getIntField());
-        //FIXME jthomas - setDateField
-        //assertEquals(date, pc.getDateField());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        assertEquals("value", pc.getStringField());
-        assertEquals(333, pc.getIntField());
-        //FIXME jthomas - setDateField
-        //assertEquals(date, pc.getDateField());
-        endEm(pm);
-    }
-
-    public void testCleanOrdering() {
-        OpenJPAEntityManager pm = getPM();
-        ModRuntimeTest1 pc = new ModRuntimeTest1("orig", 1);
-        startTx(pm);
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pm.setOptimistic(false);
-        startTx(pm);
-        ModRuntimeTest1 pc2 = new ModRuntimeTest1("foo", 2);
-        pm.persist(pc2);
-        pm.setSavepoint("s1");
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        assertTrue(pm.isTransactional(pc));
-        pm.setSavepoint("s2");
-        pc.setStringField("bar");
-        pm.rollbackToSavepoint("s2");
-        assertEquals("orig", pc.getStringField());
-        assertTrue(pm.isTransactional(pc));
-
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    public void testLastSavepoint() {
-        OpenJPAEntityManager pm = getPM();
-        ModRuntimeTest1 pc = new ModRuntimeTest1("orig", 1);
-        startTx(pm);
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pm.setOptimistic(false);
-        startTx(pm);
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        pc.setStringField("s1");
-        pm.setSavepoint("s1");
-        pc.setStringField("s2");
-        pm.setSavepoint("s2");
-        pc.setStringField("diff");
-        pm.rollbackToSavepoint();
-        assertEquals("s2", pc.getStringField());
-        pm.releaseSavepoint();
-        try {
-            pm.rollbackToSavepoint("s1");
-            fail("Exhausted.");
-        } catch (Exception e) {
-        }
-        rollbackTx(pm);
-        endEm(pm);
-    }
-
-    public void testNewRollback() {
-        doNewRollbackTest(false, 0, 0);
-        doNewRollbackTest(false, 2, 0);
-        doNewRollbackTest(false, 0, 2);
-        doNewRollbackTest(true, 0, 0);
-        doNewRollbackTest(true, 2, 0);
-        doNewRollbackTest(true, 0, 2);
-    }
-
-    public void doNewRollbackTest(boolean restore, int before, int after) {
-        OpenJPAEntityManager pm = getPM();
-        pm.setRetainState(restore);
-        startTx(pm);
-
-        for (int i = 0; i < before; i++) {
-            pm.persist(new ModRuntimeTest1("s" + i, i));
-            //pm.setSavepoint("before" + i);
-        }
-        pm.setSavepoint("test");
-
-        ModRuntimeTest1 pc = new ModRuntimeTest1();
-        pc.setStringField("orig");
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-
-        for (int i = 0; i < after; i++) {
-            pm.persist(new ModRuntimeTest1());
-            pm.setSavepoint("after" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertEquals("orig", pc.getStringField());
-        assertFalse(pm.isPersistent(pc));
-        assertEquals(before, pm.getTransactionalObjects().size());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        assertNull(pm.find(ModRuntimeTest1.class, oid));
-        endEm(pm);
-    }
-
-    public void testNewRelation() {
-        doNewRelationTest(true, 0, 0);
-        doNewRelationTest(true, 2, 0);
-        doNewRelationTest(true, 0, 2);
-        doNewRelationTest(false, 0, 0);
-        doNewRelationTest(false, 2, 0);
-        doNewRelationTest(false, 0, 2);
-    }
-
-    public void doNewRelationTest(boolean nullRel, int before, int after) {
-        deleteAll(ModRuntimeTest1.class);
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        ModRuntimeTest1 pc = new ModRuntimeTest1();
-        pc.setStringField("orig");
-        if (!nullRel)
-            pc.setSelfOneOne(new ModRuntimeTest1("one", 1));
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pm.setRetainState(true);
-        startTx(pm);
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-
-        for (int i = 0; i < before; i++) {
-            pc.setSelfOneOne(new ModRuntimeTest1("before" + i, i));
-            pm.setSavepoint("before" + i);
-        }
-
-        pm.setSavepoint("test");
-        pc.setSelfOneOne(new ModRuntimeTest1("new", 2));
-        ModRuntimeTest1 pc2 = pc.getSelfOneOne();
-
-        for (int i = 0; i < after; i++) {
-            pc.setSelfOneOne(new ModRuntimeTest1());
-            pm.setSavepoint("after" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertEquals("orig", pc.getStringField());
-        assertFalse(pm.isPersistent(pc2));
-        if (before > 0)
-            assertEquals("before" + (before - 1),
-                pc.getSelfOneOne().getStringField());
-        else {
-            if (nullRel)
-                assertNull(pc.getSelfOneOne());
-            else
-                assertEquals("one", pc.getSelfOneOne().getStringField());
-        }
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        assertEquals("orig", pc.getStringField());
-        if (before > 0)
-            assertEquals("before" + (before - 1),
-                pc.getSelfOneOne().getStringField());
-        else {
-            if (nullRel)
-                assertNull(pc.getSelfOneOne());
-            else
-                assertEquals("one", pc.getSelfOneOne().getStringField());
-        }
-        endEm(pm);
-    }
-
-    public void testNullRelation() {
-        doNullRelationTest(true, 0, 0);
-        doNullRelationTest(true, 2, 0);
-        doNullRelationTest(true, 0, 2);
-        doNullRelationTest(false, 0, 0);
-        doNullRelationTest(false, 2, 0);
-        doNullRelationTest(false, 0, 2);
-    }
-
-    public void doNullRelationTest(boolean retain, int before, int after) {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        ModRuntimeTest1 pc = new ModRuntimeTest1();
-        pc.setStringField("orig");
-        pc.setSelfOneOne(new ModRuntimeTest1("one", 1));
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pm.setRetainState(true);
-        startTx(pm);
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-
-        for (int i = 0; i < before; i++) {
-            pc.setSelfOneOne(new ModRuntimeTest1("before" + i, i));
-            pm.setSavepoint("before" + i);
-        }
-
-        pm.setSavepoint("test");
-        pc.setSelfOneOne(null);
-
-        for (int i = 0; i < after; i++) {
-            pc.setSelfOneOne(new ModRuntimeTest1());
-            pm.setSavepoint("after" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-        assertEquals("orig", pc.getStringField());
-        if (before > 0)
-            assertEquals("before" + (before - 1),
-                pc.getSelfOneOne().getStringField());
-        else
-            assertEquals("one", pc.getSelfOneOne().getStringField());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        assertEquals("orig", pc.getStringField());
-        if (before > 0)
-            assertEquals("before" + (before - 1),
-                pc.getSelfOneOne().getStringField());
-        else
-            assertEquals("one", pc.getSelfOneOne().getStringField());
-        endEm(pm);
-    }
-
-    public void testCollection() {
-        doCollectionTest(true, 0, 0);
-        doCollectionTest(true, 2, 0);
-        doCollectionTest(true, 0, 2);
-        doCollectionTest(false, 0, 0);
-        doCollectionTest(false, 2, 0);
-        doCollectionTest(false, 0, 2);
-    }
-
-    public void doCollectionTest(boolean newPC, int before, int after) {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        ModRuntimeTest1 pc = new ModRuntimeTest1("orig", 1);
-        ModRuntimeTest1 pc2 = newElement(pc, "persist", 2);
-        ModRuntimeTest1 pc3 = newElement(pc, "delete", 3);
-        pm.persist(pc);
-        pm.persist(pc3);
-        Object oid = pm.getObjectId(pc);
-        ModRuntimeTest1 temp;
-        if (!newPC) {
-            endTx(pm);
-            endEm(pm);
-
-            pm = getPM();
-            startTx(pm);
-            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-            assertEquals(2, pc.getSelfOneMany().size());
-            for (Iterator it = pc.getSelfOneMany().iterator(); it.hasNext();) {
-                temp = (ModRuntimeTest1) it.next();
-                if (temp.getIntField() == 2)
-                    pc2 = temp;
-                else if (temp.getIntField() == 3)
-                    pc3 = temp;
-                else
-                    fail("unknown");
-            }
-        }
-
-        for (int i = 0; i < before; i++) {
-            newElement(pc, "before" + i, (i + 1) * 10);
-            pm.setSavepoint("before" + i);
-        }
-        pm.setSavepoint("test");
-        pm.remove(pc3);
-        pc.getSelfOneMany().remove(pc2);
-
-        // kodo 4 is more stringent on deleted relations.
-        pc.getSelfOneMany().remove(pc3);
-        pc2.setSelfOneMany(null);
-
-        for (int i = 0; i < after; i++) {
-            newElement(pc, "after" + i, (i + 1) * -10);
-            pm.setSavepoint("after" + i);
-        }
-
-        pm.rollbackToSavepoint("test");
-
-        assertEquals("orig", pc.getStringField());
-        assertFalse(pm.isRemoved(pc2));
-        for (Iterator it = pc.getSelfOneMany().iterator(); it.hasNext();) {
-            temp = (ModRuntimeTest1) it.next();
-            assertFalse(pm.isRemoved(temp));
-            assertEquals(pc, temp.getSelfOneOne());
-            if (temp.getIntField() < 0)
-                fail("shouldn't be here:" + temp.getStringField());
-        }
-        assertTrue(pc.getSelfOneMany().contains(pc2));
-        assertTrue(pc.getSelfOneMany().contains(pc3));
-        assertEquals(2 + before, pc.getSelfOneMany().size());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        assertEquals("orig", pc.getStringField());
-        assertEquals(2 + before, pc.getSelfOneMany().size());
-        boolean found2 = false;
-        boolean found3 = false;
-        for (Iterator it = pc.getSelfOneMany().iterator(); it.hasNext();) {
-            temp = (ModRuntimeTest1) it.next();
-            assertEquals(pc, temp.getSelfOneOne());
-            if (temp.getIntField() < 0)
-                fail("shouldn't be here:" + temp.getStringField());
-            else if (temp.getIntField() == 2)
-                found2 = true;
-            else if (temp.getIntField() == 3)
-                found3 = true;
-        }
-        assertTrue(found2 && found3);
-        endEm(pm);
-    }
-
-    public void testChangeTracker() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        RuntimeTest4 pc = new RuntimeTest4("orig");
-        for (int i = 0; i < 12; i++)
-            pc.getRuntimeTest5s().add(new RuntimeTest5("five" + i));
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        startTx(pm);
-        pc = (RuntimeTest4) pm.find(RuntimeTest4.class, oid);
-        assertEquals(12, pc.getRuntimeTest5s().size());
-        int count = 0;
-        for (Iterator i = pc.getRuntimeTest5s().iterator();
-            count < 2; count++) {
-            i.next();
-            i.remove();
-        }
-        assertEquals(10, pc.getRuntimeTest5s().size());
-        pm.setSavepoint("test");
-        count = 0;
-        for (Iterator i = pc.getRuntimeTest5s().iterator();
-            count < 2; count++) {
-            i.next();
-            i.remove();
-        }
-        assertEquals(8, pc.getRuntimeTest5s().size());
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        pc = (RuntimeTest4) pm.find(RuntimeTest4.class, oid);
-        assertEquals(8, pc.getRuntimeTest5s().size());
-        endEm(pm);
-    }
-
-    private ModRuntimeTest1 newElement(ModRuntimeTest1 one, String str, int i) {
-        ModRuntimeTest1 two = new ModRuntimeTest1(str, i);
-        two.setSelfOneOne(one);
-        one.getSelfOneMany().add(two);
-        return two;
-    }
-
-    public static PCState getState(Object o) {
-        OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(o);
-
-        if (pm == null)
-            return null;
-        return JPAFacadeHelper.toBroker(pm).getStateManager(o).getPCState();
-    }
-}
+/*
+ * TestSavepoints.java
+ *
+ * Created on October 16, 2006, 11:16 AM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Iterator;
+import java.util.Properties;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest5;
+
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+public class TestSavepoints extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestSavepoints
+     */
+    public TestSavepoints(String name) {
+        super(name);
+    }
+
+    protected String getSavepointPlugin() {
+        return "in-mem";
+    }
+
+    public Properties getProperties(String[] props) {
+        Properties properties = super.getProperties(props);
+        properties.put("openjpa.SavepointManager", getSavepointPlugin());
+        return properties;
+    }
+
+    public void setUp() {
+        deleteAll(ModRuntimeTest1.class);
+        deleteAll(RuntimeTest4.class);
+        deleteAll(RuntimeTest5.class);
+    }
+
+    public void testSimple() {
+        doSimpleTest(true, 0, 0);
+        doSimpleTest(true, 2, 0);
+        doSimpleTest(true, 0, 2);
+        doSimpleTest(false, 0, 0);
+        doSimpleTest(false, 2, 0);
+        doSimpleTest(false, 0, 2);
+    }
+
+    private void doSimpleTest(boolean newPC, int before, int after) {
+        OpenJPAEntityManager pm = getPM();
+        ModRuntimeTest1 pc = new ModRuntimeTest1();
+        startTx(pm);
+        pc.setStringField("orig");
+        pc.setIntField(-11);
+        //FIXME jthomas - setDateField
+        //pc.setDateField(randomDate());
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+
+        if (!newPC) {
+            endTx(pm);
+            pm = getPM();
+            startTx(pm);
+            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        }
+        for (int i = 0; i < before; i++) {
+            pc.setStringField("before" + i);
+            pc.setIntField(i);
+            //FIXME jthomas - setDateField
+            //pc.setDateField(randomDate());
+            pm.setSavepoint("before" + i);
+        }
+
+        pc.setStringField("value");
+        pc.setIntField(333);
+        //FIXME jthomas - setDateField
+        //pc.setDateField(randomDate());
+        //Date date = (Date) pc.getDateField().clone();
+        pm.setSavepoint("test");
+
+        for (int i = 0; i < after; i++) {
+            pc.setStringField("after" + i);
+            pc.setIntField(i * 10);
+            //FIXME jthomas - setDateField
+            //pc.setDateField(randomDate());
+            pm.setSavepoint("after" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertEquals("value", pc.getStringField());
+        assertEquals(333, pc.getIntField());
+        //FIXME jthomas - setDateField
+        //assertEquals(date, pc.getDateField());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        assertEquals("value", pc.getStringField());
+        assertEquals(333, pc.getIntField());
+        //FIXME jthomas - setDateField
+        //assertEquals(date, pc.getDateField());
+        endEm(pm);
+    }
+
+    public void testCleanOrdering() {
+        OpenJPAEntityManager pm = getPM();
+        ModRuntimeTest1 pc = new ModRuntimeTest1("orig", 1);
+        startTx(pm);
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pm.setOptimistic(false);
+        startTx(pm);
+        ModRuntimeTest1 pc2 = new ModRuntimeTest1("foo", 2);
+        pm.persist(pc2);
+        pm.setSavepoint("s1");
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        assertTrue(pm.isTransactional(pc));
+        pm.setSavepoint("s2");
+        pc.setStringField("bar");
+        pm.rollbackToSavepoint("s2");
+        assertEquals("orig", pc.getStringField());
+        assertTrue(pm.isTransactional(pc));
+
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    public void testLastSavepoint() {
+        OpenJPAEntityManager pm = getPM();
+        ModRuntimeTest1 pc = new ModRuntimeTest1("orig", 1);
+        startTx(pm);
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pm.setOptimistic(false);
+        startTx(pm);
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        pc.setStringField("s1");
+        pm.setSavepoint("s1");
+        pc.setStringField("s2");
+        pm.setSavepoint("s2");
+        pc.setStringField("diff");
+        pm.rollbackToSavepoint();
+        assertEquals("s2", pc.getStringField());
+        pm.releaseSavepoint();
+        try {
+            pm.rollbackToSavepoint("s1");
+            fail("Exhausted.");
+        } catch (Exception e) {
+        }
+        rollbackTx(pm);
+        endEm(pm);
+    }
+
+    public void testNewRollback() {
+        doNewRollbackTest(false, 0, 0);
+        doNewRollbackTest(false, 2, 0);
+        doNewRollbackTest(false, 0, 2);
+        doNewRollbackTest(true, 0, 0);
+        doNewRollbackTest(true, 2, 0);
+        doNewRollbackTest(true, 0, 2);
+    }
+
+    public void doNewRollbackTest(boolean restore, int before, int after) {
+        OpenJPAEntityManager pm = getPM();
+        pm.setRetainState(restore);
+        startTx(pm);
+
+        for (int i = 0; i < before; i++) {
+            pm.persist(new ModRuntimeTest1("s" + i, i));
+            //pm.setSavepoint("before" + i);
+        }
+        pm.setSavepoint("test");
+
+        ModRuntimeTest1 pc = new ModRuntimeTest1();
+        pc.setStringField("orig");
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+
+        for (int i = 0; i < after; i++) {
+            pm.persist(new ModRuntimeTest1());
+            pm.setSavepoint("after" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertEquals("orig", pc.getStringField());
+        assertFalse(pm.isPersistent(pc));
+        assertEquals(before, pm.getTransactionalObjects().size());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        assertNull(pm.find(ModRuntimeTest1.class, oid));
+        endEm(pm);
+    }
+
+    public void testNewRelation() {
+        doNewRelationTest(true, 0, 0);
+        doNewRelationTest(true, 2, 0);
+        doNewRelationTest(true, 0, 2);
+        doNewRelationTest(false, 0, 0);
+        doNewRelationTest(false, 2, 0);
+        doNewRelationTest(false, 0, 2);
+    }
+
+    public void doNewRelationTest(boolean nullRel, int before, int after) {
+        deleteAll(ModRuntimeTest1.class);
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        ModRuntimeTest1 pc = new ModRuntimeTest1();
+        pc.setStringField("orig");
+        if (!nullRel)
+            pc.setSelfOneOne(new ModRuntimeTest1("one", 1));
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pm.setRetainState(true);
+        startTx(pm);
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+
+        for (int i = 0; i < before; i++) {
+            pc.setSelfOneOne(new ModRuntimeTest1("before" + i, i));
+            pm.setSavepoint("before" + i);
+        }
+
+        pm.setSavepoint("test");
+        pc.setSelfOneOne(new ModRuntimeTest1("new", 2));
+        ModRuntimeTest1 pc2 = pc.getSelfOneOne();
+
+        for (int i = 0; i < after; i++) {
+            pc.setSelfOneOne(new ModRuntimeTest1());
+            pm.setSavepoint("after" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertEquals("orig", pc.getStringField());
+        assertFalse(pm.isPersistent(pc2));
+        if (before > 0)
+            assertEquals("before" + (before - 1),
+                pc.getSelfOneOne().getStringField());
+        else {
+            if (nullRel)
+                assertNull(pc.getSelfOneOne());
+            else
+                assertEquals("one", pc.getSelfOneOne().getStringField());
+        }
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        assertEquals("orig", pc.getStringField());
+        if (before > 0)
+            assertEquals("before" + (before - 1),
+                pc.getSelfOneOne().getStringField());
+        else {
+            if (nullRel)
+                assertNull(pc.getSelfOneOne());
+            else
+                assertEquals("one", pc.getSelfOneOne().getStringField());
+        }
+        endEm(pm);
+    }
+
+    public void testNullRelation() {
+        doNullRelationTest(true, 0, 0);
+        doNullRelationTest(true, 2, 0);
+        doNullRelationTest(true, 0, 2);
+        doNullRelationTest(false, 0, 0);
+        doNullRelationTest(false, 2, 0);
+        doNullRelationTest(false, 0, 2);
+    }
+
+    public void doNullRelationTest(boolean retain, int before, int after) {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        ModRuntimeTest1 pc = new ModRuntimeTest1();
+        pc.setStringField("orig");
+        pc.setSelfOneOne(new ModRuntimeTest1("one", 1));
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pm.setRetainState(true);
+        startTx(pm);
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+
+        for (int i = 0; i < before; i++) {
+            pc.setSelfOneOne(new ModRuntimeTest1("before" + i, i));
+            pm.setSavepoint("before" + i);
+        }
+
+        pm.setSavepoint("test");
+        pc.setSelfOneOne(null);
+
+        for (int i = 0; i < after; i++) {
+            pc.setSelfOneOne(new ModRuntimeTest1());
+            pm.setSavepoint("after" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+        assertEquals("orig", pc.getStringField());
+        if (before > 0)
+            assertEquals("before" + (before - 1),
+                pc.getSelfOneOne().getStringField());
+        else
+            assertEquals("one", pc.getSelfOneOne().getStringField());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        assertEquals("orig", pc.getStringField());
+        if (before > 0)
+            assertEquals("before" + (before - 1),
+                pc.getSelfOneOne().getStringField());
+        else
+            assertEquals("one", pc.getSelfOneOne().getStringField());
+        endEm(pm);
+    }
+
+    public void testCollection() {
+        doCollectionTest(true, 0, 0);
+        doCollectionTest(true, 2, 0);
+        doCollectionTest(true, 0, 2);
+        doCollectionTest(false, 0, 0);
+        doCollectionTest(false, 2, 0);
+        doCollectionTest(false, 0, 2);
+    }
+
+    public void doCollectionTest(boolean newPC, int before, int after) {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        ModRuntimeTest1 pc = new ModRuntimeTest1("orig", 1);
+        ModRuntimeTest1 pc2 = newElement(pc, "persist", 2);
+        ModRuntimeTest1 pc3 = newElement(pc, "delete", 3);
+        pm.persist(pc);
+        pm.persist(pc3);
+        Object oid = pm.getObjectId(pc);
+        ModRuntimeTest1 temp;
+        if (!newPC) {
+            endTx(pm);
+            endEm(pm);
+
+            pm = getPM();
+            startTx(pm);
+            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+            assertEquals(2, pc.getSelfOneMany().size());
+            for (Iterator it = pc.getSelfOneMany().iterator(); it.hasNext();) {
+                temp = (ModRuntimeTest1) it.next();
+                if (temp.getIntField() == 2)
+                    pc2 = temp;
+                else if (temp.getIntField() == 3)
+                    pc3 = temp;
+                else
+                    fail("unknown");
+            }
+        }
+
+        for (int i = 0; i < before; i++) {
+            newElement(pc, "before" + i, (i + 1) * 10);
+            pm.setSavepoint("before" + i);
+        }
+        pm.setSavepoint("test");
+        pm.remove(pc3);
+        pc.getSelfOneMany().remove(pc2);
+
+        // kodo 4 is more stringent on deleted relations.
+        pc.getSelfOneMany().remove(pc3);
+        pc2.setSelfOneMany(null);
+
+        for (int i = 0; i < after; i++) {
+            newElement(pc, "after" + i, (i + 1) * -10);
+            pm.setSavepoint("after" + i);
+        }
+
+        pm.rollbackToSavepoint("test");
+
+        assertEquals("orig", pc.getStringField());
+        assertFalse(pm.isRemoved(pc2));
+        for (Iterator it = pc.getSelfOneMany().iterator(); it.hasNext();) {
+            temp = (ModRuntimeTest1) it.next();
+            assertFalse(pm.isRemoved(temp));
+            assertEquals(pc, temp.getSelfOneOne());
+            if (temp.getIntField() < 0)
+                fail("shouldn't be here:" + temp.getStringField());
+        }
+        assertTrue(pc.getSelfOneMany().contains(pc2));
+        assertTrue(pc.getSelfOneMany().contains(pc3));
+        assertEquals(2 + before, pc.getSelfOneMany().size());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        assertEquals("orig", pc.getStringField());
+        assertEquals(2 + before, pc.getSelfOneMany().size());
+        boolean found2 = false;
+        boolean found3 = false;
+        for (Iterator it = pc.getSelfOneMany().iterator(); it.hasNext();) {
+            temp = (ModRuntimeTest1) it.next();
+            assertEquals(pc, temp.getSelfOneOne());
+            if (temp.getIntField() < 0)
+                fail("shouldn't be here:" + temp.getStringField());
+            else if (temp.getIntField() == 2)
+                found2 = true;
+            else if (temp.getIntField() == 3)
+                found3 = true;
+        }
+        assertTrue(found2 && found3);
+        endEm(pm);
+    }
+
+    public void testChangeTracker() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        RuntimeTest4 pc = new RuntimeTest4("orig");
+        for (int i = 0; i < 12; i++)
+            pc.getRuntimeTest5s().add(new RuntimeTest5("five" + i));
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        startTx(pm);
+        pc = (RuntimeTest4) pm.find(RuntimeTest4.class, oid);
+        assertEquals(12, pc.getRuntimeTest5s().size());
+        int count = 0;
+        for (Iterator i = pc.getRuntimeTest5s().iterator();
+            count < 2; count++) {
+            i.next();
+            i.remove();
+        }
+        assertEquals(10, pc.getRuntimeTest5s().size());
+        pm.setSavepoint("test");
+        count = 0;
+        for (Iterator i = pc.getRuntimeTest5s().iterator();
+            count < 2; count++) {
+            i.next();
+            i.remove();
+        }
+        assertEquals(8, pc.getRuntimeTest5s().size());
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        pc = (RuntimeTest4) pm.find(RuntimeTest4.class, oid);
+        assertEquals(8, pc.getRuntimeTest5s().size());
+        endEm(pm);
+    }
+
+    private ModRuntimeTest1 newElement(ModRuntimeTest1 one, String str, int i) {
+        ModRuntimeTest1 two = new ModRuntimeTest1(str, i);
+        two.setSelfOneOne(one);
+        one.getSelfOneMany().add(two);
+        return two;
+    }
+
+    public static PCState getState(Object o) {
+        OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(o);
+
+        if (pm == null)
+            return null;
+        return JPAFacadeHelper.toBroker(pm).getStateManager(o).getPCState();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecondClassValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecondClassValues.java
index 96ede50..425e9cf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecondClassValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecondClassValues.java
@@ -1,780 +1,780 @@
-/*
- * TestSecondClassValues.java
- *
- * Created on October 13, 2006, 5:29 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.SCOTest;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestSecondClassValues extends BaseKernelTest {
-
-    public static double DOUBLE_PRECISION = 0.0001D;
-    public static float FLOAT_PRECISION = 0.0001F;
-    // mprudhom: use optimistic so we don't hang on some databases
-    private OpenJPAEntityManager pm;
-
-    private String newline = System.getProperty("line.separator");
-
-    /**
-     * Creates a new instance of TestSecondClassValues
-     */
-    public TestSecondClassValues() {
-    }
-
-    public TestSecondClassValues(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        pm = getPM(true, false);
-    }
-
-    private int rnd() {
-        return ((int) (Math.random() * 20)) + 5;
-    }
-
-    public void testMapDeletion() {
-        OpenJPAEntityManager pm;
-        pm = getPM();
-        startTx(pm);
-        SCOTest test = new SCOTest();
-        pm.persist(test);
-        Map map = new HashMap();
-        map.put("foo", new Integer(1));
-        map.put("bar", new Integer(2));
-        for (int i = 0; i < 10; i++)
-            map.put("baz#" + i, new Integer(i));
-
-        test.setStrIntMap(map);
-        Object id = pm.getObjectId(test);
-        endTx(pm);
-
-        startTx(pm);
-        test = (SCOTest) pm.find(SCOTest.class, id);
-        assertNotNull(test);
-        map = test.getStrIntMap();
-        assertEquals(12, map.size());
-        assertEquals(new Integer(1), map.get("foo"));
-        assertEquals(new Integer(2), map.get("bar"));
-        map.remove("bar");
-        endTx(pm);
-
-        startTx(pm);
-        test = (SCOTest) pm.find(SCOTest.class, id);
-        assertNotNull(test);
-        map = test.getStrIntMap();
-        assertEquals(11, map.size());
-        assertEquals(new Integer(1), map.get("foo"));
-        assertTrue(map.get("bar") == null);
-
-        map.clear();
-
-        endTx(pm);
-
-        startTx(pm);
-        test = (SCOTest) pm.find(SCOTest.class, id);
-        assertNotNull(test);
-        map = test.getStrIntMap();
-        assertEquals(0, map.size());
-        endTx(pm);
-    }
-
-    public void testStringCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomString());
-
-        saveSecondClassCollection(list);
-    }
-
-    public void testLongCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomLong());
-        try {
-            saveSecondClassCollection(list);
-        } catch (AssertionFailedError afe) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, afe,
-                "Empress cannot store large long values");
-        }
-    }
-
-    public void testShortCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomShort());
-        saveSecondClassCollection(list);
-    }
-
-    public void testBigIntegerCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomBigInteger());
-        saveSecondClassCollection(list);
-    }
-
-    public void testBigDecimalCollection()
-        throws Exception {
-        try {
-            ArrayList list = new ArrayList();
-            for (int i = 0; i < rnd(); i++)
-                list.add(randomBigDecimal());
-            saveSecondClassCollection(list);
-        } catch (AssertionFailedError e) {
-            bug(3, e, "Precision loss for BigDecimals");
-        }
-    }
-
-    public void testIntegerCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomInt());
-        saveSecondClassCollection(list);
-    }
-
-    public void testByteCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomByte());
-        saveSecondClassCollection(list);
-    }
-
-    public void testBooleanCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomBoolean());
-        saveSecondClassCollection(list, true);
-    }
-
-    public void testFloatCollection()
-        throws Exception {
-        try {
-            ArrayList list = new ArrayList();
-            for (int i = 0; i < rnd(); i++)
-                list.add(randomFloat());
-            saveSecondClassCollection(list);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe, "Loss of BigDecimal precision");
-        }
-    }
-
-    public void testDoubleCollection()
-        throws Exception {
-        try {
-            ArrayList list = new ArrayList();
-            for (int i = 0; i < rnd(); i++)
-                list.add(randomDouble());
-            saveSecondClassCollection(list);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe, "Loss of BigDecimal precision");
-        }
-    }
-
-    public void testDateCollection()
-        throws Exception {
-        ArrayList list = new ArrayList();
-        for (int i = 0; i < rnd(); i++)
-            list.add(randomDate());
-
-        list.add(new Date(472246800000L));
-
-        saveSecondClassCollection(list);
-    }
-
-    public void testBigDecimalBigIntegerMap()
-        throws Exception {
-        try {
-            HashMap map = new HashMap();
-            for (int i = 0; i < rnd(); i++)
-                map.put(randomBigDecimal(), randomBigInteger());
-            saveSecondClassMap(map);
-        } catch (AssertionFailedError e) {
-            bug(3, e, "Precision loss for BigDecimals");
-        }
-    }
-
-    public void testStrIntMap()
-        throws Exception {
-        HashMap map = new HashMap();
-        for (int i = 0; i < rnd(); i++)
-            map.put(randomString(), randomInt());
-        saveSecondClassMap(map);
-    }
-
-    public void testIntLongMap() throws Exception {
-        HashMap map = new HashMap();
-        for (int i = 0; i < rnd(); i++)
-            map.put(randomInt(), randomLong());
-        try {
-            saveSecondClassMap(map);
-        }
-        catch (AssertionFailedError afe) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, afe,
-                "Empress cannot store large long values");
-        }
-    }
-
-    public void testFloatByteMap()
-        throws Exception {
-        try {
-            HashMap map = new HashMap();
-            for (int i = 0; i < rnd(); i++)
-                map.put(randomFloat(), randomByte());
-            saveSecondClassMap(map);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe, "Loss of BigDecimal precision");
-        }
-    }
-
-    public void testByteDoubleMap()
-        throws Exception {
-        try {
-            HashMap map = new HashMap();
-            for (int i = 0; i < rnd(); i++)
-                map.put(randomByte(), randomDouble());
-            saveSecondClassMap(map);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe, "Loss of BigDecimal precision");
-        }
-    }
-
-    public void testDoubleCharMap()
-        throws Exception {
-        try {
-            HashMap map = new HashMap();
-            for (int i = 0; i < rnd(); i++)
-                map.put(randomDouble(), randomChar());
-            saveSecondClassMap(map);
-        } catch (AssertionFailedError afe) {
-            bug(3, afe, "Loss of BigDecimal precision");
-        }
-    }
-
-    public void testCharBooleanMap()
-        throws Exception {
-        HashMap map = new HashMap();
-        for (int i = 0; i < rnd(); i++)
-            map.put(randomChar(), randomBoolean());
-        saveSecondClassMap(map);
-    }
-
-    public void testDateStrMap() throws Exception {
-        HashMap map = new HashMap();
-        for (int i = 0; i < rnd(); i++)
-            map.put(randomDate(), randomString());
-
-        map.put(new Date(472246800000L),
-            "PostgreSQL ain't gonna like this date");
-        assertNotNull("map is null testDateStrMap", map);
-        saveSecondClassMap(map);
-    }
-
-    private void saveSecondClassMap(HashMap map)
-        throws Exception {
-        try {
-            saveSecondClassMapInternal(map);
-        } finally {
-            commit();
-        }
-    }
-
-    private void commit() {
-        try {
-            assertNotNull(pm);
-
-//  		EntityTransaction trans = pm.getTransaction();
-//  		if (trans != null && trans.isActive()) {
-//  		trans.commit();
-            endTx(pm);
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void begin() {
-        commit(); // make sure we are clean
-
-        // get a fresh PM
-        pm = getPM(true, false);
-        startTx(pm);
-    }
-
-    /**
-     * Save the specified map as a second-class object and validate
-     * its contents by reading back in the object and comparing
-     * all the values to the original. Furthermore, this method
-     * deletes each element of both maps in turn and re-validates
-     * each time to make sure updating of the map is working correctly.
-     */
-    private void saveSecondClassMapInternal(HashMap map) throws Exception {
-        begin();
-        SCOTest test = new SCOTest();
-        pm.persist(test);
-        int testID = test.getId();
-        assertNotNull("Passed Map is null", map);
-        Map smap = setGetMap(test, map, true);
-        assertNotNull("Map is null in setGetMap", smap);
-        commit();
-
-        for (Iterator mapKey = ((HashMap) map.clone()).keySet().iterator();
-            mapKey.hasNext();) {
-            Object keyToDelete = mapKey.next();
-
-            begin();
-            SCOTest retrievedObject =
-                (SCOTest) pm.find(SCOTest.class, testID);
-
-            assertNotNull(
-                "retrievedObject Obj is null - saveSecondClassMapInternal",
-                retrievedObject);
-
-            Map retrievedMap = setGetMap(retrievedObject, map, false);
-
-            assertNotNull(
-                "retrievedMap Obj is null - saveSecondClassMapInternal",
-                retrievedMap);
-
-            assertTrue(map.size() != 0);
-            assertEquals(map.size(), retrievedMap.size());
-
-            assertTrue("Incompatible types", map.keySet().iterator().next().
-                getClass().isAssignableFrom(retrievedMap.keySet().
-                iterator().next().getClass()));
-
-            // check to make sure all the keys match up to the appropriate
-            // values.
-            for (Iterator i = map.keySet().iterator(); i.hasNext();) {
-                Object key = i.next();
-                assertTrue(key != null);
-                assertTrue(map.get(key) != null);
-                if (key.getClass() == Date.class
-                    && retrievedMap.get(key) == null) {
-                    getLog().trace("Time: "
-                        + (((Date) key).getTime()));
-                    getLog().trace("List: "
-                        + dumpDates(retrievedMap.keySet()));
-
-                    /*
-                        bug (6, "Dates lose precision in some data stores "
-                            + "(" + (((Date)key).getTime ()) + ","
-                            + "[" + dumpDates (retrievedMap.keySet ()) + "])");
-                    */
-                }
-                if ((key.getClass() == Double.class ||
-                    key.getClass() == Float.class ||
-                    key.getClass() == BigDecimal.class)
-                    && retrievedMap.get(key) == null) {
-                    /*
-                         bug (3, "Doubles and Floats "
-                             + " lose precision in some data stores");
-                     */
-                }
-
-                assertTrue("The original map contained the object (class="
-                    + key.getClass().getName() + ", value="
-                    + key.toString() + "), but that object was null "
-                    + "in the map that was retrieved "
-                    + dump(retrievedMap.keySet()) + ".",
-                    retrievedMap.get(key) != null);
-                assertClassAndValueEquals(
-                    map.get(key), retrievedMap.get(key));
-            }
-
-            // now delete the first key in both maps, and make sure
-            // thinks are still OK.
-            map.remove(keyToDelete);
-            retrievedMap.remove(keyToDelete);
-        }
-    }
-
-    private void saveSecondClassCollection(ArrayList collection)
-        throws Exception {
-        saveSecondClassCollection(collection, false);
-    }
-
-    private void saveSecondClassCollection(ArrayList collection,
-        boolean useCustomCollator)
-        throws Exception {
-        try {
-            saveSecondClassCollectionInternal(collection, useCustomCollator);
-        } finally {
-            commit();
-        }
-    }
-
-    private void saveSecondClassCollectionInternal(ArrayList collection,
-        boolean useCustomCollator)
-        throws Exception {
-        Object elementToDelete = null;
-
-        if (useCustomCollator)
-            Collections.sort(collection,
-                new CollectionSorter());
-        else
-            Collections.sort(collection);
-
-        OpenJPAEntityManager pm1 = getPM();
-        startTx(pm1);
-
-        SCOTest test = new SCOTest();
-        pm1.persist(test);
-        int testID = test.getId();
-
-        Collection storedCollection = setGetCollection(test,
-            (Collection) ((ArrayList) collection).clone(), true);
-
-        assertNotNull("retrieved storedCollection is null", storedCollection);
-
-        // make sure the pre-commit collections are identical!
-        assertEquals("Pre-commit collections were not equal: " + newline
-            + dump(collection) + newline + "!=" + newline
-            + dump(storedCollection),
-            collection.size(), storedCollection.size());
-
-        endTx(pm1);
-
-        int deletionIndex = 0;
-
-        OpenJPAEntityManager pm2 = getPM();
-
-        while (collection.size() > 0) {
-            deletionIndex++;
-
-            startTx(pm2);
-            SCOTest retrievedObject =
-                (SCOTest) pm2.find(SCOTest.class, testID);
-
-            assertNotNull(
-                "retrieved obj is null saveSecondClassCollectionInternal",
-                retrievedObject);
-
-            Collection identityCollection = new LinkedList(collection);
-            assertNotNull(
-                "identityCollection is null saveSecondClassCollectionInternal",
-                identityCollection);
-            Collection retrievedCollection = setGetCollection(
-                retrievedObject, identityCollection, false);
-
-            assertNotNull(
-                "retrievedCollection is null saveSecondClassCollectionInternal",
-                retrievedCollection);
-
-            validateCollection(retrievedCollection);
-
-            assertNotNull(retrievedCollection);
-            assertTrue(collection.size() != 0);
-
-            assertEquals("Retreived collection does not match original "
-                + "after the " + deletionIndex + "th deletion ("
-                + elementToDelete + "): "
-                + newline
-                + dump(collection) + newline + "!=" + newline
-                + dump(retrievedCollection) + newline,
-                collection.size(), retrievedCollection.size());
-
-            /*
-            try
-            {
-                assertEquals (collection.size retrievedCollection.size ());
-            } catch (AssertionFailedError afe) {
-                bug (AbstractTestCase.Platform.SQLSERVER, 2, afe, "Second-class collections"
-                    + " are not being retrieved correctly");
-            }
-            */
-
-            // make sure the classes of the keys are the same.
-            Iterator ci = collection.iterator();
-            Object co = collection.iterator().next();
-
-            Iterator rci = retrievedCollection.iterator();
-            Object rco = retrievedCollection.iterator().next();
-
-            assertNotNull(co);
-            assertNotNull(rco);
-            assertEquals(co.getClass(), rco.getClass());
-
-            List sortedRetreivedCollection =
-                new ArrayList(retrievedCollection);
-
-            if (useCustomCollator)
-                Collections.sort(sortedRetreivedCollection,
-                    new CollectionSorter());
-            else
-                Collections.sort(sortedRetreivedCollection);
-
-            // make sure the collection is OK
-            for (Iterator i = collection.iterator(),
-                j = sortedRetreivedCollection.iterator();
-                i.hasNext() && j.hasNext();) {
-                assertClassAndValueEquals(i.next(), j.next());
-            }
-
-            elementToDelete = collection.iterator().next();
-            if (!(collection.remove(elementToDelete)))
-                fail("Could not delete element "
-                    + "(<" + elementToDelete.getClass().getName() + ">"
-                    + elementToDelete + ") "
-                    + "from " + dump(collection));
-
-            if (!(retrievedCollection.remove(elementToDelete)))
-                fail("Could not delete element (" + elementToDelete + ") "
-                    + "from " + dump(retrievedCollection));
-
-            endTx(pm2);
-        }
-    }
-
-    private void assertClassAndValueEquals(Object o1, Object o2) {
-        assertTrue("First object was null", o1 != null);
-        assertTrue("Second object was null", o2 != null);
-
-        assertTrue("Types did not match (class1="
-            + o1.getClass().getName() + ", class2="
-            + o2.getClass().getName() + ")",
-            o1.getClass().isAssignableFrom(o2.getClass()));
-
-        // floats and doubles are a little special: we only
-        // compare them to a certain precision, after which
-        // we give up.
-        /*
-          if (o1 instanceof Double)
-              assertEquals (((Double)o1).doubleValue (),
-                  ((Double)o2).doubleValue (),
-                  DOUBLE_PRECISION);
-          else if (o1 instanceof Float)
-              assertEquals (((Float)o1).floatValue (),
-                  ((Float)o2).floatValue (),
-                  FLOAT_PRECISION);
-          else if (o1 instanceof BigDecimal)
-              // BigDecimal equalist is a little special: see
-              // JDORuntimeTestCase.assertEquals(BigDecimal,BigDecimal)
-              assertEquals ("BigDecimal did not match",
-                  (BigDecimal)o1, (BigDecimal)o2);
-          else
-         */
-        assertEquals("Object did not match (class1="
-            + o1.getClass().getName() + ", class2="
-            + o2.getClass().getName() + ")",
-            o1, o2);
-    }
-
-    private String dump(Collection coll) {
-        List list = new LinkedList(coll);
-        try {
-            Collections.sort(list);
-        } catch (RuntimeException e) {
-
-        }
-
-        StringBuffer buf = new StringBuffer().append("[")
-            .append("(size=").append(list.size()).append(")");
-
-        Iterator it = list.iterator();
-        if (it.hasNext())
-            buf.append("<class=" + it.next().getClass().getName() + ">");
-
-        for (Iterator i = list.iterator(); i.hasNext();)
-            buf.append(i.next()).append(i.hasNext() ? "," : "");
-
-        return buf.append("]").toString();
-    }
-
-    private String dumpDates(Collection coll) {
-        StringBuffer buf = new StringBuffer();
-        for (Iterator i = coll.iterator(); i.hasNext();)
-            buf.append(((Date) i.next()).getTime()).append(
-                i.hasNext() ? "," : "");
-
-        return buf.toString();
-    }
-
-    /**
-     * Generic setter/getter for setting the maps purposes.
-     */
-    private Map setGetMap(SCOTest test, HashMap map, boolean doSet) {
-        if (map == null)
-            return null;
-
-        Object key = map.keySet().iterator().next();
-        Object val = map.get(key);
-
-        if (key instanceof Date && val instanceof String) {
-            if (doSet)
-                test.setDateStrMap(map);
-            return test.getDateStrMap();
-        } else if (key instanceof Character && val instanceof Boolean) {
-            if (doSet)
-                test.setCharBooleanMap(map);
-            return test.getCharBooleanMap();
-        } else if (key instanceof Double && val instanceof Character) {
-            if (doSet)
-                test.setDoubleCharMap(map);
-            return test.getDoubleCharMap();
-        } else if (key instanceof Byte && val instanceof Double) {
-            if (doSet)
-                test.setByteDoubleMap(map);
-            return test.getByteDoubleMap();
-        } else if (key instanceof Float && val instanceof Byte) {
-            if (doSet)
-                test.setFloatByteMap(map);
-            return test.getFloatByteMap();
-        } else if (key instanceof Long && val instanceof Float) {
-            if (doSet)
-                test.setLongFloatMap(map);
-            return test.getLongFloatMap();
-        } else if (key instanceof Integer && val instanceof Long) {
-            if (doSet)
-                test.setIntLongMap(map);
-            return test.getIntLongMap();
-        } else if (key instanceof String && val instanceof Integer) {
-            if (doSet)
-                test.setStrIntMap(map);
-            return test.getStrIntMap();
-        } else if (key instanceof BigDecimal && val instanceof BigInteger) {
-            if (doSet)
-                test.setBigDecimalBigIntegerMap(map);
-            return test.getBigDecimalBigIntegerMap();
-        }
-
-        fail("Unknown map type");
-        return null;
-    }
-
-    /**
-     * Generic setter/getter for setting the collections purposes.
-     */
-    private Collection setGetCollection(SCOTest test,
-        Collection collection, boolean doSet) {
-        if (collection == null)
-            return null;
-
-        Object first = collection.iterator().next();
-
-        if (first instanceof BigInteger) {
-            if (doSet)
-                test.setCBigInteger(collection);
-            return test.getCBigInteger();
-        } else if (first instanceof BigDecimal) {
-            if (doSet)
-                test.setCBigDecimal(collection);
-            return test.getCBigDecimal();
-        } else if (first instanceof Date) {
-            if (doSet)
-                test.setCDate(collection);
-            return test.getCDate();
-        } else if (first instanceof Character) {
-            if (doSet)
-                test.setCCharacter(collection);
-            return test.getCCharacter();
-        } else if (first instanceof Double) {
-            if (doSet)
-                test.setCDouble(collection);
-            return test.getCDouble();
-        } else if (first instanceof Byte) {
-            if (doSet)
-                test.setCByte(collection);
-            return test.getCByte();
-        } else if (first instanceof Float) {
-            if (doSet)
-                test.setCFloat(collection);
-            return test.getCFloat();
-        } else if (first instanceof Long) {
-            if (doSet)
-                test.setCLong(collection);
-            return test.getCLong();
-        } else if (first instanceof Integer) {
-            if (doSet)
-                test.setCInteger(collection);
-            return test.getCInteger();
-        } else if (first instanceof String) {
-            if (doSet)
-                test.setCString(collection);
-            return test.getCString();
-        } else if (first instanceof Short) {
-            if (doSet)
-                test.setCShort(collection);
-            return test.getCShort();
-        } else if (first instanceof Boolean) {
-            if (doSet)
-                test.setCBoolean(collection);
-            return test.getCBoolean();
-        }
-
-        fail("Unknown collection type");
-        return null;
-    }
-
-    /**
-     * A simple sorter that should always return the same sort order.
-     * The only reason we need ti use this, instead of relying on the
-     * natural order in Collections.sort is that there seems to be
-     * a bug somewhere that prevents sorting on collections of Boolean
-     * objects.
-     */
-    public static class CollectionSorter
-        implements Comparator {
-
-        private Collator collator = Collator.getInstance();
-
-        public CollectionSorter() {
-
-        }
-
-        public int compare(Object o1, Object o2) {
-            if (o1 != null && !(o1 instanceof Boolean))
-                return collator.compare(o1, o2);
-
-            return collator.compare(o1.toString(), o2.toString());
-        }
-    }
-}
+/*
+ * TestSecondClassValues.java
+ *
+ * Created on October 13, 2006, 5:29 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.SCOTest;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestSecondClassValues extends BaseKernelTest {
+
+    public static double DOUBLE_PRECISION = 0.0001D;
+    public static float FLOAT_PRECISION = 0.0001F;
+    // mprudhom: use optimistic so we don't hang on some databases
+    private OpenJPAEntityManager pm;
+
+    private String newline = System.getProperty("line.separator");
+
+    /**
+     * Creates a new instance of TestSecondClassValues
+     */
+    public TestSecondClassValues() {
+    }
+
+    public TestSecondClassValues(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        pm = getPM(true, false);
+    }
+
+    private int rnd() {
+        return ((int) (Math.random() * 20)) + 5;
+    }
+
+    public void testMapDeletion() {
+        OpenJPAEntityManager pm;
+        pm = getPM();
+        startTx(pm);
+        SCOTest test = new SCOTest();
+        pm.persist(test);
+        Map map = new HashMap();
+        map.put("foo", new Integer(1));
+        map.put("bar", new Integer(2));
+        for (int i = 0; i < 10; i++)
+            map.put("baz#" + i, new Integer(i));
+
+        test.setStrIntMap(map);
+        Object id = pm.getObjectId(test);
+        endTx(pm);
+
+        startTx(pm);
+        test = (SCOTest) pm.find(SCOTest.class, id);
+        assertNotNull(test);
+        map = test.getStrIntMap();
+        assertEquals(12, map.size());
+        assertEquals(new Integer(1), map.get("foo"));
+        assertEquals(new Integer(2), map.get("bar"));
+        map.remove("bar");
+        endTx(pm);
+
+        startTx(pm);
+        test = (SCOTest) pm.find(SCOTest.class, id);
+        assertNotNull(test);
+        map = test.getStrIntMap();
+        assertEquals(11, map.size());
+        assertEquals(new Integer(1), map.get("foo"));
+        assertTrue(map.get("bar") == null);
+
+        map.clear();
+
+        endTx(pm);
+
+        startTx(pm);
+        test = (SCOTest) pm.find(SCOTest.class, id);
+        assertNotNull(test);
+        map = test.getStrIntMap();
+        assertEquals(0, map.size());
+        endTx(pm);
+    }
+
+    public void testStringCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomString());
+
+        saveSecondClassCollection(list);
+    }
+
+    public void testLongCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomLong());
+        try {
+            saveSecondClassCollection(list);
+        } catch (AssertionFailedError afe) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, afe,
+                "Empress cannot store large long values");
+        }
+    }
+
+    public void testShortCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomShort());
+        saveSecondClassCollection(list);
+    }
+
+    public void testBigIntegerCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomBigInteger());
+        saveSecondClassCollection(list);
+    }
+
+    public void testBigDecimalCollection()
+        throws Exception {
+        try {
+            ArrayList list = new ArrayList();
+            for (int i = 0; i < rnd(); i++)
+                list.add(randomBigDecimal());
+            saveSecondClassCollection(list);
+        } catch (AssertionFailedError e) {
+            bug(3, e, "Precision loss for BigDecimals");
+        }
+    }
+
+    public void testIntegerCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomInt());
+        saveSecondClassCollection(list);
+    }
+
+    public void testByteCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomByte());
+        saveSecondClassCollection(list);
+    }
+
+    public void testBooleanCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomBoolean());
+        saveSecondClassCollection(list, true);
+    }
+
+    public void testFloatCollection()
+        throws Exception {
+        try {
+            ArrayList list = new ArrayList();
+            for (int i = 0; i < rnd(); i++)
+                list.add(randomFloat());
+            saveSecondClassCollection(list);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe, "Loss of BigDecimal precision");
+        }
+    }
+
+    public void testDoubleCollection()
+        throws Exception {
+        try {
+            ArrayList list = new ArrayList();
+            for (int i = 0; i < rnd(); i++)
+                list.add(randomDouble());
+            saveSecondClassCollection(list);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe, "Loss of BigDecimal precision");
+        }
+    }
+
+    public void testDateCollection()
+        throws Exception {
+        ArrayList list = new ArrayList();
+        for (int i = 0; i < rnd(); i++)
+            list.add(randomDate());
+
+        list.add(new Date(472246800000L));
+
+        saveSecondClassCollection(list);
+    }
+
+    public void testBigDecimalBigIntegerMap()
+        throws Exception {
+        try {
+            HashMap map = new HashMap();
+            for (int i = 0; i < rnd(); i++)
+                map.put(randomBigDecimal(), randomBigInteger());
+            saveSecondClassMap(map);
+        } catch (AssertionFailedError e) {
+            bug(3, e, "Precision loss for BigDecimals");
+        }
+    }
+
+    public void testStrIntMap()
+        throws Exception {
+        HashMap map = new HashMap();
+        for (int i = 0; i < rnd(); i++)
+            map.put(randomString(), randomInt());
+        saveSecondClassMap(map);
+    }
+
+    public void testIntLongMap() throws Exception {
+        HashMap map = new HashMap();
+        for (int i = 0; i < rnd(); i++)
+            map.put(randomInt(), randomLong());
+        try {
+            saveSecondClassMap(map);
+        }
+        catch (AssertionFailedError afe) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, afe,
+                "Empress cannot store large long values");
+        }
+    }
+
+    public void testFloatByteMap()
+        throws Exception {
+        try {
+            HashMap map = new HashMap();
+            for (int i = 0; i < rnd(); i++)
+                map.put(randomFloat(), randomByte());
+            saveSecondClassMap(map);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe, "Loss of BigDecimal precision");
+        }
+    }
+
+    public void testByteDoubleMap()
+        throws Exception {
+        try {
+            HashMap map = new HashMap();
+            for (int i = 0; i < rnd(); i++)
+                map.put(randomByte(), randomDouble());
+            saveSecondClassMap(map);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe, "Loss of BigDecimal precision");
+        }
+    }
+
+    public void testDoubleCharMap()
+        throws Exception {
+        try {
+            HashMap map = new HashMap();
+            for (int i = 0; i < rnd(); i++)
+                map.put(randomDouble(), randomChar());
+            saveSecondClassMap(map);
+        } catch (AssertionFailedError afe) {
+            bug(3, afe, "Loss of BigDecimal precision");
+        }
+    }
+
+    public void testCharBooleanMap()
+        throws Exception {
+        HashMap map = new HashMap();
+        for (int i = 0; i < rnd(); i++)
+            map.put(randomChar(), randomBoolean());
+        saveSecondClassMap(map);
+    }
+
+    public void testDateStrMap() throws Exception {
+        HashMap map = new HashMap();
+        for (int i = 0; i < rnd(); i++)
+            map.put(randomDate(), randomString());
+
+        map.put(new Date(472246800000L),
+            "PostgreSQL ain't gonna like this date");
+        assertNotNull("map is null testDateStrMap", map);
+        saveSecondClassMap(map);
+    }
+
+    private void saveSecondClassMap(HashMap map)
+        throws Exception {
+        try {
+            saveSecondClassMapInternal(map);
+        } finally {
+            commit();
+        }
+    }
+
+    private void commit() {
+        try {
+            assertNotNull(pm);
+
+//  		EntityTransaction trans = pm.getTransaction();
+//  		if (trans != null && trans.isActive()) {
+//  		trans.commit();
+            endTx(pm);
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void begin() {
+        commit(); // make sure we are clean
+
+        // get a fresh PM
+        pm = getPM(true, false);
+        startTx(pm);
+    }
+
+    /**
+     * Save the specified map as a second-class object and validate
+     * its contents by reading back in the object and comparing
+     * all the values to the original. Furthermore, this method
+     * deletes each element of both maps in turn and re-validates
+     * each time to make sure updating of the map is working correctly.
+     */
+    private void saveSecondClassMapInternal(HashMap map) throws Exception {
+        begin();
+        SCOTest test = new SCOTest();
+        pm.persist(test);
+        int testID = test.getId();
+        assertNotNull("Passed Map is null", map);
+        Map smap = setGetMap(test, map, true);
+        assertNotNull("Map is null in setGetMap", smap);
+        commit();
+
+        for (Iterator mapKey = ((HashMap) map.clone()).keySet().iterator();
+            mapKey.hasNext();) {
+            Object keyToDelete = mapKey.next();
+
+            begin();
+            SCOTest retrievedObject =
+                (SCOTest) pm.find(SCOTest.class, testID);
+
+            assertNotNull(
+                "retrievedObject Obj is null - saveSecondClassMapInternal",
+                retrievedObject);
+
+            Map retrievedMap = setGetMap(retrievedObject, map, false);
+
+            assertNotNull(
+                "retrievedMap Obj is null - saveSecondClassMapInternal",
+                retrievedMap);
+
+            assertTrue(map.size() != 0);
+            assertEquals(map.size(), retrievedMap.size());
+
+            assertTrue("Incompatible types", map.keySet().iterator().next().
+                getClass().isAssignableFrom(retrievedMap.keySet().
+                iterator().next().getClass()));
+
+            // check to make sure all the keys match up to the appropriate
+            // values.
+            for (Iterator i = map.keySet().iterator(); i.hasNext();) {
+                Object key = i.next();
+                assertTrue(key != null);
+                assertTrue(map.get(key) != null);
+                if (key.getClass() == Date.class
+                    && retrievedMap.get(key) == null) {
+                    getLog().trace("Time: "
+                        + (((Date) key).getTime()));
+                    getLog().trace("List: "
+                        + dumpDates(retrievedMap.keySet()));
+
+                    /*
+                        bug (6, "Dates lose precision in some data stores "
+                            + "(" + (((Date)key).getTime ()) + ","
+                            + "[" + dumpDates (retrievedMap.keySet ()) + "])");
+                    */
+                }
+                if ((key.getClass() == Double.class ||
+                    key.getClass() == Float.class ||
+                    key.getClass() == BigDecimal.class)
+                    && retrievedMap.get(key) == null) {
+                    /*
+                         bug (3, "Doubles and Floats "
+                             + " lose precision in some data stores");
+                     */
+                }
+
+                assertTrue("The original map contained the object (class="
+                    + key.getClass().getName() + ", value="
+                    + key.toString() + "), but that object was null "
+                    + "in the map that was retrieved "
+                    + dump(retrievedMap.keySet()) + ".",
+                    retrievedMap.get(key) != null);
+                assertClassAndValueEquals(
+                    map.get(key), retrievedMap.get(key));
+            }
+
+            // now delete the first key in both maps, and make sure
+            // thinks are still OK.
+            map.remove(keyToDelete);
+            retrievedMap.remove(keyToDelete);
+        }
+    }
+
+    private void saveSecondClassCollection(ArrayList collection)
+        throws Exception {
+        saveSecondClassCollection(collection, false);
+    }
+
+    private void saveSecondClassCollection(ArrayList collection,
+        boolean useCustomCollator)
+        throws Exception {
+        try {
+            saveSecondClassCollectionInternal(collection, useCustomCollator);
+        } finally {
+            commit();
+        }
+    }
+
+    private void saveSecondClassCollectionInternal(ArrayList collection,
+        boolean useCustomCollator)
+        throws Exception {
+        Object elementToDelete = null;
+
+        if (useCustomCollator)
+            Collections.sort(collection,
+                new CollectionSorter());
+        else
+            Collections.sort(collection);
+
+        OpenJPAEntityManager pm1 = getPM();
+        startTx(pm1);
+
+        SCOTest test = new SCOTest();
+        pm1.persist(test);
+        int testID = test.getId();
+
+        Collection storedCollection = setGetCollection(test,
+            (Collection) ((ArrayList) collection).clone(), true);
+
+        assertNotNull("retrieved storedCollection is null", storedCollection);
+
+        // make sure the pre-commit collections are identical!
+        assertEquals("Pre-commit collections were not equal: " + newline
+            + dump(collection) + newline + "!=" + newline
+            + dump(storedCollection),
+            collection.size(), storedCollection.size());
+
+        endTx(pm1);
+
+        int deletionIndex = 0;
+
+        OpenJPAEntityManager pm2 = getPM();
+
+        while (collection.size() > 0) {
+            deletionIndex++;
+
+            startTx(pm2);
+            SCOTest retrievedObject =
+                (SCOTest) pm2.find(SCOTest.class, testID);
+
+            assertNotNull(
+                "retrieved obj is null saveSecondClassCollectionInternal",
+                retrievedObject);
+
+            Collection identityCollection = new LinkedList(collection);
+            assertNotNull(
+                "identityCollection is null saveSecondClassCollectionInternal",
+                identityCollection);
+            Collection retrievedCollection = setGetCollection(
+                retrievedObject, identityCollection, false);
+
+            assertNotNull(
+                "retrievedCollection is null saveSecondClassCollectionInternal",
+                retrievedCollection);
+
+            validateCollection(retrievedCollection);
+
+            assertNotNull(retrievedCollection);
+            assertTrue(collection.size() != 0);
+
+            assertEquals("Retreived collection does not match original "
+                + "after the " + deletionIndex + "th deletion ("
+                + elementToDelete + "): "
+                + newline
+                + dump(collection) + newline + "!=" + newline
+                + dump(retrievedCollection) + newline,
+                collection.size(), retrievedCollection.size());
+
+            /*
+            try
+            {
+                assertEquals (collection.size retrievedCollection.size ());
+            } catch (AssertionFailedError afe) {
+                bug (AbstractTestCase.Platform.SQLSERVER, 2, afe, "Second-class collections"
+                    + " are not being retrieved correctly");
+            }
+            */
+
+            // make sure the classes of the keys are the same.
+            Iterator ci = collection.iterator();
+            Object co = collection.iterator().next();
+
+            Iterator rci = retrievedCollection.iterator();
+            Object rco = retrievedCollection.iterator().next();
+
+            assertNotNull(co);
+            assertNotNull(rco);
+            assertEquals(co.getClass(), rco.getClass());
+
+            List sortedRetreivedCollection =
+                new ArrayList(retrievedCollection);
+
+            if (useCustomCollator)
+                Collections.sort(sortedRetreivedCollection,
+                    new CollectionSorter());
+            else
+                Collections.sort(sortedRetreivedCollection);
+
+            // make sure the collection is OK
+            for (Iterator i = collection.iterator(),
+                j = sortedRetreivedCollection.iterator();
+                i.hasNext() && j.hasNext();) {
+                assertClassAndValueEquals(i.next(), j.next());
+            }
+
+            elementToDelete = collection.iterator().next();
+            if (!(collection.remove(elementToDelete)))
+                fail("Could not delete element "
+                    + "(<" + elementToDelete.getClass().getName() + ">"
+                    + elementToDelete + ") "
+                    + "from " + dump(collection));
+
+            if (!(retrievedCollection.remove(elementToDelete)))
+                fail("Could not delete element (" + elementToDelete + ") "
+                    + "from " + dump(retrievedCollection));
+
+            endTx(pm2);
+        }
+    }
+
+    private void assertClassAndValueEquals(Object o1, Object o2) {
+        assertTrue("First object was null", o1 != null);
+        assertTrue("Second object was null", o2 != null);
+
+        assertTrue("Types did not match (class1="
+            + o1.getClass().getName() + ", class2="
+            + o2.getClass().getName() + ")",
+            o1.getClass().isAssignableFrom(o2.getClass()));
+
+        // floats and doubles are a little special: we only
+        // compare them to a certain precision, after which
+        // we give up.
+        /*
+          if (o1 instanceof Double)
+              assertEquals (((Double)o1).doubleValue (),
+                  ((Double)o2).doubleValue (),
+                  DOUBLE_PRECISION);
+          else if (o1 instanceof Float)
+              assertEquals (((Float)o1).floatValue (),
+                  ((Float)o2).floatValue (),
+                  FLOAT_PRECISION);
+          else if (o1 instanceof BigDecimal)
+              // BigDecimal equalist is a little special: see
+              // JDORuntimeTestCase.assertEquals(BigDecimal,BigDecimal)
+              assertEquals ("BigDecimal did not match",
+                  (BigDecimal)o1, (BigDecimal)o2);
+          else
+         */
+        assertEquals("Object did not match (class1="
+            + o1.getClass().getName() + ", class2="
+            + o2.getClass().getName() + ")",
+            o1, o2);
+    }
+
+    private String dump(Collection coll) {
+        List list = new LinkedList(coll);
+        try {
+            Collections.sort(list);
+        } catch (RuntimeException e) {
+
+        }
+
+        StringBuffer buf = new StringBuffer().append("[")
+            .append("(size=").append(list.size()).append(")");
+
+        Iterator it = list.iterator();
+        if (it.hasNext())
+            buf.append("<class=" + it.next().getClass().getName() + ">");
+
+        for (Iterator i = list.iterator(); i.hasNext();)
+            buf.append(i.next()).append(i.hasNext() ? "," : "");
+
+        return buf.append("]").toString();
+    }
+
+    private String dumpDates(Collection coll) {
+        StringBuffer buf = new StringBuffer();
+        for (Iterator i = coll.iterator(); i.hasNext();)
+            buf.append(((Date) i.next()).getTime()).append(
+                i.hasNext() ? "," : "");
+
+        return buf.toString();
+    }
+
+    /**
+     * Generic setter/getter for setting the maps purposes.
+     */
+    private Map setGetMap(SCOTest test, HashMap map, boolean doSet) {
+        if (map == null)
+            return null;
+
+        Object key = map.keySet().iterator().next();
+        Object val = map.get(key);
+
+        if (key instanceof Date && val instanceof String) {
+            if (doSet)
+                test.setDateStrMap(map);
+            return test.getDateStrMap();
+        } else if (key instanceof Character && val instanceof Boolean) {
+            if (doSet)
+                test.setCharBooleanMap(map);
+            return test.getCharBooleanMap();
+        } else if (key instanceof Double && val instanceof Character) {
+            if (doSet)
+                test.setDoubleCharMap(map);
+            return test.getDoubleCharMap();
+        } else if (key instanceof Byte && val instanceof Double) {
+            if (doSet)
+                test.setByteDoubleMap(map);
+            return test.getByteDoubleMap();
+        } else if (key instanceof Float && val instanceof Byte) {
+            if (doSet)
+                test.setFloatByteMap(map);
+            return test.getFloatByteMap();
+        } else if (key instanceof Long && val instanceof Float) {
+            if (doSet)
+                test.setLongFloatMap(map);
+            return test.getLongFloatMap();
+        } else if (key instanceof Integer && val instanceof Long) {
+            if (doSet)
+                test.setIntLongMap(map);
+            return test.getIntLongMap();
+        } else if (key instanceof String && val instanceof Integer) {
+            if (doSet)
+                test.setStrIntMap(map);
+            return test.getStrIntMap();
+        } else if (key instanceof BigDecimal && val instanceof BigInteger) {
+            if (doSet)
+                test.setBigDecimalBigIntegerMap(map);
+            return test.getBigDecimalBigIntegerMap();
+        }
+
+        fail("Unknown map type");
+        return null;
+    }
+
+    /**
+     * Generic setter/getter for setting the collections purposes.
+     */
+    private Collection setGetCollection(SCOTest test,
+        Collection collection, boolean doSet) {
+        if (collection == null)
+            return null;
+
+        Object first = collection.iterator().next();
+
+        if (first instanceof BigInteger) {
+            if (doSet)
+                test.setCBigInteger(collection);
+            return test.getCBigInteger();
+        } else if (first instanceof BigDecimal) {
+            if (doSet)
+                test.setCBigDecimal(collection);
+            return test.getCBigDecimal();
+        } else if (first instanceof Date) {
+            if (doSet)
+                test.setCDate(collection);
+            return test.getCDate();
+        } else if (first instanceof Character) {
+            if (doSet)
+                test.setCCharacter(collection);
+            return test.getCCharacter();
+        } else if (first instanceof Double) {
+            if (doSet)
+                test.setCDouble(collection);
+            return test.getCDouble();
+        } else if (first instanceof Byte) {
+            if (doSet)
+                test.setCByte(collection);
+            return test.getCByte();
+        } else if (first instanceof Float) {
+            if (doSet)
+                test.setCFloat(collection);
+            return test.getCFloat();
+        } else if (first instanceof Long) {
+            if (doSet)
+                test.setCLong(collection);
+            return test.getCLong();
+        } else if (first instanceof Integer) {
+            if (doSet)
+                test.setCInteger(collection);
+            return test.getCInteger();
+        } else if (first instanceof String) {
+            if (doSet)
+                test.setCString(collection);
+            return test.getCString();
+        } else if (first instanceof Short) {
+            if (doSet)
+                test.setCShort(collection);
+            return test.getCShort();
+        } else if (first instanceof Boolean) {
+            if (doSet)
+                test.setCBoolean(collection);
+            return test.getCBoolean();
+        }
+
+        fail("Unknown collection type");
+        return null;
+    }
+
+    /**
+     * A simple sorter that should always return the same sort order.
+     * The only reason we need ti use this, instead of relying on the
+     * natural order in Collections.sort is that there seems to be
+     * a bug somewhere that prevents sorting on collections of Boolean
+     * objects.
+     */
+    public static class CollectionSorter
+        implements Comparator {
+
+        private Collator collator = Collator.getInstance();
+
+        public CollectionSorter() {
+
+        }
+
+        public int compare(Object o1, Object o2) {
+            if (o1 != null && !(o1 instanceof Boolean))
+                return collator.compare(o1, o2);
+
+            return collator.compare(o1.toString(), o2.toString());
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecurityContext.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecurityContext.java
index 9ba15d0..094fd71 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecurityContext.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSecurityContext.java
@@ -1,286 +1,286 @@
-/*
- * TestSecurityContext.java
- *
- * Created on October 13, 2006, 5:25 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.io.FileDescriptor;
-import java.net.InetAddress;
-import java.security.Permission;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestSecurityContext extends BaseKernelTest {
-
-    private SecurityManager oldManager;
-    private StrictSecurityManager ssm;
-
-    /**
-     * Creates a new instance of TestSecurityContext
-     */
-    public TestSecurityContext() {
-    }
-
-    public TestSecurityContext(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        oldManager = System.getSecurityManager();
-        // System.setSecurityManager (ssm = new StrictSecurityManager ());
-    }
-
-    public void tearDown()
-        throws Exception {
-        System.setSecurityManager(oldManager);
-        oldManager = null;
-        super.tearDown();
-    }
-
-    public void testInSecureClassLoader() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.createExtent(RuntimeTest1.class, true).iterator().hasNext();
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public class StrictSecurityManager
-        extends SecurityManager {
-
-        private void debug(String msg) {
-            // log.debug (msg);
-        }
-
-        public void checkAccept(String host, int port) {
-            debug("checkAccept: " + host + "," + port);
-            super.checkAccept(host, port);
-        }
-
-        public void checkAccess(Thread t) {
-            debug("checkAccess: " + t);
-            super.checkAccess(t);
-        }
-
-        public void checkAccess(ThreadGroup g) {
-            debug("checkAccess: " + g);
-            super.checkAccess(g);
-        }
-
-        public void checkAwtEventQueueAccess() {
-            debug("checkAwtEventQueueAccess");
-            super.checkAwtEventQueueAccess();
-        }
-
-        public void checkConnect(String host, int port) {
-            debug("checkConnect: " + host + "," + port);
-            super.checkConnect(host, port);
-        }
-
-        public void checkConnect(String host, int port, Object context) {
-            debug("checkConnect: " + host + "," + port + "," + context);
-            super.checkConnect(host, port, context);
-        }
-
-        public void checkCreateClassLoader() {
-            debug("checkCreateClassLoader");
-            super.checkCreateClassLoader();
-        }
-
-        public void checkDelete(String file) {
-            debug("checkDelete: " + file);
-            super.checkDelete(file);
-        }
-
-        public void checkExec(String cmd) {
-            debug("checkExec: " + cmd);
-            super.checkExec(cmd);
-        }
-
-        public void checkExit(int status) {
-            debug("checkExit: " + status);
-            super.checkExit(status);
-        }
-
-        public void checkLink(String lib) {
-            debug("checkLink: " + lib);
-            super.checkLink(lib);
-        }
-
-        public void checkListen(int port) {
-            debug("checkListen: " + port);
-            super.checkListen(port);
-        }
-
-        public void checkMemberAccess(Class clazz, int which) {
-            debug("checkMemberAccess: " + clazz + "," + which);
-            super.checkMemberAccess(clazz, which);
-        }
-
-        public void checkMulticast(InetAddress maddr) {
-            debug("checkMulticast: " + maddr);
-            super.checkMulticast(maddr);
-        }
-
-        public void checkMulticast(InetAddress maddr, byte ttl) {
-            debug("checkMulticast: " + maddr + "," + ttl);
-            super.checkMulticast(maddr, ttl);
-        }
-
-        public void checkPackageAccess(String pkg) {
-            debug("checkPackageAccess: " + pkg);
-            super.checkPackageAccess(pkg);
-        }
-
-        public void checkPackageDefinition(String pkg) {
-            debug("checkPackageDefinition: " + pkg);
-            super.checkPackageDefinition(pkg);
-        }
-
-        public void checkPermission(Permission perm) {
-            debug("checkPermission: " + perm);
-            super.checkPermission(perm);
-        }
-
-        public void checkPermission(Permission perm, Object context) {
-            debug("checkPermission: " + perm + "," + context);
-            super.checkPermission(perm, context);
-        }
-
-        public void checkPrintJobAccess() {
-            debug("checkPrintJobAccess");
-            super.checkPrintJobAccess();
-        }
-
-        public void checkPropertiesAccess() {
-            debug("checkPropertiesAccess");
-            super.checkPropertiesAccess();
-        }
-
-        public void checkPropertyAccess(String key) {
-            debug("checkPropertyAccess: " + key);
-            super.checkPropertyAccess(key);
-        }
-
-        public void checkRead(FileDescriptor fd) {
-            debug("checkRead: " + fd);
-            super.checkRead(fd);
-        }
-
-        public void checkRead(String file) {
-            debug("checkRead: " + file);
-            super.checkRead(file);
-        }
-
-        public void checkRead(String file, Object context) {
-            debug("checkRead: " + file + "," + context);
-            super.checkRead(file, context);
-        }
-
-        public void checkSecurityAccess(String target) {
-            debug("checkSecurityAccess: " + target);
-            super.checkSecurityAccess(target);
-        }
-
-        public void checkSetFactory() {
-            debug("checkSetFactory");
-            super.checkSetFactory();
-        }
-
-        public void checkSystemClipboardAccess() {
-            debug("checkSystemClipboardAccess");
-            super.checkSystemClipboardAccess();
-        }
-
-        public boolean checkTopLevelWindow(Object window) {
-            debug("checkTopLevelWindow: " + window);
-            return super.checkTopLevelWindow(window);
-        }
-
-        public void checkWrite(FileDescriptor fd) {
-            debug("checkWrite: " + fd);
-            super.checkWrite(fd);
-        }
-
-        public void checkWrite(String file) {
-            debug("checkWrite: " + file);
-            super.checkWrite(file);
-        }
-
-        protected int classDepth(String name) {
-            debug("classDepth: " + name);
-            return super.classDepth(name);
-        }
-
-        protected int classLoaderDepth() {
-            debug("classLoaderDepth");
-            return super.classLoaderDepth();
-        }
-
-        protected ClassLoader currentClassLoader() {
-            debug("currentClassLoader");
-            return super.currentClassLoader();
-        }
-
-        protected Class currentLoadedClass() {
-            debug("currentLoadedClass");
-            return super.currentLoadedClass();
-        }
-
-        protected Class[] getClassContext() {
-            debug("getClassContext");
-            return super.getClassContext();
-        }
-
-        public boolean getInCheck() {
-            debug("getInCheck");
-            return super.getInCheck();
-        }
-
-        public Object getSecurityContext() {
-            debug("getSecurityContext");
-            return super.getSecurityContext();
-        }
-
-        public ThreadGroup getThreadGroup() {
-            debug("getThreadGroup");
-            return super.getThreadGroup();
-        }
-
-        protected boolean inClass(String name) {
-            debug("inClass: " + name);
-            return super.inClass(name);
-        }
-
-        protected boolean inClassLoader() {
-            debug("inClassLoader");
-            return super.inClassLoader();
-        }
-    }
-}
+/*
+ * TestSecurityContext.java
+ *
+ * Created on October 13, 2006, 5:25 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+import java.security.Permission;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestSecurityContext extends BaseKernelTest {
+
+    private SecurityManager oldManager;
+    private StrictSecurityManager ssm;
+
+    /**
+     * Creates a new instance of TestSecurityContext
+     */
+    public TestSecurityContext() {
+    }
+
+    public TestSecurityContext(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        oldManager = System.getSecurityManager();
+        // System.setSecurityManager (ssm = new StrictSecurityManager ());
+    }
+
+    public void tearDown()
+        throws Exception {
+        System.setSecurityManager(oldManager);
+        oldManager = null;
+        super.tearDown();
+    }
+
+    public void testInSecureClassLoader() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.createExtent(RuntimeTest1.class, true).iterator().hasNext();
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public class StrictSecurityManager
+        extends SecurityManager {
+
+        private void debug(String msg) {
+            // log.debug (msg);
+        }
+
+        public void checkAccept(String host, int port) {
+            debug("checkAccept: " + host + "," + port);
+            super.checkAccept(host, port);
+        }
+
+        public void checkAccess(Thread t) {
+            debug("checkAccess: " + t);
+            super.checkAccess(t);
+        }
+
+        public void checkAccess(ThreadGroup g) {
+            debug("checkAccess: " + g);
+            super.checkAccess(g);
+        }
+
+        public void checkAwtEventQueueAccess() {
+            debug("checkAwtEventQueueAccess");
+            super.checkAwtEventQueueAccess();
+        }
+
+        public void checkConnect(String host, int port) {
+            debug("checkConnect: " + host + "," + port);
+            super.checkConnect(host, port);
+        }
+
+        public void checkConnect(String host, int port, Object context) {
+            debug("checkConnect: " + host + "," + port + "," + context);
+            super.checkConnect(host, port, context);
+        }
+
+        public void checkCreateClassLoader() {
+            debug("checkCreateClassLoader");
+            super.checkCreateClassLoader();
+        }
+
+        public void checkDelete(String file) {
+            debug("checkDelete: " + file);
+            super.checkDelete(file);
+        }
+
+        public void checkExec(String cmd) {
+            debug("checkExec: " + cmd);
+            super.checkExec(cmd);
+        }
+
+        public void checkExit(int status) {
+            debug("checkExit: " + status);
+            super.checkExit(status);
+        }
+
+        public void checkLink(String lib) {
+            debug("checkLink: " + lib);
+            super.checkLink(lib);
+        }
+
+        public void checkListen(int port) {
+            debug("checkListen: " + port);
+            super.checkListen(port);
+        }
+
+        public void checkMemberAccess(Class clazz, int which) {
+            debug("checkMemberAccess: " + clazz + "," + which);
+            super.checkMemberAccess(clazz, which);
+        }
+
+        public void checkMulticast(InetAddress maddr) {
+            debug("checkMulticast: " + maddr);
+            super.checkMulticast(maddr);
+        }
+
+        public void checkMulticast(InetAddress maddr, byte ttl) {
+            debug("checkMulticast: " + maddr + "," + ttl);
+            super.checkMulticast(maddr, ttl);
+        }
+
+        public void checkPackageAccess(String pkg) {
+            debug("checkPackageAccess: " + pkg);
+            super.checkPackageAccess(pkg);
+        }
+
+        public void checkPackageDefinition(String pkg) {
+            debug("checkPackageDefinition: " + pkg);
+            super.checkPackageDefinition(pkg);
+        }
+
+        public void checkPermission(Permission perm) {
+            debug("checkPermission: " + perm);
+            super.checkPermission(perm);
+        }
+
+        public void checkPermission(Permission perm, Object context) {
+            debug("checkPermission: " + perm + "," + context);
+            super.checkPermission(perm, context);
+        }
+
+        public void checkPrintJobAccess() {
+            debug("checkPrintJobAccess");
+            super.checkPrintJobAccess();
+        }
+
+        public void checkPropertiesAccess() {
+            debug("checkPropertiesAccess");
+            super.checkPropertiesAccess();
+        }
+
+        public void checkPropertyAccess(String key) {
+            debug("checkPropertyAccess: " + key);
+            super.checkPropertyAccess(key);
+        }
+
+        public void checkRead(FileDescriptor fd) {
+            debug("checkRead: " + fd);
+            super.checkRead(fd);
+        }
+
+        public void checkRead(String file) {
+            debug("checkRead: " + file);
+            super.checkRead(file);
+        }
+
+        public void checkRead(String file, Object context) {
+            debug("checkRead: " + file + "," + context);
+            super.checkRead(file, context);
+        }
+
+        public void checkSecurityAccess(String target) {
+            debug("checkSecurityAccess: " + target);
+            super.checkSecurityAccess(target);
+        }
+
+        public void checkSetFactory() {
+            debug("checkSetFactory");
+            super.checkSetFactory();
+        }
+
+        public void checkSystemClipboardAccess() {
+            debug("checkSystemClipboardAccess");
+            super.checkSystemClipboardAccess();
+        }
+
+        public boolean checkTopLevelWindow(Object window) {
+            debug("checkTopLevelWindow: " + window);
+            return super.checkTopLevelWindow(window);
+        }
+
+        public void checkWrite(FileDescriptor fd) {
+            debug("checkWrite: " + fd);
+            super.checkWrite(fd);
+        }
+
+        public void checkWrite(String file) {
+            debug("checkWrite: " + file);
+            super.checkWrite(file);
+        }
+
+        protected int classDepth(String name) {
+            debug("classDepth: " + name);
+            return super.classDepth(name);
+        }
+
+        protected int classLoaderDepth() {
+            debug("classLoaderDepth");
+            return super.classLoaderDepth();
+        }
+
+        protected ClassLoader currentClassLoader() {
+            debug("currentClassLoader");
+            return super.currentClassLoader();
+        }
+
+        protected Class currentLoadedClass() {
+            debug("currentLoadedClass");
+            return super.currentLoadedClass();
+        }
+
+        protected Class[] getClassContext() {
+            debug("getClassContext");
+            return super.getClassContext();
+        }
+
+        public boolean getInCheck() {
+            debug("getInCheck");
+            return super.getInCheck();
+        }
+
+        public Object getSecurityContext() {
+            debug("getSecurityContext");
+            return super.getSecurityContext();
+        }
+
+        public ThreadGroup getThreadGroup() {
+            debug("getThreadGroup");
+            return super.getThreadGroup();
+        }
+
+        protected boolean inClass(String name) {
+            debug("inClass: " + name);
+            return super.inClass(name);
+        }
+
+        protected boolean inClassLoader() {
+            debug("inClassLoader");
+            return super.inClassLoader();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSequence.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSequence.java
index de6d2c1..682b17a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSequence.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSequence.java
@@ -1,66 +1,66 @@
-/*
- * TestSequence.java
- *
- * Created on October 13, 2006, 5:17 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.AImplB;
-
-import org.apache.openjpa.persistence.Generator;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestSequence extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestSequence
-     */
-    public TestSequence() {
-    }
-
-    public TestSequence(String name) {
-        super(name);
-    }
-
-    public void testSequence() {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        Generator seq = pm.getIdGenerator(AImplB.class);
-        assertNotNull(seq);
-        Number val = (Number) seq.next();
-        assertNotNull(val);
-        AImplB aib = new AImplB("x", val.intValue(), "y");
-        pm.persist(aib);
-
-        for (int i = 0; i < 100; i++)
-            assertEquals(((Number) pm.getIdGenerator(AImplB.class).
-                next()).longValue() + 1,
-                ((Number) pm.getIdGenerator(AImplB.class).
-                    next()).longValue());
-
-        endTx(pm);
-    }
-}
+/*
+ * TestSequence.java
+ *
+ * Created on October 13, 2006, 5:17 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.AImplB;
+
+import org.apache.openjpa.persistence.Generator;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestSequence extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestSequence
+     */
+    public TestSequence() {
+    }
+
+    public TestSequence(String name) {
+        super(name);
+    }
+
+    public void testSequence() {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        Generator seq = pm.getIdGenerator(AImplB.class);
+        assertNotNull(seq);
+        Number val = (Number) seq.next();
+        assertNotNull(val);
+        AImplB aib = new AImplB("x", val.intValue(), "y");
+        pm.persist(aib);
+
+        for (int i = 0; i < 100; i++)
+            assertEquals(((Number) pm.getIdGenerator(AImplB.class).
+                next()).longValue() + 1,
+                ((Number) pm.getIdGenerator(AImplB.class).
+                    next()).longValue());
+
+        endTx(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSerialize.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSerialize.java
index 48b1baf..60743ed 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSerialize.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSerialize.java
@@ -1,93 +1,93 @@
-/*
- * TestSerialize.java
- *
- * Created on October 13, 2006, 5:13 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestSerialize extends BaseKernelTest {
-
-    private int _oid = 0;
-    private Object _oid2 = null;
-
-    /**
-     * Creates a new instance of TestSerialize
-     */
-    public TestSerialize() {
-    }
-
-    public TestSerialize(String name) {
-        super(name);
-    }
-
-    public void setUp() throws Exception {
-        RuntimeTest1 a = new RuntimeTest1("1NAME", 1);
-        a.setSelfOneOne(new RuntimeTest1("2NAME", 2));
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(a);
-        _oid = a.getIntField();
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testConfigurationSerializable()
-        throws Exception {
-        // validate that the hashCode() and equals() method hold true
-        // for the round-trip.
-        roundtrip(getConfiguration(), true);
-    }
-
-    public void testSerialize()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM();
-        //FIXME jthomas
-        /*pm.getFetchPlan().setDetachmentOptions
-                (FetchPlan.DETACH_ALL_FIELDS);
-         */
-        RuntimeTest1 a = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
-
-        assertEquals("1NAME", a.getStringField());
-        assertEquals(1, a.getIntField());
-        assertNotNull(a.getSelfOneOne());
-        assertEquals("2NAME", a.getSelfOneOne().getStringField());
-        assertEquals(2, a.getSelfOneOne().getIntField());
-
-        a = (RuntimeTest1) roundtrip(a, false);
-
-        assertEquals("1NAME", a.getStringField());
-        assertEquals(1, a.getIntField());
-        assertNotNull(a.getSelfOneOne());
-        assertEquals("2NAME", a.getSelfOneOne().getStringField());
-        assertEquals(2, a.getSelfOneOne().getIntField());
-    }
-}
+/*
+ * TestSerialize.java
+ *
+ * Created on October 13, 2006, 5:13 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestSerialize extends BaseKernelTest {
+
+    private int _oid = 0;
+    private Object _oid2 = null;
+
+    /**
+     * Creates a new instance of TestSerialize
+     */
+    public TestSerialize() {
+    }
+
+    public TestSerialize(String name) {
+        super(name);
+    }
+
+    public void setUp() throws Exception {
+        RuntimeTest1 a = new RuntimeTest1("1NAME", 1);
+        a.setSelfOneOne(new RuntimeTest1("2NAME", 2));
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(a);
+        _oid = a.getIntField();
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testConfigurationSerializable()
+        throws Exception {
+        // validate that the hashCode() and equals() method hold true
+        // for the round-trip.
+        roundtrip(getConfiguration(), true);
+    }
+
+    public void testSerialize()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM();
+        //FIXME jthomas
+        /*pm.getFetchPlan().setDetachmentOptions
+                (FetchPlan.DETACH_ALL_FIELDS);
+         */
+        RuntimeTest1 a = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+
+        assertEquals("1NAME", a.getStringField());
+        assertEquals(1, a.getIntField());
+        assertNotNull(a.getSelfOneOne());
+        assertEquals("2NAME", a.getSelfOneOne().getStringField());
+        assertEquals(2, a.getSelfOneOne().getIntField());
+
+        a = (RuntimeTest1) roundtrip(a, false);
+
+        assertEquals("1NAME", a.getStringField());
+        assertEquals(1, a.getIntField());
+        assertNotNull(a.getSelfOneOne());
+        assertEquals("2NAME", a.getSelfOneOne().getStringField());
+        assertEquals(2, a.getSelfOneOne().getIntField());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSimple.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSimple.java
index 364ac2c..c1b5747 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSimple.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSimple.java
@@ -1,136 +1,136 @@
-/*
- * TestSimple.java
- *
- * Created on October 13, 2006, 5:03 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.List;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
-
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestSimple extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestSimple
-     */
-    public TestSimple(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-    }
-
-    public void testSimple() {
-        // test create
-        {
-            OpenJPAEntityManager pm = getPM();
-            startTx(pm);
-            pm.persist(new RuntimeTest1("testSimple", 12));
-            endTx(pm);
-            endEm(pm);
-        }
-
-        // test Query
-        {
-            OpenJPAEntityManager pm = getPM();
-            startTx(pm);
-            String theQuery =
-                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple\'";
-            OpenJPAQuery query = pm.createQuery(theQuery);
-            List list = query.getResultList();
-            assertSize(1, list);
-            endTx(pm);
-            endEm(pm);
-        }
-
-        // test Update
-        {
-            OpenJPAEntityManager pm = getPM();
-            startTx(pm);
-            String theQuery =
-                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple\'";
-            OpenJPAQuery query = pm.createQuery(theQuery);
-            RuntimeTest1 toUpdate = (RuntimeTest1) query.getSingleResult();
-            toUpdate.setStringField("testSimple2");
-            endTx(pm);
-            endEm(pm);
-
-            pm = getPM();
-            startTx(pm);
-            String query1 =
-                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple\'";
-            String query2 =
-                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple2\'";
-            OpenJPAQuery q1 = pm.createQuery(query1);
-            OpenJPAQuery q2 = pm.createQuery(query2);
-            assertSize(0, q1.getResultList());
-            assertSize(1, q2.getResultList());
-            endTx(pm);
-            endEm(pm);
-        }
-
-        // test Extent
-        {
-            OpenJPAEntityManager pm = getPM();
-            startTx(pm);
-            Extent e = pm.createExtent(RuntimeTest1.class, true);
-            assertTrue(e.iterator().hasNext());
-            assertEquals("testSimple2", ((RuntimeTest1) e.iterator().next()).
-                getStringField());
-            endTx(pm);
-            endEm(pm);
-        }
-
-        // test delete
-        {
-            OpenJPAEntityManager pm = getPM();
-            startTx(pm);
-            String delete =
-                "DELETE FROM RuntimeTest1 r WHERE r.stringField = \'testSimple2\'";
-            OpenJPAQuery deleteQuery = pm.createQuery(delete);
-            int deleted = deleteQuery.executeUpdate();
-            endTx(pm);
-            endEm(pm);
-
-            pm = getPM();
-            startTx(pm);
-            String select =
-                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple2\'";
-            OpenJPAQuery selectQuery = pm.createQuery(select);
-
-            assertSize(0, selectQuery.getResultList());
-
-            endTx(pm);
-            endEm(pm);
-        }
-    }
-}
+/*
+ * TestSimple.java
+ *
+ * Created on October 13, 2006, 5:03 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.List;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestSimple extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestSimple
+     */
+    public TestSimple(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testSimple() {
+        // test create
+        {
+            OpenJPAEntityManager pm = getPM();
+            startTx(pm);
+            pm.persist(new RuntimeTest1("testSimple", 12));
+            endTx(pm);
+            endEm(pm);
+        }
+
+        // test Query
+        {
+            OpenJPAEntityManager pm = getPM();
+            startTx(pm);
+            String theQuery =
+                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple\'";
+            OpenJPAQuery query = pm.createQuery(theQuery);
+            List list = query.getResultList();
+            assertSize(1, list);
+            endTx(pm);
+            endEm(pm);
+        }
+
+        // test Update
+        {
+            OpenJPAEntityManager pm = getPM();
+            startTx(pm);
+            String theQuery =
+                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple\'";
+            OpenJPAQuery query = pm.createQuery(theQuery);
+            RuntimeTest1 toUpdate = (RuntimeTest1) query.getSingleResult();
+            toUpdate.setStringField("testSimple2");
+            endTx(pm);
+            endEm(pm);
+
+            pm = getPM();
+            startTx(pm);
+            String query1 =
+                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple\'";
+            String query2 =
+                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple2\'";
+            OpenJPAQuery q1 = pm.createQuery(query1);
+            OpenJPAQuery q2 = pm.createQuery(query2);
+            assertSize(0, q1.getResultList());
+            assertSize(1, q2.getResultList());
+            endTx(pm);
+            endEm(pm);
+        }
+
+        // test Extent
+        {
+            OpenJPAEntityManager pm = getPM();
+            startTx(pm);
+            Extent e = pm.createExtent(RuntimeTest1.class, true);
+            assertTrue(e.iterator().hasNext());
+            assertEquals("testSimple2", ((RuntimeTest1) e.iterator().next()).
+                getStringField());
+            endTx(pm);
+            endEm(pm);
+        }
+
+        // test delete
+        {
+            OpenJPAEntityManager pm = getPM();
+            startTx(pm);
+            String delete =
+                "DELETE FROM RuntimeTest1 r WHERE r.stringField = \'testSimple2\'";
+            OpenJPAQuery deleteQuery = pm.createQuery(delete);
+            int deleted = deleteQuery.executeUpdate();
+            endTx(pm);
+            endEm(pm);
+
+            pm = getPM();
+            startTx(pm);
+            String select =
+                "SELECT r FROM RuntimeTest1 r WHERE r.stringField = \'testSimple2\'";
+            OpenJPAQuery selectQuery = pm.createQuery(select);
+
+            assertSize(0, selectQuery.getResultList());
+
+            endTx(pm);
+            endEm(pm);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers.java
index 5ba87df..022d526 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers.java
@@ -1,315 +1,315 @@
-/*
- * TestSpecialNumbers.java
- *
- * Created on October 13, 2006, 4:56 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.math.BigInteger;
-import java.util.Collection;
-import java.util.EnumSet;
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestSpecialNumbers extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestSpecialNumbers
-     */
-    public TestSpecialNumbers() {
-    }
-
-    public TestSpecialNumbers(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        try {
-            deleteAll(AllFieldTypesTest.class);
-        } catch (Exception e) {
-            // catch errors when deleting ... PostgreSQL has
-            // a couple problems with some of the values that
-            // try to get inserted.
-        }
-    }
-
-    public void testShortMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestshort(Short.MAX_VALUE);
-        saveAndQuery(aftt, "testshort = :param", new Short(Short.MAX_VALUE));
-    }
-
-    public void testShortMin() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestshort(Short.MIN_VALUE);
-        try {
-            saveAndQuery(aftt, "testshort = :param",
-                new Short(Short.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
-                "Empress cannot store min values");
-        }
-    }
-
-    public void testLongMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestlong(Long.MAX_VALUE);
-        saveAndQuery(aftt, "testlong = :param", new Long(Long.MAX_VALUE));
-    }
-
-    public void testLongMin() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestlong(Long.MIN_VALUE);
-            saveAndQuery(aftt, "testlong = :param", new Long(Long.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.HYPERSONIC, 474, t,
-                "Some databases cannot store Long.MIN_VALUE");
-        }
-    }
-
-    public void testIntegerMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestint(Integer.MAX_VALUE);
-        saveAndQuery(aftt, "testint = :param",
-            new Integer(Integer.MAX_VALUE));
-    }
-
-    public void testIntegerMin() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestint(Integer.MIN_VALUE);
-        try {
-            saveAndQuery(aftt, "testint = :param",
-                new Integer(Integer.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
-                "Empress cannot store min values");
-        }
-    }
-
-    public void testFloatMax() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.MAX_VALUE);
-            saveAndQuery(aftt, "testfloat = :param",
-                new Float(Float.MAX_VALUE));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.MYSQL,
-                AbstractTestCase.Platform.DERBY), 494, e,
-                "Some datastores cannot store Float.MAX_VALUE");
-        }
-    }
-
-    public void testFloatMin() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.MIN_VALUE);
-            saveAndQuery(aftt, "testfloat = :param",
-                new Float(Float.MIN_VALUE));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.SQLSERVER,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.DERBY), 494, e,
-                "Some databases cannot store Float.MIN_VALUE");
-        } catch (AssertionFailedError e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.MYSQL,
-                AbstractTestCase.Platform.SQLSERVER), 494, e,
-                "Some databases cannot store Float.MIN_VALUE");
-        }
-    }
-
-    public void testFloatNaN() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.NaN);
-            saveAndQuery(aftt, "testfloat = :param", new Float(Float.NaN));
-        } catch (Throwable t) {
-            bug(461, t, "NaN problems");
-        }
-    }
-
-    public void testFloatNegativeInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.NEGATIVE_INFINITY);
-            saveAndQuery(aftt, "testfloat = :param",
-                new Float(Float.NEGATIVE_INFINITY));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
-                AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.MYSQL,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.ORACLE,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.DERBY,
-                AbstractTestCase.Platform.SQLSERVER), 494, e,
-                "Some databases cannot store Float.NEGATIVE_INFINITY");
-        }
-    }
-
-    public void testFloatPostivieInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.POSITIVE_INFINITY);
-            saveAndQuery(aftt, "testfloat = :param",
-                new Float(Float.POSITIVE_INFINITY));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
-                AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.MYSQL,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.ORACLE,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.DERBY,
-                AbstractTestCase.Platform.SQLSERVER), 494, e,
-                "Some databases cannot store Float.POSITIVE_INFINITY");
-        }
-    }
-
-    public void testDoubleMax() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.MAX_VALUE);
-            saveAndQuery(aftt, "testdouble = :param",
-                new Double(Double.MAX_VALUE));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
-                AbstractTestCase.Platform.MYSQL,
-                AbstractTestCase.Platform.ORACLE,
-                AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.EMPRESS,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.DERBY), 494, e,
-                "Some databases cannot store Double.MAX_VALUE");
-        }
-    }
-
-    public void testDoubleMin() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.MIN_VALUE);
-            saveAndQuery(aftt, "testdouble = :param",
-                new Double(Double.MIN_VALUE));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.SQLSERVER,
-                AbstractTestCase.Platform.ORACLE,
-                AbstractTestCase.Platform.EMPRESS,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.DERBY), 494, e,
-                "Some databases cannot store Double.MIN_VALUE");
-        } catch (AssertionFailedError e) {
-            bug(AbstractTestCase.Platform.MYSQL, 494, e,
-                "Some databases cannot store Double.MIN_VALUE");
-        }
-    }
-
-    public void testDoubleNaN() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.NaN);
-            saveAndQuery(aftt, "testdouble = :param", new Double(Double.NaN));
-        } catch (Throwable t) {
-            bug(461, t, "NaN problems");
-        }
-    }
-
-    public void testDoubleNegativeInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.NEGATIVE_INFINITY);
-            saveAndQuery(aftt, "testdouble = :param",
-                new Double(Double.NEGATIVE_INFINITY));
-        } catch (Throwable t) {
-            bug(461, t, "infinity problems");
-        }
-    }
-
-    public void testDoublePostivieInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.POSITIVE_INFINITY);
-            saveAndQuery(aftt, "testdouble = :param",
-                new Double(Double.POSITIVE_INFINITY));
-        } catch (Throwable t) {
-            bug(461, t, "infinity problems");
-        }
-    }
-
-    public void testByteMin() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestbyte(Byte.MIN_VALUE);
-        try {
-            saveAndQuery(aftt, "testbyte = :param", new Byte(Byte.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
-                "Empress cannot store min values");
-        }
-    }
-
-    public void testByteMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestbyte(Byte.MAX_VALUE);
-        saveAndQuery(aftt, "testbyte = :param", new Byte(Byte.MAX_VALUE));
-    }
-
-    public void testZeroBigInteger() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestBigInteger(BigInteger.ZERO);
-        saveAndQuery(aftt, "testBigInteger = :param", BigInteger.ZERO);
-    }
-
-    public void testOneBigInteger() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestBigInteger(BigInteger.ONE);
-        saveAndQuery(aftt, "testBigInteger = :param", BigInteger.ONE);
-    }
-
-    private void saveAndQuery(Object obj, String query, Object param) {
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(obj);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM();
-        OpenJPAQuery q = pm.createQuery("select o from "
-            + obj.getClass().getName() + " o where " + query);
-        q.setParameter("param", param);
-        Collection c = (Collection) q.getResultList();
-        assertSize(1, c);
-        endEm(pm);
-    }
-}
+/*
+ * TestSpecialNumbers.java
+ *
+ * Created on October 13, 2006, 4:56 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.EnumSet;
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestSpecialNumbers extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestSpecialNumbers
+     */
+    public TestSpecialNumbers() {
+    }
+
+    public TestSpecialNumbers(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        try {
+            deleteAll(AllFieldTypesTest.class);
+        } catch (Exception e) {
+            // catch errors when deleting ... PostgreSQL has
+            // a couple problems with some of the values that
+            // try to get inserted.
+        }
+    }
+
+    public void testShortMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestshort(Short.MAX_VALUE);
+        saveAndQuery(aftt, "testshort = :param", new Short(Short.MAX_VALUE));
+    }
+
+    public void testShortMin() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestshort(Short.MIN_VALUE);
+        try {
+            saveAndQuery(aftt, "testshort = :param",
+                new Short(Short.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
+                "Empress cannot store min values");
+        }
+    }
+
+    public void testLongMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestlong(Long.MAX_VALUE);
+        saveAndQuery(aftt, "testlong = :param", new Long(Long.MAX_VALUE));
+    }
+
+    public void testLongMin() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestlong(Long.MIN_VALUE);
+            saveAndQuery(aftt, "testlong = :param", new Long(Long.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.HYPERSONIC, 474, t,
+                "Some databases cannot store Long.MIN_VALUE");
+        }
+    }
+
+    public void testIntegerMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestint(Integer.MAX_VALUE);
+        saveAndQuery(aftt, "testint = :param",
+            new Integer(Integer.MAX_VALUE));
+    }
+
+    public void testIntegerMin() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestint(Integer.MIN_VALUE);
+        try {
+            saveAndQuery(aftt, "testint = :param",
+                new Integer(Integer.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
+                "Empress cannot store min values");
+        }
+    }
+
+    public void testFloatMax() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.MAX_VALUE);
+            saveAndQuery(aftt, "testfloat = :param",
+                new Float(Float.MAX_VALUE));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.MYSQL,
+                AbstractTestCase.Platform.DERBY), 494, e,
+                "Some datastores cannot store Float.MAX_VALUE");
+        }
+    }
+
+    public void testFloatMin() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.MIN_VALUE);
+            saveAndQuery(aftt, "testfloat = :param",
+                new Float(Float.MIN_VALUE));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.SQLSERVER,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.DERBY), 494, e,
+                "Some databases cannot store Float.MIN_VALUE");
+        } catch (AssertionFailedError e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.MYSQL,
+                AbstractTestCase.Platform.SQLSERVER), 494, e,
+                "Some databases cannot store Float.MIN_VALUE");
+        }
+    }
+
+    public void testFloatNaN() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.NaN);
+            saveAndQuery(aftt, "testfloat = :param", new Float(Float.NaN));
+        } catch (Throwable t) {
+            bug(461, t, "NaN problems");
+        }
+    }
+
+    public void testFloatNegativeInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.NEGATIVE_INFINITY);
+            saveAndQuery(aftt, "testfloat = :param",
+                new Float(Float.NEGATIVE_INFINITY));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
+                AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.MYSQL,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.ORACLE,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.DERBY,
+                AbstractTestCase.Platform.SQLSERVER), 494, e,
+                "Some databases cannot store Float.NEGATIVE_INFINITY");
+        }
+    }
+
+    public void testFloatPostivieInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.POSITIVE_INFINITY);
+            saveAndQuery(aftt, "testfloat = :param",
+                new Float(Float.POSITIVE_INFINITY));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
+                AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.MYSQL,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.ORACLE,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.DERBY,
+                AbstractTestCase.Platform.SQLSERVER), 494, e,
+                "Some databases cannot store Float.POSITIVE_INFINITY");
+        }
+    }
+
+    public void testDoubleMax() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.MAX_VALUE);
+            saveAndQuery(aftt, "testdouble = :param",
+                new Double(Double.MAX_VALUE));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POINTBASE,
+                AbstractTestCase.Platform.MYSQL,
+                AbstractTestCase.Platform.ORACLE,
+                AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.EMPRESS,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.DERBY), 494, e,
+                "Some databases cannot store Double.MAX_VALUE");
+        }
+    }
+
+    public void testDoubleMin() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.MIN_VALUE);
+            saveAndQuery(aftt, "testdouble = :param",
+                new Double(Double.MIN_VALUE));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.SQLSERVER,
+                AbstractTestCase.Platform.ORACLE,
+                AbstractTestCase.Platform.EMPRESS,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.DERBY), 494, e,
+                "Some databases cannot store Double.MIN_VALUE");
+        } catch (AssertionFailedError e) {
+            bug(AbstractTestCase.Platform.MYSQL, 494, e,
+                "Some databases cannot store Double.MIN_VALUE");
+        }
+    }
+
+    public void testDoubleNaN() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.NaN);
+            saveAndQuery(aftt, "testdouble = :param", new Double(Double.NaN));
+        } catch (Throwable t) {
+            bug(461, t, "NaN problems");
+        }
+    }
+
+    public void testDoubleNegativeInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.NEGATIVE_INFINITY);
+            saveAndQuery(aftt, "testdouble = :param",
+                new Double(Double.NEGATIVE_INFINITY));
+        } catch (Throwable t) {
+            bug(461, t, "infinity problems");
+        }
+    }
+
+    public void testDoublePostivieInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.POSITIVE_INFINITY);
+            saveAndQuery(aftt, "testdouble = :param",
+                new Double(Double.POSITIVE_INFINITY));
+        } catch (Throwable t) {
+            bug(461, t, "infinity problems");
+        }
+    }
+
+    public void testByteMin() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestbyte(Byte.MIN_VALUE);
+        try {
+            saveAndQuery(aftt, "testbyte = :param", new Byte(Byte.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
+                "Empress cannot store min values");
+        }
+    }
+
+    public void testByteMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestbyte(Byte.MAX_VALUE);
+        saveAndQuery(aftt, "testbyte = :param", new Byte(Byte.MAX_VALUE));
+    }
+
+    public void testZeroBigInteger() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestBigInteger(BigInteger.ZERO);
+        saveAndQuery(aftt, "testBigInteger = :param", BigInteger.ZERO);
+    }
+
+    public void testOneBigInteger() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestBigInteger(BigInteger.ONE);
+        saveAndQuery(aftt, "testBigInteger = :param", BigInteger.ONE);
+    }
+
+    private void saveAndQuery(Object obj, String query, Object param) {
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(obj);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM();
+        OpenJPAQuery q = pm.createQuery("select o from "
+            + obj.getClass().getName() + " o where " + query);
+        q.setParameter("param", param);
+        Collection c = (Collection) q.getResultList();
+        assertSize(1, c);
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers2.java
index ad72d70..af2f8e5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestSpecialNumbers2.java
@@ -1,285 +1,285 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.Collection;
-import java.util.EnumSet;
-import java.math.BigInteger;
-
-import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import junit.framework.Assert;
-import junit.framework.AssertionFailedError;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-/**
- * Test various special numbers, such as Double.NaN.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public class TestSpecialNumbers2 extends BaseKernelTest {
-
-    public TestSpecialNumbers2(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        try {
-            deleteAll(AllFieldTypesTest.class);
-        }
-        catch (Exception e) {
-            // catch errors when deleting ... PostgreSQL has
-            // a couple problems with some of the values that
-            // try to get inserted.
-        }
-    }
-
-    public void testShortMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestshort(Short.MAX_VALUE);
-        saveAndQuery(aftt, "testshort =", new Short(Short.MAX_VALUE));
-    }
-    
-    public void testShortMin() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestshort(Short.MIN_VALUE);
-        try {
-            saveAndQuery(aftt, "testshort =",
-                    new Short(Short.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
-                    "Empress cannot store min values");
-        }
-    }
-    
-    public void testLongMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestlong(Long.MAX_VALUE);
-        saveAndQuery(aftt, "testlong =", new Long(Long.MAX_VALUE));
-    }
-    
-    public void testLongMin() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestlong(Long.MIN_VALUE);
-            saveAndQuery(aftt, "testlong =", new Long(Long.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.HYPERSONIC, 474, t,
-                    "Some databases cannot store Long.MIN_VALUE");
-        }
-    }
-    
-    public void testIntegerMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestint(Integer.MAX_VALUE);
-        saveAndQuery(aftt, "testint =",
-                new Integer(Integer.MAX_VALUE));
-    }
-    
-    public void testIntegerMin() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestint(Integer.MIN_VALUE);
-        try {
-            saveAndQuery(aftt, "testint =",
-                    new Integer(Integer.MIN_VALUE));
-        } catch (Throwable t) {
-            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
-                    "Empress cannot store min values");
-        }
-    }
-    
-    public void testFloatMax() {
-        try {
-        	AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.MAX_VALUE);
-            saveAndQuery(aftt, "testfloat =",
-                    new Float(Float.MAX_VALUE));
-        } catch (Exception e) {
-            bug(getCurrentPlatform(), 494, e,
-                    "Some datastores cannot store Float.MAX_VALUE");
-        }
-    }
-    
-    public void testFloatMin() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.MIN_VALUE);
-            saveAndQuery(aftt, "testfloat =",
-                    new Float(Float.MIN_VALUE));
-        } catch (Exception e) {
-            bug(getCurrentPlatform(), 494, e,
-                    "Some databases cannot store Float.MIN_VALUE");
-        } catch (AssertionFailedError e) {
-            bug(getCurrentPlatform(), 494, e,
-                    "Some databases cannot store Float.MIN_VALUE");
-        }
-    }
-    
-    public void testFloatNaN() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.NaN);
-            saveAndQuery(aftt, "testfloat =", new Float(Float.NaN));
-        } catch (Throwable t) {
-            bug(461, t, "NaN problems");
-        }
-    }
-    
-    public void testFloatNegativeInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.NEGATIVE_INFINITY);
-            saveAndQuery(aftt, "testfloat =",
-                    new Float(Float.NEGATIVE_INFINITY));
-        } catch (Exception e) {
-            bug(getCurrentPlatform(), 494, e,
-                    "Some databases cannot store Float.NEGATIVE_INFINITY");
-        }
-    }
-    
-    public void testFloatPostivieInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestfloat(Float.POSITIVE_INFINITY);
-            saveAndQuery(aftt, "testfloat =",
-                    new Float(Float.POSITIVE_INFINITY));
-        } catch (Exception e) {
-            bug(getCurrentPlatform(), 494, e,
-                    "Some databases cannot store Float.POSITIVE_INFINITY");
-        }
-    }
-    
-    public void testDoubleMax() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.MAX_VALUE);
-            saveAndQuery(aftt, "testdouble =",
-                    new Double(Double.MAX_VALUE));
-        } catch (Exception e) {
-            bug(getCurrentPlatform(), 494, e,
-                    "Some databases cannot store Double.MAX_VALUE");
-        }
-    }
-    
-    public void testDoubleMin() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.MIN_VALUE);
-            saveAndQuery(aftt, "testdouble =",
-                    new Double(Double.MIN_VALUE));
-        } catch (Exception e) {
-            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
-                AbstractTestCase.Platform.SQLSERVER,
-                AbstractTestCase.Platform.ORACLE,
-                AbstractTestCase.Platform.EMPRESS,
-                AbstractTestCase.Platform.DB2,
-                AbstractTestCase.Platform.INFORMIX,
-                AbstractTestCase.Platform.DERBY), 494, e,
-                "Some databases cannot store Double.MIN_VALUE");
-        } catch (AssertionFailedError e) {
-            bug(AbstractTestCase.Platform.MYSQL, 494, e,
-                    "Some databases cannot store Double.MIN_VALUE");
-        }
-    }
-    
-    public void testDoubleNaN() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.NaN);
-            saveAndQuery(aftt, "testdouble =", new Double(Double.NaN));
-        } catch (Throwable t) {
-            bug(461, t, "NaN problems");
-        }
-    }
-    
-    public void testDoubleNegativeInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.NEGATIVE_INFINITY);
-            saveAndQuery(aftt, "testdouble =",
-                    new Double(Double.NEGATIVE_INFINITY));
-        } catch (Throwable t) {
-            bug(461, t, "infinity problems");
-        }
-    }
-    
-    public void testDoublePostivieInfinity() {
-        try {
-            AllFieldTypesTest aftt = new AllFieldTypesTest();
-            aftt.setTestdouble(Double.POSITIVE_INFINITY);
-            saveAndQuery(aftt, "testdouble =",
-                    new Double(Double.POSITIVE_INFINITY));
-        } catch (Throwable t) {
-            bug(461, t, "infinity problems");
-        }
-    }
-
-    public void testByteMin() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestbyte(Byte.MIN_VALUE);
-        try {
-            saveAndQuery(aftt, "testbyte =", new Byte(Byte.MIN_VALUE));
-        } catch (Throwable t) {
-            //bug(AbstractTestCase.Platform.EMPRESS, 889, t, "Empress cannot store min values");
-            Assert.fail(
-                "Exception was thrown while storing Byte.MIN_VALUE : \n" +
-                    getStackTrace(t));
-        }
-    }
-
-    public void testByteMax() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestbyte(Byte.MAX_VALUE);
-        saveAndQuery(aftt, "testbyte =", new Byte(Byte.MAX_VALUE));
-    }
-    
-    public void testZeroBigInteger() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestBigInteger(BigInteger.ZERO);
-        saveAndQuery(aftt, "testBigInteger =", BigInteger.ZERO);
-    }
-    
-    public void testOneBigInteger() {
-        AllFieldTypesTest aftt = new AllFieldTypesTest();
-        aftt.setTestBigInteger(BigInteger.ONE);
-        saveAndQuery(aftt, "testBigInteger =", BigInteger.ONE);
-    }
-    
-    private void saveAndQuery(Object obj, String query, Object param) {
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        pm.persist(obj);
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM(false, false);
-//        Query q = pm.newQuery(obj.getClassquery);
-//        q.declareParameters("Object param");
-//        Collection c = (Collection) q.execute(param);
-        OpenJPAQuery q = pm.createQuery(
-            "SELECT a FROM AllFieldTypesTest a WHERE a." + query + " " + param);
-        Collection c = (Collection) q.getResultList();
-        assertSize(1, c);
-        pm.close();
-    }
-}
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.Collection;
+import java.util.EnumSet;
+import java.math.BigInteger;
+
+import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.Assert;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+/**
+ * Test various special numbers, such as Double.NaN.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class TestSpecialNumbers2 extends BaseKernelTest {
+
+    public TestSpecialNumbers2(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        try {
+            deleteAll(AllFieldTypesTest.class);
+        }
+        catch (Exception e) {
+            // catch errors when deleting ... PostgreSQL has
+            // a couple problems with some of the values that
+            // try to get inserted.
+        }
+    }
+
+    public void testShortMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestshort(Short.MAX_VALUE);
+        saveAndQuery(aftt, "testshort =", new Short(Short.MAX_VALUE));
+    }
+    
+    public void testShortMin() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestshort(Short.MIN_VALUE);
+        try {
+            saveAndQuery(aftt, "testshort =",
+                    new Short(Short.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
+                    "Empress cannot store min values");
+        }
+    }
+    
+    public void testLongMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestlong(Long.MAX_VALUE);
+        saveAndQuery(aftt, "testlong =", new Long(Long.MAX_VALUE));
+    }
+    
+    public void testLongMin() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestlong(Long.MIN_VALUE);
+            saveAndQuery(aftt, "testlong =", new Long(Long.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.HYPERSONIC, 474, t,
+                    "Some databases cannot store Long.MIN_VALUE");
+        }
+    }
+    
+    public void testIntegerMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestint(Integer.MAX_VALUE);
+        saveAndQuery(aftt, "testint =",
+                new Integer(Integer.MAX_VALUE));
+    }
+    
+    public void testIntegerMin() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestint(Integer.MIN_VALUE);
+        try {
+            saveAndQuery(aftt, "testint =",
+                    new Integer(Integer.MIN_VALUE));
+        } catch (Throwable t) {
+            bug(AbstractTestCase.Platform.EMPRESS, 889, t,
+                    "Empress cannot store min values");
+        }
+    }
+    
+    public void testFloatMax() {
+        try {
+        	AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.MAX_VALUE);
+            saveAndQuery(aftt, "testfloat =",
+                    new Float(Float.MAX_VALUE));
+        } catch (Exception e) {
+            bug(getCurrentPlatform(), 494, e,
+                    "Some datastores cannot store Float.MAX_VALUE");
+        }
+    }
+    
+    public void testFloatMin() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.MIN_VALUE);
+            saveAndQuery(aftt, "testfloat =",
+                    new Float(Float.MIN_VALUE));
+        } catch (Exception e) {
+            bug(getCurrentPlatform(), 494, e,
+                    "Some databases cannot store Float.MIN_VALUE");
+        } catch (AssertionFailedError e) {
+            bug(getCurrentPlatform(), 494, e,
+                    "Some databases cannot store Float.MIN_VALUE");
+        }
+    }
+    
+    public void testFloatNaN() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.NaN);
+            saveAndQuery(aftt, "testfloat =", new Float(Float.NaN));
+        } catch (Throwable t) {
+            bug(461, t, "NaN problems");
+        }
+    }
+    
+    public void testFloatNegativeInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.NEGATIVE_INFINITY);
+            saveAndQuery(aftt, "testfloat =",
+                    new Float(Float.NEGATIVE_INFINITY));
+        } catch (Exception e) {
+            bug(getCurrentPlatform(), 494, e,
+                    "Some databases cannot store Float.NEGATIVE_INFINITY");
+        }
+    }
+    
+    public void testFloatPostivieInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestfloat(Float.POSITIVE_INFINITY);
+            saveAndQuery(aftt, "testfloat =",
+                    new Float(Float.POSITIVE_INFINITY));
+        } catch (Exception e) {
+            bug(getCurrentPlatform(), 494, e,
+                    "Some databases cannot store Float.POSITIVE_INFINITY");
+        }
+    }
+    
+    public void testDoubleMax() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.MAX_VALUE);
+            saveAndQuery(aftt, "testdouble =",
+                    new Double(Double.MAX_VALUE));
+        } catch (Exception e) {
+            bug(getCurrentPlatform(), 494, e,
+                    "Some databases cannot store Double.MAX_VALUE");
+        }
+    }
+    
+    public void testDoubleMin() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.MIN_VALUE);
+            saveAndQuery(aftt, "testdouble =",
+                    new Double(Double.MIN_VALUE));
+        } catch (Exception e) {
+            bug(EnumSet.of(AbstractTestCase.Platform.POSTGRESQL,
+                AbstractTestCase.Platform.SQLSERVER,
+                AbstractTestCase.Platform.ORACLE,
+                AbstractTestCase.Platform.EMPRESS,
+                AbstractTestCase.Platform.DB2,
+                AbstractTestCase.Platform.INFORMIX,
+                AbstractTestCase.Platform.DERBY), 494, e,
+                "Some databases cannot store Double.MIN_VALUE");
+        } catch (AssertionFailedError e) {
+            bug(AbstractTestCase.Platform.MYSQL, 494, e,
+                    "Some databases cannot store Double.MIN_VALUE");
+        }
+    }
+    
+    public void testDoubleNaN() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.NaN);
+            saveAndQuery(aftt, "testdouble =", new Double(Double.NaN));
+        } catch (Throwable t) {
+            bug(461, t, "NaN problems");
+        }
+    }
+    
+    public void testDoubleNegativeInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.NEGATIVE_INFINITY);
+            saveAndQuery(aftt, "testdouble =",
+                    new Double(Double.NEGATIVE_INFINITY));
+        } catch (Throwable t) {
+            bug(461, t, "infinity problems");
+        }
+    }
+    
+    public void testDoublePostivieInfinity() {
+        try {
+            AllFieldTypesTest aftt = new AllFieldTypesTest();
+            aftt.setTestdouble(Double.POSITIVE_INFINITY);
+            saveAndQuery(aftt, "testdouble =",
+                    new Double(Double.POSITIVE_INFINITY));
+        } catch (Throwable t) {
+            bug(461, t, "infinity problems");
+        }
+    }
+
+    public void testByteMin() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestbyte(Byte.MIN_VALUE);
+        try {
+            saveAndQuery(aftt, "testbyte =", new Byte(Byte.MIN_VALUE));
+        } catch (Throwable t) {
+            //bug(AbstractTestCase.Platform.EMPRESS, 889, t, "Empress cannot store min values");
+            Assert.fail(
+                "Exception was thrown while storing Byte.MIN_VALUE : \n" +
+                    getStackTrace(t));
+        }
+    }
+
+    public void testByteMax() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestbyte(Byte.MAX_VALUE);
+        saveAndQuery(aftt, "testbyte =", new Byte(Byte.MAX_VALUE));
+    }
+    
+    public void testZeroBigInteger() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestBigInteger(BigInteger.ZERO);
+        saveAndQuery(aftt, "testBigInteger =", BigInteger.ZERO);
+    }
+    
+    public void testOneBigInteger() {
+        AllFieldTypesTest aftt = new AllFieldTypesTest();
+        aftt.setTestBigInteger(BigInteger.ONE);
+        saveAndQuery(aftt, "testBigInteger =", BigInteger.ONE);
+    }
+    
+    private void saveAndQuery(Object obj, String query, Object param) {
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        pm.persist(obj);
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM(false, false);
+//        Query q = pm.newQuery(obj.getClassquery);
+//        q.declareParameters("Object param");
+//        Collection c = (Collection) q.execute(param);
+        OpenJPAQuery q = pm.createQuery(
+            "SELECT a FROM AllFieldTypesTest a WHERE a." + query + " " + param);
+        Collection c = (Collection) q.getResultList();
+        assertSize(1, c);
+        pm.close();
+    }
+}
+
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStateManagerImplData.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStateManagerImplData.java
index 99891b3..68cc365 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStateManagerImplData.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStateManagerImplData.java
@@ -1,193 +1,193 @@
-/*
- * TestStateManagerImplData.java
- *
- * Created on October 13, 2006, 5:40 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
-
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestStateManagerImplData extends BaseKernelTest {
-
-    ClassMetaData _meta;
-
-    Boolean _f1;
-
-    Boolean _f3;
-
-    /**
-     * Creates a new instance of TestStateManagerImplData
-     */
-    public TestStateManagerImplData() {
-    }
-
-    public TestStateManagerImplData(String test) {
-        super(test);
-    }
-
-    public void setUpMetaData(ClassMetaData meta) {
-        _meta = meta;
-        _f1 = _meta.getField(1).usesImplData();
-        _f3 = _meta.getField(3).usesImplData();
-        _meta.getField(1).setUsesImplData(Boolean.TRUE);
-        _meta.getField(3).setUsesImplData(null);
-    }
-
-    public void tearDownMetaData() {
-        _meta.getField(1).setUsesImplData(_f1);
-        _meta.getField(3).setUsesImplData(_f3);
-    }
-
-    public void testImplData() {
-        ModRuntimeTest1 pc = new ModRuntimeTest1();
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        pm.persist(pc);
-        OpenJPAStateManager sm = getStateManager(pc, pm);
-        setUpMetaData(sm.getMetaData());
-        try {
-            // test instance level
-            Object inst = new Object();
-            assertNull(sm.getImplData());
-            assertNull(sm.setImplData(inst, true));
-            assertEquals(inst, sm.getImplData());
-            assertTrue(sm.isImplDataCacheable());
-            assertEquals(inst, sm.setImplData(null, false));
-            assertNull(sm.getImplData());
-            assertFalse(sm.isImplDataCacheable());
-            sm.setImplData(inst, false);
-            assertFalse(sm.isImplDataCacheable());
-
-            // test field level
-            Object f1 = new Object();
-            Object f3 = new Object();
-
-            assertNull(sm.getImplData(1));
-            assertFalse(sm.isImplDataCacheable(1));
-            assertNull(sm.setImplData(1, f1));
-            assertEquals(f1, sm.getImplData(1));
-            assertTrue(!sm.isImplDataCacheable(1));
-            assertEquals(f1, sm.setImplData(1, null));
-            assertNull(sm.getImplData(1));
-            assertFalse(sm.isImplDataCacheable(1));
-            sm.setImplData(1, f1);
-
-            assertNull(sm.setImplData(3, f3));
-            assertEquals(f3, sm.getImplData(3));
-            assertTrue(sm.isImplDataCacheable(3));
-            assertEquals(f1, sm.getImplData(1));
-
-            // this should clear field data
-            endTx(pm);
-
-            assertEquals(inst, sm.getImplData());
-            assertNull(sm.getImplData(1));
-            assertNull(sm.getImplData(3));
-
-            endEm(pm);
-        } finally {
-            tearDownMetaData();
-        }
-    }
-
-    public void testNotClearedIfRetainValues() {
-        deleteAll(ModRuntimeTest1.class);
-        notClearedIfRetainValuesTest(true);
-        notClearedIfRetainValuesTest(false);
-    }
-
-    private void notClearedIfRetainValuesTest(boolean optimistic) {
-        ModRuntimeTest1 pc = new ModRuntimeTest1("pc", 1);
-        int key = 1;
-        Object value = new Object();
-
-        // make instance persistent
-        OpenJPAEntityManager pm = getPM(optimistic, true);
-        startTx(pm);
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-
-        OpenJPAStateManager sm = getStateManager(pc, pm);
-        assertNotNull(sm);
-        setUpMetaData(sm.getMetaData());
-        try {
-            // set impl data
-            sm.setImplData(key, value);
-            assertEquals(value, sm.getImplData(key));
-            endTx(pm);
-
-            // test in nontransactional setting
-            assertEquals(value, sm.getImplData(key));
-
-            // test in next transaction
-            startTx(pm);
-            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-            sm = getStateManager(pc, pm);
-            assertNotNull(sm);
-            if (pm.getOptimistic())
-                assertEquals(value, sm.getImplData(key));
-            else
-                assertNull(sm.getImplData(key));
-            endTx(pm);
-            endEm(pm);
-        } finally {
-            tearDownMetaData();
-        }
-
-        // test in another pm for good measure
-        pm = getPM(optimistic, true);
-        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-        sm = getStateManager(pc, pm);
-        assertNotNull(sm);
-        setUpMetaData(sm.getMetaData());
-        try {
-            sm.setImplData(key, value);
-            assertEquals(value, sm.getImplData(key));
-
-            // test in transaction; re-lookup pc to be sure it enters the trans
-            startTx(pm);
-            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
-            if (pm.getOptimistic())
-                assertEquals(value, sm.getImplData(key));
-            else {
-                assertNull(sm.getImplData(key));
-                sm.setImplData(key, value);
-            }
-            endTx(pm);
-
-            // test outside of transaction
-            assertEquals(value, sm.getImplData(key));
-            endEm(pm);
-        } finally {
-            tearDownMetaData();
-        }
-    }
-}
+/*
+ * TestStateManagerImplData.java
+ *
+ * Created on October 13, 2006, 5:40 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestStateManagerImplData extends BaseKernelTest {
+
+    ClassMetaData _meta;
+
+    Boolean _f1;
+
+    Boolean _f3;
+
+    /**
+     * Creates a new instance of TestStateManagerImplData
+     */
+    public TestStateManagerImplData() {
+    }
+
+    public TestStateManagerImplData(String test) {
+        super(test);
+    }
+
+    public void setUpMetaData(ClassMetaData meta) {
+        _meta = meta;
+        _f1 = _meta.getField(1).usesImplData();
+        _f3 = _meta.getField(3).usesImplData();
+        _meta.getField(1).setUsesImplData(Boolean.TRUE);
+        _meta.getField(3).setUsesImplData(null);
+    }
+
+    public void tearDownMetaData() {
+        _meta.getField(1).setUsesImplData(_f1);
+        _meta.getField(3).setUsesImplData(_f3);
+    }
+
+    public void testImplData() {
+        ModRuntimeTest1 pc = new ModRuntimeTest1();
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        pm.persist(pc);
+        OpenJPAStateManager sm = getStateManager(pc, pm);
+        setUpMetaData(sm.getMetaData());
+        try {
+            // test instance level
+            Object inst = new Object();
+            assertNull(sm.getImplData());
+            assertNull(sm.setImplData(inst, true));
+            assertEquals(inst, sm.getImplData());
+            assertTrue(sm.isImplDataCacheable());
+            assertEquals(inst, sm.setImplData(null, false));
+            assertNull(sm.getImplData());
+            assertFalse(sm.isImplDataCacheable());
+            sm.setImplData(inst, false);
+            assertFalse(sm.isImplDataCacheable());
+
+            // test field level
+            Object f1 = new Object();
+            Object f3 = new Object();
+
+            assertNull(sm.getImplData(1));
+            assertFalse(sm.isImplDataCacheable(1));
+            assertNull(sm.setImplData(1, f1));
+            assertEquals(f1, sm.getImplData(1));
+            assertTrue(!sm.isImplDataCacheable(1));
+            assertEquals(f1, sm.setImplData(1, null));
+            assertNull(sm.getImplData(1));
+            assertFalse(sm.isImplDataCacheable(1));
+            sm.setImplData(1, f1);
+
+            assertNull(sm.setImplData(3, f3));
+            assertEquals(f3, sm.getImplData(3));
+            assertTrue(sm.isImplDataCacheable(3));
+            assertEquals(f1, sm.getImplData(1));
+
+            // this should clear field data
+            endTx(pm);
+
+            assertEquals(inst, sm.getImplData());
+            assertNull(sm.getImplData(1));
+            assertNull(sm.getImplData(3));
+
+            endEm(pm);
+        } finally {
+            tearDownMetaData();
+        }
+    }
+
+    public void testNotClearedIfRetainValues() {
+        deleteAll(ModRuntimeTest1.class);
+        notClearedIfRetainValuesTest(true);
+        notClearedIfRetainValuesTest(false);
+    }
+
+    private void notClearedIfRetainValuesTest(boolean optimistic) {
+        ModRuntimeTest1 pc = new ModRuntimeTest1("pc", 1);
+        int key = 1;
+        Object value = new Object();
+
+        // make instance persistent
+        OpenJPAEntityManager pm = getPM(optimistic, true);
+        startTx(pm);
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+
+        OpenJPAStateManager sm = getStateManager(pc, pm);
+        assertNotNull(sm);
+        setUpMetaData(sm.getMetaData());
+        try {
+            // set impl data
+            sm.setImplData(key, value);
+            assertEquals(value, sm.getImplData(key));
+            endTx(pm);
+
+            // test in nontransactional setting
+            assertEquals(value, sm.getImplData(key));
+
+            // test in next transaction
+            startTx(pm);
+            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+            sm = getStateManager(pc, pm);
+            assertNotNull(sm);
+            if (pm.getOptimistic())
+                assertEquals(value, sm.getImplData(key));
+            else
+                assertNull(sm.getImplData(key));
+            endTx(pm);
+            endEm(pm);
+        } finally {
+            tearDownMetaData();
+        }
+
+        // test in another pm for good measure
+        pm = getPM(optimistic, true);
+        pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+        sm = getStateManager(pc, pm);
+        assertNotNull(sm);
+        setUpMetaData(sm.getMetaData());
+        try {
+            sm.setImplData(key, value);
+            assertEquals(value, sm.getImplData(key));
+
+            // test in transaction; re-lookup pc to be sure it enters the trans
+            startTx(pm);
+            pc = (ModRuntimeTest1) pm.find(ModRuntimeTest1.class, oid);
+            if (pm.getOptimistic())
+                assertEquals(value, sm.getImplData(key));
+            else {
+                assertNull(sm.getImplData(key));
+                sm.setImplData(key, value);
+            }
+            endTx(pm);
+
+            // test outside of transaction
+            assertEquals(value, sm.getImplData(key));
+            endEm(pm);
+        } finally {
+            tearDownMetaData();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStaticInnerClasses.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStaticInnerClasses.java
index 2759b88..dd09b91 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStaticInnerClasses.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStaticInnerClasses.java
@@ -1,141 +1,141 @@
-/*
- * TestStaticInnerClasses.java
- *
- * Created on October 13, 2006, 5:45 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-import java.util.LinkedList;
-import java.util.List;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestStaticInnerClasses extends BaseKernelTest {
-
-    private Object _oid = null;
-
-    /**
-     * Creates a new instance of TestStaticInnerClasses
-     */
-    public TestStaticInnerClasses() {
-    }
-
-    public TestStaticInnerClasses(String name) {
-        super(name);
-    }
-
-    public void setUp()
-        throws Exception {
-        Inner inner = new Inner("foo");
-        inner.addTwin();
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-        pm.persist(inner);
-        _oid = pm.getObjectId(inner);
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testGetById() {
-        OpenJPAEntityManager pm = getPM();
-        Inner inner = (Inner) pm.find(Inner.class, _oid);
-        assertNotNull(inner);
-        assertEquals("foo", inner.getString());
-        endEm(pm);
-    }
-
-    public void testGetByQuery() {
-//        OpenJPAEntityManager pm = getPM();
-//
-//        OpenJPAQuery q = pm.createNativeQuery("",Inner.class);
-//        //FIXME jthomas
-//        /*
-//        q.ssetCandidates(pm.createExtent(Inner.class, false));
-//        q.declareVariables(Inner.class.getName() + " inner;");
-//        q.setFilter("twins.contains (inner) && inner.string == \"foo\"");
-//        q.setOrdering("string ascending, num descending");
-//        Iterator iter = null;
-//        try {
-//            iter = ((Collection) q.execute()).iterator();
-//        } catch (JDOException jdoe) {
-//            if (jdoe.getMessage().indexOf("is ambiguous") != -1)
-//                bug(AbstractTestCase.Platform.POSTGRESQL, 74, jdoe,
-//                        "Sorts in PostgreSQL may result"
-//                        + "in \"ORDER BY 'my_sort_key' is ambiguous\"");
-//            else
-//                throw jdoe;
-//        }
-//
-//        assertNotNull(iter);
-//        assertTrue(iter.hasNext());
-//        assertEquals("foo", ((Inner) iter.next()).getString());
-//        */
-//        endEm(pm,());
-        /*OpenJPAEntityManager pm = getPM();
-          OpenJPAQuery q = pm.createQuery("SELECT c FROM TestStaticInnerClasses.Inner c WHERE c.string = 'foo' ORDER BY c.string ASC");
-          q.setCandidateCollection((Collection)pm.createExtent(TestStaticInnerClasses.Inner.class, false));
-
-          try
-          {
-              Iterator iter = ((Collection) q.getResultList()).iterator();
-          }
-          catch (Exception jdoe)
-          {
-              if (jdoe.getMessage().indexOf("is ambiguous") != -1)
-                  bug(AbstractTestCase.Platform.POSTGRESQL, 74, jdoe,
-                          "Sorts in PostgreSQL may result"
-                          + "in \"ORDER BY 'my_sort_key' is ambiguous\"");
-              else
-                  throw jdoe;
-          }*/
-
-    }
-
-    @Entity
-    @Table(name="StaticInner")
-    public static class Inner {
-
-        private int num = 0;
-        private String string = null;
-        private List twins = new LinkedList();
-
-        protected Inner() {
-        }
-
-        public Inner(String string) {
-            this.string = string;
-        }
-
-        public void addTwin() {
-            twins.add(new Inner(string));
-        }
-
-        public String getString() {
-            return string;
-        }
-    }
-}
+/*
+ * TestStaticInnerClasses.java
+ *
+ * Created on October 13, 2006, 5:45 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+import java.util.LinkedList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestStaticInnerClasses extends BaseKernelTest {
+
+    private Object _oid = null;
+
+    /**
+     * Creates a new instance of TestStaticInnerClasses
+     */
+    public TestStaticInnerClasses() {
+    }
+
+    public TestStaticInnerClasses(String name) {
+        super(name);
+    }
+
+    public void setUp()
+        throws Exception {
+        Inner inner = new Inner("foo");
+        inner.addTwin();
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+        pm.persist(inner);
+        _oid = pm.getObjectId(inner);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testGetById() {
+        OpenJPAEntityManager pm = getPM();
+        Inner inner = (Inner) pm.find(Inner.class, _oid);
+        assertNotNull(inner);
+        assertEquals("foo", inner.getString());
+        endEm(pm);
+    }
+
+    public void testGetByQuery() {
+//        OpenJPAEntityManager pm = getPM();
+//
+//        OpenJPAQuery q = pm.createNativeQuery("",Inner.class);
+//        //FIXME jthomas
+//        /*
+//        q.ssetCandidates(pm.createExtent(Inner.class, false));
+//        q.declareVariables(Inner.class.getName() + " inner;");
+//        q.setFilter("twins.contains (inner) && inner.string == \"foo\"");
+//        q.setOrdering("string ascending, num descending");
+//        Iterator iter = null;
+//        try {
+//            iter = ((Collection) q.execute()).iterator();
+//        } catch (JDOException jdoe) {
+//            if (jdoe.getMessage().indexOf("is ambiguous") != -1)
+//                bug(AbstractTestCase.Platform.POSTGRESQL, 74, jdoe,
+//                        "Sorts in PostgreSQL may result"
+//                        + "in \"ORDER BY 'my_sort_key' is ambiguous\"");
+//            else
+//                throw jdoe;
+//        }
+//
+//        assertNotNull(iter);
+//        assertTrue(iter.hasNext());
+//        assertEquals("foo", ((Inner) iter.next()).getString());
+//        */
+//        endEm(pm,());
+        /*OpenJPAEntityManager pm = getPM();
+          OpenJPAQuery q = pm.createQuery("SELECT c FROM TestStaticInnerClasses.Inner c WHERE c.string = 'foo' ORDER BY c.string ASC");
+          q.setCandidateCollection((Collection)pm.createExtent(TestStaticInnerClasses.Inner.class, false));
+
+          try
+          {
+              Iterator iter = ((Collection) q.getResultList()).iterator();
+          }
+          catch (Exception jdoe)
+          {
+              if (jdoe.getMessage().indexOf("is ambiguous") != -1)
+                  bug(AbstractTestCase.Platform.POSTGRESQL, 74, jdoe,
+                          "Sorts in PostgreSQL may result"
+                          + "in \"ORDER BY 'my_sort_key' is ambiguous\"");
+              else
+                  throw jdoe;
+          }*/
+
+    }
+
+    @Entity
+    @Table(name="StaticInner")
+    public static class Inner {
+
+        private int num = 0;
+        private String string = null;
+        private List twins = new LinkedList();
+
+        protected Inner() {
+        }
+
+        public Inner(String string) {
+            this.string = string;
+        }
+
+        public void addTwin() {
+            twins.add(new Inner(string));
+        }
+
+        public String getString() {
+            return string;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStoreBlob.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStoreBlob.java
index dadf444..5657ee3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStoreBlob.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestStoreBlob.java
@@ -1,86 +1,86 @@
-/*
- * TestStoreBlob.java
- *
- * Created on October 13, 2006, 5:50 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.BlobTest;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestStoreBlob extends BaseKernelTest {
-
-    /**
-     * Creates a new instance of TestStoreBlob
-     */
-    public TestStoreBlob() {
-    }
-
-    public TestStoreBlob(String name) {
-        super(name);
-    }
-
-    public void testStoreBlob() {
-        OpenJPAEntityManager pm;
-
-        pm = getPM(false, false);
-        startTx(pm);
-        BlobTest blob = new BlobTest();
-        byte[] bytes = new byte[2048];
-        for (int i = 0; i < bytes.length; i++)
-            bytes[i] = randomByte().byteValue();
-
-        blob.setBlob(bytes);
-        pm.persist(blob);
-        int id = blob.getId();
-        endTx(pm);
-
-        byte[] b1 = blob.getBlob();
-        endEm(pm);
-
-        pm = getPM(false, false);
-        startTx(pm);
-        BlobTest blob2 = pm.find(BlobTest.class, id);
-
-        byte[] b2 = blob2.getBlob();
-
-        assertNotNull("Original blob was null", b1);
-        assertNotNull("Retrieved blob was null", b2);
-        assertEquals("Blob length was not the same", b1.length, b2.length);
-        assertBytesEquals("Blob contents did not match", b1, b2);
-
-        endTx(pm);
-    }
-
-    private void assertBytesEquals(String str,
-        byte[] a, byte[] b) {
-        for (int i = 0; i < a.length; i++) {
-            assertEquals(str + " [" + i + "]", a[i], b[i]);
-        }
-    }
-}
+/*
+ * TestStoreBlob.java
+ *
+ * Created on October 13, 2006, 5:50 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.BlobTest;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestStoreBlob extends BaseKernelTest {
+
+    /**
+     * Creates a new instance of TestStoreBlob
+     */
+    public TestStoreBlob() {
+    }
+
+    public TestStoreBlob(String name) {
+        super(name);
+    }
+
+    public void testStoreBlob() {
+        OpenJPAEntityManager pm;
+
+        pm = getPM(false, false);
+        startTx(pm);
+        BlobTest blob = new BlobTest();
+        byte[] bytes = new byte[2048];
+        for (int i = 0; i < bytes.length; i++)
+            bytes[i] = randomByte().byteValue();
+
+        blob.setBlob(bytes);
+        pm.persist(blob);
+        int id = blob.getId();
+        endTx(pm);
+
+        byte[] b1 = blob.getBlob();
+        endEm(pm);
+
+        pm = getPM(false, false);
+        startTx(pm);
+        BlobTest blob2 = pm.find(BlobTest.class, id);
+
+        byte[] b2 = blob2.getBlob();
+
+        assertNotNull("Original blob was null", b1);
+        assertNotNull("Retrieved blob was null", b2);
+        assertEquals("Blob length was not the same", b1.length, b2.length);
+        assertBytesEquals("Blob contents did not match", b1, b2);
+
+        endTx(pm);
+    }
+
+    private void assertBytesEquals(String str,
+        byte[] a, byte[] b) {
+        for (int i = 0; i < a.length; i++) {
+            assertEquals(str + " [" + i + "]", a[i], b[i]);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestTransition2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestTransition2.java
index 2ac792e..201b48f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestTransition2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestTransition2.java
@@ -1,994 +1,994 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel;
-
-
-
-import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
-import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest2;
-import org.apache.openjpa.persistence.kernel.common.apps.PersistenceAware;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.persistence.RestoreStateType;
-
-public class TestTransition2 extends BaseKernelTest {
-
-    private boolean supportsPessimistic = true;
-
-    private int _id = 0;
-
-    /**
-     * Creates a new instance of TestTransitions
-     */
-    public TestTransition2() {
-    }
-
-    public TestTransition2(String name) {
-        super(name);
-    }
-
-    public void setUp() throws Exception {
-        try {
-            OpenJPAEntityManager pm = getPM(false, false);
-            supportsPessimistic = !pm.getOptimistic();
-            pm.close();
-        }
-        catch (Exception e) {
-            supportsPessimistic = false;
-        }
-
-        OpenJPAEntityManager pm = getPM();
-        startTx(pm);
-
-        ModRuntimeTest2 b = createTest2();
-        pm.persist(b);
-        _id = b.getId();
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions from transient to
-     * persistent-transactional and back to transient after rollback.
-     */
-    public void testFlagTransitions1()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-        assertTransient(b);
-        assertTransient(b.getSelfOneOne());
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        pm.persist(b);
-
-        assertPersistent(b, true, true, false, true);
-
-        rollbackTx(pm);
-
-        assertTransient(b);
-        assertTransient(b.getSelfOneOne());
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions from transient to
-     * persistent-transactional to persistent-nontransactional after commit.
-     */
-    public void testFlagTransitions2()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-        assertTransient(b);
-        assertTransient(b.getSelfOneOne());
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        pm.persist(b);
-
-        assertPersistent(b, true, true, false, true);
-
-        endTx(pm);
-
-        assertPersistent(b, false, false, false, false);
-        assertPersistent(b.getSelfOneOne(), false, false, false, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions when finding a transactional instance by
-     * id, then committing.
-     */
-    public void testFlagTransitions3() throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertPersistent(b, true, false, false, false);
-        assertPersistent(b.getSelfOneOne(), true, false, false, false);
-
-        endTx(pm);
-
-        assertPersistent(b, false, false, false, false);
-        assertPersistent(b.getSelfOneOne(), false, false, false, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions when finding a transactional
-     * instance by id, then rolling back.
-     */
-    public void testFlagTransitions4()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertPersistent(b, true, false, false, false);
-        assertPersistent(b.getSelfOneOne(), true, false, false, false);
-
-        rollbackTx(pm);
-        //pm.getTransaction().rollback();
-
-        assertPersistent(b, false, false, false, false);
-        assertPersistent(b.getSelfOneOne(), false, false, false, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions when finding a non-transactional
-     * instance by id.
-     */
-    public void testFlagTransitions5()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-
-        assertPersistent(b, false, false, false, false);
-        assertPersistent(b.getSelfOneOne(), false, false, false, false);
-
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions from persistent-transactional
-     * to transient after delete and commit.
-     */
-    public void testFlagTransitions6()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        ModRuntimeTest1 parent = b.getSelfOneOne();
-        pm.remove(b);
-        assertPersistent(b, true, false, true, true);
-        assertPersistent(parent, true, false, false, false);
-
-        endTx(pm);
-
-        assertTransient(b);
-        assertPersistent(parent, false, false, false, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic jdo flag transitions from persistent-transactional
-     * to persistent-nontransactional after delete and rollback.
-     */
-    public void testFlagTransitions7()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        ModRuntimeTest1 parent = b.getSelfOneOne();
-        pm.remove(b);
-        assertPersistent(b, true, false, true, true);
-        assertPersistent(parent, true, false, false, false);
-
-        rollbackTx(pm);
-
-        assertPersistent(b, false, false, false, false);
-        assertPersistent(parent, false, false, false, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional and back to transient after rollback.
-     */
-    public void testStateTransitions1()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        pm.persist(b);
-        pm.persist(b.getSelfOneOne());
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional to persistent-nontransactional after commit.
-     */
-    public void testStateTransitions2()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        pm.persist(b);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then committing.
-     */
-    public void testStateTransitions3()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then committing.
-     */
-    public void testStateTransitions3a()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then rolling back.
-     */
-    public void testStateTransitions4()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then rolling back.
-     */
-    public void testStateTransitions4a()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to transient after delete and commit.
-     */
-    public void testStateTransitions5()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        ModRuntimeTest1 parent = b.getSelfOneOne();
-        assertNotNull("parent is null", parent);
-        pm.remove(b);
-
-        endTx(pm);
-
-        // parent should be valid
-        assertEquals("PARENT", parent.getStringField());
-
-        // 'b' should be cleared
-        assertNull(b.getStringField());
-        assertEquals(0, b.getIntField());
-        assertNull(b.getSelfOneOne());
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to persistent-nontransactional after delete and rollback.
-     */
-    public void testStateTransitions6()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        pm.remove(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional and back to transient after rollback.
-     */
-    public void testOptStateTransitions1()
-        throws Exception {
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        pm.persist(b);
-        pm.persist(b.getSelfOneOne());
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional to persistent-nontransactional after commit.
-     */
-    public void testOptStateTransitions2()
-        throws Exception {
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        pm.persist(b);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then committing.
-     */
-    public void testOptStateTransitions3()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then rolling back.
-     */
-    public void testOptStateTransitions4()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to transient after delete and commit.
-     */
-    public void testOptStateTransitions5()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        ModRuntimeTest1 parent = b.getSelfOneOne();
-        assertNotNull("parent is null", parent);
-        pm.remove(b);
-
-        endTx(pm);
-
-        // parent should be valid
-        assertEquals("PARENT", parent.getStringField());
-
-        // 'b' should be cleared
-        assertNull(b.getStringField());
-        assertEquals(0, b.getIntField());
-        assertNull(b.getSelfOneOne());
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to persistent-nontransactional after delete and rollback.
-     */
-    public void testOptStateTransitions6()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, false);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        pm.remove(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional and back to transient after rollback.
-     */
-    public void testOptRetainStateTransitions1()
-        throws Exception {
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-
-        pm.persist(b);
-        pm.persist(b.getSelfOneOne());
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional to persistent-nontransactional after commit.
-     */
-    public void testOptRetainStateTransitions2()
-        throws Exception {
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-
-        pm.persist(b);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, true);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then committing.
-     */
-    public void testOptRetainStateTransitions3()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, true);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then rolling back.
-     */
-    public void testOptRetainStateTransitions4()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to transient after delete and commit.
-     */
-    public void testOptRetainStateTransitions5()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        ModRuntimeTest1 parent = b.getSelfOneOne();
-
-        assertNotNull("parent is null", parent);
-        pm.remove(b);
-
-        endTx(pm);
-
-        // parent should be valid
-        assertEquals("PARENT", parent.getStringField());
-
-        // 'b' should be cleared
-        assertNull(b.getStringField());
-        assertEquals(0, b.getIntField());
-        assertNull(b.getSelfOneOne());
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to persistent-nontransactional after delete and rollback.
-     */
-    public void testOptRetainStateTransitions6()
-        throws Exception {
-        OpenJPAEntityManager pm = getPM(true, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        pm.remove(b);
-
-        rollbackTx(pm);
-
-        if (pm.getRestoreState() != RestoreStateType.NONE)
-            assertTest2Orig(b);
-        else
-            assertNull(b.getStringField());
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional and back to transient after rollback.
-     */
-    public void testRetainStateTransitions1()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, true);
-        startTx(pm);
-
-        pm.persist(b);
-        pm.persist(b.getSelfOneOne());
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * persistent-transactional to persistent-nontransactional after commit.
-     */
-    public void testRetainStateTransitions2()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, true);
-        startTx(pm);
-
-        pm.persist(b);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, true);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then committing.
-     */
-    public void testRetainStateTransitions3()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, true);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions when finding a transactional
-     * instance by id, then rolling back.
-     */
-    public void testRetainStateTransitions4()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        assertTest2Orig(b);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to transient after delete and commit.
-     */
-    public void testRetainStateTransitions5() throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b = (ModRuntimeTest2) pm.find(ModRuntimeTest2.class,
-            _id);
-        ModRuntimeTest1 parent = b.getSelfOneOne();
-        assertNotNull("parent is null", parent);
-        pm.remove(b);
-
-        endTx(pm);
-
-        // parent should be valid
-        assertEquals("PARENT", parent.getStringField());
-
-        // 'b' should be cleared
-        assertNull(b.getStringField());
-        assertEquals(0, b.getIntField());
-        assertNull(b.getSelfOneOne());
-    }
-
-    /**
-     * Tests basic state transitions from persistent-transactional
-     * to persistent-nontransactional after delete and rollback.
-     */
-    public void testRetainStateTransitions6()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        OpenJPAEntityManager pm = getPM(false, true);
-        startTx(pm);
-
-        ModRuntimeTest2 b =
-            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
-        pm.remove(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * transient-dirty and back to transient after rollback.
-     */
-    public void testTransientStateTransitions1()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        pm.transactional(b, true);
-        pm.transactional(b.getSelfOneOne(), true);
-        changeTest2(b);
-
-        rollbackTx(pm);
-
-        assertTest2Orig(b);
-        endEm(pm);
-    }
-
-    /**
-     * Tests basic state transitions from transient to
-     * transient-transactional and stick on commit.
-     */
-    public void testTransientStateTransitions2()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-
-        pm.transactional(b, true);
-        pm.transactional(b.getSelfOneOne(), true);
-        changeTest2(b);
-
-        endTx(pm);
-
-        assertTest2Changed(b, false);
-        endEm(pm);
-    }
-
-    /**
-     * Tests state transitions from PClean to transient.
-     */
-    public void testTransientStateTransitions3()
-        throws Exception {
-        if (!supportsPessimistic)
-            return;
-
-        ModRuntimeTest2 b = createTest2();
-
-        OpenJPAEntityManager pm = getPM(false, false);
-        startTx(pm);
-        pm.persist(b);
-        int oid = b.getId();
-        endTx(pm);
-        endEm(pm);
-
-        pm = getPM(false, false);
-        //FIXME jthomas
-        b = (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, oid);
-        pm.retrieve(b);
-        //FIXME jthomas
-        endEm(pm);
-
-        // note that at this point, parent is not transient, just retrieved.
-        assertNotNull("b is null", b.getSelfOneOne());
-    }
-
-    private ModRuntimeTest2 createTest2() {
-        return createTest2("NAME", 50);
-    }
-
-    private ModRuntimeTest2 createTest2(String str, int i) {
-        return createTest2(new ModRuntimeTest2(str, i));
-    }
-
-    private ModRuntimeTest2 createTest2(ModRuntimeTest2 b) {
-        ModRuntimeTest1 parent = new ModRuntimeTest1("PARENT", 70);
-        b.setSelfOneOne(parent);
-        return b;
-    }
-
-    private void changeTest2(ModRuntimeTest2 b) {
-        PersistenceAware.setModTransString(b, "999");
-        b.setStringField("CHANGED");
-        b.setIntField(1000);
-        b.getSelfOneOne().setStringField("PCHANGED");
-        b.setSelfOneOne(null);
-    }
-
-    private void assertTest2Changed(ModRuntimeTest2 b, boolean retainValues) {
-        if (retainValues)
-            assertEquals("999", PersistenceAware.getModTransString(b));
-        assertEquals("CHANGED", b.getStringField());
-        assertEquals(1000, b.getIntField());
-        assertNull(b.getSelfOneOne());
-    }
-
-    private void assertTest2Orig(ModRuntimeTest2 b) {
-        assertEquals("NAME", b.getStringField());
-        assertEquals(50, b.getIntField());
-        assertNotNull(b.getSelfOneOne());
-        assertEquals("PARENT", b.getSelfOneOne().getStringField());
-
-        assertEquals(
-            "transactional field 'transString' was not the "
-                + "same as it was originally. Ensure that "
-                + "openjpa.kernel.PersistenceAware is enhanced. "
-                +
-                "It is persistence-aware, so will not be enhanced by commands "
-                + "like jdoc $(find test -name '*.jdo').", null,
-            PersistenceAware.getModTransString(b));
-    }
-
-    /**
-     * Assert that the given object is persistent.
-     */
-    public void assertTransient(Object a) {
-        OpenJPAEntityManager pm = currentEntityManager();
-        assertTrue(!pm.isPersistent(a));
-        assertTrue(!pm.isTransactional(a));
-        assertTrue(!pm.isNewlyPersistent(a));
-        assertTrue(!pm.isDirty(a));
-        assertTrue(!pm.isRemoved(a));
-        assertNull(pm.getObjectId(a));
-        assertNull(OpenJPAPersistence.getEntityManager(a));
-        endEm(pm);
-    }
-
-    /**
-     * Assert that the given object is persistent and is in the given state.
-     */
-    public void assertPersistent(Object a, boolean isTrans, boolean isNew,
-        boolean isDeleted, boolean isDirty) {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        assertTrue(pm.isPersistent(a));
-
-        PersistenceCapable xman = (PersistenceCapable) a;
-
-        assertEquals(isTrans, pm.isTransactional(a));
-		assertEquals(isNew, pm.isNewlyPersistent(a));
-		assertEquals(isDeleted, pm.isRemoved(a));
-		assertEquals(isDirty || isNew || isDeleted, pm.isDirty(a));
-		assertNotNull(pm.getObjectId(a));
-		assertNotNull(OpenJPAPersistence.getEntityManager(a));
-
-		endEm(pm);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel;
+
+
+
+import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1;
+import org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest2;
+import org.apache.openjpa.persistence.kernel.common.apps.PersistenceAware;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.RestoreStateType;
+
+public class TestTransition2 extends BaseKernelTest {
+
+    private boolean supportsPessimistic = true;
+
+    private int _id = 0;
+
+    /**
+     * Creates a new instance of TestTransitions
+     */
+    public TestTransition2() {
+    }
+
+    public TestTransition2(String name) {
+        super(name);
+    }
+
+    public void setUp() throws Exception {
+        try {
+            OpenJPAEntityManager pm = getPM(false, false);
+            supportsPessimistic = !pm.getOptimistic();
+            pm.close();
+        }
+        catch (Exception e) {
+            supportsPessimistic = false;
+        }
+
+        OpenJPAEntityManager pm = getPM();
+        startTx(pm);
+
+        ModRuntimeTest2 b = createTest2();
+        pm.persist(b);
+        _id = b.getId();
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions from transient to
+     * persistent-transactional and back to transient after rollback.
+     */
+    public void testFlagTransitions1()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+        assertTransient(b);
+        assertTransient(b.getSelfOneOne());
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        pm.persist(b);
+
+        assertPersistent(b, true, true, false, true);
+
+        rollbackTx(pm);
+
+        assertTransient(b);
+        assertTransient(b.getSelfOneOne());
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions from transient to
+     * persistent-transactional to persistent-nontransactional after commit.
+     */
+    public void testFlagTransitions2()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+        assertTransient(b);
+        assertTransient(b.getSelfOneOne());
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        pm.persist(b);
+
+        assertPersistent(b, true, true, false, true);
+
+        endTx(pm);
+
+        assertPersistent(b, false, false, false, false);
+        assertPersistent(b.getSelfOneOne(), false, false, false, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions when finding a transactional instance by
+     * id, then committing.
+     */
+    public void testFlagTransitions3() throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertPersistent(b, true, false, false, false);
+        assertPersistent(b.getSelfOneOne(), true, false, false, false);
+
+        endTx(pm);
+
+        assertPersistent(b, false, false, false, false);
+        assertPersistent(b.getSelfOneOne(), false, false, false, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions when finding a transactional
+     * instance by id, then rolling back.
+     */
+    public void testFlagTransitions4()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertPersistent(b, true, false, false, false);
+        assertPersistent(b.getSelfOneOne(), true, false, false, false);
+
+        rollbackTx(pm);
+        //pm.getTransaction().rollback();
+
+        assertPersistent(b, false, false, false, false);
+        assertPersistent(b.getSelfOneOne(), false, false, false, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions when finding a non-transactional
+     * instance by id.
+     */
+    public void testFlagTransitions5()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+
+        assertPersistent(b, false, false, false, false);
+        assertPersistent(b.getSelfOneOne(), false, false, false, false);
+
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions from persistent-transactional
+     * to transient after delete and commit.
+     */
+    public void testFlagTransitions6()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        ModRuntimeTest1 parent = b.getSelfOneOne();
+        pm.remove(b);
+        assertPersistent(b, true, false, true, true);
+        assertPersistent(parent, true, false, false, false);
+
+        endTx(pm);
+
+        assertTransient(b);
+        assertPersistent(parent, false, false, false, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic jdo flag transitions from persistent-transactional
+     * to persistent-nontransactional after delete and rollback.
+     */
+    public void testFlagTransitions7()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        ModRuntimeTest1 parent = b.getSelfOneOne();
+        pm.remove(b);
+        assertPersistent(b, true, false, true, true);
+        assertPersistent(parent, true, false, false, false);
+
+        rollbackTx(pm);
+
+        assertPersistent(b, false, false, false, false);
+        assertPersistent(parent, false, false, false, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional and back to transient after rollback.
+     */
+    public void testStateTransitions1()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        pm.persist(b);
+        pm.persist(b.getSelfOneOne());
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional to persistent-nontransactional after commit.
+     */
+    public void testStateTransitions2()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        pm.persist(b);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then committing.
+     */
+    public void testStateTransitions3()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then committing.
+     */
+    public void testStateTransitions3a()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then rolling back.
+     */
+    public void testStateTransitions4()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then rolling back.
+     */
+    public void testStateTransitions4a()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to transient after delete and commit.
+     */
+    public void testStateTransitions5()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        ModRuntimeTest1 parent = b.getSelfOneOne();
+        assertNotNull("parent is null", parent);
+        pm.remove(b);
+
+        endTx(pm);
+
+        // parent should be valid
+        assertEquals("PARENT", parent.getStringField());
+
+        // 'b' should be cleared
+        assertNull(b.getStringField());
+        assertEquals(0, b.getIntField());
+        assertNull(b.getSelfOneOne());
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to persistent-nontransactional after delete and rollback.
+     */
+    public void testStateTransitions6()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        pm.remove(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional and back to transient after rollback.
+     */
+    public void testOptStateTransitions1()
+        throws Exception {
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        pm.persist(b);
+        pm.persist(b.getSelfOneOne());
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional to persistent-nontransactional after commit.
+     */
+    public void testOptStateTransitions2()
+        throws Exception {
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        pm.persist(b);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then committing.
+     */
+    public void testOptStateTransitions3()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then rolling back.
+     */
+    public void testOptStateTransitions4()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to transient after delete and commit.
+     */
+    public void testOptStateTransitions5()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        ModRuntimeTest1 parent = b.getSelfOneOne();
+        assertNotNull("parent is null", parent);
+        pm.remove(b);
+
+        endTx(pm);
+
+        // parent should be valid
+        assertEquals("PARENT", parent.getStringField());
+
+        // 'b' should be cleared
+        assertNull(b.getStringField());
+        assertEquals(0, b.getIntField());
+        assertNull(b.getSelfOneOne());
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to persistent-nontransactional after delete and rollback.
+     */
+    public void testOptStateTransitions6()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, false);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        pm.remove(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional and back to transient after rollback.
+     */
+    public void testOptRetainStateTransitions1()
+        throws Exception {
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+
+        pm.persist(b);
+        pm.persist(b.getSelfOneOne());
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional to persistent-nontransactional after commit.
+     */
+    public void testOptRetainStateTransitions2()
+        throws Exception {
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+
+        pm.persist(b);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, true);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then committing.
+     */
+    public void testOptRetainStateTransitions3()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, true);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then rolling back.
+     */
+    public void testOptRetainStateTransitions4()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to transient after delete and commit.
+     */
+    public void testOptRetainStateTransitions5()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        ModRuntimeTest1 parent = b.getSelfOneOne();
+
+        assertNotNull("parent is null", parent);
+        pm.remove(b);
+
+        endTx(pm);
+
+        // parent should be valid
+        assertEquals("PARENT", parent.getStringField());
+
+        // 'b' should be cleared
+        assertNull(b.getStringField());
+        assertEquals(0, b.getIntField());
+        assertNull(b.getSelfOneOne());
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to persistent-nontransactional after delete and rollback.
+     */
+    public void testOptRetainStateTransitions6()
+        throws Exception {
+        OpenJPAEntityManager pm = getPM(true, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        pm.remove(b);
+
+        rollbackTx(pm);
+
+        if (pm.getRestoreState() != RestoreStateType.NONE)
+            assertTest2Orig(b);
+        else
+            assertNull(b.getStringField());
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional and back to transient after rollback.
+     */
+    public void testRetainStateTransitions1()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, true);
+        startTx(pm);
+
+        pm.persist(b);
+        pm.persist(b.getSelfOneOne());
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * persistent-transactional to persistent-nontransactional after commit.
+     */
+    public void testRetainStateTransitions2()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, true);
+        startTx(pm);
+
+        pm.persist(b);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, true);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then committing.
+     */
+    public void testRetainStateTransitions3()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, true);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions when finding a transactional
+     * instance by id, then rolling back.
+     */
+    public void testRetainStateTransitions4()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        assertTest2Orig(b);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to transient after delete and commit.
+     */
+    public void testRetainStateTransitions5() throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b = (ModRuntimeTest2) pm.find(ModRuntimeTest2.class,
+            _id);
+        ModRuntimeTest1 parent = b.getSelfOneOne();
+        assertNotNull("parent is null", parent);
+        pm.remove(b);
+
+        endTx(pm);
+
+        // parent should be valid
+        assertEquals("PARENT", parent.getStringField());
+
+        // 'b' should be cleared
+        assertNull(b.getStringField());
+        assertEquals(0, b.getIntField());
+        assertNull(b.getSelfOneOne());
+    }
+
+    /**
+     * Tests basic state transitions from persistent-transactional
+     * to persistent-nontransactional after delete and rollback.
+     */
+    public void testRetainStateTransitions6()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        OpenJPAEntityManager pm = getPM(false, true);
+        startTx(pm);
+
+        ModRuntimeTest2 b =
+            (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, _id);
+        pm.remove(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * transient-dirty and back to transient after rollback.
+     */
+    public void testTransientStateTransitions1()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        pm.transactional(b, true);
+        pm.transactional(b.getSelfOneOne(), true);
+        changeTest2(b);
+
+        rollbackTx(pm);
+
+        assertTest2Orig(b);
+        endEm(pm);
+    }
+
+    /**
+     * Tests basic state transitions from transient to
+     * transient-transactional and stick on commit.
+     */
+    public void testTransientStateTransitions2()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+
+        pm.transactional(b, true);
+        pm.transactional(b.getSelfOneOne(), true);
+        changeTest2(b);
+
+        endTx(pm);
+
+        assertTest2Changed(b, false);
+        endEm(pm);
+    }
+
+    /**
+     * Tests state transitions from PClean to transient.
+     */
+    public void testTransientStateTransitions3()
+        throws Exception {
+        if (!supportsPessimistic)
+            return;
+
+        ModRuntimeTest2 b = createTest2();
+
+        OpenJPAEntityManager pm = getPM(false, false);
+        startTx(pm);
+        pm.persist(b);
+        int oid = b.getId();
+        endTx(pm);
+        endEm(pm);
+
+        pm = getPM(false, false);
+        //FIXME jthomas
+        b = (ModRuntimeTest2) pm.find(ModRuntimeTest2.class, oid);
+        pm.retrieve(b);
+        //FIXME jthomas
+        endEm(pm);
+
+        // note that at this point, parent is not transient, just retrieved.
+        assertNotNull("b is null", b.getSelfOneOne());
+    }
+
+    private ModRuntimeTest2 createTest2() {
+        return createTest2("NAME", 50);
+    }
+
+    private ModRuntimeTest2 createTest2(String str, int i) {
+        return createTest2(new ModRuntimeTest2(str, i));
+    }
+
+    private ModRuntimeTest2 createTest2(ModRuntimeTest2 b) {
+        ModRuntimeTest1 parent = new ModRuntimeTest1("PARENT", 70);
+        b.setSelfOneOne(parent);
+        return b;
+    }
+
+    private void changeTest2(ModRuntimeTest2 b) {
+        PersistenceAware.setModTransString(b, "999");
+        b.setStringField("CHANGED");
+        b.setIntField(1000);
+        b.getSelfOneOne().setStringField("PCHANGED");
+        b.setSelfOneOne(null);
+    }
+
+    private void assertTest2Changed(ModRuntimeTest2 b, boolean retainValues) {
+        if (retainValues)
+            assertEquals("999", PersistenceAware.getModTransString(b));
+        assertEquals("CHANGED", b.getStringField());
+        assertEquals(1000, b.getIntField());
+        assertNull(b.getSelfOneOne());
+    }
+
+    private void assertTest2Orig(ModRuntimeTest2 b) {
+        assertEquals("NAME", b.getStringField());
+        assertEquals(50, b.getIntField());
+        assertNotNull(b.getSelfOneOne());
+        assertEquals("PARENT", b.getSelfOneOne().getStringField());
+
+        assertEquals(
+            "transactional field 'transString' was not the "
+                + "same as it was originally. Ensure that "
+                + "openjpa.kernel.PersistenceAware is enhanced. "
+                +
+                "It is persistence-aware, so will not be enhanced by commands "
+                + "like jdoc $(find test -name '*.jdo').", null,
+            PersistenceAware.getModTransString(b));
+    }
+
+    /**
+     * Assert that the given object is persistent.
+     */
+    public void assertTransient(Object a) {
+        OpenJPAEntityManager pm = currentEntityManager();
+        assertTrue(!pm.isPersistent(a));
+        assertTrue(!pm.isTransactional(a));
+        assertTrue(!pm.isNewlyPersistent(a));
+        assertTrue(!pm.isDirty(a));
+        assertTrue(!pm.isRemoved(a));
+        assertNull(pm.getObjectId(a));
+        assertNull(OpenJPAPersistence.getEntityManager(a));
+        endEm(pm);
+    }
+
+    /**
+     * Assert that the given object is persistent and is in the given state.
+     */
+    public void assertPersistent(Object a, boolean isTrans, boolean isNew,
+        boolean isDeleted, boolean isDirty) {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        assertTrue(pm.isPersistent(a));
+
+        PersistenceCapable xman = (PersistenceCapable) a;
+
+        assertEquals(isTrans, pm.isTransactional(a));
+		assertEquals(isNew, pm.isNewlyPersistent(a));
+		assertEquals(isDeleted, pm.isRemoved(a));
+		assertEquals(isDirty || isNew || isDeleted, pm.isDirty(a));
+		assertNotNull(pm.getObjectId(a));
+		assertNotNull(OpenJPAPersistence.getEntityManager(a));
+
+		endEm(pm);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AImplB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AImplB.java
index f0a6b67..d10ad43 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AImplB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AImplB.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "aimplb")
-@IdClass(AImplB.Idkey.class)
-public class AImplB implements AIntf {
-
-    private String name;
-    @Id
-    private int pk1;
-    @Id
-    private String pk2;
-
-    protected AImplB() {
-    }
-
-    public AImplB(String name, int pk1, String pk2) {
-        setName(name);
-        this.pk1 = pk1;
-        this.pk2 = pk2;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setPK1(int pk1) {
-        this.pk1 = pk1;
-    }
-
-    public int getPK1() {
-        return this.pk1;
-    }
-
-    public void setPK2(String pk2) {
-        this.pk2 = pk2;
-    }
-
-    public String getPK2() {
-        return this.pk2;
-    }
-
-    public static class Idkey implements Serializable {
-
-        public int pk1;
-        public String pk2;
-
-        public Idkey() {
-        }
-
-        public Idkey(String str) {
-            int index = str.indexOf("/");
-            if (index != -1) {
-                pk1 = Integer.parseInt(str.substring(0, index));
-                pk2 = str.substring(index + 1);
-            }
-        }
-
-        public String toString() {
-            return pk1 + "/" + pk2;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof Idkey))
-                return false;
-
-            Idkey id = (Idkey) other;
-            if (pk2 == null && id.pk2 != null)
-                return false;
-            if (pk2 != null && id.pk2 == null)
-                return false;
-            if (!(pk1 == id.pk1))
-                return false;
-            if (!(pk2.equals(id.pk2)))
-                return false;
-
-            return true;
-        }
-
-        @Override
-        public int hashCode() {
-            return (pk1 + pk2).hashCode();
-        }
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "aimplb")
+@IdClass(AImplB.Idkey.class)
+public class AImplB implements AIntf {
+
+    private String name;
+    @Id
+    private int pk1;
+    @Id
+    private String pk2;
+
+    protected AImplB() {
+    }
+
+    public AImplB(String name, int pk1, String pk2) {
+        setName(name);
+        this.pk1 = pk1;
+        this.pk2 = pk2;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setPK1(int pk1) {
+        this.pk1 = pk1;
+    }
+
+    public int getPK1() {
+        return this.pk1;
+    }
+
+    public void setPK2(String pk2) {
+        this.pk2 = pk2;
+    }
+
+    public String getPK2() {
+        return this.pk2;
+    }
+
+    public static class Idkey implements Serializable {
+
+        public int pk1;
+        public String pk2;
+
+        public Idkey() {
+        }
+
+        public Idkey(String str) {
+            int index = str.indexOf("/");
+            if (index != -1) {
+                pk1 = Integer.parseInt(str.substring(0, index));
+                pk2 = str.substring(index + 1);
+            }
+        }
+
+        public String toString() {
+            return pk1 + "/" + pk2;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof Idkey))
+                return false;
+
+            Idkey id = (Idkey) other;
+            if (pk2 == null && id.pk2 != null)
+                return false;
+            if (pk2 != null && id.pk2 == null)
+                return false;
+            if (!(pk1 == id.pk1))
+                return false;
+            if (!(pk2.equals(id.pk2)))
+                return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return (pk1 + pk2).hashCode();
+        }
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AIntf.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AIntf.java
index 4db730c..5de5f8c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AIntf.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AIntf.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * Interface inplemented by {@link A}, used for interface
- * testing.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public interface AIntf {
-
-    public String getName();
-
-    public void setName(String name);
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * Interface inplemented by {@link A}, used for interface
+ * testing.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public interface AIntf {
+
+    public String getName();
+
+    public void setName(String name);
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AbstractMappedAppIdSuper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AbstractMappedAppIdSuper.java
index 8b6bc67..34da30e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AbstractMappedAppIdSuper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AbstractMappedAppIdSuper.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-
-@MappedSuperclass
-public abstract class AbstractMappedAppIdSuper {
-
-    @Id
-    private String pk;
-
-    public String getPk() {
-        return this.pk;
-    }
-
-    public void setPk(String pk) {
-        this.pk = pk;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+@MappedSuperclass
+public abstract class AbstractMappedAppIdSuper {
+
+    @Id
+    private String pk;
+
+    public String getPk() {
+        return this.pk;
+    }
+
+    public void setPk(String pk) {
+        this.pk = pk;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
index c518695..6966270 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
@@ -1,303 +1,303 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Table(name = "ALL_FLDTYPETEST")
-public class AllFieldTypesTest {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    private int testint;
-    private long testlong;
-    private short testshort;
-    private float testfloat;
-    private double testdouble;
-    private byte testbyte;
-    private boolean testboolean;
-    private char testchar;
-    private String testString;
-    private String testBigString;
-    @Temporal(TemporalType.DATE)
-    private Date testDate;
-    @Temporal(TemporalType.DATE)
-    private Calendar testCalendar;
-    private Object testObject;
-    private BigInteger testBigInteger;
-    private BigDecimal testBigDecimal;
-
-    public AllFieldTypesTest() {
-        testfloat = 1f;
-        testdouble = 1.0;
-    }
-
-    public Date getTestDate() {
-        return this.testDate;
-    }
-
-    public void setTestDate(Date testDate) {
-        this.testDate = testDate;
-    }
-
-    public void setTestCalendar(Calendar testCalendar) {
-        this.testCalendar = testCalendar;
-    }
-
-    public Calendar getTestCalendar() {
-        return this.testCalendar;
-    }
-
-    public Object getTestObject() {
-        return this.testObject;
-    }
-
-    public void setTestObject(Object testObject) {
-        this.testObject = testObject;
-    }
-
-    public char getTestchar() {
-        return this.testchar;
-    }
-
-    public void setTestchar(char testchar) {
-        this.testchar = testchar;
-    }
-
-    public int getTestint() {
-        return this.testint;
-    }
-
-    public void setTestint(int testint) {
-        this.testint = testint;
-    }
-
-    public short getTestshort() {
-        return this.testshort;
-    }
-
-    public void setTestshort(short testshort) {
-        this.testshort = testshort;
-    }
-
-    public long getTestlong() {
-        return this.testlong;
-    }
-
-    public void setTestlong(long testlong) {
-        this.testlong = testlong;
-    }
-
-    public boolean getTestboolean() {
-        return this.testboolean;
-    }
-
-    public void setTestboolean(boolean testboolean) {
-        this.testboolean = testboolean;
-    }
-
-    public float getTestfloat() {
-        return this.testfloat;
-    }
-
-    public void setTestfloat(float testfloat) {
-        this.testfloat = testfloat;
-    }
-
-    public double getTestdouble() {
-        return this.testdouble;
-    }
-
-    public void setTestdouble(double testdouble) {
-        this.testdouble = testdouble;
-    }
-
-    public String getTestString() {
-        return this.testString;
-    }
-
-    public void setTestString(String testString) {
-        this.testString = testString;
-    }
-
-    public void setTestBigString(String testBigString) {
-        this.testBigString = testBigString;
-    }
-
-    public String getTestBigString() {
-        return this.testBigString;
-    }
-
-    public byte getTestbyte() {
-        return this.testbyte;
-    }
-
-    public void setTestbyte(byte testbyte) {
-        this.testbyte = testbyte;
-    }
-
-    public BigInteger getTestBigInteger() {
-        return this.testBigInteger;
-    }
-
-    public void setTestBigInteger(BigInteger testBigInteger) {
-        this.testBigInteger = testBigInteger;
-    }
-
-    public BigDecimal getTestBigDecimal() {
-        return this.testBigDecimal;
-    }
-
-    public void setTestBigDecimal(BigDecimal testBigDecimal) {
-        this.testBigDecimal = testBigDecimal;
-    }
-
-    public void randomize(boolean objects, boolean blobs) {
-        testint = AbstractTestCase.randomInt().intValue();
-        testlong = AbstractTestCase.randomLong().longValue();
-        testshort = AbstractTestCase.randomShort().shortValue();
-        testfloat = AbstractTestCase.randomFloat().floatValue();
-        testdouble = AbstractTestCase.randomDouble().doubleValue();
-        testbyte = AbstractTestCase.randomByte().byteValue();
-        testboolean = AbstractTestCase.randomBoolean().booleanValue();
-        testchar = AbstractTestCase.randomChar().charValue();
-
-        if (objects) {
-            testString = AbstractTestCase.randomString();
-            testDate = AbstractTestCase.randomDate();
-
-            testCalendar = Calendar.getInstance();
-            testCalendar.setTime(AbstractTestCase.randomDate());
-
-            testBigInteger = AbstractTestCase.randomBigInteger();
-            testBigDecimal = AbstractTestCase.randomBigDecimal();
-        }
-
-        if (blobs && objects) {
-            testObject = AbstractTestCase.randomBlob();
-            testBigString = AbstractTestCase.randomClob();
-        }
-    }
-
-    public String toString() {
-        return "\n{"
-            + "testint=" + testint + ";"
-            + "testlong=" + testlong + ";"
-            + "testshort=" + testshort + ";"
-            + "testfloat=" + testfloat + ";"
-            + "testdouble=" + testdouble + ";"
-            + "testbyte=" + testbyte + ";"
-            + "testboolean=" + testboolean + ";"
-            + "testchar=" + testchar + ";"
-            + "testString=" + testString + ";"
-            + "testBigString=" + testBigString + ";"
-            + "testDate=" + testDate + ";"
-            + "testCalendar=" + testCalendar + ";"
-            + "testObject=" + testObject
-            + "(" + ((testObject instanceof byte[]) ?
-            "(byte[])" + ((byte[]) testObject).length + "" :
-            (testObject == null ? "null" :
-                testObject.getClass().getName())) + ")"
-            + ";"
-            + "testBigInteger=" + testBigInteger + ";"
-            + "testBigDecimal=" + testBigDecimal + ";"
-            + "}";
-    }
-
-    public int hashCode() {
-        return (int) ((
-            testint
-                + testlong
-                + testshort
-                + testfloat
-                + testdouble
-                + testbyte
-                + (testboolean ? 1 : 0)
-                + testchar
-                + (testString == null ? 0 : testString.hashCode())
-                + (testBigString == null ? 0 : testBigString.hashCode())
-                + (testDate == null ? 0 : testDate.hashCode())
-                + (testCalendar == null ? 0 : testCalendar.hashCode())
-                + (testObject == null ? 0 : testObject.hashCode())
-                + (testBigInteger == null ? 0 : testBigInteger.hashCode())
-                + (testBigDecimal == null ? 0 : testBigDecimal.hashCode())))
-            % Integer.MAX_VALUE;
-    }
-
-    public boolean equals(Object other) {
-        if (other == null && !(other instanceof AllFieldTypesTest))
-            return false;
-
-        AllFieldTypesTest o = (AllFieldTypesTest) other;
-
-        return
-            o.testint == testint &&
-                o.testlong == testlong &&
-                o.testshort == testshort &&
-                o.testfloat == testfloat &&
-                o.testdouble == testdouble &&
-                o.testbyte == testbyte &&
-                o.testboolean == testboolean &&
-                o.testchar == testchar &&
-                eq(o.testString, testString) &&
-                eq(o.testBigString, testBigString) &&
-                eq(o.testDate, testDate) &&
-                eq(o.testCalendar, testCalendar) &&
-                eq(o.testObject, testObject) &&
-                eq(o.testBigInteger, o.testBigInteger) &&
-                eq(o.testBigDecimal, o.testBigDecimal);
-    }
-
-    private boolean eq(Object a, Object b) {
-        if (a == b)
-            return true;
-        if (a == null && b != null)
-            return false;
-        if (a != null && b == null)
-            return false;
-
-        // OK, this is stupid, but we want to special-case blobs
-        // thay are byte arrays, since new byte [] { 1, 2} does not
-        // equals inew byte [] { 1, 2}
-        if (a instanceof byte[] && b instanceof byte[])
-            return Arrays.equals((byte[]) a, (byte[]) b);
-
-        return a.equals(b);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Table(name = "ALL_FLDTYPETEST")
+public class AllFieldTypesTest {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    private int testint;
+    private long testlong;
+    private short testshort;
+    private float testfloat;
+    private double testdouble;
+    private byte testbyte;
+    private boolean testboolean;
+    private char testchar;
+    private String testString;
+    private String testBigString;
+    @Temporal(TemporalType.DATE)
+    private Date testDate;
+    @Temporal(TemporalType.DATE)
+    private Calendar testCalendar;
+    private Object testObject;
+    private BigInteger testBigInteger;
+    private BigDecimal testBigDecimal;
+
+    public AllFieldTypesTest() {
+        testfloat = 1f;
+        testdouble = 1.0;
+    }
+
+    public Date getTestDate() {
+        return this.testDate;
+    }
+
+    public void setTestDate(Date testDate) {
+        this.testDate = testDate;
+    }
+
+    public void setTestCalendar(Calendar testCalendar) {
+        this.testCalendar = testCalendar;
+    }
+
+    public Calendar getTestCalendar() {
+        return this.testCalendar;
+    }
+
+    public Object getTestObject() {
+        return this.testObject;
+    }
+
+    public void setTestObject(Object testObject) {
+        this.testObject = testObject;
+    }
+
+    public char getTestchar() {
+        return this.testchar;
+    }
+
+    public void setTestchar(char testchar) {
+        this.testchar = testchar;
+    }
+
+    public int getTestint() {
+        return this.testint;
+    }
+
+    public void setTestint(int testint) {
+        this.testint = testint;
+    }
+
+    public short getTestshort() {
+        return this.testshort;
+    }
+
+    public void setTestshort(short testshort) {
+        this.testshort = testshort;
+    }
+
+    public long getTestlong() {
+        return this.testlong;
+    }
+
+    public void setTestlong(long testlong) {
+        this.testlong = testlong;
+    }
+
+    public boolean getTestboolean() {
+        return this.testboolean;
+    }
+
+    public void setTestboolean(boolean testboolean) {
+        this.testboolean = testboolean;
+    }
+
+    public float getTestfloat() {
+        return this.testfloat;
+    }
+
+    public void setTestfloat(float testfloat) {
+        this.testfloat = testfloat;
+    }
+
+    public double getTestdouble() {
+        return this.testdouble;
+    }
+
+    public void setTestdouble(double testdouble) {
+        this.testdouble = testdouble;
+    }
+
+    public String getTestString() {
+        return this.testString;
+    }
+
+    public void setTestString(String testString) {
+        this.testString = testString;
+    }
+
+    public void setTestBigString(String testBigString) {
+        this.testBigString = testBigString;
+    }
+
+    public String getTestBigString() {
+        return this.testBigString;
+    }
+
+    public byte getTestbyte() {
+        return this.testbyte;
+    }
+
+    public void setTestbyte(byte testbyte) {
+        this.testbyte = testbyte;
+    }
+
+    public BigInteger getTestBigInteger() {
+        return this.testBigInteger;
+    }
+
+    public void setTestBigInteger(BigInteger testBigInteger) {
+        this.testBigInteger = testBigInteger;
+    }
+
+    public BigDecimal getTestBigDecimal() {
+        return this.testBigDecimal;
+    }
+
+    public void setTestBigDecimal(BigDecimal testBigDecimal) {
+        this.testBigDecimal = testBigDecimal;
+    }
+
+    public void randomize(boolean objects, boolean blobs) {
+        testint = AbstractTestCase.randomInt().intValue();
+        testlong = AbstractTestCase.randomLong().longValue();
+        testshort = AbstractTestCase.randomShort().shortValue();
+        testfloat = AbstractTestCase.randomFloat().floatValue();
+        testdouble = AbstractTestCase.randomDouble().doubleValue();
+        testbyte = AbstractTestCase.randomByte().byteValue();
+        testboolean = AbstractTestCase.randomBoolean().booleanValue();
+        testchar = AbstractTestCase.randomChar().charValue();
+
+        if (objects) {
+            testString = AbstractTestCase.randomString();
+            testDate = AbstractTestCase.randomDate();
+
+            testCalendar = Calendar.getInstance();
+            testCalendar.setTime(AbstractTestCase.randomDate());
+
+            testBigInteger = AbstractTestCase.randomBigInteger();
+            testBigDecimal = AbstractTestCase.randomBigDecimal();
+        }
+
+        if (blobs && objects) {
+            testObject = AbstractTestCase.randomBlob();
+            testBigString = AbstractTestCase.randomClob();
+        }
+    }
+
+    public String toString() {
+        return "\n{"
+            + "testint=" + testint + ";"
+            + "testlong=" + testlong + ";"
+            + "testshort=" + testshort + ";"
+            + "testfloat=" + testfloat + ";"
+            + "testdouble=" + testdouble + ";"
+            + "testbyte=" + testbyte + ";"
+            + "testboolean=" + testboolean + ";"
+            + "testchar=" + testchar + ";"
+            + "testString=" + testString + ";"
+            + "testBigString=" + testBigString + ";"
+            + "testDate=" + testDate + ";"
+            + "testCalendar=" + testCalendar + ";"
+            + "testObject=" + testObject
+            + "(" + ((testObject instanceof byte[]) ?
+            "(byte[])" + ((byte[]) testObject).length + "" :
+            (testObject == null ? "null" :
+                testObject.getClass().getName())) + ")"
+            + ";"
+            + "testBigInteger=" + testBigInteger + ";"
+            + "testBigDecimal=" + testBigDecimal + ";"
+            + "}";
+    }
+
+    public int hashCode() {
+        return (int) ((
+            testint
+                + testlong
+                + testshort
+                + testfloat
+                + testdouble
+                + testbyte
+                + (testboolean ? 1 : 0)
+                + testchar
+                + (testString == null ? 0 : testString.hashCode())
+                + (testBigString == null ? 0 : testBigString.hashCode())
+                + (testDate == null ? 0 : testDate.hashCode())
+                + (testCalendar == null ? 0 : testCalendar.hashCode())
+                + (testObject == null ? 0 : testObject.hashCode())
+                + (testBigInteger == null ? 0 : testBigInteger.hashCode())
+                + (testBigDecimal == null ? 0 : testBigDecimal.hashCode())))
+            % Integer.MAX_VALUE;
+    }
+
+    public boolean equals(Object other) {
+        if (other == null && !(other instanceof AllFieldTypesTest))
+            return false;
+
+        AllFieldTypesTest o = (AllFieldTypesTest) other;
+
+        return
+            o.testint == testint &&
+                o.testlong == testlong &&
+                o.testshort == testshort &&
+                o.testfloat == testfloat &&
+                o.testdouble == testdouble &&
+                o.testbyte == testbyte &&
+                o.testboolean == testboolean &&
+                o.testchar == testchar &&
+                eq(o.testString, testString) &&
+                eq(o.testBigString, testBigString) &&
+                eq(o.testDate, testDate) &&
+                eq(o.testCalendar, testCalendar) &&
+                eq(o.testObject, testObject) &&
+                eq(o.testBigInteger, o.testBigInteger) &&
+                eq(o.testBigDecimal, o.testBigDecimal);
+    }
+
+    private boolean eq(Object a, Object b) {
+        if (a == b)
+            return true;
+        if (a == null && b != null)
+            return false;
+        if (a != null && b == null)
+            return false;
+
+        // OK, this is stupid, but we want to special-case blobs
+        // thay are byte arrays, since new byte [] { 1, 2} does not
+        // equals inew byte [] { 1, 2}
+        if (a instanceof byte[] && b instanceof byte[])
+            return Arrays.equals((byte[]) a, (byte[]) b);
+
+        return a.equals(b);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldsTypeTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldsTypeTest.java
index 9dfa48c..486c6d6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldsTypeTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldsTypeTest.java
@@ -1,269 +1,269 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Table(name = "afieldstt")
-public class AllFieldsTypeTest {
-
-    @Id
-    private int id;
-    private int testint;
-    private long testlong;
-    private short testshort;
-    private float testfloat;
-    private double testdouble;
-    private byte testbyte;
-    private boolean testboolean;
-    private char testchar;
-    private String testString;
-    private String testBigString;
-    private Date testDate;
-    private Calendar testCalendar;
-    private Object testObject;
-    private BigInteger testBigInteger;
-    private BigDecimal testBigDecimal;
-
-    public Date getTestDate() {
-        return this.testDate;
-    }
-
-    public void setTestDate(Date testDate) {
-        this.testDate = testDate;
-    }
-
-    public void setTestCalendar(Calendar testCalendar) {
-        this.testCalendar = testCalendar;
-    }
-
-    public Calendar getTestCalendar() {
-        return this.testCalendar;
-    }
-
-    public Object getTestObject() {
-        return this.testObject;
-    }
-
-    public void setTestObject(Object testObject) {
-        this.testObject = testObject;
-    }
-
-    public char getTestchar() {
-        return this.testchar;
-    }
-
-    public void setTestchar(char testchar) {
-        this.testchar = testchar;
-    }
-
-    public int getTestint() {
-        return this.testint;
-    }
-
-    public void setTestint(int testint) {
-        this.testint = testint;
-    }
-
-    public short getTestshort() {
-        return this.testshort;
-    }
-
-    public void setTestshort(short testshort) {
-        this.testshort = testshort;
-    }
-
-    public long getTestlong() {
-        return this.testlong;
-    }
-
-    public void setTestlong(long testlong) {
-        this.testlong = testlong;
-    }
-
-    public boolean getTestboolean() {
-        return this.testboolean;
-    }
-
-    public void setTestboolean(boolean testboolean) {
-        this.testboolean = testboolean;
-    }
-
-    public float getTestfloat() {
-        return this.testfloat;
-    }
-
-    public void setTestfloat(float testfloat) {
-        this.testfloat = testfloat;
-    }
-
-    public double getTestdouble() {
-        return this.testdouble;
-    }
-
-    public void setTestdouble(double testdouble) {
-        this.testdouble = testdouble;
-    }
-
-    public String getTestString() {
-        return this.testString;
-    }
-
-    public void setTestString(String testString) {
-        this.testString = testString;
-    }
-
-    public void setTestBigString(String testBigString) {
-        this.testBigString = testBigString;
-    }
-
-    public String getTestBigString() {
-        return this.testBigString;
-    }
-
-    public byte getTestbyte() {
-        return this.testbyte;
-    }
-
-    public void setTestbyte(byte testbyte) {
-        this.testbyte = testbyte;
-    }
-
-    public BigInteger getTestBigInteger() {
-        return this.testBigInteger;
-    }
-
-    public void setTestBigInteger(BigInteger testBigInteger) {
-        this.testBigInteger = testBigInteger;
-    }
-
-    public BigDecimal getTestBigDecimal() {
-        return this.testBigDecimal;
-    }
-
-    public void setTestBigDecimal(BigDecimal testBigDecimal) {
-        this.testBigDecimal = testBigDecimal;
-    }
-
-    public String toString() {
-        return "\n{"
-            + "testint=" + testint + ";"
-            + "testlong=" + testlong + ";"
-            + "testshort=" + testshort + ";"
-            + "testfloat=" + testfloat + ";"
-            + "testdouble=" + testdouble + ";"
-            + "testbyte=" + testbyte + ";"
-            + "testboolean=" + testboolean + ";"
-            + "testchar=" + testchar + ";"
-            + "testString=" + testString + ";"
-            + "testBigString=" + testBigString + ";"
-            + "testDate=" + testDate + ";"
-            + "testCalendar=" + testCalendar + ";"
-            + "testObject=" + testObject
-            + "(" + ((testObject instanceof byte[]) ?
-            "(byte[])" + ((byte[]) testObject).length + "" :
-            (testObject == null ? "null" :
-                testObject.getClass().getName())) + ")"
-            + ";"
-            + "testBigInteger=" + testBigInteger + ";"
-            + "testBigDecimal=" + testBigDecimal + ";"
-            + "}";
-    }
-
-    public int hashCode() {
-        return (int) ((
-            testint
-                + testlong
-                + testshort
-                + testfloat
-                + testdouble
-                + testbyte
-                + (testboolean ? 1 : 0)
-                + testchar
-                + (testString == null ? 0 : testString.hashCode())
-                + (testBigString == null ? 0 : testBigString.hashCode())
-                + (testDate == null ? 0 : testDate.hashCode())
-                + (testCalendar == null ? 0 : testCalendar.hashCode())
-                + (testObject == null ? 0 : testObject.hashCode())
-                + (testBigInteger == null ? 0 : testBigInteger.hashCode())
-                + (testBigDecimal == null ? 0 : testBigDecimal.hashCode())))
-            % Integer.MAX_VALUE;
-    }
-
-    public boolean equals(Object other) {
-        if (other == null && !(other instanceof AllFieldsTypeTest))
-            return false;
-
-        AllFieldsTypeTest o = (AllFieldsTypeTest) other;
-
-        return
-            o.testint == testint &&
-                o.testlong == testlong &&
-                o.testshort == testshort &&
-                o.testfloat == testfloat &&
-                o.testdouble == testdouble &&
-                o.testbyte == testbyte &&
-                o.testboolean == testboolean &&
-                o.testchar == testchar &&
-                eq(o.testString, testString) &&
-                eq(o.testBigString, testBigString) &&
-                eq(o.testDate, testDate) &&
-                eq(o.testCalendar, testCalendar) &&
-                eq(o.testObject, testObject) &&
-                eq(o.testBigInteger, o.testBigInteger) &&
-                eq(o.testBigDecimal, o.testBigDecimal);
-    }
-
-    private boolean eq(Object a, Object b) {
-        if (a == b)
-            return true;
-        if (a == null && b != null)
-            return false;
-        if (a != null && b == null)
-            return false;
-
-        // OK, this is stupid, but we want to special-case blobs
-        // thay are byte arrays, since new byte [] { 1, 2} does not
-        // equals inew byte [] { 1, 2}
-        if (a instanceof byte[] && b instanceof byte[])
-            return Arrays.equals((byte[]) a, (byte[]) b);
-
-        return a.equals(b);
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Table(name = "afieldstt")
+public class AllFieldsTypeTest {
+
+    @Id
+    private int id;
+    private int testint;
+    private long testlong;
+    private short testshort;
+    private float testfloat;
+    private double testdouble;
+    private byte testbyte;
+    private boolean testboolean;
+    private char testchar;
+    private String testString;
+    private String testBigString;
+    private Date testDate;
+    private Calendar testCalendar;
+    private Object testObject;
+    private BigInteger testBigInteger;
+    private BigDecimal testBigDecimal;
+
+    public Date getTestDate() {
+        return this.testDate;
+    }
+
+    public void setTestDate(Date testDate) {
+        this.testDate = testDate;
+    }
+
+    public void setTestCalendar(Calendar testCalendar) {
+        this.testCalendar = testCalendar;
+    }
+
+    public Calendar getTestCalendar() {
+        return this.testCalendar;
+    }
+
+    public Object getTestObject() {
+        return this.testObject;
+    }
+
+    public void setTestObject(Object testObject) {
+        this.testObject = testObject;
+    }
+
+    public char getTestchar() {
+        return this.testchar;
+    }
+
+    public void setTestchar(char testchar) {
+        this.testchar = testchar;
+    }
+
+    public int getTestint() {
+        return this.testint;
+    }
+
+    public void setTestint(int testint) {
+        this.testint = testint;
+    }
+
+    public short getTestshort() {
+        return this.testshort;
+    }
+
+    public void setTestshort(short testshort) {
+        this.testshort = testshort;
+    }
+
+    public long getTestlong() {
+        return this.testlong;
+    }
+
+    public void setTestlong(long testlong) {
+        this.testlong = testlong;
+    }
+
+    public boolean getTestboolean() {
+        return this.testboolean;
+    }
+
+    public void setTestboolean(boolean testboolean) {
+        this.testboolean = testboolean;
+    }
+
+    public float getTestfloat() {
+        return this.testfloat;
+    }
+
+    public void setTestfloat(float testfloat) {
+        this.testfloat = testfloat;
+    }
+
+    public double getTestdouble() {
+        return this.testdouble;
+    }
+
+    public void setTestdouble(double testdouble) {
+        this.testdouble = testdouble;
+    }
+
+    public String getTestString() {
+        return this.testString;
+    }
+
+    public void setTestString(String testString) {
+        this.testString = testString;
+    }
+
+    public void setTestBigString(String testBigString) {
+        this.testBigString = testBigString;
+    }
+
+    public String getTestBigString() {
+        return this.testBigString;
+    }
+
+    public byte getTestbyte() {
+        return this.testbyte;
+    }
+
+    public void setTestbyte(byte testbyte) {
+        this.testbyte = testbyte;
+    }
+
+    public BigInteger getTestBigInteger() {
+        return this.testBigInteger;
+    }
+
+    public void setTestBigInteger(BigInteger testBigInteger) {
+        this.testBigInteger = testBigInteger;
+    }
+
+    public BigDecimal getTestBigDecimal() {
+        return this.testBigDecimal;
+    }
+
+    public void setTestBigDecimal(BigDecimal testBigDecimal) {
+        this.testBigDecimal = testBigDecimal;
+    }
+
+    public String toString() {
+        return "\n{"
+            + "testint=" + testint + ";"
+            + "testlong=" + testlong + ";"
+            + "testshort=" + testshort + ";"
+            + "testfloat=" + testfloat + ";"
+            + "testdouble=" + testdouble + ";"
+            + "testbyte=" + testbyte + ";"
+            + "testboolean=" + testboolean + ";"
+            + "testchar=" + testchar + ";"
+            + "testString=" + testString + ";"
+            + "testBigString=" + testBigString + ";"
+            + "testDate=" + testDate + ";"
+            + "testCalendar=" + testCalendar + ";"
+            + "testObject=" + testObject
+            + "(" + ((testObject instanceof byte[]) ?
+            "(byte[])" + ((byte[]) testObject).length + "" :
+            (testObject == null ? "null" :
+                testObject.getClass().getName())) + ")"
+            + ";"
+            + "testBigInteger=" + testBigInteger + ";"
+            + "testBigDecimal=" + testBigDecimal + ";"
+            + "}";
+    }
+
+    public int hashCode() {
+        return (int) ((
+            testint
+                + testlong
+                + testshort
+                + testfloat
+                + testdouble
+                + testbyte
+                + (testboolean ? 1 : 0)
+                + testchar
+                + (testString == null ? 0 : testString.hashCode())
+                + (testBigString == null ? 0 : testBigString.hashCode())
+                + (testDate == null ? 0 : testDate.hashCode())
+                + (testCalendar == null ? 0 : testCalendar.hashCode())
+                + (testObject == null ? 0 : testObject.hashCode())
+                + (testBigInteger == null ? 0 : testBigInteger.hashCode())
+                + (testBigDecimal == null ? 0 : testBigDecimal.hashCode())))
+            % Integer.MAX_VALUE;
+    }
+
+    public boolean equals(Object other) {
+        if (other == null && !(other instanceof AllFieldsTypeTest))
+            return false;
+
+        AllFieldsTypeTest o = (AllFieldsTypeTest) other;
+
+        return
+            o.testint == testint &&
+                o.testlong == testlong &&
+                o.testshort == testshort &&
+                o.testfloat == testfloat &&
+                o.testdouble == testdouble &&
+                o.testbyte == testbyte &&
+                o.testboolean == testboolean &&
+                o.testchar == testchar &&
+                eq(o.testString, testString) &&
+                eq(o.testBigString, testBigString) &&
+                eq(o.testDate, testDate) &&
+                eq(o.testCalendar, testCalendar) &&
+                eq(o.testObject, testObject) &&
+                eq(o.testBigInteger, o.testBigInteger) &&
+                eq(o.testBigDecimal, o.testBigDecimal);
+    }
+
+    private boolean eq(Object a, Object b) {
+        if (a == b)
+            return true;
+        if (a == null && b != null)
+            return false;
+        if (a != null && b == null)
+            return false;
+
+        // OK, this is stupid, but we want to special-case blobs
+        // thay are byte arrays, since new byte [] { 1, 2} does not
+        // equals inew byte [] { 1, 2}
+        if (a instanceof byte[] && b instanceof byte[])
+            return Arrays.equals((byte[]) a, (byte[]) b);
+
+        return a.equals(b);
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdClassString.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdClassString.java
index 8fa4b71..adceb19 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdClassString.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdClassString.java
@@ -1,72 +1,72 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Table;
-
-//import java.lang.annotation.Annotation;
-
-@Entity
-@Table(name = "APP_IDCS")
-@IdClass(AppIdClassString.Idkey.class)
-public class AppIdClassString {
-
-    @Id
-    private int pk;
-
-    public AppIdClassString(int pk) {
-        this.pk = pk;
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public static class Idkey implements java.io.Serializable {
-
-        public int pk;
-
-        public Idkey() {
-        }
-
-        public Idkey(String pk) {
-            if (pk != null)
-                this.pk = Integer.parseInt(pk);
-        }
-
-        @Override
-        public int hashCode() {
-            return pk;
-        }
-
-        public String toString() {
-            return pk + "";
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof Id))
-                return false;
-            return pk == ((Idkey) o).pk;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+
+//import java.lang.annotation.Annotation;
+
+@Entity
+@Table(name = "APP_IDCS")
+@IdClass(AppIdClassString.Idkey.class)
+public class AppIdClassString {
+
+    @Id
+    private int pk;
+
+    public AppIdClassString(int pk) {
+        this.pk = pk;
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public static class Idkey implements java.io.Serializable {
+
+        public int pk;
+
+        public Idkey() {
+        }
+
+        public Idkey(String pk) {
+            if (pk != null)
+                this.pk = Integer.parseInt(pk);
+        }
+
+        @Override
+        public int hashCode() {
+            return pk;
+        }
+
+        public String toString() {
+            return pk + "";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof Id))
+                return false;
+            return pk == ((Idkey) o).pk;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdHolder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdHolder.java
index cba4b84..98e51cb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdHolder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdHolder.java
@@ -1,179 +1,179 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import javax.persistence.Entity;
-
-/**
- * Holder for one-one and one-many relations to app id hierarchy classes.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class AppIdHolder {
-
-    private int id = Math.abs((int) (Math.random() * (Integer.MAX_VALUE)));
-
-    private String someField;
-
-    // one-to-one relations
-    private AppIdSuper appIdSuper;
-    private AppIdSubA appIdSubA;
-    private AppIdSubB appIdSubB;
-    private AppIdSubC appIdSubC;
-    private AppIdSubD appIdSubD;
-    private AppIdSubE appIdSubE;
-    private AppIdSubF appIdSubF;
-
-    // one-to-many relations
-    private Set appIdSupers;
-    private Collection appIdSubAs;
-    private List appIdSubBs;
-    private Set appIdSubCs;
-    private LinkedList appIdSubDs;
-    private HashSet appIdSubEs;
-    private ArrayList appIdSubFs;
-
-    public void setSomeField(String someField) {
-        this.someField = someField;
-    }
-
-    public String getSomeField() {
-        return this.someField;
-    }
-
-    public void setAppIdSuper(AppIdSuper appIdSuper) {
-        this.appIdSuper = appIdSuper;
-    }
-
-    public AppIdSuper getAppIdSuper() {
-        return this.appIdSuper;
-    }
-
-    public void setAppIdSubA(AppIdSubA appIdSubA) {
-        this.appIdSubA = appIdSubA;
-    }
-
-    public AppIdSubA getAppIdSubA() {
-        return this.appIdSubA;
-    }
-
-    public void setAppIdSubB(AppIdSubB appIdSubB) {
-        this.appIdSubB = appIdSubB;
-    }
-
-    public AppIdSubB getAppIdSubB() {
-        return this.appIdSubB;
-    }
-
-    public void setAppIdSubC(AppIdSubC appIdSubC) {
-        this.appIdSubC = appIdSubC;
-    }
-
-    public AppIdSubC getAppIdSubC() {
-        return this.appIdSubC;
-    }
-
-    public void setAppIdSubD(AppIdSubD appIdSubD) {
-        this.appIdSubD = appIdSubD;
-    }
-
-    public AppIdSubD getAppIdSubD() {
-        return this.appIdSubD;
-    }
-
-    public void setAppIdSubE(AppIdSubE appIdSubE) {
-        this.appIdSubE = appIdSubE;
-    }
-
-    public AppIdSubE getAppIdSubE() {
-        return this.appIdSubE;
-    }
-
-    public void setAppIdSubF(AppIdSubF appIdSubF) {
-        this.appIdSubF = appIdSubF;
-    }
-
-    public AppIdSubF getAppIdSubF() {
-        return this.appIdSubF;
-    }
-
-    public void setAppIdSubAs(Collection appIdSubAs) {
-        this.appIdSubAs = appIdSubAs;
-    }
-
-    public Collection getAppIdSubAs() {
-        return this.appIdSubAs;
-    }
-
-    public void setAppIdSubBs(List appIdSubBs) {
-        this.appIdSubBs = appIdSubBs;
-    }
-
-    public List getAppIdSubBs() {
-        return this.appIdSubBs;
-    }
-
-    public void setAppIdSubCs(Set appIdSubCs) {
-        this.appIdSubCs = appIdSubCs;
-    }
-
-    public Set getAppIdSubCs() {
-        return this.appIdSubCs;
-    }
-
-    public void setAppIdSubDs(LinkedList appIdSubDs) {
-        this.appIdSubDs = appIdSubDs;
-    }
-
-    public LinkedList getAppIdSubDs() {
-        return this.appIdSubDs;
-    }
-
-    public void setAppIdSubEs(HashSet appIdSubEs) {
-        this.appIdSubEs = appIdSubEs;
-    }
-
-    public HashSet getAppIdSubEs() {
-        return this.appIdSubEs;
-    }
-
-    public void setAppIdSubFs(ArrayList appIdSubFs) {
-        this.appIdSubFs = appIdSubFs;
-    }
-
-    public ArrayList getAppIdSubFs() {
-        return this.appIdSubFs;
-    }
-
-    public void setAppIdSupers(Set appIdSupers) {
-        this.appIdSupers = appIdSupers;
-    }
-
-    public Set getAppIdSupers() {
-        return this.appIdSupers;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.Entity;
+
+/**
+ * Holder for one-one and one-many relations to app id hierarchy classes.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class AppIdHolder {
+
+    private int id = Math.abs((int) (Math.random() * (Integer.MAX_VALUE)));
+
+    private String someField;
+
+    // one-to-one relations
+    private AppIdSuper appIdSuper;
+    private AppIdSubA appIdSubA;
+    private AppIdSubB appIdSubB;
+    private AppIdSubC appIdSubC;
+    private AppIdSubD appIdSubD;
+    private AppIdSubE appIdSubE;
+    private AppIdSubF appIdSubF;
+
+    // one-to-many relations
+    private Set appIdSupers;
+    private Collection appIdSubAs;
+    private List appIdSubBs;
+    private Set appIdSubCs;
+    private LinkedList appIdSubDs;
+    private HashSet appIdSubEs;
+    private ArrayList appIdSubFs;
+
+    public void setSomeField(String someField) {
+        this.someField = someField;
+    }
+
+    public String getSomeField() {
+        return this.someField;
+    }
+
+    public void setAppIdSuper(AppIdSuper appIdSuper) {
+        this.appIdSuper = appIdSuper;
+    }
+
+    public AppIdSuper getAppIdSuper() {
+        return this.appIdSuper;
+    }
+
+    public void setAppIdSubA(AppIdSubA appIdSubA) {
+        this.appIdSubA = appIdSubA;
+    }
+
+    public AppIdSubA getAppIdSubA() {
+        return this.appIdSubA;
+    }
+
+    public void setAppIdSubB(AppIdSubB appIdSubB) {
+        this.appIdSubB = appIdSubB;
+    }
+
+    public AppIdSubB getAppIdSubB() {
+        return this.appIdSubB;
+    }
+
+    public void setAppIdSubC(AppIdSubC appIdSubC) {
+        this.appIdSubC = appIdSubC;
+    }
+
+    public AppIdSubC getAppIdSubC() {
+        return this.appIdSubC;
+    }
+
+    public void setAppIdSubD(AppIdSubD appIdSubD) {
+        this.appIdSubD = appIdSubD;
+    }
+
+    public AppIdSubD getAppIdSubD() {
+        return this.appIdSubD;
+    }
+
+    public void setAppIdSubE(AppIdSubE appIdSubE) {
+        this.appIdSubE = appIdSubE;
+    }
+
+    public AppIdSubE getAppIdSubE() {
+        return this.appIdSubE;
+    }
+
+    public void setAppIdSubF(AppIdSubF appIdSubF) {
+        this.appIdSubF = appIdSubF;
+    }
+
+    public AppIdSubF getAppIdSubF() {
+        return this.appIdSubF;
+    }
+
+    public void setAppIdSubAs(Collection appIdSubAs) {
+        this.appIdSubAs = appIdSubAs;
+    }
+
+    public Collection getAppIdSubAs() {
+        return this.appIdSubAs;
+    }
+
+    public void setAppIdSubBs(List appIdSubBs) {
+        this.appIdSubBs = appIdSubBs;
+    }
+
+    public List getAppIdSubBs() {
+        return this.appIdSubBs;
+    }
+
+    public void setAppIdSubCs(Set appIdSubCs) {
+        this.appIdSubCs = appIdSubCs;
+    }
+
+    public Set getAppIdSubCs() {
+        return this.appIdSubCs;
+    }
+
+    public void setAppIdSubDs(LinkedList appIdSubDs) {
+        this.appIdSubDs = appIdSubDs;
+    }
+
+    public LinkedList getAppIdSubDs() {
+        return this.appIdSubDs;
+    }
+
+    public void setAppIdSubEs(HashSet appIdSubEs) {
+        this.appIdSubEs = appIdSubEs;
+    }
+
+    public HashSet getAppIdSubEs() {
+        return this.appIdSubEs;
+    }
+
+    public void setAppIdSubFs(ArrayList appIdSubFs) {
+        this.appIdSubFs = appIdSubFs;
+    }
+
+    public ArrayList getAppIdSubFs() {
+        return this.appIdSubFs;
+    }
+
+    public void setAppIdSupers(Set appIdSupers) {
+        this.appIdSupers = appIdSupers;
+    }
+
+    public Set getAppIdSupers() {
+        return this.appIdSupers;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubA.java
index 3ea7095..1f2cf0c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubA.java
@@ -1,84 +1,84 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.StringTokenizer;
-
-/**
- * Abstract subclass that defines one more primary key field than its
- * abstract superclass.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public abstract class AppIdSubA
-    extends AppIdSuper {
-
-    private int pka;
-    private String stringFieldA;
-
-    public void setPka(int pka) {
-        this.pka = pka;
-    }
-
-    public int getPka() {
-        return this.pka;
-    }
-
-    public void setStringFieldA(String stringFieldA) {
-        this.stringFieldA = stringFieldA;
-    }
-
-    public String getStringFieldA() {
-        return this.stringFieldA;
-    }
-
-    public static abstract class ID
-        extends AppIdSuper.ID {
-
-        public int pka;
-
-        public ID() {
-            super();
-        }
-
-        public ID(String str) {
-            super();
-            fromString(str);
-        }
-
-        public int hashCode() {
-            return (super.hashCode() + pka) % Integer.MAX_VALUE;
-        }
-
-        public boolean equals(Object other) {
-            return super.equals(other)
-                && ((ID) other).pka == pka;
-        }
-
-        public String toString() {
-            return super.toString() + DELIMITER + pka;
-        }
-
-        StringTokenizer fromString(String idString) {
-            StringTokenizer tok = super.fromString(idString);
-            pka = new Integer(tok.nextToken()).intValue();
-            return tok; // return the tokenizer for subclasses to use
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.StringTokenizer;
+
+/**
+ * Abstract subclass that defines one more primary key field than its
+ * abstract superclass.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public abstract class AppIdSubA
+    extends AppIdSuper {
+
+    private int pka;
+    private String stringFieldA;
+
+    public void setPka(int pka) {
+        this.pka = pka;
+    }
+
+    public int getPka() {
+        return this.pka;
+    }
+
+    public void setStringFieldA(String stringFieldA) {
+        this.stringFieldA = stringFieldA;
+    }
+
+    public String getStringFieldA() {
+        return this.stringFieldA;
+    }
+
+    public static abstract class ID
+        extends AppIdSuper.ID {
+
+        public int pka;
+
+        public ID() {
+            super();
+        }
+
+        public ID(String str) {
+            super();
+            fromString(str);
+        }
+
+        public int hashCode() {
+            return (super.hashCode() + pka) % Integer.MAX_VALUE;
+        }
+
+        public boolean equals(Object other) {
+            return super.equals(other)
+                && ((ID) other).pka == pka;
+        }
+
+        public String toString() {
+            return super.toString() + DELIMITER + pka;
+        }
+
+        StringTokenizer fromString(String idString) {
+            StringTokenizer tok = super.fromString(idString);
+            pka = new Integer(tok.nextToken()).intValue();
+            return tok; // return the tokenizer for subclasses to use
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubB.java
index 06e1caa..3b027a1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubB.java
@@ -1,88 +1,88 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.StringTokenizer;
-import javax.persistence.Entity;
-
-/**
- * Abstract subclass that defines one more primary key field than its
- * abstract superclass.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public abstract class AppIdSubB
-    extends AppIdSubA {
-
-    private String pkb;
-    private String stringFieldB;
-
-    public void setStringFieldB(String stringFieldB) {
-        this.stringFieldB = stringFieldB;
-    }
-
-    public String getStringFieldB() {
-        return this.stringFieldB;
-    }
-
-    public void setPkb(String pkb) {
-        this.pkb = pkb;
-    }
-
-    public String getPkb() {
-        return this.pkb;
-    }
-
-    public static abstract class ID
-        extends AppIdSubA.ID {
-
-        public String pkb;
-
-        public ID() {
-            super();
-        }
-
-        public ID(String str) {
-            super();
-            fromString(str);
-        }
-
-        public int hashCode() {
-            return (super.hashCode() + (pkb == null ? 0 : pkb.hashCode()))
-                % Integer.MAX_VALUE;
-        }
-
-        public boolean equals(Object other) {
-            return super.equals(other)
-                && ((ID) other).pkb == null ? pkb == null
-                : ((ID) other).pkb.equals(pkb);
-        }
-
-        public String toString() {
-            return super.toString() + DELIMITER + pkb;
-        }
-
-        StringTokenizer fromString(String idString) {
-            StringTokenizer tok = super.fromString(idString);
-            pkb = tok.nextToken();
-            return tok; // return the tokenizer for subclasses to use
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.StringTokenizer;
+import javax.persistence.Entity;
+
+/**
+ * Abstract subclass that defines one more primary key field than its
+ * abstract superclass.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public abstract class AppIdSubB
+    extends AppIdSubA {
+
+    private String pkb;
+    private String stringFieldB;
+
+    public void setStringFieldB(String stringFieldB) {
+        this.stringFieldB = stringFieldB;
+    }
+
+    public String getStringFieldB() {
+        return this.stringFieldB;
+    }
+
+    public void setPkb(String pkb) {
+        this.pkb = pkb;
+    }
+
+    public String getPkb() {
+        return this.pkb;
+    }
+
+    public static abstract class ID
+        extends AppIdSubA.ID {
+
+        public String pkb;
+
+        public ID() {
+            super();
+        }
+
+        public ID(String str) {
+            super();
+            fromString(str);
+        }
+
+        public int hashCode() {
+            return (super.hashCode() + (pkb == null ? 0 : pkb.hashCode()))
+                % Integer.MAX_VALUE;
+        }
+
+        public boolean equals(Object other) {
+            return super.equals(other)
+                && ((ID) other).pkb == null ? pkb == null
+                : ((ID) other).pkb.equals(pkb);
+        }
+
+        public String toString() {
+            return super.toString() + DELIMITER + pkb;
+        }
+
+        StringTokenizer fromString(String idString) {
+            StringTokenizer tok = super.fromString(idString);
+            pkb = tok.nextToken();
+            return tok; // return the tokenizer for subclasses to use
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubC.java
index 306fb24..c297bc7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubC.java
@@ -1,113 +1,113 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Concrete subclass that defines two more primary key fields than its
- * abstract superclass.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class AppIdSubC
-    extends AppIdSubB {
-
-    private long pk1c;
-    private String pk2c;
-    private String stringFieldC;
-
-    public void setPk1c(long pk1c) {
-        this.pk1c = pk1c;
-    }
-
-    public long getPk1c() {
-        return this.pk1c;
-    }
-
-    public void setPk2c(String pk2c) {
-        this.pk2c = pk2c;
-    }
-
-    public String getPk2c() {
-        return this.pk2c;
-    }
-
-    public void setStringFieldC(String stringFieldC) {
-        this.stringFieldC = stringFieldC;
-    }
-
-    public String getStringFieldC() {
-        return this.stringFieldC;
-    }
-
-    /*
-     public static class ID
-         extends AppIdSubB.ID
-     {
-         private long pk1c;
-         private String pk2c;
-
-
-         public ID ()
-         {
-             super ();
-         }
-
-
-         public ID (String str)
-         {
-             super ();
-             fromString (str);
-         }
-
-
-         public int hashCode ()
-         {
-             return (int)((super.hashCode () + pk1c
-                 + (pk2c == null ? 0 : pk2c.hashCode ())) % Integer.MAX_VALUE);
-         }
-
-
-         public boolean equals (Object other)
-         {
-             return super.equals (other)
-                 && ((ID)other).pk1c == pk1c
-                 && ((ID)other).pk2c == null ? pk2c == null
-                     : ((ID)other).pk2c.equals (pk2c);
-         }
-
-
-         public String toString ()
-         {
-             return super.toString () + DELIMITER + pk1c + DELIMITER + pk2c;
-         }
-
-
-         StringTokenizer fromString (String idString)
-         {
-             StringTokenizer tok = super.fromString (idString);
-             pk1c = new Long (tok.nextToken ()).longValue ();
-             pk2c = tok.nextToken ();
-             return tok; // return the tokenizer for subclasses to use
-         }
-     }
-     */
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Concrete subclass that defines two more primary key fields than its
+ * abstract superclass.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class AppIdSubC
+    extends AppIdSubB {
+
+    private long pk1c;
+    private String pk2c;
+    private String stringFieldC;
+
+    public void setPk1c(long pk1c) {
+        this.pk1c = pk1c;
+    }
+
+    public long getPk1c() {
+        return this.pk1c;
+    }
+
+    public void setPk2c(String pk2c) {
+        this.pk2c = pk2c;
+    }
+
+    public String getPk2c() {
+        return this.pk2c;
+    }
+
+    public void setStringFieldC(String stringFieldC) {
+        this.stringFieldC = stringFieldC;
+    }
+
+    public String getStringFieldC() {
+        return this.stringFieldC;
+    }
+
+    /*
+     public static class ID
+         extends AppIdSubB.ID
+     {
+         private long pk1c;
+         private String pk2c;
+
+
+         public ID ()
+         {
+             super ();
+         }
+
+
+         public ID (String str)
+         {
+             super ();
+             fromString (str);
+         }
+
+
+         public int hashCode ()
+         {
+             return (int)((super.hashCode () + pk1c
+                 + (pk2c == null ? 0 : pk2c.hashCode ())) % Integer.MAX_VALUE);
+         }
+
+
+         public boolean equals (Object other)
+         {
+             return super.equals (other)
+                 && ((ID)other).pk1c == pk1c
+                 && ((ID)other).pk2c == null ? pk2c == null
+                     : ((ID)other).pk2c.equals (pk2c);
+         }
+
+
+         public String toString ()
+         {
+             return super.toString () + DELIMITER + pk1c + DELIMITER + pk2c;
+         }
+
+
+         StringTokenizer fromString (String idString)
+         {
+             StringTokenizer tok = super.fromString (idString);
+             pk1c = new Long (tok.nextToken ()).longValue ();
+             pk2c = tok.nextToken ();
+             return tok; // return the tokenizer for subclasses to use
+         }
+     }
+     */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubD.java
index 03985a0..1b53fc8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubD.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Concrete subclass that defines one more primary key field than its
- * abstract superclass.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class AppIdSubD
-    extends AppIdSubB {
-
-    private double pkd;
-    private String stringFieldD;
-
-    public void setPkd(double pkd) {
-        this.pkd = pkd;
-    }
-
-    public double getPkd() {
-        return this.pkd;
-    }
-
-    public void setStringFieldD(String stringFieldD) {
-        this.stringFieldD = stringFieldD;
-    }
-
-    public String getStringFieldD() {
-        return this.stringFieldD;
-    }
-
-    /*
-     public static class ID
-         extends AppIdSubB.ID
-     {
-         private double pkd;
-
-
-         public ID ()
-         {
-             super ();
-         }
-
-
-         public ID (String str)
-         {
-             super ();
-             fromString (str);
-         }
-
-
-         public int hashCode ()
-         {
-             return (int)((super.hashCode () + pkd) % Integer.MAX_VALUE);
-         }
-
-
-         public boolean equals (Object other)
-         {
-             return super.equals (other)
-                 && ((ID)other).pkd == pkd;
-         }
-
-
-         public String toString ()
-         {
-             return super.toString () + DELIMITER + pkd;
-         }
-
-
-         StringTokenizer fromString (String idString)
-         {
-             StringTokenizer tok = super.fromString (idString);
-             pkd = new Double (tok.nextToken ()).doubleValue ();
-             return tok; // return the tokenizer for subclasses to use
-         }
-     }
-     */
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Concrete subclass that defines one more primary key field than its
+ * abstract superclass.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class AppIdSubD
+    extends AppIdSubB {
+
+    private double pkd;
+    private String stringFieldD;
+
+    public void setPkd(double pkd) {
+        this.pkd = pkd;
+    }
+
+    public double getPkd() {
+        return this.pkd;
+    }
+
+    public void setStringFieldD(String stringFieldD) {
+        this.stringFieldD = stringFieldD;
+    }
+
+    public String getStringFieldD() {
+        return this.stringFieldD;
+    }
+
+    /*
+     public static class ID
+         extends AppIdSubB.ID
+     {
+         private double pkd;
+
+
+         public ID ()
+         {
+             super ();
+         }
+
+
+         public ID (String str)
+         {
+             super ();
+             fromString (str);
+         }
+
+
+         public int hashCode ()
+         {
+             return (int)((super.hashCode () + pkd) % Integer.MAX_VALUE);
+         }
+
+
+         public boolean equals (Object other)
+         {
+             return super.equals (other)
+                 && ((ID)other).pkd == pkd;
+         }
+
+
+         public String toString ()
+         {
+             return super.toString () + DELIMITER + pkd;
+         }
+
+
+         StringTokenizer fromString (String idString)
+         {
+             StringTokenizer tok = super.fromString (idString);
+             pkd = new Double (tok.nextToken ()).doubleValue ();
+             return tok; // return the tokenizer for subclasses to use
+         }
+     }
+     */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubE.java
index 5288811..e7b77f4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubE.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Concrete subclass that does not define any more primary key fields
- * than its concrete superclass.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class AppIdSubE
-    extends AppIdSubD {
-
-    private String stringFieldE;
-
-    public void setStringFieldE(String stringFieldE) {
-        this.stringFieldE = stringFieldE;
-    }
-
-    public String getStringFieldE() {
-        return this.stringFieldE;
-    }
-
-    /*
-     public static class ID
-         extends AppIdSubD.ID
-     {
-         public ID ()
-         {
-             super ();
-         }
-
-
-         public ID (String str)
-         {
-             super ();
-             fromString (str);
-         }
-     }
-     */
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Concrete subclass that does not define any more primary key fields
+ * than its concrete superclass.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class AppIdSubE
+    extends AppIdSubD {
+
+    private String stringFieldE;
+
+    public void setStringFieldE(String stringFieldE) {
+        this.stringFieldE = stringFieldE;
+    }
+
+    public String getStringFieldE() {
+        return this.stringFieldE;
+    }
+
+    /*
+     public static class ID
+         extends AppIdSubD.ID
+     {
+         public ID ()
+         {
+             super ();
+         }
+
+
+         public ID (String str)
+         {
+             super ();
+             fromString (str);
+         }
+     }
+     */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubF.java
index ae72e74..4200a7e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSubF.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * Concrete subclass that does not define any more primary key fields
- * than its abstract superclass.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-@Entity
-public class AppIdSubF
-    extends AppIdSubB {
-
-    private String stringFieldF;
-
-    public void setStringFieldF(String stringFieldF) {
-        this.stringFieldF = stringFieldF;
-    }
-
-    public String getStringFieldF() {
-        return this.stringFieldF;
-    }
-
-    /*
-     public static class ID
-         extends AppIdSubB.ID
-     {
-         public ID ()
-         {
-             super ();
-         }
-
-
-         public ID (String str)
-         {
-             super ();
-             fromString (str);
-         }
-     }
-     */
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * Concrete subclass that does not define any more primary key fields
+ * than its abstract superclass.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+@Entity
+public class AppIdSubF
+    extends AppIdSubB {
+
+    private String stringFieldF;
+
+    public void setStringFieldF(String stringFieldF) {
+        this.stringFieldF = stringFieldF;
+    }
+
+    public String getStringFieldF() {
+        return this.stringFieldF;
+    }
+
+    /*
+     public static class ID
+         extends AppIdSubB.ID
+     {
+         public ID ()
+         {
+             super ();
+         }
+
+
+         public ID (String str)
+         {
+             super ();
+             fromString (str);
+         }
+     }
+     */
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSuper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSuper.java
index 785c5b2..322d1b3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSuper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AppIdSuper.java
@@ -1,71 +1,71 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.util.StringTokenizer;
-
-/**
- * Abstract superclass with no primary key fields defined.
- *
- * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
- */
-public abstract class AppIdSuper {
-
-    private String superField;
-
-    public void setSuperField(String superField) {
-        this.superField = superField;
-    }
-
-    public String getSuperField() {
-        return this.superField;
-    }
-
-    public static abstract class ID
-        implements Serializable {
-
-        static String DELIMITER = ":";
-
-        public ID() {
-        }
-
-        public ID(String str) {
-            fromString(str);
-        }
-
-        public int hashCode() {
-            // no key codes; all classes are equal
-            return 1;
-        }
-
-        public boolean equals(Object other) {
-            return other != null && other.getClass() == getClass();
-        }
-
-        public String toString() {
-            return "";
-        }
-
-        StringTokenizer fromString(String idString) {
-            return new StringTokenizer(idString, DELIMITER);
-        }
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.util.StringTokenizer;
+
+/**
+ * Abstract superclass with no primary key fields defined.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public abstract class AppIdSuper {
+
+    private String superField;
+
+    public void setSuperField(String superField) {
+        this.superField = superField;
+    }
+
+    public String getSuperField() {
+        return this.superField;
+    }
+
+    public static abstract class ID
+        implements Serializable {
+
+        static String DELIMITER = ":";
+
+        public ID() {
+        }
+
+        public ID(String str) {
+            fromString(str);
+        }
+
+        public int hashCode() {
+            // no key codes; all classes are equal
+            return 1;
+        }
+
+        public boolean equals(Object other) {
+            return other != null && other.getClass() == getClass();
+        }
+
+        public String toString() {
+            return "";
+        }
+
+        StringTokenizer fromString(String idString) {
+            return new StringTokenizer(idString, DELIMITER);
+        }
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ArraysTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ArraysTest.java
index 5f7cc54..073bb36 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ArraysTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ArraysTest.java
@@ -1,277 +1,277 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.Date;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-public class ArraysTest
-    implements Comparable {
-
-    private static long counter = 0;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    @PersistentCollection
-    private String[] aString;
-
-    @PersistentCollection
-    private Date[] aDate;
-
-    @PersistentCollection
-    private Integer[] aInt;
-
-    @PersistentCollection
-    private Long[] aLong;
-
-    @PersistentCollection
-
-    private Float[] aFloat;
-
-    private Byte[] aByte;
-
-    @PersistentCollection
-    private Double[] aDouble;
-
-    @PersistentCollection
-    private Boolean[] aBoolean;
-
-    @PersistentCollection
-    private Short[] aShort;
-
-    private Character[] aCharacter;
-
-    @PersistentCollection
-    private int[] aIntP;
-
-    @PersistentCollection
-    private long[] aLongP;
-
-    @PersistentCollection
-    private float[] aFloatP;
-
-    private byte[] aByteP;
-
-    @PersistentCollection
-    private double[] aDoubleP;
-
-    @PersistentCollection
-    private boolean[] aBooleanP;
-
-    @PersistentCollection
-    private short[] aShortP;
-
-    private char[] aCharacterP;
-
-    private char[] aCharacterPClob;
-
-    @PersistentCollection
-    private ArraysTest[] aArraysTest;
-
-    public ArraysTest() {
-    }
-
-    public boolean equals(Object other) {
-        return (other instanceof ArraysTest) && id == ((ArraysTest) other).id;
-    }
-
-    public int compareTo(Object other) {
-        ArraysTest t = (ArraysTest) other;
-        if (id < t.id)
-            return -1;
-        if (id == t.id)
-            return 0;
-        return 1;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public String[] getString() {
-        return aString;
-    }
-
-    public Date[] getDate() {
-        return aDate;
-    }
-
-    public Integer[] getInt() {
-        return aInt;
-    }
-
-    public Long[] getLong() {
-        return aLong;
-    }
-
-    public Float[] getFloat() {
-        return aFloat;
-    }
-
-    public Byte[] getByte() {
-        return aByte;
-    }
-
-    public Double[] getDouble() {
-        return aDouble;
-    }
-
-    public Boolean[] getBoolean() {
-        return aBoolean;
-    }
-
-    public Short[] getShort() {
-        return aShort;
-    }
-
-    public Character[] getCharacter() {
-        return aCharacter;
-    }
-
-    public int[] getIntP() {
-        return aIntP;
-    }
-
-    public long[] getLongP() {
-        return aLongP;
-    }
-
-    public float[] getFloatP() {
-        return aFloatP;
-    }
-
-    public byte[] getByteP() {
-        return aByteP;
-    }
-
-    public double[] getDoubleP() {
-        return aDoubleP;
-    }
-
-    public boolean[] getBooleanP() {
-        return aBooleanP;
-    }
-
-    public short[] getShortP() {
-        return aShortP;
-    }
-
-    public char[] getCharacterP() {
-        return aCharacterP;
-    }
-
-    public char[] getCharacterPClob() {
-        return aCharacterPClob;
-    }
-
-    public ArraysTest[] getArraysTest() {
-        return aArraysTest;
-    }
-
-    public void setString(String[] val) {
-        aString = val;
-    }
-
-    public void setDate(Date[] val) {
-        aDate = val;
-    }
-
-    public void setInt(Integer[] val) {
-        aInt = val;
-    }
-
-    public void setLong(Long[] val) {
-        aLong = val;
-    }
-
-    public void setFloat(Float[] val) {
-        aFloat = val;
-    }
-
-    public void setByte(Byte[] val) {
-        aByte = val;
-    }
-
-    public void setDouble(Double[] val) {
-        aDouble = val;
-    }
-
-    public void setBoolean(Boolean[] val) {
-        aBoolean = val;
-    }
-
-    public void setShort(Short[] val) {
-        aShort = val;
-    }
-
-    public void setCharacter(Character[] val) {
-        aCharacter = val;
-    }
-
-    public void setIntP(int[] val) {
-        aIntP = val;
-    }
-
-    public void setLongP(long[] val) {
-        aLongP = val;
-    }
-
-    public void setFloatP(float[] val) {
-        aFloatP = val;
-    }
-
-    public void setByteP(byte[] val) {
-        aByteP = val;
-    }
-
-    public void setDoubleP(double[] val) {
-        aDoubleP = val;
-    }
-
-    public void setBooleanP(boolean[] val) {
-        aBooleanP = val;
-    }
-
-    public void setShortP(short[] val) {
-        aShortP = val;
-    }
-
-    public void setCharacterP(char[] val) {
-        aCharacterP = val;
-    }
-
-    public void setCharacterPClob(char[] val) {
-        aCharacterPClob = val;
-    }
-
-    public void setArraysTest(ArraysTest[] val) {
-        aArraysTest = val;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.Date;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+public class ArraysTest
+    implements Comparable {
+
+    private static long counter = 0;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    @PersistentCollection
+    private String[] aString;
+
+    @PersistentCollection
+    private Date[] aDate;
+
+    @PersistentCollection
+    private Integer[] aInt;
+
+    @PersistentCollection
+    private Long[] aLong;
+
+    @PersistentCollection
+
+    private Float[] aFloat;
+
+    private Byte[] aByte;
+
+    @PersistentCollection
+    private Double[] aDouble;
+
+    @PersistentCollection
+    private Boolean[] aBoolean;
+
+    @PersistentCollection
+    private Short[] aShort;
+
+    private Character[] aCharacter;
+
+    @PersistentCollection
+    private int[] aIntP;
+
+    @PersistentCollection
+    private long[] aLongP;
+
+    @PersistentCollection
+    private float[] aFloatP;
+
+    private byte[] aByteP;
+
+    @PersistentCollection
+    private double[] aDoubleP;
+
+    @PersistentCollection
+    private boolean[] aBooleanP;
+
+    @PersistentCollection
+    private short[] aShortP;
+
+    private char[] aCharacterP;
+
+    private char[] aCharacterPClob;
+
+    @PersistentCollection
+    private ArraysTest[] aArraysTest;
+
+    public ArraysTest() {
+    }
+
+    public boolean equals(Object other) {
+        return (other instanceof ArraysTest) && id == ((ArraysTest) other).id;
+    }
+
+    public int compareTo(Object other) {
+        ArraysTest t = (ArraysTest) other;
+        if (id < t.id)
+            return -1;
+        if (id == t.id)
+            return 0;
+        return 1;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String[] getString() {
+        return aString;
+    }
+
+    public Date[] getDate() {
+        return aDate;
+    }
+
+    public Integer[] getInt() {
+        return aInt;
+    }
+
+    public Long[] getLong() {
+        return aLong;
+    }
+
+    public Float[] getFloat() {
+        return aFloat;
+    }
+
+    public Byte[] getByte() {
+        return aByte;
+    }
+
+    public Double[] getDouble() {
+        return aDouble;
+    }
+
+    public Boolean[] getBoolean() {
+        return aBoolean;
+    }
+
+    public Short[] getShort() {
+        return aShort;
+    }
+
+    public Character[] getCharacter() {
+        return aCharacter;
+    }
+
+    public int[] getIntP() {
+        return aIntP;
+    }
+
+    public long[] getLongP() {
+        return aLongP;
+    }
+
+    public float[] getFloatP() {
+        return aFloatP;
+    }
+
+    public byte[] getByteP() {
+        return aByteP;
+    }
+
+    public double[] getDoubleP() {
+        return aDoubleP;
+    }
+
+    public boolean[] getBooleanP() {
+        return aBooleanP;
+    }
+
+    public short[] getShortP() {
+        return aShortP;
+    }
+
+    public char[] getCharacterP() {
+        return aCharacterP;
+    }
+
+    public char[] getCharacterPClob() {
+        return aCharacterPClob;
+    }
+
+    public ArraysTest[] getArraysTest() {
+        return aArraysTest;
+    }
+
+    public void setString(String[] val) {
+        aString = val;
+    }
+
+    public void setDate(Date[] val) {
+        aDate = val;
+    }
+
+    public void setInt(Integer[] val) {
+        aInt = val;
+    }
+
+    public void setLong(Long[] val) {
+        aLong = val;
+    }
+
+    public void setFloat(Float[] val) {
+        aFloat = val;
+    }
+
+    public void setByte(Byte[] val) {
+        aByte = val;
+    }
+
+    public void setDouble(Double[] val) {
+        aDouble = val;
+    }
+
+    public void setBoolean(Boolean[] val) {
+        aBoolean = val;
+    }
+
+    public void setShort(Short[] val) {
+        aShort = val;
+    }
+
+    public void setCharacter(Character[] val) {
+        aCharacter = val;
+    }
+
+    public void setIntP(int[] val) {
+        aIntP = val;
+    }
+
+    public void setLongP(long[] val) {
+        aLongP = val;
+    }
+
+    public void setFloatP(float[] val) {
+        aFloatP = val;
+    }
+
+    public void setByteP(byte[] val) {
+        aByteP = val;
+    }
+
+    public void setDoubleP(double[] val) {
+        aDoubleP = val;
+    }
+
+    public void setBooleanP(boolean[] val) {
+        aBooleanP = val;
+    }
+
+    public void setShortP(short[] val) {
+        aShortP = val;
+    }
+
+    public void setCharacterP(char[] val) {
+        aCharacterP = val;
+    }
+
+    public void setCharacterPClob(char[] val) {
+        aCharacterPClob = val;
+    }
+
+    public void setArraysTest(ArraysTest[] val) {
+        aArraysTest = val;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachA.java
index 9d9160c..1898552 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachA.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-@Entity
-@DiscriminatorValue("ATTACH_A")
-@FetchGroups({
-@FetchGroup(name = "all", attributes = {
-@FetchAttribute(name = "stringArray", recursionDepth = 0),
-@FetchAttribute(name = "attachEArray", recursionDepth = 0)
-    })
-    })
-public class AttachA implements Serializable {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "A_ID")
-    private int id;
-
-    @Version
-    private int version;
-
-    private String astr;
-    private int aint;
-    private double adbl;
-
-    private String[] stringArray = new String[0];
-    private AttachE[] attachEArray = new AttachE[0];
-
-    public int getId() {
-        return id;
-    }
-
-    public void setAstr(String astr) {
-        this.astr = astr;
-    }
-
-    public String getAstr() {
-        return this.astr;
-    }
-
-    public void setAint(int aint) {
-        this.aint = aint;
-    }
-
-    public int getAint() {
-        return this.aint;
-    }
-
-    public void setAdbl(double adbl) {
-        this.adbl = adbl;
-    }
-
-    public double getAdbl() {
-        return this.adbl;
-    }
-
-    public void setStringArray(String[] stringArray) {
-        this.stringArray = stringArray;
-    }
-
-    public String[] getStringArray() {
-        return this.stringArray;
-    }
-
-    public void setAttachEArray(AttachE[] attachEArray) {
-        this.attachEArray = attachEArray;
-    }
-
-    public AttachE[] getAttachEArray() {
-        return this.attachEArray;
-    }
-
-    private void writeObject(ObjectOutputStream out)
-        throws IOException {
-        out.defaultWriteObject();
-    }
-
-    private void readObject(ObjectInputStream in)
-        throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+@Entity
+@DiscriminatorValue("ATTACH_A")
+@FetchGroups({
+@FetchGroup(name = "all", attributes = {
+@FetchAttribute(name = "stringArray", recursionDepth = 0),
+@FetchAttribute(name = "attachEArray", recursionDepth = 0)
+    })
+    })
+public class AttachA implements Serializable {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "A_ID")
+    private int id;
+
+    @Version
+    private int version;
+
+    private String astr;
+    private int aint;
+    private double adbl;
+
+    private String[] stringArray = new String[0];
+    private AttachE[] attachEArray = new AttachE[0];
+
+    public int getId() {
+        return id;
+    }
+
+    public void setAstr(String astr) {
+        this.astr = astr;
+    }
+
+    public String getAstr() {
+        return this.astr;
+    }
+
+    public void setAint(int aint) {
+        this.aint = aint;
+    }
+
+    public int getAint() {
+        return this.aint;
+    }
+
+    public void setAdbl(double adbl) {
+        this.adbl = adbl;
+    }
+
+    public double getAdbl() {
+        return this.adbl;
+    }
+
+    public void setStringArray(String[] stringArray) {
+        this.stringArray = stringArray;
+    }
+
+    public String[] getStringArray() {
+        return this.stringArray;
+    }
+
+    public void setAttachEArray(AttachE[] attachEArray) {
+        this.attachEArray = attachEArray;
+    }
+
+    public AttachE[] getAttachEArray() {
+        return this.attachEArray;
+    }
+
+    private void writeObject(ObjectOutputStream out)
+        throws IOException {
+        out.defaultWriteObject();
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachB.java
index 9eed34c..9a5c2fc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachB.java
@@ -1,100 +1,100 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.ManyToMany;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-
-@Entity
-@DiscriminatorValue("ATTACH_B")
-@FetchGroups({
-@FetchGroup(name = "all", attributes = {
-@FetchAttribute(name = "ds", recursionDepth = 0),
-@FetchAttribute(name = "stringIntMap", recursionDepth = 0)
-    })
-    })
-public class AttachB extends AttachA {
-
-    private String bstr;
-    private int bint;
-    private double bdbl;
-
-    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private Set<AttachD> ds = new HashSet();
-
-    @PersistentMap
-    @KeyColumn(name = "strngmap")
-    private Map<String, Integer> stringIntMap = new TreeMap<String, Integer>();
-
-    public AttachB() {
-    }
-
-    public void setBstr(String bstr) {
-        this.bstr = bstr;
-    }
-
-    public String getBstr() {
-        return this.bstr;
-    }
-
-    public void setBint(int bint) {
-        this.bint = bint;
-    }
-
-    public int getBint() {
-        return this.bint;
-    }
-
-    public void setBdbl(double bdbl) {
-        this.bdbl = bdbl;
-    }
-
-    public double getBdbl() {
-        return this.bdbl;
-    }
-
-    public void setDs(Set ds) {
-        this.ds = ds;
-    }
-
-    public Set getDs() {
-        return this.ds;
-    }
-
-    public void setStringIntMap(Map stringIntMap) {
-        this.stringIntMap = stringIntMap;
-    }
-
-    public Map getStringIntMap() {
-        return this.stringIntMap;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.ManyToMany;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+
+@Entity
+@DiscriminatorValue("ATTACH_B")
+@FetchGroups({
+@FetchGroup(name = "all", attributes = {
+@FetchAttribute(name = "ds", recursionDepth = 0),
+@FetchAttribute(name = "stringIntMap", recursionDepth = 0)
+    })
+    })
+public class AttachB extends AttachA {
+
+    private String bstr;
+    private int bint;
+    private double bdbl;
+
+    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private Set<AttachD> ds = new HashSet();
+
+    @PersistentMap
+    @KeyColumn(name = "strngmap")
+    private Map<String, Integer> stringIntMap = new TreeMap<String, Integer>();
+
+    public AttachB() {
+    }
+
+    public void setBstr(String bstr) {
+        this.bstr = bstr;
+    }
+
+    public String getBstr() {
+        return this.bstr;
+    }
+
+    public void setBint(int bint) {
+        this.bint = bint;
+    }
+
+    public int getBint() {
+        return this.bint;
+    }
+
+    public void setBdbl(double bdbl) {
+        this.bdbl = bdbl;
+    }
+
+    public double getBdbl() {
+        return this.bdbl;
+    }
+
+    public void setDs(Set ds) {
+        this.ds = ds;
+    }
+
+    public Set getDs() {
+        return this.ds;
+    }
+
+    public void setStringIntMap(Map stringIntMap) {
+        this.stringIntMap = stringIntMap;
+    }
+
+    public Map getStringIntMap() {
+        return this.stringIntMap;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachC.java
index e40231a..c643ac5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachC.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.LinkedList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.ManyToMany;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-@Entity
-@DiscriminatorValue("ATTACH_C")
-@FetchGroups({
-@FetchGroup(name = "all", attributes = {
-@FetchAttribute(name = "es", recursionDepth = 0)
-    })
-    })
-public class AttachC
-    extends AttachB {
-
-    private String cstr;
-    private int cint;
-    private double cdbl;
-
-    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private List<AttachE> es = new LinkedList(); // non-DFG
-
-    public void setCstr(String cstr) {
-        this.cstr = cstr;
-    }
-
-    public String getCstr() {
-        return this.cstr;
-    }
-
-    public void setCint(int cint) {
-        this.cint = cint;
-    }
-
-    public int getCint() {
-        return this.cint;
-    }
-
-    public void setCdbl(double cdbl) {
-        this.cdbl = cdbl;
-    }
-
-    public double getCdbl() {
-        return this.cdbl;
-    }
-
-    public void setEs(List es) {
-        this.es = es;
-    }
-
-    public List getEs() {
-        return this.es;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.LinkedList;
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.ManyToMany;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+@Entity
+@DiscriminatorValue("ATTACH_C")
+@FetchGroups({
+@FetchGroup(name = "all", attributes = {
+@FetchAttribute(name = "es", recursionDepth = 0)
+    })
+    })
+public class AttachC
+    extends AttachB {
+
+    private String cstr;
+    private int cint;
+    private double cdbl;
+
+    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private List<AttachE> es = new LinkedList(); // non-DFG
+
+    public void setCstr(String cstr) {
+        this.cstr = cstr;
+    }
+
+    public String getCstr() {
+        return this.cstr;
+    }
+
+    public void setCint(int cint) {
+        this.cint = cint;
+    }
+
+    public int getCint() {
+        return this.cint;
+    }
+
+    public void setCdbl(double cdbl) {
+        this.cdbl = cdbl;
+    }
+
+    public double getCdbl() {
+        return this.cdbl;
+    }
+
+    public void setEs(List es) {
+        this.es = es;
+    }
+
+    public List getEs() {
+        return this.es;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachD.java
index 3f00d0b..2923164 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachD.java
@@ -1,174 +1,174 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-
-@Entity
-@FetchGroups({
-@FetchGroup(name = "all", attributes = {
-@FetchAttribute(name = "bs", recursionDepth = 0),
-@FetchAttribute(name = "pcStringMap"),
-@FetchAttribute(name = "bigIntegerPCMap", recursionDepth = 0),
-@FetchAttribute(name = "embeddedE", recursionDepth = 0),
-@FetchAttribute(name = "embeddedA", recursionDepth = 0)
-
-    })
-    })
-public class AttachD implements Serializable {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "D_ID")
-    private int id;
-
-    private Object version;
-
-    @Basic
-    private String dstr;
-    @Basic
-    private int dint;
-    @Basic
-    private double ddbl;
-
-    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private AttachA a;
-
-    @ManyToMany(mappedBy = "ds",
-        cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private Set<AttachB> bs = new HashSet();
-
-    @PersistentMap(keyCascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    @KeyColumn(name = "strngmap")
-    private Map<AttachA, String> pcStringMap = new HashMap();
-
-    @PersistentMap(elementCascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    @KeyColumn(name = "intmap")
-    private TreeMap<BigInteger, AttachF> bigIntegerPCMap =
-        new TreeMap<BigInteger, AttachF>();
-
-    @Embedded
-    private AttachE embeddedE;
-
-    @Embedded
-    private AttachA embeddedA;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setDstr(String dstr) {
-        this.dstr = dstr;
-    }
-
-    public String getDstr() {
-        return this.dstr;
-    }
-
-    public void setDint(int dint) {
-        this.dint = dint;
-    }
-
-    public int getDint() {
-        return this.dint;
-    }
-
-    public void setDdbl(double ddbl) {
-        this.ddbl = ddbl;
-    }
-
-    public double getDdbl() {
-        return this.ddbl;
-    }
-
-    public AttachA getA() {
-        return a;
-    }
-
-    public void setA(AttachA a) {
-        this.a = a;
-    }
-
-    public void setBs(Set bs) {
-        this.bs = bs;
-    }
-
-    public Set getBs() {
-        return this.bs;
-    }
-
-    public void setPcStringMap(Map pcStringMap) {
-        this.pcStringMap = pcStringMap;
-    }
-
-    public Map getPcStringMap() {
-        return this.pcStringMap;
-    }
-
-    public void setBigIntegerPCMap(TreeMap bigIntegerPCMap) {
-        this.bigIntegerPCMap = bigIntegerPCMap;
-    }
-
-    public TreeMap getBigIntegerPCMap() {
-        return this.bigIntegerPCMap;
-    }
-
-    public void setEmbeddedE(AttachE embeddedE) {
-        this.embeddedE = embeddedE;
-    }
-
-    public AttachE getEmbeddedE() {
-        return this.embeddedE;
-    }
-
-    public void setEmbeddedA(AttachA embeddedA) {
-        this.embeddedA = embeddedA;
-    }
-
-    public AttachA getEmbeddedA() {
-        return this.embeddedA;
-    }
-
-    public Object getVersion() {
-        return this.version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+
+@Entity
+@FetchGroups({
+@FetchGroup(name = "all", attributes = {
+@FetchAttribute(name = "bs", recursionDepth = 0),
+@FetchAttribute(name = "pcStringMap"),
+@FetchAttribute(name = "bigIntegerPCMap", recursionDepth = 0),
+@FetchAttribute(name = "embeddedE", recursionDepth = 0),
+@FetchAttribute(name = "embeddedA", recursionDepth = 0)
+
+    })
+    })
+public class AttachD implements Serializable {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "D_ID")
+    private int id;
+
+    private Object version;
+
+    @Basic
+    private String dstr;
+    @Basic
+    private int dint;
+    @Basic
+    private double ddbl;
+
+    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private AttachA a;
+
+    @ManyToMany(mappedBy = "ds",
+        cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private Set<AttachB> bs = new HashSet();
+
+    @PersistentMap(keyCascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    @KeyColumn(name = "strngmap")
+    private Map<AttachA, String> pcStringMap = new HashMap();
+
+    @PersistentMap(elementCascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    @KeyColumn(name = "intmap")
+    private TreeMap<BigInteger, AttachF> bigIntegerPCMap =
+        new TreeMap<BigInteger, AttachF>();
+
+    @Embedded
+    private AttachE embeddedE;
+
+    @Embedded
+    private AttachA embeddedA;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setDstr(String dstr) {
+        this.dstr = dstr;
+    }
+
+    public String getDstr() {
+        return this.dstr;
+    }
+
+    public void setDint(int dint) {
+        this.dint = dint;
+    }
+
+    public int getDint() {
+        return this.dint;
+    }
+
+    public void setDdbl(double ddbl) {
+        this.ddbl = ddbl;
+    }
+
+    public double getDdbl() {
+        return this.ddbl;
+    }
+
+    public AttachA getA() {
+        return a;
+    }
+
+    public void setA(AttachA a) {
+        this.a = a;
+    }
+
+    public void setBs(Set bs) {
+        this.bs = bs;
+    }
+
+    public Set getBs() {
+        return this.bs;
+    }
+
+    public void setPcStringMap(Map pcStringMap) {
+        this.pcStringMap = pcStringMap;
+    }
+
+    public Map getPcStringMap() {
+        return this.pcStringMap;
+    }
+
+    public void setBigIntegerPCMap(TreeMap bigIntegerPCMap) {
+        this.bigIntegerPCMap = bigIntegerPCMap;
+    }
+
+    public TreeMap getBigIntegerPCMap() {
+        return this.bigIntegerPCMap;
+    }
+
+    public void setEmbeddedE(AttachE embeddedE) {
+        this.embeddedE = embeddedE;
+    }
+
+    public AttachE getEmbeddedE() {
+        return this.embeddedE;
+    }
+
+    public void setEmbeddedA(AttachA embeddedA) {
+        this.embeddedA = embeddedA;
+    }
+
+    public AttachA getEmbeddedA() {
+        return this.embeddedA;
+    }
+
+    public Object getVersion() {
+        return this.version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachE.java
index d2df177..1684a70 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachE.java
@@ -1,127 +1,127 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.util.Date;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-@Entity
-@DiscriminatorValue("ATTACH_E")
-@FetchGroups({
-@FetchGroup(name = "all", attributes = {
-@FetchAttribute(name = "b"),
-@FetchAttribute(name = "f")
-    })
-    })
-public class AttachE implements Serializable {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "E_ID")
-    private int id;
-
-    private Object version;
-
-    @Basic
-    private String estr;
-
-    private int eint;
-
-    private double edbl;
-
-    @ManyToOne(fetch = FetchType.LAZY,
-        cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private AttachB b;
-
-    @OneToOne(fetch = FetchType.LAZY, mappedBy = "e",
-        cascade = { CascadeType.PERSIST, CascadeType.MERGE })
-    private AttachF f;
-
-    @Temporal(TemporalType.DATE)
-    private Date dateField;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setEstr(String estr) {
-        this.estr = estr;
-    }
-
-    public String getEstr() {
-        return this.estr;
-    }
-
-    public void setEint(int eint) {
-        this.eint = eint;
-    }
-
-    public int getEint() {
-        return this.eint;
-    }
-
-    public void setEdbl(double edbl) {
-        this.edbl = edbl;
-    }
-
-    public double getEdbl() {
-        return this.edbl;
-    }
-
-    public void setB(AttachB b) {
-        this.b = b;
-    }
-
-    public AttachB getB() {
-        return this.b;
-    }
-
-    public void setF(AttachF f) {
-        this.f = f;
-    }
-
-    public AttachF getF() {
-        return this.f;
-    }
-
-    public void setDateField(Date date) {
-        this.dateField = date;
-    }
-
-    public Date getDateField() {
-        return this.dateField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+@Entity
+@DiscriminatorValue("ATTACH_E")
+@FetchGroups({
+@FetchGroup(name = "all", attributes = {
+@FetchAttribute(name = "b"),
+@FetchAttribute(name = "f")
+    })
+    })
+public class AttachE implements Serializable {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "E_ID")
+    private int id;
+
+    private Object version;
+
+    @Basic
+    private String estr;
+
+    private int eint;
+
+    private double edbl;
+
+    @ManyToOne(fetch = FetchType.LAZY,
+        cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private AttachB b;
+
+    @OneToOne(fetch = FetchType.LAZY, mappedBy = "e",
+        cascade = { CascadeType.PERSIST, CascadeType.MERGE })
+    private AttachF f;
+
+    @Temporal(TemporalType.DATE)
+    private Date dateField;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setEstr(String estr) {
+        this.estr = estr;
+    }
+
+    public String getEstr() {
+        return this.estr;
+    }
+
+    public void setEint(int eint) {
+        this.eint = eint;
+    }
+
+    public int getEint() {
+        return this.eint;
+    }
+
+    public void setEdbl(double edbl) {
+        this.edbl = edbl;
+    }
+
+    public double getEdbl() {
+        return this.edbl;
+    }
+
+    public void setB(AttachB b) {
+        this.b = b;
+    }
+
+    public AttachB getB() {
+        return this.b;
+    }
+
+    public void setF(AttachF f) {
+        this.f = f;
+    }
+
+    public AttachF getF() {
+        return this.f;
+    }
+
+    public void setDateField(Date date) {
+        this.dateField = date;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachF.java
index 89a13b0..9da171e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachF.java
@@ -1,166 +1,166 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-import org.apache.openjpa.persistence.PersistentCollection;
-
-@Entity
-@DiscriminatorValue("ATTACH_F")
-@IdClass(AttachF.ID.class)
-@FetchGroups({
-@FetchGroup(name = "all", attributes = {
-@FetchAttribute(name = "e", recursionDepth = 0),
-@FetchAttribute(name = "strings"),
-@FetchAttribute(name = "embeddedC", recursionDepth = 0)
-    })
-    })
-public class AttachF implements Serializable {
-
-    @Id
-    private int id1;
-
-    @Id
-    private String id2;
-
-    private String fstr;
-    private int fint;
-    private double fdbl;
-
-    @ManyToOne
-    @JoinColumn(name = "ATT_E")
-    private AttachE e;
-
-    @PersistentCollection
-    private List<String> strings = new ArrayList();
-
-    @Embedded
-    private AttachC embeddedC;
-
-    public void setFstr(String fstr) {
-        this.fstr = fstr;
-    }
-
-    public String getFstr() {
-        return this.fstr;
-    }
-
-    public void setFint(int fint) {
-        this.fint = fint;
-    }
-
-    public int getFint() {
-        return this.fint;
-    }
-
-    public void setFdbl(double fdbl) {
-        this.fdbl = fdbl;
-    }
-
-    public double getFdbl() {
-        return this.fdbl;
-    }
-
-    public void setE(AttachE e) {
-        this.e = e;
-    }
-
-    public AttachE getE() {
-        return this.e;
-    }
-
-    public void setStrings(List strings) {
-        this.strings = strings;
-    }
-
-    public List getStrings() {
-        return this.strings;
-    }
-
-    public static class ID {
-
-        public int id1;
-        public String id2;
-
-        public ID() {
-        }
-
-        public ID(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ":");
-            id1 = Integer.parseInt(tok.nextToken());
-            id2 = tok.nextToken();
-        }
-
-        @Override
-        public int hashCode() {
-            return id1 + (id2 == null ? 0 : id2.hashCode());
-        }
-
-        public String toString() {
-            return id1 + ":" + id2;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            return other instanceof ID
-                && ((ID) other).id1 == id1
-                && (id2 == null ? ((ID) other).id2 == null
-                : id2.equals(((ID) other).id2));
-        }
-    }
-
-    public void setId1(int id1) {
-        this.id1 = id1;
-    }
-
-    public int getId1() {
-        return this.id1;
-    }
-
-    public void setId2(String id2) {
-        this.id2 = id2;
-    }
-
-    public String getId2() {
-        return this.id2;
-    }
-
-    public void setEmbeddedC(AttachC embeddedC) {
-        this.embeddedC = embeddedC;
-    }
-
-    public AttachC getEmbeddedC() {
-        return this.embeddedC;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+@DiscriminatorValue("ATTACH_F")
+@IdClass(AttachF.ID.class)
+@FetchGroups({
+@FetchGroup(name = "all", attributes = {
+@FetchAttribute(name = "e", recursionDepth = 0),
+@FetchAttribute(name = "strings"),
+@FetchAttribute(name = "embeddedC", recursionDepth = 0)
+    })
+    })
+public class AttachF implements Serializable {
+
+    @Id
+    private int id1;
+
+    @Id
+    private String id2;
+
+    private String fstr;
+    private int fint;
+    private double fdbl;
+
+    @ManyToOne
+    @JoinColumn(name = "ATT_E")
+    private AttachE e;
+
+    @PersistentCollection
+    private List<String> strings = new ArrayList();
+
+    @Embedded
+    private AttachC embeddedC;
+
+    public void setFstr(String fstr) {
+        this.fstr = fstr;
+    }
+
+    public String getFstr() {
+        return this.fstr;
+    }
+
+    public void setFint(int fint) {
+        this.fint = fint;
+    }
+
+    public int getFint() {
+        return this.fint;
+    }
+
+    public void setFdbl(double fdbl) {
+        this.fdbl = fdbl;
+    }
+
+    public double getFdbl() {
+        return this.fdbl;
+    }
+
+    public void setE(AttachE e) {
+        this.e = e;
+    }
+
+    public AttachE getE() {
+        return this.e;
+    }
+
+    public void setStrings(List strings) {
+        this.strings = strings;
+    }
+
+    public List getStrings() {
+        return this.strings;
+    }
+
+    public static class ID {
+
+        public int id1;
+        public String id2;
+
+        public ID() {
+        }
+
+        public ID(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ":");
+            id1 = Integer.parseInt(tok.nextToken());
+            id2 = tok.nextToken();
+        }
+
+        @Override
+        public int hashCode() {
+            return id1 + (id2 == null ? 0 : id2.hashCode());
+        }
+
+        public String toString() {
+            return id1 + ":" + id2;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            return other instanceof ID
+                && ((ID) other).id1 == id1
+                && (id2 == null ? ((ID) other).id2 == null
+                : id2.equals(((ID) other).id2));
+        }
+    }
+
+    public void setId1(int id1) {
+        this.id1 = id1;
+    }
+
+    public int getId1() {
+        return this.id1;
+    }
+
+    public void setId2(String id2) {
+        this.id2 = id2;
+    }
+
+    public String getId2() {
+        return this.id2;
+    }
+
+    public void setEmbeddedC(AttachC embeddedC) {
+        this.embeddedC = embeddedC;
+    }
+
+    public AttachC getEmbeddedC() {
+        return this.embeddedC;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionA.java
index d80e3cb..2d27496 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionA.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.Set;
-import javax.persistence.Entity;
-
-@Entity
-public class AttachVersionA {
-
-    private int pk;
-    private int version;
-    private String stringField;
-    private String fetchA;
-    private String fetchB;
-    private AttachVersionA pc;
-    private AttachVersionC embedded;
-    private Set many;
-
-    public AttachVersionA() {
-    }
-
-    public AttachVersionA(int pk) {
-        this.pk = pk;
-    }
-
-    public AttachVersionA(int pk, String s) {
-        this.pk = pk;
-        stringField = s;
-    }
-
-    public void setPk(int pk) {
-        this.pk = pk;
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public void setVersion(int v) {
-        version = v;
-    }
-
-    public int getVersion() {
-        return version;
-    }
-
-    public Object getVersionObject() {
-        return new Integer(version);
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public void setFetchA(String fetchA) {
-        this.fetchA = fetchA;
-    }
-
-    public String getFetchA() {
-        return fetchA;
-    }
-
-    public void setFetchB(String fetchB) {
-        this.fetchB = fetchB;
-    }
-
-    public String getFetchB() {
-        return fetchB;
-    }
-
-    public void setPC(AttachVersionA pc) {
-        this.pc = pc;
-    }
-
-    public AttachVersionA getPC() {
-        return pc;
-    }
-
-    public void setMany(Set many) {
-        this.many = many;
-    }
-
-    public Set getMany() {
-        return many;
-    }
-
-    public void setEmbedded(AttachVersionC embedded) {
-        this.embedded = embedded;
-    }
-
-    public AttachVersionC getEmbedded() {
-        return embedded;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.Set;
+import javax.persistence.Entity;
+
+@Entity
+public class AttachVersionA {
+
+    private int pk;
+    private int version;
+    private String stringField;
+    private String fetchA;
+    private String fetchB;
+    private AttachVersionA pc;
+    private AttachVersionC embedded;
+    private Set many;
+
+    public AttachVersionA() {
+    }
+
+    public AttachVersionA(int pk) {
+        this.pk = pk;
+    }
+
+    public AttachVersionA(int pk, String s) {
+        this.pk = pk;
+        stringField = s;
+    }
+
+    public void setPk(int pk) {
+        this.pk = pk;
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public void setVersion(int v) {
+        version = v;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public Object getVersionObject() {
+        return new Integer(version);
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public void setFetchA(String fetchA) {
+        this.fetchA = fetchA;
+    }
+
+    public String getFetchA() {
+        return fetchA;
+    }
+
+    public void setFetchB(String fetchB) {
+        this.fetchB = fetchB;
+    }
+
+    public String getFetchB() {
+        return fetchB;
+    }
+
+    public void setPC(AttachVersionA pc) {
+        this.pc = pc;
+    }
+
+    public AttachVersionA getPC() {
+        return pc;
+    }
+
+    public void setMany(Set many) {
+        this.many = many;
+    }
+
+    public Set getMany() {
+        return many;
+    }
+
+    public void setEmbedded(AttachVersionC embedded) {
+        this.embedded = embedded;
+    }
+
+    public AttachVersionC getEmbedded() {
+        return embedded;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionB.java
index f8f3cba..eaf1cec 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionB.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class AttachVersionB
-    extends AttachVersionA {
-
-    private String stringField2;
-
-    public AttachVersionB() {
-    }
-
-    public AttachVersionB(int pk) {
-        super(pk);
-    }
-
-    public AttachVersionB(int pk, String s, String s2) {
-        super(pk, s);
-        stringField2 = s2;
-    }
-
-    public String getStringField2() {
-        return stringField2;
-    }
-
-    public void setStringField2(String s) {
-        stringField2 = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class AttachVersionB
+    extends AttachVersionA {
+
+    private String stringField2;
+
+    public AttachVersionB() {
+    }
+
+    public AttachVersionB(int pk) {
+        super(pk);
+    }
+
+    public AttachVersionB(int pk, String s, String s2) {
+        super(pk, s);
+        stringField2 = s2;
+    }
+
+    public String getStringField2() {
+        return stringField2;
+    }
+
+    public void setStringField2(String s) {
+        stringField2 = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionC.java
index 3e39acd..6598922 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AttachVersionC.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class AttachVersionC {
-
-    private int intField;
-    private AttachVersionA pc;
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setPc(AttachVersionA pc) {
-        this.pc = pc;
-    }
-
-    public AttachVersionA getPc() {
-        return pc;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class AttachVersionC {
+
+    private int intField;
+    private AttachVersionA pc;
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setPc(AttachVersionA pc) {
+        this.pc = pc;
+    }
+
+    public AttachVersionA getPc() {
+        return pc;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/BlobTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/BlobTest.java
index 0e14d1d..e271640 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/BlobTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/BlobTest.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-
-@Entity
-public class BlobTest {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    @Column(name = "blobtab")
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private Object blob;
-
-    public BlobTest() {
-    }
-
-    public void setBlob(Object blob) {
-        this.blob = blob;
-    }
-
-    public byte[] getBlob() {
-        return (byte[]) this.blob;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+
+@Entity
+public class BlobTest {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    @Column(name = "blobtab")
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private Object blob;
+
+    public BlobTest() {
+    }
+
+    public void setBlob(Object blob) {
+        this.blob = blob;
+    }
+
+    public byte[] getBlob() {
+        return (byte[]) this.blob;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ByteArray.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ByteArray.java
index 049fbbd..4837432 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ByteArray.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ByteArray.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "bytearray")
-public class ByteArray {
-
-    @Id
-    private int ids;
-
-    @Column(length = 50)
-    private String string;
-
-    public byte[] bytes;
-
-    public ByteArray() {
-    }
-
-    public ByteArray(String str, int id) {
-        string = str;
-        this.ids = id;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public void setString(String s) {
-        string = s;
-    }
-
-    public byte[] getBytes() {
-        return bytes;
-    }
-
-    public void setBytes(byte[] bs) {
-        bytes = bs;
-    }
-
-    public int getIds() {
-        return ids;
-    }
-
-    public void setIds(int ids) {
-        this.ids = ids;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "bytearray")
+public class ByteArray {
+
+    @Id
+    private int ids;
+
+    @Column(length = 50)
+    private String string;
+
+    public byte[] bytes;
+
+    public ByteArray() {
+    }
+
+    public ByteArray(String str, int id) {
+        string = str;
+        this.ids = id;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public void setString(String s) {
+        string = s;
+    }
+
+    public byte[] getBytes() {
+        return bytes;
+    }
+
+    public void setBytes(byte[] bs) {
+        bytes = bs;
+    }
+
+    public int getIds() {
+        return ids;
+    }
+
+    public void setIds(int ids) {
+        this.ids = ids;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/CalendarFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/CalendarFields.java
index c60fe71..4ba008e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/CalendarFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/CalendarFields.java
@@ -1,111 +1,111 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.List;
-import java.util.TimeZone;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "CAL_FLDS")
-public class CalendarFields {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    private Calendar unassigned;
-    private Calendar gmt = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-    private Calendar pacific =
-        Calendar.getInstance(TimeZone.getTimeZone("US/Pacific"));
-    private Calendar newYork =
-        Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
-    private Calendar berlin =
-        Calendar.getInstance(TimeZone.getTimeZone("Europe/Berlin"));
-    private Calendar singapore =
-        Calendar.getInstance(TimeZone.getTimeZone("Asia/Singapore"));
-
-    public CalendarFields() {
-    }
-
-    public void setGmt(Calendar gmt) {
-        this.gmt = gmt;
-    }
-
-    public Calendar getGmt() {
-        return this.gmt;
-    }
-
-    public void setPacific(Calendar pacific) {
-        this.pacific = pacific;
-    }
-
-    public Calendar getPacific() {
-        return this.pacific;
-    }
-
-    public void setNewYork(Calendar newYork) {
-        this.newYork = newYork;
-    }
-
-    public Calendar getNewYork() {
-        return this.newYork;
-    }
-
-    public void setBerlin(Calendar berlin) {
-        this.berlin = berlin;
-    }
-
-    public Calendar getBerlin() {
-        return this.berlin;
-    }
-
-    public void setSingapore(Calendar singapore) {
-        this.singapore = singapore;
-    }
-
-    public Calendar getSingapore() {
-        return this.singapore;
-    }
-
-    public void setUnassigned(Calendar unassigned) {
-        this.unassigned = unassigned;
-    }
-
-    public Calendar getUnassigned() {
-        return this.unassigned;
-    }
-
-    public List getCalendars() {
-        return Arrays.asList(new Calendar[]{
-            unassigned, gmt, pacific, newYork, berlin, singapore
-        });
-    }
-
-    public int getId() {
-        return id;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "CAL_FLDS")
+public class CalendarFields {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    private Calendar unassigned;
+    private Calendar gmt = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+    private Calendar pacific =
+        Calendar.getInstance(TimeZone.getTimeZone("US/Pacific"));
+    private Calendar newYork =
+        Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
+    private Calendar berlin =
+        Calendar.getInstance(TimeZone.getTimeZone("Europe/Berlin"));
+    private Calendar singapore =
+        Calendar.getInstance(TimeZone.getTimeZone("Asia/Singapore"));
+
+    public CalendarFields() {
+    }
+
+    public void setGmt(Calendar gmt) {
+        this.gmt = gmt;
+    }
+
+    public Calendar getGmt() {
+        return this.gmt;
+    }
+
+    public void setPacific(Calendar pacific) {
+        this.pacific = pacific;
+    }
+
+    public Calendar getPacific() {
+        return this.pacific;
+    }
+
+    public void setNewYork(Calendar newYork) {
+        this.newYork = newYork;
+    }
+
+    public Calendar getNewYork() {
+        return this.newYork;
+    }
+
+    public void setBerlin(Calendar berlin) {
+        this.berlin = berlin;
+    }
+
+    public Calendar getBerlin() {
+        return this.berlin;
+    }
+
+    public void setSingapore(Calendar singapore) {
+        this.singapore = singapore;
+    }
+
+    public Calendar getSingapore() {
+        return this.singapore;
+    }
+
+    public void setUnassigned(Calendar unassigned) {
+        this.unassigned = unassigned;
+    }
+
+    public Calendar getUnassigned() {
+        return this.unassigned;
+    }
+
+    public List getCalendars() {
+        return Arrays.asList(new Calendar[]{
+            unassigned, gmt, pacific, newYork, berlin, singapore
+        });
+    }
+
+    public int getId() {
+        return id;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ColumnIOPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ColumnIOPC.java
index 65d8ab7..6253465 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ColumnIOPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ColumnIOPC.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "columnpc")
-public class ColumnIOPC {
-
-    @Column(length = 40)
-    private String name;
-
-    @Column(name = "ignsert")
-    private int ignoreInsert;
-
-    @Column(name = "ignpdate")
-    private int ignoreUpdate;
-
-    private int ident;
-
-    @Id
-    private int id;
-
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ColumnIOPC rel;
-
-    public ColumnIOPC() {
-
-    }
-
-    public ColumnIOPC(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public int getIgnoreInsert() {
-        return this.ignoreInsert;
-    }
-
-    public void setIgnoreInsert(int ignoreInsert) {
-        this.ignoreInsert = ignoreInsert;
-    }
-
-    public int getIgnoreUpdate() {
-        return this.ignoreUpdate;
-    }
-
-    public void setIgnoreUpdate(int ignoreUpdate) {
-        this.ignoreUpdate = ignoreUpdate;
-    }
-
-    public int getIdent() {
-        return this.ident;
-    }
-
-    public void setIdent(int ident) {
-        this.ident = ident;
-    }
-
-    public ColumnIOPC getRel() {
-        return this.rel;
-    }
-
-    public void setRel(ColumnIOPC rel) {
-        this.rel = rel;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "columnpc")
+public class ColumnIOPC {
+
+    @Column(length = 40)
+    private String name;
+
+    @Column(name = "ignsert")
+    private int ignoreInsert;
+
+    @Column(name = "ignpdate")
+    private int ignoreUpdate;
+
+    private int ident;
+
+    @Id
+    private int id;
+
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ColumnIOPC rel;
+
+    public ColumnIOPC() {
+
+    }
+
+    public ColumnIOPC(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getIgnoreInsert() {
+        return this.ignoreInsert;
+    }
+
+    public void setIgnoreInsert(int ignoreInsert) {
+        this.ignoreInsert = ignoreInsert;
+    }
+
+    public int getIgnoreUpdate() {
+        return this.ignoreUpdate;
+    }
+
+    public void setIgnoreUpdate(int ignoreUpdate) {
+        this.ignoreUpdate = ignoreUpdate;
+    }
+
+    public int getIdent() {
+        return this.ident;
+    }
+
+    public void setIdent(int ident) {
+        this.ident = ident;
+    }
+
+    public ColumnIOPC getRel() {
+        return this.rel;
+    }
+
+    public void setRel(ColumnIOPC rel) {
+        this.rel = rel;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ComplexEmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ComplexEmbeddedPC.java
index f6876ef..5253263 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ComplexEmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ComplexEmbeddedPC.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-
-/**
- * <p>Embedded type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-//@DiscriminatorValue("cep")
-public class ComplexEmbeddedPC //extends RecursivelyEmbeddedPC
-{
-
-    @Basic
-    @Column(name = "cembedstring")
-    private String stringField;
-
-    @OneToOne
-    private EmbeddedOwnerPC ownerField;
-
-    private Set<String> stringSet = new HashSet<String>();
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public EmbeddedOwnerPC getOwnerField() {
-        return this.ownerField;
-    }
-
-    public void setOwnerField(EmbeddedOwnerPC ownerField) {
-        this.ownerField = ownerField;
-    }
-
-    public Set getStringSet() {
-        return this.stringSet;
-    }
-
-    public void setStringSet(Set stringSet) {
-        this.stringSet = stringSet;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+
+/**
+ * <p>Embedded type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+//@DiscriminatorValue("cep")
+public class ComplexEmbeddedPC //extends RecursivelyEmbeddedPC
+{
+
+    @Basic
+    @Column(name = "cembedstring")
+    private String stringField;
+
+    @OneToOne
+    private EmbeddedOwnerPC ownerField;
+
+    private Set<String> stringSet = new HashSet<String>();
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public EmbeddedOwnerPC getOwnerField() {
+        return this.ownerField;
+    }
+
+    public void setOwnerField(EmbeddedOwnerPC ownerField) {
+        this.ownerField = ownerField;
+    }
+
+    public Set getStringSet() {
+        return this.stringSet;
+    }
+
+    public void setStringSet(Set stringSet) {
+        this.stringSet = stringSet;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ConcreteMappedAppIdSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ConcreteMappedAppIdSub.java
index aceda12..1257ff0 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ConcreteMappedAppIdSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ConcreteMappedAppIdSub.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ConcreteMappedAppIdSub
-    extends AbstractMappedAppIdSuper {
-
-    private String name;
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ConcreteMappedAppIdSub
+    extends AbstractMappedAppIdSuper {
+
+    private String name;
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DateVersion.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DateVersion.java
index 3b07331..de22f8f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DateVersion.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DateVersion.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "dversion")
-public class DateVersion {
-
-    @Column(length = 35)
-    private String string;
-
-    @Id
-    private int id;
-
-    public DateVersion(String s, int id) {
-        string = s;
-        this.id = id;
-    }
-
-    public void setString(String s) {
-        string = s;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public String toString() {
-        return string;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "dversion")
+public class DateVersion {
+
+    @Column(length = 35)
+    private String string;
+
+    @Id
+    private int id;
+
+    public DateVersion(String s, int id) {
+        string = s;
+        this.id = id;
+    }
+
+    public void setString(String s) {
+        string = s;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public String toString() {
+        return string;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DependentFieldsPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DependentFieldsPC.java
index 1329034..505c54f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DependentFieldsPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DependentFieldsPC.java
@@ -1,155 +1,155 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.openjpa.persistence.Dependent;
-import org.apache.openjpa.persistence.ElementDependent;
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-
-/**
- * <p>Persistent type used in testing dependent field deletion through
- * {@link TestDependentFields}.</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "DEPFIELDPC")
-public class DependentFieldsPC {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "ID")
-    private long pk;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private DependentFieldsPC relation = null;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    //@ForeignKey(deleteAction=ForeignKeyAction.RESTRICT)
-    @ForeignKey
-    private DependentFieldsPC owner = null;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    private List<DependentFieldsPC> list = new ArrayList();
-
-    @PersistentMap(elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "depfpc")
-    private Map<String, DependentFieldsPC> map = new HashMap();
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    @Dependent
-    private DependentFieldsPC dependentRelation = null;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    @ElementDependent
-    private List<DependentFieldsPC> dependentList = new ArrayList();
-
-    @OneToMany(mappedBy = "owner", cascade = CascadeType.PERSIST)
-    @ElementDependent
-    private List<DependentFieldsPC> dependentMappedList = new ArrayList();
-
-    @OneToMany(cascade = CascadeType.PERSIST)
-    @ElementDependent
-    @ElementJoinColumn(name = "DEP_INV_KEY", referencedColumnName = "ID")
-    private List<DependentFieldsPC> dependentInverseKeyList = new ArrayList();
-
-    @PersistentMap(elementCascade = CascadeType.PERSIST)
-    @ElementDependent
-    @KeyColumn(name = "depmap")
-    private Map<String, DependentFieldsPC> dependentMap = new HashMap();
-
-    public DependentFieldsPC() {
-    }
-
-    public long getPK() {
-        return this.pk;
-    }
-
-    public void setPK(long pk) {
-        this.pk = pk;
-    }
-
-    public DependentFieldsPC getRelation() {
-        return this.relation;
-    }
-
-    public void setRelation(DependentFieldsPC relation) {
-        this.relation = relation;
-    }
-
-    public DependentFieldsPC getOwner() {
-        return this.owner;
-    }
-
-    public void setOwner(DependentFieldsPC owner) {
-        this.owner = owner;
-    }
-
-    public List getList() {
-        return this.list;
-    }
-
-    public Map getMap() {
-        return this.map;
-    }
-
-    public DependentFieldsPC getDependentRelation() {
-        return this.dependentRelation;
-    }
-
-    public void setDependentRelation(DependentFieldsPC relation) {
-        this.dependentRelation = relation;
-    }
-
-    public List getDependentList() {
-        return this.dependentList;
-    }
-
-    public List getDependentMappedList() {
-        return this.dependentMappedList;
-    }
-
-    public List getDependentInverseKeyList() {
-        return this.dependentInverseKeyList;
-    }
-
-    public Map getDependentMap() {
-        return this.dependentMap;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.Dependent;
+import org.apache.openjpa.persistence.ElementDependent;
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+
+/**
+ * <p>Persistent type used in testing dependent field deletion through
+ * {@link TestDependentFields}.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "DEPFIELDPC")
+public class DependentFieldsPC {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "ID")
+    private long pk;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private DependentFieldsPC relation = null;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    //@ForeignKey(deleteAction=ForeignKeyAction.RESTRICT)
+    @ForeignKey
+    private DependentFieldsPC owner = null;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    private List<DependentFieldsPC> list = new ArrayList();
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "depfpc")
+    private Map<String, DependentFieldsPC> map = new HashMap();
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    @Dependent
+    private DependentFieldsPC dependentRelation = null;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    @ElementDependent
+    private List<DependentFieldsPC> dependentList = new ArrayList();
+
+    @OneToMany(mappedBy = "owner", cascade = CascadeType.PERSIST)
+    @ElementDependent
+    private List<DependentFieldsPC> dependentMappedList = new ArrayList();
+
+    @OneToMany(cascade = CascadeType.PERSIST)
+    @ElementDependent
+    @ElementJoinColumn(name = "DEP_INV_KEY", referencedColumnName = "ID")
+    private List<DependentFieldsPC> dependentInverseKeyList = new ArrayList();
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    @ElementDependent
+    @KeyColumn(name = "depmap")
+    private Map<String, DependentFieldsPC> dependentMap = new HashMap();
+
+    public DependentFieldsPC() {
+    }
+
+    public long getPK() {
+        return this.pk;
+    }
+
+    public void setPK(long pk) {
+        this.pk = pk;
+    }
+
+    public DependentFieldsPC getRelation() {
+        return this.relation;
+    }
+
+    public void setRelation(DependentFieldsPC relation) {
+        this.relation = relation;
+    }
+
+    public DependentFieldsPC getOwner() {
+        return this.owner;
+    }
+
+    public void setOwner(DependentFieldsPC owner) {
+        this.owner = owner;
+    }
+
+    public List getList() {
+        return this.list;
+    }
+
+    public Map getMap() {
+        return this.map;
+    }
+
+    public DependentFieldsPC getDependentRelation() {
+        return this.dependentRelation;
+    }
+
+    public void setDependentRelation(DependentFieldsPC relation) {
+        this.dependentRelation = relation;
+    }
+
+    public List getDependentList() {
+        return this.dependentList;
+    }
+
+    public List getDependentMappedList() {
+        return this.dependentMappedList;
+    }
+
+    public List getDependentInverseKeyList() {
+        return this.dependentInverseKeyList;
+    }
+
+    public Map getDependentMap() {
+        return this.dependentMap;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DetachSMPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DetachSMPC.java
index 4de76f8..cf68771 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DetachSMPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/DetachSMPC.java
@@ -1,61 +1,61 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.openjpa.persistence.PersistentCollection;
-
-@Entity
-public class DetachSMPC
-    implements Serializable {
-
-    private int intField;
-
-    @PersistentCollection
-    private Set relSet = new HashSet();
-    @KeyColumn(name = "strngkey")
-    private Map stringIntMap = new TreeMap();
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public Set getRelSet() {
-        return this.relSet;
-    }
-
-    public void setStringIntMap(Map stringIntMap) {
-        this.stringIntMap = stringIntMap;
-    }
-
-    public Map getStringIntMap() {
-        return this.stringIntMap;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+public class DetachSMPC
+    implements Serializable {
+
+    private int intField;
+
+    @PersistentCollection
+    private Set relSet = new HashSet();
+    @KeyColumn(name = "strngkey")
+    private Map stringIntMap = new TreeMap();
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public Set getRelSet() {
+        return this.relSet;
+    }
+
+    public void setStringIntMap(Map stringIntMap) {
+        this.stringIntMap = stringIntMap;
+    }
+
+    public Map getStringIntMap() {
+        return this.stringIntMap;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedOwnerPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedOwnerPC.java
index 921f363..e2f3014 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedOwnerPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedOwnerPC.java
@@ -1,125 +1,125 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.jdbc.EmbeddedMapping;
-
-/**
- * <p>Persistent type used in testing embedded instances.</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "embownpc")
-@IdClass(EmbeddedOwnerPC.EmbKey.class)
-public class EmbeddedOwnerPC {
-
-    @Id
-    private int id1;
-    @Id
-    private int id2;
-    @Basic
-    private String stringField;
-
-    @Embedded
-    @EmbeddedMapping(nullIndicatorAttributeName = "stringField")
-    private EmbeddedPC embedded;
-
-    @Embedded
-    private ComplexEmbeddedPC complexEmbedded;
-
-    protected EmbeddedOwnerPC() {
-    }
-
-    public EmbeddedOwnerPC(int id1, int id2) {
-        this.id1 = id1;
-        this.id2 = id2;
-    }
-
-    public int getId1() {
-        return id1;
-    }
-
-    public int getId2() {
-        return id2;
-    }
-
-    public EmbeddedPC getEmbedded() {
-        return this.embedded;
-    }
-
-    public void setEmbedded(EmbeddedPC embedded) {
-        this.embedded = embedded;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public ComplexEmbeddedPC getComplexEmbedded() {
-        return this.complexEmbedded;
-    }
-
-    public void setComplexEmbedded(ComplexEmbeddedPC complexEmbedded) {
-        this.complexEmbedded = complexEmbedded;
-    }
-
-    public static class EmbKey implements Serializable {
-
-        public int id1;
-        public int id2;
-
-        public EmbKey() {
-        }
-
-        public EmbKey(String str) {
-            int index = str.indexOf(":");
-            if (index != -1) {
-                id1 = Integer.parseInt(str.substring(0, index));
-                id2 = Integer.parseInt(str.substring(index + 1));
-            }
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof EmbKey))
-                return false;
-
-            EmbKey touse = (EmbKey) other;
-            return touse.id1 == id1 && touse.id2 == id2;
-        }
-
-        @Override
-        public int hashCode() {
-            return (id1 + id2 + "").hashCode();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.jdbc.EmbeddedMapping;
+
+/**
+ * <p>Persistent type used in testing embedded instances.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "embownpc")
+@IdClass(EmbeddedOwnerPC.EmbKey.class)
+public class EmbeddedOwnerPC {
+
+    @Id
+    private int id1;
+    @Id
+    private int id2;
+    @Basic
+    private String stringField;
+
+    @Embedded
+    @EmbeddedMapping(nullIndicatorAttributeName = "stringField")
+    private EmbeddedPC embedded;
+
+    @Embedded
+    private ComplexEmbeddedPC complexEmbedded;
+
+    protected EmbeddedOwnerPC() {
+    }
+
+    public EmbeddedOwnerPC(int id1, int id2) {
+        this.id1 = id1;
+        this.id2 = id2;
+    }
+
+    public int getId1() {
+        return id1;
+    }
+
+    public int getId2() {
+        return id2;
+    }
+
+    public EmbeddedPC getEmbedded() {
+        return this.embedded;
+    }
+
+    public void setEmbedded(EmbeddedPC embedded) {
+        this.embedded = embedded;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public ComplexEmbeddedPC getComplexEmbedded() {
+        return this.complexEmbedded;
+    }
+
+    public void setComplexEmbedded(ComplexEmbeddedPC complexEmbedded) {
+        this.complexEmbedded = complexEmbedded;
+    }
+
+    public static class EmbKey implements Serializable {
+
+        public int id1;
+        public int id2;
+
+        public EmbKey() {
+        }
+
+        public EmbKey(String str) {
+            int index = str.indexOf(":");
+            if (index != -1) {
+                id1 = Integer.parseInt(str.substring(0, index));
+                id2 = Integer.parseInt(str.substring(index + 1));
+            }
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof EmbKey))
+                return false;
+
+            EmbKey touse = (EmbKey) other;
+            return touse.id1 == id1 && touse.id2 == id2;
+        }
+
+        @Override
+        public int hashCode() {
+            return (id1 + id2 + "").hashCode();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedPC.java
index b3c5c58..9a2404d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/EmbeddedPC.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-/**
- * <p>Embedded type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "embpc")
-public class EmbeddedPC {
-
-    @Column(name = "embedint")
-    private int intField;
-
-    @Column(name = "embedint1")
-    private int intField1;
-
-    @Column(name = "embedstring")
-    private String stringField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public int getIntField1() {
-        return this.intField1;
-    }
-
-    public void setIntField1(int intField1) {
-        this.intField1 = intField1;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * <p>Embedded type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "embpc")
+public class EmbeddedPC {
+
+    @Column(name = "embedint")
+    private int intField;
+
+    @Column(name = "embedint1")
+    private int intField1;
+
+    @Column(name = "embedstring")
+    private String stringField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public int getIntField1() {
+        return this.intField1;
+    }
+
+    public void setIntField1(int intField1) {
+        this.intField1 = intField1;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity1.java
index b78871d..8d7cf8f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity1.java
@@ -1,101 +1,101 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name = "entity_1")
-@Inheritance(strategy = InheritanceType.JOINED)
-@SqlResultSetMapping(name = "NativeTestResult", entities = @EntityResult(
-    entityClass = org.apache.openjpa.persistence.kernel.common.apps.Entity1.class))
-public class Entity1 implements Serializable {
-
-    private static final long serialVersionUID = 2882935803066041165L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
-    protected Entity2 entity2Field;
-
-    @Version
-    protected int versionField;
-
-    public Entity1() {
-    }
-
-    public Entity1(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setEntity2Field(Entity2 val) {
-        entity2Field = val;
-    }
-
-    public Entity2 getEntity2Field() {
-        return entity2Field;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "entity_1")
+@Inheritance(strategy = InheritanceType.JOINED)
+@SqlResultSetMapping(name = "NativeTestResult", entities = @EntityResult(
+    entityClass = org.apache.openjpa.persistence.kernel.common.apps.Entity1.class))
+public class Entity1 implements Serializable {
+
+    private static final long serialVersionUID = 2882935803066041165L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
+    protected Entity2 entity2Field;
+
+    @Version
+    protected int versionField;
+
+    public Entity1() {
+    }
+
+    public Entity1(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setEntity2Field(Entity2 val) {
+        entity2Field = val;
+    }
+
+    public Entity2 getEntity2Field() {
+        return entity2Field;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity2.java
index 09b6437..8c199b6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Entity2.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-
-@Entity(name = "entity2ExplicitName")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class Entity2 implements Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 4723739219953167343L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    public Entity2() {
-    }
-
-    public Entity2(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+@Entity(name = "entity2ExplicitName")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class Entity2 implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4723739219953167343L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    public Entity2() {
+    }
+
+    public Entity2(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ExternalValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ExternalValues.java
index 61521be..424da9d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ExternalValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ExternalValues.java
@@ -1,129 +1,129 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "extnlval")
-public class ExternalValues {
-
-    private boolean booleanToShort;
-    private byte byteToDouble;
-    private int intToFloat;
-    private long longToChar;
-    private short shortToString;
-    private float floatToBoolean;
-    private double doubleToByte;
-    private char charToInt;
-    @Column(length = 50)
-    private String stringToLong;
-    @Id
-    private int id;
-
-    public ExternalValues() {
-    }
-
-    public ExternalValues(int id) {
-        this.id = id;
-    }
-
-    public boolean getBooleanToShort() {
-        return booleanToShort;
-    }
-
-    public void setBooleanToShort(boolean b) {
-        booleanToShort = b;
-    }
-
-    public byte getByteToDouble() {
-        return byteToDouble;
-    }
-
-    public void setByteToDouble(byte b) {
-        byteToDouble = b;
-    }
-
-    public int getIntToFloat() {
-        return intToFloat;
-    }
-
-    public void setIntToFloat(int i) {
-        intToFloat = i;
-    }
-
-    public long getLongToChar() {
-        return longToChar;
-    }
-
-    public void setLongToChar(long l) {
-        longToChar = l;
-    }
-
-    public short getShortToString() {
-        return shortToString;
-    }
-
-    public void setShortToString(short s) {
-        shortToString = s;
-    }
-
-    public double getDoubleToByte() {
-        return doubleToByte;
-    }
-
-    public void setDoubleToByte(double d) {
-        doubleToByte = d;
-    }
-
-    public float getFloatToBoolean() {
-        return floatToBoolean;
-    }
-
-    public void setFloatToBoolean(float f) {
-        floatToBoolean = f;
-    }
-
-    public char getCharToInt() {
-        return charToInt;
-    }
-
-    public void setCharToInt(char c) {
-        charToInt = c;
-    }
-
-    public String getStringToLong() {
-        return stringToLong;
-    }
-
-    public void setStringToLong(String s) {
-        stringToLong = s;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "extnlval")
+public class ExternalValues {
+
+    private boolean booleanToShort;
+    private byte byteToDouble;
+    private int intToFloat;
+    private long longToChar;
+    private short shortToString;
+    private float floatToBoolean;
+    private double doubleToByte;
+    private char charToInt;
+    @Column(length = 50)
+    private String stringToLong;
+    @Id
+    private int id;
+
+    public ExternalValues() {
+    }
+
+    public ExternalValues(int id) {
+        this.id = id;
+    }
+
+    public boolean getBooleanToShort() {
+        return booleanToShort;
+    }
+
+    public void setBooleanToShort(boolean b) {
+        booleanToShort = b;
+    }
+
+    public byte getByteToDouble() {
+        return byteToDouble;
+    }
+
+    public void setByteToDouble(byte b) {
+        byteToDouble = b;
+    }
+
+    public int getIntToFloat() {
+        return intToFloat;
+    }
+
+    public void setIntToFloat(int i) {
+        intToFloat = i;
+    }
+
+    public long getLongToChar() {
+        return longToChar;
+    }
+
+    public void setLongToChar(long l) {
+        longToChar = l;
+    }
+
+    public short getShortToString() {
+        return shortToString;
+    }
+
+    public void setShortToString(short s) {
+        shortToString = s;
+    }
+
+    public double getDoubleToByte() {
+        return doubleToByte;
+    }
+
+    public void setDoubleToByte(double d) {
+        doubleToByte = d;
+    }
+
+    public float getFloatToBoolean() {
+        return floatToBoolean;
+    }
+
+    public void setFloatToBoolean(float f) {
+        floatToBoolean = f;
+    }
+
+    public char getCharToInt() {
+        return charToInt;
+    }
+
+    public void setCharToInt(char c) {
+        charToInt = c;
+    }
+
+    public String getStringToLong() {
+        return stringToLong;
+    }
+
+    public void setStringToLong(String s) {
+        stringToLong = s;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObject.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObject.java
index b2cf940..66461e5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObject.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObject.java
@@ -1,157 +1,157 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.math.BigInteger;
-import java.util.Date;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-import org.apache.openjpa.persistence.LoadFetchGroup;
-
-@Entity
-@Table(name = "FETCH_GRP_TOBJ")
-@FetchGroups({
-@FetchGroup(name = "g1", attributes = {
-@FetchAttribute(name = "b"),
-@FetchAttribute(name = "c"),
-@FetchAttribute(name = "d")
-    }),
-@FetchGroup(name = "g2", attributes = {
-@FetchAttribute(name = "e"),
-@FetchAttribute(name = "f"),
-@FetchAttribute(name = "g")
-    })
-    })
-public class FetchGroupTestObject {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    private int a;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g1")
-    private String b;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g1")
-    private BigInteger c;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g1")
-    @Temporal(TemporalType.DATE)
-    private Date d;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g2")
-    private String e;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g2")
-    private String f;
-
-    @OneToOne(cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY)
-    @LoadFetchGroup("g2")
-    private FetchGroupTestObject g;
-
-    @OneToOne(cascade = { CascadeType.PERSIST })
-    private FetchGroupTestObject h;
-
-    public int getId() {
-        return this.id;
-    }
-
-    public void setA(int val) {
-        a = val;
-    }
-
-    public int getA() {
-        return a;
-    }
-
-    public void setB(String val) {
-        b = val;
-    }
-
-    public String getB() {
-        return b;
-    }
-
-    public void setC(BigInteger val) {
-        c = val;
-    }
-
-    public BigInteger getC() {
-        return c;
-    }
-
-    public void setD(Date val) {
-        d = val;
-    }
-
-    public Date getD() {
-        return d;
-    }
-
-    public void setE(String val) {
-        e = val;
-    }
-
-    public String getE() {
-        return e;
-    }
-
-    public void setF(String val) {
-        f = val;
-    }
-
-    public String getF() {
-        return f;
-    }
-
-    public void setG(FetchGroupTestObject val) {
-        g = val;
-    }
-
-    public FetchGroupTestObject getG() {
-        return g;
-    }
-
-    public void setH(FetchGroupTestObject val) {
-        h = val;
-    }
-
-    public FetchGroupTestObject getH() {
-        return h;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.math.BigInteger;
+import java.util.Date;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+import org.apache.openjpa.persistence.LoadFetchGroup;
+
+@Entity
+@Table(name = "FETCH_GRP_TOBJ")
+@FetchGroups({
+@FetchGroup(name = "g1", attributes = {
+@FetchAttribute(name = "b"),
+@FetchAttribute(name = "c"),
+@FetchAttribute(name = "d")
+    }),
+@FetchGroup(name = "g2", attributes = {
+@FetchAttribute(name = "e"),
+@FetchAttribute(name = "f"),
+@FetchAttribute(name = "g")
+    })
+    })
+public class FetchGroupTestObject {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    private int a;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g1")
+    private String b;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g1")
+    private BigInteger c;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g1")
+    @Temporal(TemporalType.DATE)
+    private Date d;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g2")
+    private String e;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g2")
+    private String f;
+
+    @OneToOne(cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY)
+    @LoadFetchGroup("g2")
+    private FetchGroupTestObject g;
+
+    @OneToOne(cascade = { CascadeType.PERSIST })
+    private FetchGroupTestObject h;
+
+    public int getId() {
+        return this.id;
+    }
+
+    public void setA(int val) {
+        a = val;
+    }
+
+    public int getA() {
+        return a;
+    }
+
+    public void setB(String val) {
+        b = val;
+    }
+
+    public String getB() {
+        return b;
+    }
+
+    public void setC(BigInteger val) {
+        c = val;
+    }
+
+    public BigInteger getC() {
+        return c;
+    }
+
+    public void setD(Date val) {
+        d = val;
+    }
+
+    public Date getD() {
+        return d;
+    }
+
+    public void setE(String val) {
+        e = val;
+    }
+
+    public String getE() {
+        return e;
+    }
+
+    public void setF(String val) {
+        f = val;
+    }
+
+    public String getF() {
+        return f;
+    }
+
+    public void setG(FetchGroupTestObject val) {
+        g = val;
+    }
+
+    public FetchGroupTestObject getG() {
+        return g;
+    }
+
+    public void setH(FetchGroupTestObject val) {
+        h = val;
+    }
+
+    public FetchGroupTestObject getH() {
+        return h;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObjectChild.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObjectChild.java
index 76fdb8d..1eb3e93 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObjectChild.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/FetchGroupTestObjectChild.java
@@ -1,91 +1,91 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Basic;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-import org.apache.openjpa.persistence.LoadFetchGroup;
-
-@Entity
-@DiscriminatorValue("FETCH_GRP_TOBJCHILD")
-@FetchGroups({
-@FetchGroup(name = "g1", attributes = {
-@FetchAttribute(name = "childB")
-    }),
-@FetchGroup(name = "g2", attributes = {
-@FetchAttribute(name = "childC")
-    }),
-@FetchGroup(name = "g3", attributes = {
-@FetchAttribute(name = "childD")
-    })
-    })
-public class FetchGroupTestObjectChild extends FetchGroupTestObject {
-
-    private int childA;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g1")
-    private int childB;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g2")
-    private int childC;
-
-    @Basic(fetch = FetchType.LAZY)
-    @LoadFetchGroup("g3")
-    private int childD;
-
-    public void setChildA(int val) {
-        childA = val;
-    }
-
-    public int getChildA() {
-        return childA;
-    }
-
-    public void setChildB(int val) {
-        childB = val;
-    }
-
-    public int getChildB() {
-        return childB;
-    }
-
-    public void setChildC(int val) {
-        childC = val;
-    }
-
-    public int getChildC() {
-        return childC;
-    }
-
-    public void setChildD(int val) {
-        childD = val;
-    }
-
-    public int getChildD() {
-        return childD;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Basic;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+import org.apache.openjpa.persistence.LoadFetchGroup;
+
+@Entity
+@DiscriminatorValue("FETCH_GRP_TOBJCHILD")
+@FetchGroups({
+@FetchGroup(name = "g1", attributes = {
+@FetchAttribute(name = "childB")
+    }),
+@FetchGroup(name = "g2", attributes = {
+@FetchAttribute(name = "childC")
+    }),
+@FetchGroup(name = "g3", attributes = {
+@FetchAttribute(name = "childD")
+    })
+    })
+public class FetchGroupTestObjectChild extends FetchGroupTestObject {
+
+    private int childA;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g1")
+    private int childB;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g2")
+    private int childC;
+
+    @Basic(fetch = FetchType.LAZY)
+    @LoadFetchGroup("g3")
+    private int childD;
+
+    public void setChildA(int val) {
+        childA = val;
+    }
+
+    public int getChildA() {
+        return childA;
+    }
+
+    public void setChildB(int val) {
+        childB = val;
+    }
+
+    public int getChildB() {
+        return childB;
+    }
+
+    public void setChildC(int val) {
+        childC = val;
+    }
+
+    public int getChildC() {
+        return childC;
+    }
+
+    public void setChildD(int val) {
+        childD = val;
+    }
+
+    public int getChildD() {
+        return childD;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Inner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Inner.java
index 9e1636f..779fbfa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Inner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Inner.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Basic;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Column;
-
-@Entity
-@Table(name = "nullvalue")
-public class Inner {
-
-    @Basic
-    private Integer none = null;
-
-    @Basic(optional = false)
-    @Column(name="exception_col")
-    private Integer exception = null;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int Id;
-
-    public Inner() {
-    }
-
-    public int getId() {
-        return Id;
-    }
-
-    public Integer getNone() {
-        return none;
-    }
-
-    public Integer getException() {
-        return exception;
-    }
-
-    public void setNone(Integer val) {
-        none = val;
-    }
-
-    public void setException(Integer val) {
-        exception = val;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Column;
+
+@Entity
+@Table(name = "nullvalue")
+public class Inner {
+
+    @Basic
+    private Integer none = null;
+
+    @Basic(optional = false)
+    @Column(name="exception_col")
+    private Integer exception = null;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int Id;
+
+    public Inner() {
+    }
+
+    public int getId() {
+        return Id;
+    }
+
+    public Integer getNone() {
+        return none;
+    }
+
+    public Integer getException() {
+        return exception;
+    }
+
+    public void setNone(Integer val) {
+        none = val;
+    }
+
+    public void setException(Integer val) {
+        exception = val;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InstanceCallbacksTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InstanceCallbacksTest.java
index 32a05dc..2f057b3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InstanceCallbacksTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InstanceCallbacksTest.java
@@ -1,186 +1,186 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.PostLoad;
-import javax.persistence.PrePersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PreUpdate;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Table(name = "icbt")
-public class InstanceCallbacksTest {
-
-    public static long preDeleteInvocations = 0;
-    public static long postLoadInvocations = 0;
-    public static long preStoreInvocations = 0;
-    public static long preClearInvocations = 0;
-
-    public transient boolean postLoadCalled = false;
-    public transient boolean preStoreCalled = false;
-    public transient boolean preDeleteCalled = false;
-    public transient boolean preClearCalled = false;
-
-    public transient int preDeleteCycle = -1;
-    public transient boolean flushInPreStore = false;
-
-    // this string should never be null in jdoPostLoad
-    @Column(length = 35)
-    private String nonNullString = null;
-
-    @Column(length = 35)
-    private String stringField = null;
-    @Basic
-    private int intField = 0;
-    @Basic
-    private int nonDFGField = 0;
-
-    @OneToOne(cascade = CascadeType.PERSIST)
-    private RuntimeTest1 oneOne = null;
-
-    @OneToOne(cascade = CascadeType.PERSIST)
-    private InstanceCallbacksTest rel;
-    private transient Object relId;
-
-    public InstanceCallbacksTest() {
-    }
-
-    public InstanceCallbacksTest(String stringField, int intField) {
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public void setNonNullString(String val) {
-        nonNullString = val;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public int getNonDFGField() {
-        return this.nonDFGField;
-    }
-
-    public void setNonDFGField(int nonDFGField) {
-        this.nonDFGField = nonDFGField;
-    }
-
-    public RuntimeTest1 getOneOne() {
-        return this.oneOne;
-    }
-
-    public void setOneOne(RuntimeTest1 oneOne) {
-        this.oneOne = oneOne;
-    }
-
-    @PostLoad
-    public void jdoPostLoad() {
-        postLoadInvocations++;
-
-        postLoadCalled = true;
-        if (nonNullString == null)
-            throw new IllegalStateException();
-    }
-
-    public void jdoPreClear() {
-        preClearInvocations++;
-
-        preClearCalled = true;
-    }
-
-    @PrePersist
-    @PreUpdate
-    public void jdoPreStore() {
-        preStoreInvocations++;
-
-        preStoreCalled = true;
-
-        // ensure that whenever this object is persisted,
-        // nonNullString is, in fact, not null.
-        if (nonNullString == null)
-            nonNullString = "** this string is not null **";
-
-        // assign new value to relation; should get persisted
-        if ("bar".equals(stringField))
-            oneOne = new RuntimeTest1("jdoPreStore",
-                (int) (Math.random() * Integer.MAX_VALUE));
-        OpenJPAEntityManager em = OpenJPAPersistence.getEntityManager(this);
-        if (em != null) {
-            if (relId != null) {
-                InstanceCallbacksTest rel = em.find(InstanceCallbacksTest.class,
-                    relId);
-                rel.setRel(this);
-                rel.setIntField(8888);
-            }
-            if (flushInPreStore)
-                em.flush();
-        }
-    }
-
-    @PreRemove
-    public void jdoPreDelete() {
-        preDeleteInvocations++;
-        preDeleteCalled = true;
-        if (preDeleteCycle >= 0 && preDeleteCycle < 5) {
-            preDeleteCycle++;
-            OpenJPAPersistence.getEntityManager(this).remove(this);
-        }
-    }
-
-    public InstanceCallbacksTest getRel() {
-        return this.rel;
-    }
-
-    public void setRel(InstanceCallbacksTest rel) {
-        this.rel = rel;
-    }
-
-    public Object getRelId() {
-        return this.relId;
-    }
-
-    public void setRelId(Object relId) {
-        this.relId = relId;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.PostLoad;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Table(name = "icbt")
+public class InstanceCallbacksTest {
+
+    public static long preDeleteInvocations = 0;
+    public static long postLoadInvocations = 0;
+    public static long preStoreInvocations = 0;
+    public static long preClearInvocations = 0;
+
+    public transient boolean postLoadCalled = false;
+    public transient boolean preStoreCalled = false;
+    public transient boolean preDeleteCalled = false;
+    public transient boolean preClearCalled = false;
+
+    public transient int preDeleteCycle = -1;
+    public transient boolean flushInPreStore = false;
+
+    // this string should never be null in jdoPostLoad
+    @Column(length = 35)
+    private String nonNullString = null;
+
+    @Column(length = 35)
+    private String stringField = null;
+    @Basic
+    private int intField = 0;
+    @Basic
+    private int nonDFGField = 0;
+
+    @OneToOne(cascade = CascadeType.PERSIST)
+    private RuntimeTest1 oneOne = null;
+
+    @OneToOne(cascade = CascadeType.PERSIST)
+    private InstanceCallbacksTest rel;
+    private transient Object relId;
+
+    public InstanceCallbacksTest() {
+    }
+
+    public InstanceCallbacksTest(String stringField, int intField) {
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public void setNonNullString(String val) {
+        nonNullString = val;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public int getNonDFGField() {
+        return this.nonDFGField;
+    }
+
+    public void setNonDFGField(int nonDFGField) {
+        this.nonDFGField = nonDFGField;
+    }
+
+    public RuntimeTest1 getOneOne() {
+        return this.oneOne;
+    }
+
+    public void setOneOne(RuntimeTest1 oneOne) {
+        this.oneOne = oneOne;
+    }
+
+    @PostLoad
+    public void jdoPostLoad() {
+        postLoadInvocations++;
+
+        postLoadCalled = true;
+        if (nonNullString == null)
+            throw new IllegalStateException();
+    }
+
+    public void jdoPreClear() {
+        preClearInvocations++;
+
+        preClearCalled = true;
+    }
+
+    @PrePersist
+    @PreUpdate
+    public void jdoPreStore() {
+        preStoreInvocations++;
+
+        preStoreCalled = true;
+
+        // ensure that whenever this object is persisted,
+        // nonNullString is, in fact, not null.
+        if (nonNullString == null)
+            nonNullString = "** this string is not null **";
+
+        // assign new value to relation; should get persisted
+        if ("bar".equals(stringField))
+            oneOne = new RuntimeTest1("jdoPreStore",
+                (int) (Math.random() * Integer.MAX_VALUE));
+        OpenJPAEntityManager em = OpenJPAPersistence.getEntityManager(this);
+        if (em != null) {
+            if (relId != null) {
+                InstanceCallbacksTest rel = em.find(InstanceCallbacksTest.class,
+                    relId);
+                rel.setRel(this);
+                rel.setIntField(8888);
+            }
+            if (flushInPreStore)
+                em.flush();
+        }
+    }
+
+    @PreRemove
+    public void jdoPreDelete() {
+        preDeleteInvocations++;
+        preDeleteCalled = true;
+        if (preDeleteCycle >= 0 && preDeleteCycle < 5) {
+            preDeleteCycle++;
+            OpenJPAPersistence.getEntityManager(this).remove(this);
+        }
+    }
+
+    public InstanceCallbacksTest getRel() {
+        return this.rel;
+    }
+
+    public void setRel(InstanceCallbacksTest rel) {
+        this.rel = rel;
+    }
+
+    public Object getRelId() {
+        return this.relId;
+    }
+
+    public void setRelId(Object relId) {
+        this.relId = relId;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceHolder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceHolder.java
index 7a2706d..b630152 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceHolder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceHolder.java
@@ -1,85 +1,85 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "holder")
-public class InterfaceHolder implements Serializable {
-
-    private Set intfs = new HashSet();
-
-    @Basic
-    @Column(length = 35)
-    private String stringField;
-
-    @OneToOne(fetch = FetchType.LAZY,
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private InterfaceTest intf;
-
-    @Id
-    private int id;
-
-    public InterfaceHolder() {
-    }
-
-    public InterfaceHolder(int id) {
-        this.id = id;
-    }
-
-    public void setIntf(InterfaceTest intf) {
-        this.intf = intf;
-    }
-
-    public InterfaceTest getIntf() {
-        return this.intf;
-    }
-
-    public void setIntfs(Set intfs) {
-        this.intfs = intfs;
-    }
-
-    public Set getIntfs() {
-        return this.intfs;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public String toString() {
-        return "intfs: " + intfs + ", StringField: " + stringField +
-            ", Intf: " + intf + ".";
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "holder")
+public class InterfaceHolder implements Serializable {
+
+    private Set intfs = new HashSet();
+
+    @Basic
+    @Column(length = 35)
+    private String stringField;
+
+    @OneToOne(fetch = FetchType.LAZY,
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private InterfaceTest intf;
+
+    @Id
+    private int id;
+
+    public InterfaceHolder() {
+    }
+
+    public InterfaceHolder(int id) {
+        this.id = id;
+    }
+
+    public void setIntf(InterfaceTest intf) {
+        this.intf = intf;
+    }
+
+    public InterfaceTest getIntf() {
+        return this.intf;
+    }
+
+    public void setIntfs(Set intfs) {
+        this.intfs = intfs;
+    }
+
+    public Set getIntfs() {
+        return this.intfs;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public String toString() {
+        return "intfs: " + intfs + ", StringField: " + stringField +
+            ", Intf: " + intf + ".";
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest.java
index e68eb45..3507abf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * <p>Interface used in testing</p>
- *
- * @author Abe White
- */
-
-public interface InterfaceTest {
-
-    public String getStringField();
-
-    public void setStringField(String str);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * <p>Interface used in testing</p>
+ *
+ * @author Abe White
+ */
+
+public interface InterfaceTest {
+
+    public String getStringField();
+
+    public void setStringField(String str);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest2.java
index e8dcaec..8808429 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTest2.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * <p>Interface used in testing</p>
- *
- * @author Abe White
- */
-public interface InterfaceTest2
-    extends InterfaceTest {
-
-    public int getIntField();
-
-    public void setIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * <p>Interface used in testing</p>
+ *
+ * @author Abe White
+ */
+public interface InterfaceTest2
+    extends InterfaceTest {
+
+    public int getIntField();
+
+    public void setIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl1.java
index 9423e94..20eadee 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl1.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-/**
- * <p>Persistent type used in testing</p>
- *
- * @author Abe White
- */
-
-@SuppressWarnings("serial")
-@Entity
-@Table(name = "impl_1")
-public class InterfaceTestImpl1 implements InterfaceTest, Serializable {
-
-    private String stringField;
-
-    protected InterfaceTestImpl1() {
-    }
-
-    public InterfaceTestImpl1(String str) {
-        this.stringField = str;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String str) {
-        this.stringField = str;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * <p>Persistent type used in testing</p>
+ *
+ * @author Abe White
+ */
+
+@SuppressWarnings("serial")
+@Entity
+@Table(name = "impl_1")
+public class InterfaceTestImpl1 implements InterfaceTest, Serializable {
+
+    private String stringField;
+
+    protected InterfaceTestImpl1() {
+    }
+
+    public InterfaceTestImpl1(String str) {
+        this.stringField = str;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String str) {
+        this.stringField = str;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl2.java
index 76a6b09..a587064 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl2.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-/**
- * <p>Persistent type used in testing</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "impl_2")
-public class InterfaceTestImpl2 implements InterfaceTest, Serializable {
-
-    private String stringField;
-
-    protected InterfaceTestImpl2() {
-    }
-
-    public InterfaceTestImpl2(String str) {
-        this.stringField = str;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String str) {
-        this.stringField = str;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * <p>Persistent type used in testing</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "impl_2")
+public class InterfaceTestImpl2 implements InterfaceTest, Serializable {
+
+    private String stringField;
+
+    protected InterfaceTestImpl2() {
+    }
+
+    public InterfaceTestImpl2(String str) {
+        this.stringField = str;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String str) {
+        this.stringField = str;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl3.java
index b5d427f..14da1b7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl3.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type used in testing</p>
- *
- * @author Abe White
- */
-@Entity
-public class InterfaceTestImpl3
-    extends InterfaceTestImpl2
-    implements InterfaceTest2 {
-
-    private int intField;
-
-    protected InterfaceTestImpl3() {
-    }
-
-    public InterfaceTestImpl3(String str) {
-        super(str);
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int i) {
-        this.intField = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type used in testing</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class InterfaceTestImpl3
+    extends InterfaceTestImpl2
+    implements InterfaceTest2 {
+
+    private int intField;
+
+    protected InterfaceTestImpl3() {
+    }
+
+    public InterfaceTestImpl3(String str) {
+        super(str);
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int i) {
+        this.intField = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl4.java
index 758deeb..0801d45 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InterfaceTestImpl4.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persistent type used in testing</p>
- *
- * @author Abe White
- */
-
-@Entity
-public class InterfaceTestImpl4
-    implements InterfaceTest2 {
-
-    private String stringField;
-    private int intField;
-
-    protected InterfaceTestImpl4() {
-    }
-
-    public InterfaceTestImpl4(String str) {
-        this.stringField = str;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String str) {
-        this.stringField = str;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int i) {
-        this.intField = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persistent type used in testing</p>
+ *
+ * @author Abe White
+ */
+
+@Entity
+public class InterfaceTestImpl4
+    implements InterfaceTest2 {
+
+    private String stringField;
+    private int intField;
+
+    protected InterfaceTestImpl4() {
+    }
+
+    public InterfaceTestImpl4(String str) {
+        this.stringField = str;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String str) {
+        this.stringField = str;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int i) {
+        this.intField = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseA.java
index 14247d4..3a92ab8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseA.java
@@ -1,118 +1,118 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "inverseA")
-public class InverseA {
-
-    @Column(length = 35)
-    private String stringField;
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int intField;
-    @Column(name = "oneone")
-    private InverseA oneOne;
-    @Column(name = "oneowner")
-    private InverseA oneOneOwner;
-    @Column(name = "onemany")
-    private InverseA oneMany;
-    private Set manyOne = new HashSet();
-    private Set manyMany = new HashSet();
-    private Set manyManyOwner = new HashSet();
-    private Set nullSet = null;
-    private InverseA nullOwner;
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public InverseA getOneOne() {
-        return oneOne;
-    }
-
-    public void setOneOne(InverseA a) {
-        oneOne = a;
-    }
-
-    public InverseA getOneOneOwner() {
-        return oneOneOwner;
-    }
-
-    public void setOneOneOwner(InverseA a) {
-        oneOneOwner = a;
-    }
-
-    public InverseA getOneMany() {
-        return oneMany;
-    }
-
-    public void setOneMany(InverseA a) {
-        oneMany = a;
-    }
-
-    public Set getManyOne() {
-        return manyOne;
-    }
-
-    public Set getManyMany() {
-        return manyMany;
-    }
-
-    public Set getManyManyOwner() {
-        return manyManyOwner;
-    }
-
-    public Set getNullSet() {
-        return nullSet;
-    }
-
-    public void setNullSet(Set s) {
-        nullSet = s;
-    }
-
-    public InverseA getNullOwner() {
-        return nullOwner;
-    }
-
-    public void setNullOwner(InverseA a) {
-        nullOwner = a;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "inverseA")
+public class InverseA {
+
+    @Column(length = 35)
+    private String stringField;
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int intField;
+    @Column(name = "oneone")
+    private InverseA oneOne;
+    @Column(name = "oneowner")
+    private InverseA oneOneOwner;
+    @Column(name = "onemany")
+    private InverseA oneMany;
+    private Set manyOne = new HashSet();
+    private Set manyMany = new HashSet();
+    private Set manyManyOwner = new HashSet();
+    private Set nullSet = null;
+    private InverseA nullOwner;
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public InverseA getOneOne() {
+        return oneOne;
+    }
+
+    public void setOneOne(InverseA a) {
+        oneOne = a;
+    }
+
+    public InverseA getOneOneOwner() {
+        return oneOneOwner;
+    }
+
+    public void setOneOneOwner(InverseA a) {
+        oneOneOwner = a;
+    }
+
+    public InverseA getOneMany() {
+        return oneMany;
+    }
+
+    public void setOneMany(InverseA a) {
+        oneMany = a;
+    }
+
+    public Set getManyOne() {
+        return manyOne;
+    }
+
+    public Set getManyMany() {
+        return manyMany;
+    }
+
+    public Set getManyManyOwner() {
+        return manyManyOwner;
+    }
+
+    public Set getNullSet() {
+        return nullSet;
+    }
+
+    public void setNullSet(Set s) {
+        nullSet = s;
+    }
+
+    public InverseA getNullOwner() {
+        return nullOwner;
+    }
+
+    public void setNullOwner(InverseA a) {
+        nullOwner = a;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseB.java
index 560a64d..ad9884e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/InverseB.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "inverseB")
-public class InverseB {
-
-    private String stringField;
-    private InverseB oneOne;
-    private Set manyMany = new HashSet();
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String s) {
-        stringField = s;
-    }
-
-    public InverseB getOneOne() {
-        return oneOne;
-    }
-
-    public void setOneOne(InverseB a) {
-        oneOne = a;
-    }
-
-    public Set getManyMany() {
-        return manyMany;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "inverseB")
+public class InverseB {
+
+    private String stringField;
+    private InverseB oneOne;
+    private Set manyMany = new HashSet();
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String s) {
+        stringField = s;
+    }
+
+    public InverseB getOneOne() {
+        return oneOne;
+    }
+
+    public void setOneOne(InverseB a) {
+        oneOne = a;
+    }
+
+    public Set getManyMany() {
+        return manyMany;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Lobs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Lobs.java
index 88da6c7..647be15 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Lobs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/Lobs.java
@@ -1,77 +1,77 @@
-/**
- *
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.Table;
-
-/**
- * @author aokeke
- */
-@Entity
-@Table(name = "lobs")
-public class Lobs implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @Lob
-    @Basic(fetch = FetchType.EAGER)
-    @Column(name = "report")
-    protected String lob = null;
-
-    @Id
-    public int id;
-
-    public Lobs() {
-    }
-
-    public Lobs(int key) {
-        id = key;
-    }
-
-    public Lobs(String report, int key) {
-        this.lob = report;
-        this.id = key;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getLob() {
-        return lob;
-    }
-
-    public void setLob(String lob) {
-        this.lob = lob;
-    }
-}
+/**
+ *
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+
+/**
+ * @author aokeke
+ */
+@Entity
+@Table(name = "lobs")
+public class Lobs implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Lob
+    @Basic(fetch = FetchType.EAGER)
+    @Column(name = "report")
+    protected String lob = null;
+
+    @Id
+    public int id;
+
+    public Lobs() {
+    }
+
+    public Lobs(int key) {
+        id = key;
+    }
+
+    public Lobs(String report, int key) {
+        this.lob = report;
+        this.id = key;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getLob() {
+        return lob;
+    }
+
+    public void setLob(String lob) {
+        this.lob = lob;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC.java
index adf8f74..dd0db4d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-
-@Entity
-public class LockGroupPC
-    implements Serializable {
-
-    @Column(name = "DEF_LockGSF")
-    private String defaultLockGroupStringField;
-    @Column(name = "EXDEF_LockGIF")
-    private int explicitDefaultLockGroupIntField;
-
-    @Column(name = "LockGIF")
-    private int lockGroup0IntField;
-    @Column(name = "LockGSF")
-    private String lockGroup0StringField;
-
-    @Column(name = "LockGRF")
-    private transient RuntimeTest1 lockGroup1RelationField;
-    @Column(name = "LGF")
-    private int lockGroup1IntField;
-
-    @Column(name = "UNLS")
-    private String unlockedStringField;
-
-    public void setDefaultLockGroupStringField(String val) {
-        defaultLockGroupStringField = val;
-    }
-
-    public String getDefaultLockGroupStringField() {
-        return defaultLockGroupStringField;
-    }
-
-    public void setExplicitDefaultLockGroupIntField(int val) {
-        explicitDefaultLockGroupIntField = val;
-    }
-
-    public int getExplicitDefaultLockGroupIntField() {
-        return explicitDefaultLockGroupIntField;
-    }
-
-    public void setLockGroup0IntField(int val) {
-        lockGroup0IntField = val;
-    }
-
-    public int getLockGroup0IntField() {
-        return lockGroup0IntField;
-    }
-
-    public void setLockGroup0StringField(String val) {
-        lockGroup0StringField = val;
-    }
-
-    public String getLockGroup0StringField() {
-        return lockGroup0StringField;
-    }
-
-    public void setLockGroup1RelationField(RuntimeTest1 val) {
-        lockGroup1RelationField = val;
-    }
-
-    public RuntimeTest1 getLockGroup1RelationField() {
-        return lockGroup1RelationField;
-    }
-
-    public void setLockGroup1IntField(int val) {
-        lockGroup1IntField = val;
-    }
-
-    public int getLockGroup1IntField() {
-        return lockGroup1IntField;
-    }
-
-    public void setUnlockedStringField(String val) {
-        unlockedStringField = val;
-    }
-
-    public String getUnlockedStringField() {
-        return unlockedStringField;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+
+@Entity
+public class LockGroupPC
+    implements Serializable {
+
+    @Column(name = "DEF_LockGSF")
+    private String defaultLockGroupStringField;
+    @Column(name = "EXDEF_LockGIF")
+    private int explicitDefaultLockGroupIntField;
+
+    @Column(name = "LockGIF")
+    private int lockGroup0IntField;
+    @Column(name = "LockGSF")
+    private String lockGroup0StringField;
+
+    @Column(name = "LockGRF")
+    private transient RuntimeTest1 lockGroup1RelationField;
+    @Column(name = "LGF")
+    private int lockGroup1IntField;
+
+    @Column(name = "UNLS")
+    private String unlockedStringField;
+
+    public void setDefaultLockGroupStringField(String val) {
+        defaultLockGroupStringField = val;
+    }
+
+    public String getDefaultLockGroupStringField() {
+        return defaultLockGroupStringField;
+    }
+
+    public void setExplicitDefaultLockGroupIntField(int val) {
+        explicitDefaultLockGroupIntField = val;
+    }
+
+    public int getExplicitDefaultLockGroupIntField() {
+        return explicitDefaultLockGroupIntField;
+    }
+
+    public void setLockGroup0IntField(int val) {
+        lockGroup0IntField = val;
+    }
+
+    public int getLockGroup0IntField() {
+        return lockGroup0IntField;
+    }
+
+    public void setLockGroup0StringField(String val) {
+        lockGroup0StringField = val;
+    }
+
+    public String getLockGroup0StringField() {
+        return lockGroup0StringField;
+    }
+
+    public void setLockGroup1RelationField(RuntimeTest1 val) {
+        lockGroup1RelationField = val;
+    }
+
+    public RuntimeTest1 getLockGroup1RelationField() {
+        return lockGroup1RelationField;
+    }
+
+    public void setLockGroup1IntField(int val) {
+        lockGroup1IntField = val;
+    }
+
+    public int getLockGroup1IntField() {
+        return lockGroup1IntField;
+    }
+
+    public void setUnlockedStringField(String val) {
+        unlockedStringField = val;
+    }
+
+    public String getUnlockedStringField() {
+        return unlockedStringField;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC2.java
index f1b6a30..a293740 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPC2.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Entity;
-
-/**
- * <p>Used to test lock-group="none" in isolation.</p>
- *
- * @author Abe White
- */
-@Entity
-public class LockGroupPC2 {
-
-    private String name;
-    private List list = new ArrayList();
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public List getList() {
-        return this.list;
-    }
-
-    public void setList(List list) {
-        this.list = list;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+
+/**
+ * <p>Used to test lock-group="none" in isolation.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class LockGroupPC2 {
+
+    private String name;
+    private List list = new ArrayList();
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List getList() {
+        return this.list;
+    }
+
+    public void setList(List list) {
+        this.list = list;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPCKnownSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPCKnownSubclass.java
index 47dfb15..f193df3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPCKnownSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/LockGroupPCKnownSubclass.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class LockGroupPCKnownSubclass
-    extends LockGroupPC {
-
-    private String knownSubclassStringField;
-
-    public void setKnownSubclassStringField(String knownSubclassStringField) {
-        this.knownSubclassStringField = knownSubclassStringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class LockGroupPCKnownSubclass
+    extends LockGroupPC {
+
+    private String knownSubclassStringField;
+
+    public void setKnownSubclassStringField(String knownSubclassStringField) {
+        this.knownSubclassStringField = knownSubclassStringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterface.java
index 3be85ef..7b700b5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterface.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.Set;
-
-public interface ManagedInterface extends ManagedInterfaceSup {
-
-    public int getIntField();
-
-    public void setIntField(int i);
-
-    public ManagedInterfaceEmbed getEmbed();
-
-    public void setEmbed(ManagedInterfaceEmbed embed);
-
-    public ManagedInterface getSelf();
-
-    public void setSelf(ManagedInterface iface);
-
-    public Set getSetInteger();
-
-    public void setSetInteger(Set collection);
-
-    public Set getSetPC();
-
-    public void setSetPC(Set collection);
-
-    public Set getSetI();
-
-    public void setSetI(Set collection);
-
-    public RuntimeTest1 getPC();
-
-    public void setPC(RuntimeTest1 pc);
-
-    public void unimplemented();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.Set;
+
+public interface ManagedInterface extends ManagedInterfaceSup {
+
+    public int getIntField();
+
+    public void setIntField(int i);
+
+    public ManagedInterfaceEmbed getEmbed();
+
+    public void setEmbed(ManagedInterfaceEmbed embed);
+
+    public ManagedInterface getSelf();
+
+    public void setSelf(ManagedInterface iface);
+
+    public Set getSetInteger();
+
+    public void setSetInteger(Set collection);
+
+    public Set getSetPC();
+
+    public void setSetPC(Set collection);
+
+    public Set getSetI();
+
+    public void setSetI(Set collection);
+
+    public RuntimeTest1 getPC();
+
+    public void setPC(RuntimeTest1 pc);
+
+    public void unimplemented();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceAppId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceAppId.java
index 9e83e4e..dfc5806 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceAppId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceAppId.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.Set;
-
-public interface ManagedInterfaceAppId extends ManagedInterfaceSupAppId {
-
-    public int getIntField();
-
-    public void setIntField(int i);
-
-    public ManagedInterfaceEmbed getEmbed();
-
-    public void setEmbed(ManagedInterfaceEmbed embed);
-
-    public ManagedInterfaceAppId getSelf();
-
-    public void setSelf(ManagedInterfaceAppId iface);
-
-    public Set getSetInteger();
-
-    public void setSetInteger(Set collection);
-
-    public Set getSetPC();
-
-    public void setSetPC(Set collection);
-
-    public Set getSetI();
-
-    public void setSetI(Set collection);
-
-    public RuntimeTest1 getPC();
-
-    public void setPC(RuntimeTest1 pc);
-
-    public void unimplemented();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.Set;
+
+public interface ManagedInterfaceAppId extends ManagedInterfaceSupAppId {
+
+    public int getIntField();
+
+    public void setIntField(int i);
+
+    public ManagedInterfaceEmbed getEmbed();
+
+    public void setEmbed(ManagedInterfaceEmbed embed);
+
+    public ManagedInterfaceAppId getSelf();
+
+    public void setSelf(ManagedInterfaceAppId iface);
+
+    public Set getSetInteger();
+
+    public void setSetInteger(Set collection);
+
+    public Set getSetPC();
+
+    public void setSetPC(Set collection);
+
+    public Set getSetI();
+
+    public void setSetI(Set collection);
+
+    public RuntimeTest1 getPC();
+
+    public void setPC(RuntimeTest1 pc);
+
+    public void unimplemented();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceEmbed.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceEmbed.java
index c1324de..3061c8b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceEmbed.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceEmbed.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-public interface ManagedInterfaceEmbed {
-
-    public int getIntField();
-
-    public void setIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+public interface ManagedInterfaceEmbed {
+
+    public int getIntField();
+
+    public void setIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwner.java
index c673ca8..d31da31 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwner.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ManagedInterfaceOwner {
-
-    private int intField;
-    private ManagedInterfaceSup iface;
-    private ManagedInterfaceEmbed embed;
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public ManagedInterfaceSup getIFace() {
-        return iface;
-    }
-
-    public void setIFace(ManagedInterfaceSup iface) {
-        this.iface = iface;
-    }
-
-    public ManagedInterfaceEmbed getEmbed() {
-        return embed;
-    }
-
-    public void setEmbed(ManagedInterfaceEmbed embed) {
-        this.embed = embed;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ManagedInterfaceOwner {
+
+    private int intField;
+    private ManagedInterfaceSup iface;
+    private ManagedInterfaceEmbed embed;
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public ManagedInterfaceSup getIFace() {
+        return iface;
+    }
+
+    public void setIFace(ManagedInterfaceSup iface) {
+        this.iface = iface;
+    }
+
+    public ManagedInterfaceEmbed getEmbed() {
+        return embed;
+    }
+
+    public void setEmbed(ManagedInterfaceEmbed embed) {
+        this.embed = embed;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwnerAppId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwnerAppId.java
index 731052b..3c1c395 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwnerAppId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceOwnerAppId.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ManagedInterfaceOwnerAppId {
-
-    private int intField;
-    private ManagedInterfaceSupAppId iface;
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public ManagedInterfaceSupAppId getIFace() {
-        return iface;
-    }
-
-    public void setIFace(ManagedInterfaceSupAppId iface) {
-        this.iface = iface;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ManagedInterfaceOwnerAppId {
+
+    private int intField;
+    private ManagedInterfaceSupAppId iface;
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public ManagedInterfaceSupAppId getIFace() {
+        return iface;
+    }
+
+    public void setIFace(ManagedInterfaceSupAppId iface) {
+        this.iface = iface;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSup.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSup.java
index 79ae0c8..2f53e63 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSup.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSup.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-public interface ManagedInterfaceSup {
-
-    public int getIntFieldSup();
-
-    public void setIntFieldSup(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+public interface ManagedInterfaceSup {
+
+    public int getIntFieldSup();
+
+    public void setIntFieldSup(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSupAppId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSupAppId.java
index 910f182..8081aeb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSupAppId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ManagedInterfaceSupAppId.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.StringTokenizer;
-
-public interface ManagedInterfaceSupAppId {
-
-    public int getId1();
-
-    public void setId1(int i);
-
-    public int getId2();
-
-    public void setId2(int i);
-
-    public int getIntFieldSup();
-
-    public void setIntFieldSup(int i);
-
-    public static class Id implements java.io.Serializable {
-
-        public int id1;
-        public int id2;
-
-        public Id() {
-        }
-
-        public Id(String str) {
-            StringTokenizer tok = new StringTokenizer(str, ",");
-            id1 = Integer.parseInt(tok.nextToken());
-            id2 = Integer.parseInt(tok.nextToken());
-        }
-
-        public String toString() {
-            return id1 + "," + id2;
-        }
-
-        public int hashCode() {
-            return id1 + id2;
-        }
-
-        public boolean equals(Object o) {
-            if (!(o instanceof Id))
-                return false;
-            Id other = (Id) o;
-            return id1 == other.id1 && id2 == other.id2;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.StringTokenizer;
+
+public interface ManagedInterfaceSupAppId {
+
+    public int getId1();
+
+    public void setId1(int i);
+
+    public int getId2();
+
+    public void setId2(int i);
+
+    public int getIntFieldSup();
+
+    public void setIntFieldSup(int i);
+
+    public static class Id implements java.io.Serializable {
+
+        public int id1;
+        public int id2;
+
+        public Id() {
+        }
+
+        public Id(String str) {
+            StringTokenizer tok = new StringTokenizer(str, ",");
+            id1 = Integer.parseInt(tok.nextToken());
+            id2 = Integer.parseInt(tok.nextToken());
+        }
+
+        public String toString() {
+            return id1 + "," + id2;
+        }
+
+        public int hashCode() {
+            return id1 + id2;
+        }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof Id))
+                return false;
+            Id other = (Id) o;
+            return id1 == other.id1 && id2 == other.id2;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementIntf.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementIntf.java
index 9e29bd7..ff32fd6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementIntf.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementIntf.java
@@ -1,24 +1,24 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-public interface MapElementIntf {
-
-    public String getElementData();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+public interface MapElementIntf {
+
+    public String getElementData();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPC.java
index 07b1f81..fb26d26 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPC.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-@Entity
-public class MapElementPC
-    implements MapElementIntf {
-
-    private String elementData = AbstractTestCase.randomString();
-
-    public void setElementData(String elementData) {
-        this.elementData = elementData;
-    }
-
-    public String getElementData() {
-        return this.elementData;
-    }
-
-    public int hashCode() {
-        return elementData.hashCode();
-    }
-
-    public boolean equals(Object other) {
-        return ((MapElementPC) other).elementData.equals(elementData);
-    }
-
-    public String toString() {
-        return super.toString() + "::" + elementData;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+@Entity
+public class MapElementPC
+    implements MapElementIntf {
+
+    private String elementData = AbstractTestCase.randomString();
+
+    public void setElementData(String elementData) {
+        this.elementData = elementData;
+    }
+
+    public String getElementData() {
+        return this.elementData;
+    }
+
+    public int hashCode() {
+        return elementData.hashCode();
+    }
+
+    public boolean equals(Object other) {
+        return ((MapElementPC) other).elementData.equals(elementData);
+    }
+
+    public String toString() {
+        return super.toString() + "::" + elementData;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPCChild.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPCChild.java
index 682c40b..32d9eb5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPCChild.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MapElementPCChild.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-
-@Entity
-public class MapElementPCChild
-    extends MapElementPC {
-
-    private String elementDataChild = AbstractTestCase.randomString();
-
-    public void setElementDataChild(String elementDataChild) {
-        this.elementDataChild = elementDataChild;
-    }
-
-    public String getElementDataChild() {
-        return this.elementDataChild;
-    }
-
-    public int hashCode() {
-        return (super.hashCode() + elementDataChild.hashCode())
-            % Integer.MAX_VALUE;
-    }
-
-    public boolean equals(Object other) {
-        return super.equals(other) &&
-            ((MapElementPCChild) other)
-                .elementDataChild.equals(elementDataChild);
-    }
-
-    public String toString() {
-        return super.toString() + "::" + elementDataChild;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+@Entity
+public class MapElementPCChild
+    extends MapElementPC {
+
+    private String elementDataChild = AbstractTestCase.randomString();
+
+    public void setElementDataChild(String elementDataChild) {
+        this.elementDataChild = elementDataChild;
+    }
+
+    public String getElementDataChild() {
+        return this.elementDataChild;
+    }
+
+    public int hashCode() {
+        return (super.hashCode() + elementDataChild.hashCode())
+            % Integer.MAX_VALUE;
+    }
+
+    public boolean equals(Object other) {
+        return super.equals(other) &&
+            ((MapElementPCChild) other)
+                .elementDataChild.equals(elementDataChild);
+    }
+
+    public String toString() {
+        return super.toString() + "::" + elementDataChild;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterface.java
index 9738e23..b4eb8dc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterface.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-public interface MixedInterface {
-
-    public int getIntField();
-
-    public void setIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+public interface MixedInterface {
+
+    public int getIntField();
+
+    public void setIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterfaceImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterfaceImpl.java
index e482cfa..4ad85ad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterfaceImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/MixedInterfaceImpl.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class MixedInterfaceImpl implements MixedInterface {
-
-    private int intField;
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class MixedInterfaceImpl implements MixedInterface {
+
+    private int intField;
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModInstanceCallbackTests.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModInstanceCallbackTests.java
index 8549a8d..cc728c5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModInstanceCallbackTests.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModInstanceCallbackTests.java
@@ -1,187 +1,187 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.PostLoad;
-import javax.persistence.PrePersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PreUpdate;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-@Table(name = "modicbt")
-public class ModInstanceCallbackTests {
-
-    public static long preDeleteInvocations = 0;
-    public static long postLoadInvocations = 0;
-    public static long preStoreInvocations = 0;
-    public static long preClearInvocations = 0;
-
-    public transient boolean postLoadCalled = false;
-    public transient boolean preStoreCalled = false;
-    public transient boolean preDeleteCalled = false;
-    public transient boolean preClearCalled = false;
-
-    public transient int preDeleteCycle = -1;
-    public transient boolean flushInPreStore = false;
-
-    // this string should never be null in jdoPostLoad
-    @Column(length = 35)
-    private String nonNullString = null;
-
-    @Column(length = 35)
-    private String stringField = null;
-    @Basic
-    private int intField = 0;
-    @Basic
-    private int nonDFGField = 0;
-
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ModRuntimeTest1 oneOne = null;
-
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ModInstanceCallbackTests rel;
-    private transient Object relId;
-
-    public ModInstanceCallbackTests() {
-    }
-
-    public ModInstanceCallbackTests(String stringField, int intField) {
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public void setNonNullString(String val) {
-        nonNullString = val;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public int getNonDFGField() {
-        return this.nonDFGField;
-    }
-
-    public void setNonDFGField(int nonDFGField) {
-        this.nonDFGField = nonDFGField;
-    }
-
-    public ModRuntimeTest1 getOneOne() {
-        return this.oneOne;
-    }
-
-    public void setOneOne(ModRuntimeTest1 oneOne) {
-        this.oneOne = oneOne;
-    }
-
-    @PostLoad
-    public void jdoPostLoad() {
-        postLoadInvocations++;
-
-        postLoadCalled = true;
-        if (nonNullString == null)
-            throw new IllegalStateException();
-    }
-
-    public void jdoPreClear() {
-        preClearInvocations++;
-
-        preClearCalled = true;
-    }
-
-    @PrePersist
-    @PreUpdate
-    public void jdoPreStore() {
-        preStoreInvocations++;
-
-        preStoreCalled = true;
-
-        // ensure that whenever this object is persisted,
-        // nonNullString is, in fact, not null.
-        if (nonNullString == null)
-            nonNullString = "** this string is not null **";
-
-        // assign new value to relation; should get persisted
-        if ("bar".equals(stringField))
-            oneOne = new ModRuntimeTest1("jdoPreStore", 100);
-        if (relId != null) {
-            ModInstanceCallbackTests rel = (ModInstanceCallbackTests)
-                OpenJPAPersistence.getEntityManager(this)
-                    .find(ModInstanceCallbackTests.class, relId);
-            rel.setRel(this);
-            rel.setIntField(8888);
-        }
-
-        if (flushInPreStore) {
-            OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(this);
-            if (pm != null)
-                pm.flush();
-        }
-    }
-
-    @PreRemove
-    public void jdoPreDelete() {
-        preDeleteInvocations++;
-        preDeleteCalled = true;
-        if (preDeleteCycle >= 0 && preDeleteCycle < 5) {
-            preDeleteCycle++;
-            OpenJPAPersistence.getEntityManager(this).remove(this);
-        }
-    }
-
-    public ModInstanceCallbackTests getRel() {
-        return this.rel;
-    }
-
-    public void setRel(ModInstanceCallbackTests rel) {
-        this.rel = rel;
-    }
-
-    public Object getRelId() {
-        return this.relId;
-    }
-
-    public void setRelId(Object relId) {
-        this.relId = relId;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.PostLoad;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+@Table(name = "modicbt")
+public class ModInstanceCallbackTests {
+
+    public static long preDeleteInvocations = 0;
+    public static long postLoadInvocations = 0;
+    public static long preStoreInvocations = 0;
+    public static long preClearInvocations = 0;
+
+    public transient boolean postLoadCalled = false;
+    public transient boolean preStoreCalled = false;
+    public transient boolean preDeleteCalled = false;
+    public transient boolean preClearCalled = false;
+
+    public transient int preDeleteCycle = -1;
+    public transient boolean flushInPreStore = false;
+
+    // this string should never be null in jdoPostLoad
+    @Column(length = 35)
+    private String nonNullString = null;
+
+    @Column(length = 35)
+    private String stringField = null;
+    @Basic
+    private int intField = 0;
+    @Basic
+    private int nonDFGField = 0;
+
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ModRuntimeTest1 oneOne = null;
+
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ModInstanceCallbackTests rel;
+    private transient Object relId;
+
+    public ModInstanceCallbackTests() {
+    }
+
+    public ModInstanceCallbackTests(String stringField, int intField) {
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public void setNonNullString(String val) {
+        nonNullString = val;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public int getNonDFGField() {
+        return this.nonDFGField;
+    }
+
+    public void setNonDFGField(int nonDFGField) {
+        this.nonDFGField = nonDFGField;
+    }
+
+    public ModRuntimeTest1 getOneOne() {
+        return this.oneOne;
+    }
+
+    public void setOneOne(ModRuntimeTest1 oneOne) {
+        this.oneOne = oneOne;
+    }
+
+    @PostLoad
+    public void jdoPostLoad() {
+        postLoadInvocations++;
+
+        postLoadCalled = true;
+        if (nonNullString == null)
+            throw new IllegalStateException();
+    }
+
+    public void jdoPreClear() {
+        preClearInvocations++;
+
+        preClearCalled = true;
+    }
+
+    @PrePersist
+    @PreUpdate
+    public void jdoPreStore() {
+        preStoreInvocations++;
+
+        preStoreCalled = true;
+
+        // ensure that whenever this object is persisted,
+        // nonNullString is, in fact, not null.
+        if (nonNullString == null)
+            nonNullString = "** this string is not null **";
+
+        // assign new value to relation; should get persisted
+        if ("bar".equals(stringField))
+            oneOne = new ModRuntimeTest1("jdoPreStore", 100);
+        if (relId != null) {
+            ModInstanceCallbackTests rel = (ModInstanceCallbackTests)
+                OpenJPAPersistence.getEntityManager(this)
+                    .find(ModInstanceCallbackTests.class, relId);
+            rel.setRel(this);
+            rel.setIntField(8888);
+        }
+
+        if (flushInPreStore) {
+            OpenJPAEntityManager pm = OpenJPAPersistence.getEntityManager(this);
+            if (pm != null)
+                pm.flush();
+        }
+    }
+
+    @PreRemove
+    public void jdoPreDelete() {
+        preDeleteInvocations++;
+        preDeleteCalled = true;
+        if (preDeleteCycle >= 0 && preDeleteCycle < 5) {
+            preDeleteCycle++;
+            OpenJPAPersistence.getEntityManager(this).remove(this);
+        }
+    }
+
+    public ModInstanceCallbackTests getRel() {
+        return this.rel;
+    }
+
+    public void setRel(ModInstanceCallbackTests rel) {
+        this.rel = rel;
+    }
+
+    public Object getRelId() {
+        return this.relId;
+    }
+
+    public void setRelId(Object relId) {
+        this.relId = relId;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest1.java
index 701c8bf..edbf318 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest1.java
@@ -1,122 +1,122 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-@Entity
-@Table(name = "Modrtest1")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class ModRuntimeTest1 {
-
-    private static final long serialVersionUID = 1L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    public int id;
-
-    @Transient
-    public static final String someStaticField = "someField";
-
-    private Locale localeField;
-
-    private int intField;
-
-    @Column(length = 35)
-    private String stringField;
-
-    @Column(length = 35)
-    public String transString;
-
-    @ManyToOne(cascade = { CascadeType.PERSIST })
-    private ModRuntimeTest1 selfOneOne;
-
-    @OneToMany(cascade = { CascadeType.PERSIST })
-    private Set<ModRuntimeTest1> selfOneMany = new HashSet<ModRuntimeTest1>();
-
-    public ModRuntimeTest1() {
-    }
-
-    public ModRuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public ModRuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(ModRuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-
-    public String toString() {
-        return "IntField: " + intField + ", StringField: " + stringField + " .";
-    }
-
-    public Locale getLocaleField() {
-        return localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+@Entity
+@Table(name = "Modrtest1")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class ModRuntimeTest1 {
+
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    public int id;
+
+    @Transient
+    public static final String someStaticField = "someField";
+
+    private Locale localeField;
+
+    private int intField;
+
+    @Column(length = 35)
+    private String stringField;
+
+    @Column(length = 35)
+    public String transString;
+
+    @ManyToOne(cascade = { CascadeType.PERSIST })
+    private ModRuntimeTest1 selfOneOne;
+
+    @OneToMany(cascade = { CascadeType.PERSIST })
+    private Set<ModRuntimeTest1> selfOneMany = new HashSet<ModRuntimeTest1>();
+
+    public ModRuntimeTest1() {
+    }
+
+    public ModRuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public ModRuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(ModRuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+
+    public String toString() {
+        return "IntField: " + intField + ", StringField: " + stringField + " .";
+    }
+
+    public Locale getLocaleField() {
+        return localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest2.java
index 1f7c910..8584018 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ModRuntimeTest2.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity
-@DiscriminatorValue("ModRT2")
-public class ModRuntimeTest2 extends ModRuntimeTest1 {
-
-    private static final long serialVersionUID = 1L;
-
-    private int intField2;
-
-    public ModRuntimeTest2() {
-    }
-
-    public ModRuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-
-    public String toString() {
-        return "IntField: " + intField2 + ", StringField: "
-            + super.getStringField() + " .";
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("ModRT2")
+public class ModRuntimeTest2 extends ModRuntimeTest1 {
+
+    private static final long serialVersionUID = 1L;
+
+    private int intField2;
+
+    public ModRuntimeTest2() {
+    }
+
+    public ModRuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+
+    public String toString() {
+        return "IntField: " + intField2 + ", StringField: "
+            + super.getStringField() + " .";
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterface.java
index e112338..ccc608c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterface.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-public interface NonMappedInterface {
-
-    public int getIntField();
-
-    public void setIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+public interface NonMappedInterface {
+
+    public int getIntField();
+
+    public void setIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterfaceImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterfaceImpl.java
index d7b1014..df36694 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterfaceImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/NonMappedInterfaceImpl.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class NonMappedInterfaceImpl
-    implements NonMappedInterface {
-
-    private int mismatch;
-
-    public int getIntField() {
-        return mismatch;
-    }
-
-    public void setIntField(int i) {
-        mismatch = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class NonMappedInterfaceImpl
+    implements NonMappedInterface {
+
+    private int mismatch;
+
+    public int getIntField() {
+        return mismatch;
+    }
+
+    public void setIntField(int i) {
+        mismatch = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ObjectCollectionHolder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ObjectCollectionHolder.java
index 2a93b1f..29074c6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ObjectCollectionHolder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ObjectCollectionHolder.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "objchol")
-public class ObjectCollectionHolder {
-
-    @Id
-    private int id;
-    private HashSet hashSet = new HashSet();
-
-    public void setHashSet(HashSet hashSet) {
-        this.hashSet = hashSet;
-    }
-
-    public HashSet getHashSet() {
-        return this.hashSet;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void addToHashSet(Object ob) {
-        getHashSet().add(ob);
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "objchol")
+public class ObjectCollectionHolder {
+
+    @Id
+    private int id;
+    private HashSet hashSet = new HashSet();
+
+    public void setHashSet(HashSet hashSet) {
+        this.hashSet = hashSet;
+    }
+
+    public HashSet getHashSet() {
+        return this.hashSet;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void addToHashSet(Object ob) {
+        getHashSet().add(ob);
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/OuterJoinValuePC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/OuterJoinValuePC.java
index ca4a3dd..d15a2ed 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/OuterJoinValuePC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/OuterJoinValuePC.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "outerjvp")
-public class OuterJoinValuePC {
-
-    private String stringField;
-    private int value1;
-    private int value2;
-
-    private int id;
-
-    public OuterJoinValuePC() {
-    }
-
-    public OuterJoinValuePC(int id) {
-        this.id = id;
-    }
-
-    @Column(length = 50)
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public int getValue1() {
-        return this.value1;
-    }
-
-    public void setValue1(int value1) {
-        this.value1 = value1;
-    }
-
-    public int getValue2() {
-        return this.value2;
-    }
-
-    public void setValue2(int value2) {
-        this.value2 = value2;
-    }
-
-    @Id
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "outerjvp")
+public class OuterJoinValuePC {
+
+    private String stringField;
+    private int value1;
+    private int value2;
+
+    private int id;
+
+    public OuterJoinValuePC() {
+    }
+
+    public OuterJoinValuePC(int id) {
+        this.id = id;
+    }
+
+    @Column(length = 50)
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public int getValue1() {
+        return this.value1;
+    }
+
+    public void setValue1(int value1) {
+        this.value1 = value1;
+    }
+
+    public int getValue2() {
+        return this.value2;
+    }
+
+    public void setValue2(int value2) {
+        this.value2 = value2;
+    }
+
+    @Id
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCAddress.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCAddress.java
index e0286c8..cecb808 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCAddress.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCAddress.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-@FetchGroup(name = "address.country",
-    attributes = @FetchAttribute(name = "country"))
-public class PCAddress {
-
-    private String street;
-    private String city;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCCountry country;
-
-    protected PCAddress() {
-        super();
-    }
-
-    public PCAddress(String street, String city, PCCountry country) {
-        setStreet(street);
-        setCity(city);
-        setCountry(country);
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public PCCountry getCountry() {
-        return country;
-    }
-
-    public void setCountry(PCCountry country) {
-        this.country = country;
-    }
-
-    public String getStreet() {
-        return street;
-    }
-
-    public void setStreet(String street) {
-        this.street = street;
-    }
-
-    public static Object reflect(PCAddress instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCAddress.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+@FetchGroup(name = "address.country",
+    attributes = @FetchAttribute(name = "country"))
+public class PCAddress {
+
+    private String street;
+    private String city;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCCountry country;
+
+    protected PCAddress() {
+        super();
+    }
+
+    public PCAddress(String street, String city, PCCountry country) {
+        setStreet(street);
+        setCity(city);
+        setCountry(country);
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public PCCountry getCountry() {
+        return country;
+    }
+
+    public void setCountry(PCCountry country) {
+        this.country = country;
+    }
+
+    public String getStreet() {
+        return street;
+    }
+
+    public void setStreet(String street) {
+        this.street = street;
+    }
+
+    public static Object reflect(PCAddress instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCAddress.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassInterface.java
index 8e8e9d2..e407d24 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassInterface.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * <p>Interface used with {@link PCClassPC} in testing.</p>
- *
- * @author Abe White
- */
-public interface PCClassInterface {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * <p>Interface used with {@link PCClassPC} in testing.</p>
+ *
+ * @author Abe White
+ */
+public interface PCClassInterface {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassPC.java
index 79bd501..0f29767 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCClassPC.java
@@ -1,116 +1,116 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.Persistent;
-import org.apache.openjpa.persistence.Type;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-public class PCClassPC
-    implements PCClassInterface, Serializable {
-
-    @Persistent
-    @Type(PCClassPC.class)
-    private Object specificPC;
-
-    @Persistent
-    @Type(Entity.class)
-    private Object genericPC;
-
-    @Persistent
-    private Object genericObject;
-
-    @Persistent
-    @Type(PCClassPC.class)
-    private PCClassInterface specificInterface;
-
-    @Persistent
-    private PCClassInterface defaultInterface;
-
-    @Persistent
-    private Serializable serializableInterface;
-
-    @Persistent
-    @Type(Object.class)
-    private PCClassInterface genericInterface;
-
-    public Object getSpecificPC() {
-        return this.specificPC;
-    }
-
-    public void setSpecificPC(Object specificPC) {
-        this.specificPC = specificPC;
-    }
-
-    public Object getGenericPC() {
-        return this.genericPC;
-    }
-
-    public void setGenericPC(Object genericPC) {
-        this.genericPC = genericPC;
-    }
-
-    public Object getGenericObject() {
-        return this.genericObject;
-    }
-
-    public void setGenericObject(Object genericObject) {
-        this.genericObject = genericObject;
-    }
-
-    public PCClassInterface getSpecificInterface() {
-        return this.specificInterface;
-    }
-
-    public void setSpecificInterface(PCClassInterface specificInterface) {
-        this.specificInterface = specificInterface;
-    }
-
-    public PCClassInterface getDefaultInterface() {
-        return this.defaultInterface;
-    }
-
-    public void setDefaultInterface(PCClassInterface defaultInterface) {
-        this.defaultInterface = defaultInterface;
-    }
-
-    public Serializable getSerializableInterface() {
-        return this.serializableInterface;
-    }
-
-    public void setSerializableInterface(Serializable serializableInterface) {
-        this.serializableInterface = serializableInterface;
-    }
-
-    public PCClassInterface getGenericInterface() {
-        return this.genericInterface;
-    }
-
-    public void setGenericInterface(PCClassInterface genericInterface) {
-        this.genericInterface = genericInterface;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.Persistent;
+import org.apache.openjpa.persistence.Type;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class PCClassPC
+    implements PCClassInterface, Serializable {
+
+    @Persistent
+    @Type(PCClassPC.class)
+    private Object specificPC;
+
+    @Persistent
+    @Type(Entity.class)
+    private Object genericPC;
+
+    @Persistent
+    private Object genericObject;
+
+    @Persistent
+    @Type(PCClassPC.class)
+    private PCClassInterface specificInterface;
+
+    @Persistent
+    private PCClassInterface defaultInterface;
+
+    @Persistent
+    private Serializable serializableInterface;
+
+    @Persistent
+    @Type(Object.class)
+    private PCClassInterface genericInterface;
+
+    public Object getSpecificPC() {
+        return this.specificPC;
+    }
+
+    public void setSpecificPC(Object specificPC) {
+        this.specificPC = specificPC;
+    }
+
+    public Object getGenericPC() {
+        return this.genericPC;
+    }
+
+    public void setGenericPC(Object genericPC) {
+        this.genericPC = genericPC;
+    }
+
+    public Object getGenericObject() {
+        return this.genericObject;
+    }
+
+    public void setGenericObject(Object genericObject) {
+        this.genericObject = genericObject;
+    }
+
+    public PCClassInterface getSpecificInterface() {
+        return this.specificInterface;
+    }
+
+    public void setSpecificInterface(PCClassInterface specificInterface) {
+        this.specificInterface = specificInterface;
+    }
+
+    public PCClassInterface getDefaultInterface() {
+        return this.defaultInterface;
+    }
+
+    public void setDefaultInterface(PCClassInterface defaultInterface) {
+        this.defaultInterface = defaultInterface;
+    }
+
+    public Serializable getSerializableInterface() {
+        return this.serializableInterface;
+    }
+
+    public void setSerializableInterface(Serializable serializableInterface) {
+        this.serializableInterface = serializableInterface;
+    }
+
+    public PCClassInterface getGenericInterface() {
+        return this.genericInterface;
+    }
+
+    public void setGenericInterface(PCClassInterface genericInterface) {
+        this.genericInterface = genericInterface;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCompany.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCompany.java
index 9c48120..03a2e8b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCompany.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCompany.java
@@ -1,119 +1,119 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-@FetchGroups({
-@FetchGroup(name = "company.address",
-    attributes = @FetchAttribute(name = "address")),
-@FetchGroup(name = "company.departments",
-    attributes = @FetchAttribute(name = "departments")),
-@FetchGroup(name = "default", postLoad = false,
-    attributes = @FetchAttribute(name = "name"))
-    })
-public class PCCompany {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    private String name;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCAddress address;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    private Set<PCDepartment> departments;
-
-    public PCCompany() {
-        super();
-    }
-
-    public PCCompany(String name) {
-        super();
-        setName(name);
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public PCAddress getAddress() {
-        return address;
-    }
-
-    public void setAddress(PCAddress address) {
-        this.address = address;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Set getDepartments() {
-        return departments;
-    }
-
-    public void setDepartments(Set departments) {
-        this.departments = departments;
-    }
-
-    public void addDepartment(PCDepartment dept) {
-        if (departments == null)
-            departments = new HashSet();
-        departments.add(dept);
-        dept.setCompany(this);
-    }
-
-    public boolean contains(PCDepartment dept) {
-        return departments != null && departments.contains(dept);
-    }
-
-    public static Object reflect(PCCompany instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCCompany.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+@FetchGroups({
+@FetchGroup(name = "company.address",
+    attributes = @FetchAttribute(name = "address")),
+@FetchGroup(name = "company.departments",
+    attributes = @FetchAttribute(name = "departments")),
+@FetchGroup(name = "default", postLoad = false,
+    attributes = @FetchAttribute(name = "name"))
+    })
+public class PCCompany {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    private String name;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCAddress address;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    private Set<PCDepartment> departments;
+
+    public PCCompany() {
+        super();
+    }
+
+    public PCCompany(String name) {
+        super();
+        setName(name);
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public PCAddress getAddress() {
+        return address;
+    }
+
+    public void setAddress(PCAddress address) {
+        this.address = address;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Set getDepartments() {
+        return departments;
+    }
+
+    public void setDepartments(Set departments) {
+        this.departments = departments;
+    }
+
+    public void addDepartment(PCDepartment dept) {
+        if (departments == null)
+            departments = new HashSet();
+        departments.add(dept);
+        dept.setCompany(this);
+    }
+
+    public boolean contains(PCDepartment dept) {
+        return departments != null && departments.contains(dept);
+    }
+
+    public static Object reflect(PCCompany instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCCompany.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCountry.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCountry.java
index fc37206..ed9f91f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCountry.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCCountry.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-public class PCCountry {
-
-    private String code;
-    private String name;
-
-    protected PCCountry() {
-        super();
-    }
-
-    public PCCountry(String name, String code) {
-        setName(name);
-        setCode(code);
-    }
-
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public static Object reflect(PCCountry instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCCountry.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+public class PCCountry {
+
+    private String code;
+    private String name;
+
+    protected PCCountry() {
+        super();
+    }
+
+    public PCCountry(String name, String code) {
+        setName(name);
+        setCode(code);
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public static Object reflect(PCCountry instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCCountry.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDepartment.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDepartment.java
index a114a30..9ea46ad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDepartment.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDepartment.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-@FetchGroups({
-@FetchGroup(name = "department.employees",
-    attributes = @FetchAttribute(name = "employees")),
-@FetchGroup(name = "department.company",
-    attributes = @FetchAttribute(name = "company"))
-    })
-public class PCDepartment {
-
-    private String name;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCCompany company;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    private Set<PCEmployee> employees;
-
-    public PCDepartment() {
-        super();
-    }
-
-    public PCDepartment(String name) {
-        super();
-        setName(name);
-    }
-
-    public PCCompany getCompany() {
-        return company;
-    }
-
-    public void setCompany(PCCompany company) {
-        this.company = company;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Set getEmployees() {
-        return employees;
-    }
-
-    public void setEmployees(Set employees) {
-        this.employees = employees;
-    }
-
-    public void addEmployee(PCEmployee emp) {
-        if (employees == null)
-            employees = new HashSet();
-        employees.add(emp);
-        emp.setDepartment(this);
-    }
-
-    public boolean contains(PCEmployee emp) {
-        return employees != null && employees.contains(emp);
-    }
-
-    public static Object reflect(PCDepartment instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCDepartment.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+@FetchGroups({
+@FetchGroup(name = "department.employees",
+    attributes = @FetchAttribute(name = "employees")),
+@FetchGroup(name = "department.company",
+    attributes = @FetchAttribute(name = "company"))
+    })
+public class PCDepartment {
+
+    private String name;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCCompany company;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    private Set<PCEmployee> employees;
+
+    public PCDepartment() {
+        super();
+    }
+
+    public PCDepartment(String name) {
+        super();
+        setName(name);
+    }
+
+    public PCCompany getCompany() {
+        return company;
+    }
+
+    public void setCompany(PCCompany company) {
+        this.company = company;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Set getEmployees() {
+        return employees;
+    }
+
+    public void setEmployees(Set employees) {
+        this.employees = employees;
+    }
+
+    public void addEmployee(PCEmployee emp) {
+        if (employees == null)
+            employees = new HashSet();
+        employees.add(emp);
+        emp.setDepartment(this);
+    }
+
+    public boolean contains(PCEmployee emp) {
+        return employees != null && employees.contains(emp);
+    }
+
+    public static Object reflect(PCDepartment instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCDepartment.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDirectory.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDirectory.java
index a61f7dd..3087418 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDirectory.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCDirectory.java
@@ -1,178 +1,178 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.Column;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-@FetchGroups({
-@FetchGroup(name = "name+parent+grandparent", attributes = {
-@FetchAttribute(name = "_name"),
-@FetchAttribute(name = "_parent", recursionDepth = 2)
-    }),
-@FetchGroup(name = "name+parent+grandparent+greatgrandparent", attributes = {
-@FetchAttribute(name = "_name"),
-@FetchAttribute(name = "_parent", recursionDepth = 3)
-    }),
-@FetchGroup(name = "name+parent", attributes = {
-@FetchAttribute(name = "_name"),
-@FetchAttribute(name = "_parent")
-    }),
-@FetchGroup(name = "allparents", attributes = {
-@FetchAttribute(name = "_name"),
-@FetchAttribute(name = "_parent", recursionDepth = -1)
-    }),
-@FetchGroup(name = "name", attributes = @FetchAttribute(name = "_name"))
-    })
-public class PCDirectory {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    @Column(name="name_col")
-    private String _name;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCDirectory _parent;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    private Set<PCDirectory> _children;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    private Set<PCFile> _files;
-
-    /**
-     *
-     */
-    public PCDirectory() {
-        super();
-    }
-
-    public PCDirectory(String name) {
-        super();
-        _name = name;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public String getName() {
-        return _name;
-    }
-
-    public PCDirectory getParent() {
-        return _parent;
-    }
-
-    public Set getChildren() {
-        return _children;
-    }
-
-    public Set getFiles() {
-        return _files;
-    }
-
-    public void add(PCDirectory dir) {
-        if (dir == null)
-            throw new NullPointerException("null directory");
-        if (dir.getParent() != null && dir.getParent() != this)
-            throw new IllegalArgumentException(dir + " has a different parent");
-        if (_children == null)
-            _children = new HashSet();
-        _children.add(dir);
-        dir._parent = this;
-    }
-
-    public PCFile add(String name) {
-        if (name == null)
-            throw new NullPointerException("null file");
-        PCFile file = new PCFile(this, name);
-        if (_files == null)
-            _files = new HashSet();
-        if (_files.contains(file))
-            throw new IllegalArgumentException("duplicate file" + file);
-        _files.add(file);
-        return file;
-    }
-
-    public boolean isChild(PCDirectory dir, boolean recurse) {
-        if (_children == null)
-            return false;
-
-        if (_children.contains(dir))
-            return true;
-        if (recurse) {
-            Iterator i = _children.iterator();
-            while (i.hasNext()) {
-                PCDirectory child = (PCDirectory) i.next();
-                if (child.isChild(dir, recurse))
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean isChild(PCFile file, boolean recurse) {
-        if (_files != null && _files.contains(file))
-            return true;
-
-        if (_children == null)
-            return false;
-
-        if (recurse) {
-            Iterator i = _children.iterator();
-            while (i.hasNext()) {
-                PCDirectory child = (PCDirectory) i.next();
-                if (child.isChild(file, recurse))
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    public static Object reflect(PCDirectory instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCDirectory.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.Column;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+@FetchGroups({
+@FetchGroup(name = "name+parent+grandparent", attributes = {
+@FetchAttribute(name = "_name"),
+@FetchAttribute(name = "_parent", recursionDepth = 2)
+    }),
+@FetchGroup(name = "name+parent+grandparent+greatgrandparent", attributes = {
+@FetchAttribute(name = "_name"),
+@FetchAttribute(name = "_parent", recursionDepth = 3)
+    }),
+@FetchGroup(name = "name+parent", attributes = {
+@FetchAttribute(name = "_name"),
+@FetchAttribute(name = "_parent")
+    }),
+@FetchGroup(name = "allparents", attributes = {
+@FetchAttribute(name = "_name"),
+@FetchAttribute(name = "_parent", recursionDepth = -1)
+    }),
+@FetchGroup(name = "name", attributes = @FetchAttribute(name = "_name"))
+    })
+public class PCDirectory {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    @Column(name="name_col")
+    private String _name;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCDirectory _parent;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    private Set<PCDirectory> _children;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    private Set<PCFile> _files;
+
+    /**
+     *
+     */
+    public PCDirectory() {
+        super();
+    }
+
+    public PCDirectory(String name) {
+        super();
+        _name = name;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public PCDirectory getParent() {
+        return _parent;
+    }
+
+    public Set getChildren() {
+        return _children;
+    }
+
+    public Set getFiles() {
+        return _files;
+    }
+
+    public void add(PCDirectory dir) {
+        if (dir == null)
+            throw new NullPointerException("null directory");
+        if (dir.getParent() != null && dir.getParent() != this)
+            throw new IllegalArgumentException(dir + " has a different parent");
+        if (_children == null)
+            _children = new HashSet();
+        _children.add(dir);
+        dir._parent = this;
+    }
+
+    public PCFile add(String name) {
+        if (name == null)
+            throw new NullPointerException("null file");
+        PCFile file = new PCFile(this, name);
+        if (_files == null)
+            _files = new HashSet();
+        if (_files.contains(file))
+            throw new IllegalArgumentException("duplicate file" + file);
+        _files.add(file);
+        return file;
+    }
+
+    public boolean isChild(PCDirectory dir, boolean recurse) {
+        if (_children == null)
+            return false;
+
+        if (_children.contains(dir))
+            return true;
+        if (recurse) {
+            Iterator i = _children.iterator();
+            while (i.hasNext()) {
+                PCDirectory child = (PCDirectory) i.next();
+                if (child.isChild(dir, recurse))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isChild(PCFile file, boolean recurse) {
+        if (_files != null && _files.contains(file))
+            return true;
+
+        if (_children == null)
+            return false;
+
+        if (recurse) {
+            Iterator i = _children.iterator();
+            while (i.hasNext()) {
+                PCDirectory child = (PCDirectory) i.next();
+                if (child.isChild(file, recurse))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    public static Object reflect(PCDirectory instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCDirectory.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCEmployee.java
index afacb7a..e03fc9f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCEmployee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCEmployee.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-@FetchGroup(name = "employee.department",
-    attributes = @FetchAttribute(name = "department"))
-public class PCEmployee extends PCPerson {
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCDepartment department;
-
-    protected PCEmployee() {
-        super();
-    }
-
-    public PCEmployee(String name) {
-        super(name);
-    }
-
-    public PCDepartment getDepartment() {
-        return department;
-    }
-
-    public void setDepartment(PCDepartment department) {
-        this.department = department;
-    }
-
-    public static Object reflect(PCEmployee instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCEmployee.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+@FetchGroup(name = "employee.department",
+    attributes = @FetchAttribute(name = "department"))
+public class PCEmployee extends PCPerson {
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCDepartment department;
+
+    protected PCEmployee() {
+        super();
+    }
+
+    public PCEmployee(String name) {
+        super(name);
+    }
+
+    public PCDepartment getDepartment() {
+        return department;
+    }
+
+    public void setDepartment(PCDepartment department) {
+        this.department = department;
+    }
+
+    public static Object reflect(PCEmployee instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCEmployee.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCFile.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCFile.java
index b1258ed..781981f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCFile.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCFile.java
@@ -1,65 +1,65 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToOne;
-import javax.persistence.Column;
-
-@Entity
-public class PCFile {
-
-    @Column(name="name_col")
-    private String _name;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCDirectory _dir;
-
-    /**
-     *
-     */
-    protected PCFile() {
-        super();
-    }
-
-    PCFile(PCDirectory dir, String name) {
-        super();
-        if (dir == null)
-            throw new NullPointerException("null directory");
-        if (name == null || name.trim().length() == 0)
-            throw new NullPointerException("null name");
-
-        _dir = dir;
-        _name = name;
-    }
-
-    public PCDirectory getDir() {
-        return _dir;
-    }
-
-    public String getName() {
-        return _name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Column;
+
+@Entity
+public class PCFile {
+
+    @Column(name="name_col")
+    private String _name;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCDirectory _dir;
+
+    /**
+     *
+     */
+    protected PCFile() {
+        super();
+    }
+
+    PCFile(PCDirectory dir, String name) {
+        super();
+        if (dir == null)
+            throw new NullPointerException("null directory");
+        if (name == null || name.trim().length() == 0)
+            throw new NullPointerException("null name");
+
+        _dir = dir;
+        _name = name;
+    }
+
+    public PCDirectory getDir() {
+        return _dir;
+    }
+
+    public String getName() {
+        return _name;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCPerson.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCPerson.java
index d21c0eb..ecdbb4a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCPerson.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PCPerson.java
@@ -1,114 +1,114 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-
-import org.apache.openjpa.persistence.FetchAttribute;
-import org.apache.openjpa.persistence.FetchGroup;
-import org.apache.openjpa.persistence.FetchGroups;
-
-/**
- * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
- */
-@Entity
-@FetchGroups({
-@FetchGroup(name = "detail+children-names", fetchGroups = "detail"),
-@FetchGroup(name = "detail", fetchGroups = "default",
-    attributes = @FetchAttribute(name = "address")),
-@FetchGroup(name = "detail+children-list", fetchGroups = "detail",
-    attributes = @FetchAttribute(name = "children")),
-@FetchGroup(name = "person.address",
-    attributes = @FetchAttribute(name = "address"))
-    })
-public class PCPerson {
-
-    private String name;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCAddress address;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private PCPerson parent;
-
-    @ManyToMany(cascade = CascadeType.PERSIST)
-    private Set<PCPerson> children;
-
-    protected PCPerson() {
-        super();
-    }
-
-    public PCPerson(String name) {
-        setName(name);
-    }
-
-    public PCAddress getAddress() {
-        return address;
-    }
-
-    public void setAddress(PCAddress address) {
-        this.address = address;
-    }
-
-    public Set getChildren() {
-        return children;
-    }
-
-    public void setChildren(Set children) {
-        this.children = children;
-    }
-
-    public void addChildren(PCPerson child) {
-        if (children == null)
-            children = new HashSet();
-        children.add(child);
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public PCPerson getParent() {
-        return parent;
-    }
-
-    public void setParent(PCPerson parent) {
-        this.parent = parent;
-    }
-
-    public static Object reflect(PCPerson instance, String name) {
-        if (instance == null)
-            return null;
-        try {
-            return PCPerson.class.getDeclaredField(name).get(instance);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.FetchAttribute;
+import org.apache.openjpa.persistence.FetchGroup;
+import org.apache.openjpa.persistence.FetchGroups;
+
+/**
+ * @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
+ */
+@Entity
+@FetchGroups({
+@FetchGroup(name = "detail+children-names", fetchGroups = "detail"),
+@FetchGroup(name = "detail", fetchGroups = "default",
+    attributes = @FetchAttribute(name = "address")),
+@FetchGroup(name = "detail+children-list", fetchGroups = "detail",
+    attributes = @FetchAttribute(name = "children")),
+@FetchGroup(name = "person.address",
+    attributes = @FetchAttribute(name = "address"))
+    })
+public class PCPerson {
+
+    private String name;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCAddress address;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private PCPerson parent;
+
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    private Set<PCPerson> children;
+
+    protected PCPerson() {
+        super();
+    }
+
+    public PCPerson(String name) {
+        setName(name);
+    }
+
+    public PCAddress getAddress() {
+        return address;
+    }
+
+    public void setAddress(PCAddress address) {
+        this.address = address;
+    }
+
+    public Set getChildren() {
+        return children;
+    }
+
+    public void setChildren(Set children) {
+        this.children = children;
+    }
+
+    public void addChildren(PCPerson child) {
+        if (children == null)
+            children = new HashSet();
+        children.add(child);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public PCPerson getParent() {
+        return parent;
+    }
+
+    public void setParent(PCPerson parent) {
+        this.parent = parent;
+    }
+
+    public static Object reflect(PCPerson instance, String name) {
+        if (instance == null)
+            return null;
+        try {
+            return PCPerson.class.getDeclaredField(name).get(instance);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistenceAware.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistenceAware.java
index c5d5675..05ef8e6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistenceAware.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistenceAware.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>A persistence-aware type that should be enhanced.</p>
- *
- * @author Abe White
- */
-@Entity
-public class PersistenceAware {
-
-    public static String getTransString(RuntimeTest1 rt) {
-        return rt.transString;
-    }
-
-    public static void setTransString(RuntimeTest1 rt, String value) {
-        rt.transString = value;
-    }
-
-    public static String getModTransString(ModRuntimeTest1 rt) {
-        return rt.transString;
-    }
-
-    public static void setModTransString(ModRuntimeTest1 rt, String value) {
-        rt.transString = value;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>A persistence-aware type that should be enhanced.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class PersistenceAware {
+
+    public static String getTransString(RuntimeTest1 rt) {
+        return rt.transString;
+    }
+
+    public static void setTransString(RuntimeTest1 rt, String value) {
+        rt.transString = value;
+    }
+
+    public static String getModTransString(ModRuntimeTest1 rt) {
+        return rt.transString;
+    }
+
+    public static void setModTransString(ModRuntimeTest1 rt, String value) {
+        rt.transString = value;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistentMapHolder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistentMapHolder.java
index cb17b72..b63b80c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistentMapHolder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/PersistentMapHolder.java
@@ -1,118 +1,118 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.openjpa.persistence.PersistentMap;
-
-@Entity
-public class PersistentMapHolder {
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCKeyStringValue")
-    private Map<MapElementPC, String> testPCKeyStringValue =
-        new HashMap<MapElementPC, String>();
-
-    @PersistentMap(elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testStringKeyPCValue")
-    private Map<String, MapElementPC> testStringKeyPCValue =
-        new HashMap<String, MapElementPC>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST,
-        elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCKeyPCValue")
-    private Map<MapElementPC, MapElementPC> testPCKeyPCValue =
-        new HashMap<MapElementPC, MapElementPC>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCSubKeyStringValue")
-    private Map<MapElementPCChild, String> testPCSubKeyStringValue =
-        new HashMap<MapElementPCChild, String>();
-
-    @PersistentMap(elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testStringKeyPCSubValue")
-    private Map<String, MapElementPCChild> testStringKeyPCSubValue =
-        new HashMap<String, MapElementPCChild>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST,
-        elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCSubKeyPCValue")
-    private Map<MapElementPCChild, MapElementPC> testPCSubKeyPCValue =
-        new HashMap<MapElementPCChild, MapElementPC>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST,
-        elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCSubKeyPCSubValue")
-    private Map<MapElementPCChild, MapElementPCChild> testPCSubKeyPCSubValue =
-        new HashMap<MapElementPCChild, MapElementPCChild>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST,
-        elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCKeyPCSubValue")
-    private Map<MapElementPC, MapElementPCChild> testPCKeyPCSubValue =
-        new HashMap<MapElementPC, MapElementPCChild>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCIntfKeyStringValue")
-    private Map<MapElementIntf, String> testPCIntfKeyStringValue =
-        new HashMap<MapElementIntf, String>();
-
-    @PersistentMap(elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testStringKeyPCIntfValue")
-    private Map<String, MapElementIntf> testStringKeyPCIntfValue =
-        new HashMap<String, MapElementIntf>();
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST,
-        elementCascade = CascadeType.PERSIST)
-    @KeyColumn(name = "testPCIntfKeyPCValue")
-    private Map<MapElementIntf, MapElementPC> testPCIntfKeyPCValue =
-        new HashMap<MapElementIntf, MapElementPC>();
-
-    public Map getNamedMap(String name) {
-        if (name.equals("testPCKeyStringValue"))
-            return testPCKeyStringValue;
-        if (name.equals("testStringKeyPCValue"))
-            return testStringKeyPCValue;
-        if (name.equals("testPCKeyPCValue"))
-            return testPCKeyPCValue;
-        if (name.equals("testPCSubKeyStringValue"))
-            return testPCSubKeyStringValue;
-        if (name.equals("testStringKeyPCSubValue"))
-            return testStringKeyPCSubValue;
-        if (name.equals("testPCSubKeyPCValue"))
-            return testPCSubKeyPCValue;
-        if (name.equals("testPCSubKeyPCSubValue"))
-            return testPCSubKeyPCSubValue;
-        if (name.equals("testPCKeyPCSubValue"))
-            return testPCKeyPCSubValue;
-        if (name.equals("testPCIntfKeyStringValue"))
-            return testPCIntfKeyStringValue;
-        if (name.equals("testStringKeyPCIntfValue"))
-            return testStringKeyPCIntfValue;
-        if (name.equals("testPCIntfKeyPCValue"))
-            return testPCIntfKeyPCValue;
-
-        return null;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.PersistentMap;
+
+@Entity
+public class PersistentMapHolder {
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCKeyStringValue")
+    private Map<MapElementPC, String> testPCKeyStringValue =
+        new HashMap<MapElementPC, String>();
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testStringKeyPCValue")
+    private Map<String, MapElementPC> testStringKeyPCValue =
+        new HashMap<String, MapElementPC>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST,
+        elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCKeyPCValue")
+    private Map<MapElementPC, MapElementPC> testPCKeyPCValue =
+        new HashMap<MapElementPC, MapElementPC>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCSubKeyStringValue")
+    private Map<MapElementPCChild, String> testPCSubKeyStringValue =
+        new HashMap<MapElementPCChild, String>();
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testStringKeyPCSubValue")
+    private Map<String, MapElementPCChild> testStringKeyPCSubValue =
+        new HashMap<String, MapElementPCChild>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST,
+        elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCSubKeyPCValue")
+    private Map<MapElementPCChild, MapElementPC> testPCSubKeyPCValue =
+        new HashMap<MapElementPCChild, MapElementPC>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST,
+        elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCSubKeyPCSubValue")
+    private Map<MapElementPCChild, MapElementPCChild> testPCSubKeyPCSubValue =
+        new HashMap<MapElementPCChild, MapElementPCChild>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST,
+        elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCKeyPCSubValue")
+    private Map<MapElementPC, MapElementPCChild> testPCKeyPCSubValue =
+        new HashMap<MapElementPC, MapElementPCChild>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCIntfKeyStringValue")
+    private Map<MapElementIntf, String> testPCIntfKeyStringValue =
+        new HashMap<MapElementIntf, String>();
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testStringKeyPCIntfValue")
+    private Map<String, MapElementIntf> testStringKeyPCIntfValue =
+        new HashMap<String, MapElementIntf>();
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST,
+        elementCascade = CascadeType.PERSIST)
+    @KeyColumn(name = "testPCIntfKeyPCValue")
+    private Map<MapElementIntf, MapElementPC> testPCIntfKeyPCValue =
+        new HashMap<MapElementIntf, MapElementPC>();
+
+    public Map getNamedMap(String name) {
+        if (name.equals("testPCKeyStringValue"))
+            return testPCKeyStringValue;
+        if (name.equals("testStringKeyPCValue"))
+            return testStringKeyPCValue;
+        if (name.equals("testPCKeyPCValue"))
+            return testPCKeyPCValue;
+        if (name.equals("testPCSubKeyStringValue"))
+            return testPCSubKeyStringValue;
+        if (name.equals("testStringKeyPCSubValue"))
+            return testStringKeyPCSubValue;
+        if (name.equals("testPCSubKeyPCValue"))
+            return testPCSubKeyPCValue;
+        if (name.equals("testPCSubKeyPCSubValue"))
+            return testPCSubKeyPCSubValue;
+        if (name.equals("testPCKeyPCSubValue"))
+            return testPCKeyPCSubValue;
+        if (name.equals("testPCIntfKeyStringValue"))
+            return testPCIntfKeyStringValue;
+        if (name.equals("testStringKeyPCIntfValue"))
+            return testStringKeyPCIntfValue;
+        if (name.equals("testPCIntfKeyPCValue"))
+            return testPCIntfKeyPCValue;
+
+        return null;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ProxiesPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ProxiesPC.java
index c77f177..e47abdf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ProxiesPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ProxiesPC.java
@@ -1,179 +1,179 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.commons.collections.comparators.ComparableComparator;
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.PersistentMap;
-
-/**
- * <p>Persistent type used in the {@link TestProxies} tests.</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "PROX_PC")
-public class ProxiesPC implements Comparable {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    public int id;
-
-    private String name = null;
-
-    @PersistentCollection
-    private Set<String> stringSet = new HashSet();
-
-    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private TreeSet<ProxiesPC> proxySet = new TreeSet();
-
-    @PersistentMap
-    @KeyColumn(name = "strngkey")
-    private Map<String, String> stringMap = new HashMap();
-
-    //    @PersistentMap
-    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    @KeyColumn(name = "prxykey")
-    private TreeMap<String, ProxiesPC> proxyMap = new TreeMap();
-
-    @PersistentCollection
-    private List<String> list = new ArrayList();
-
-    @PersistentCollection
-    private Collection<String> comp = new TreeSet(new ComparableComparator());
-
-    @Temporal(TemporalType.DATE)
-    private Date date = null;
-
-    // sql types
-    private java.sql.Date sqlDate = null;
-    private java.sql.Timestamp timestamp = null;
-
-    public ProxiesPC() {
-    }
-
-    public ProxiesPC(String name) {
-        this.name = name;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Set getStringSet() {
-        return stringSet;
-    }
-
-    public void setStringSet(Set stringSet) {
-        this.stringSet = stringSet;
-    }
-
-    public TreeSet getProxySet() {
-        return proxySet;
-    }
-
-    public void setProxySet(TreeSet proxySet) {
-        this.proxySet = proxySet;
-    }
-
-    public Map getStringMap() {
-        return stringMap;
-    }
-
-    public void setStringMap(Map stringMap) {
-        this.stringMap = stringMap;
-    }
-
-    public TreeMap getProxyMap() {
-        return proxyMap;
-    }
-
-    public void setProxyMap(TreeMap proxyMap) {
-        this.proxyMap = proxyMap;
-    }
-
-    public int compareTo(Object other) {
-        return name.compareTo(((ProxiesPC) other).getName());
-    }
-
-    public List getList() {
-        return this.list;
-    }
-
-    public void setList(List list) {
-        this.list = list;
-    }
-
-    public Collection getComp() {
-        return this.comp;
-    }
-
-    public void setComp(Collection comp) {
-        this.comp = comp;
-    }
-
-    public java.sql.Date getSQLDate() {
-        return this.sqlDate;
-    }
-
-    public void setSQLDate(java.sql.Date sqlDate) {
-        this.sqlDate = sqlDate;
-    }
-
-    public java.sql.Timestamp getTimestamp() {
-        return this.timestamp;
-    }
-
-    public void setTimestamp(java.sql.Timestamp timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    public Date getDate() {
-        return this.date;
-    }
-
-    public void setDate(Date date) {
-        this.date = date;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.commons.collections.comparators.ComparableComparator;
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.PersistentMap;
+
+/**
+ * <p>Persistent type used in the {@link TestProxies} tests.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "PROX_PC")
+public class ProxiesPC implements Comparable {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    public int id;
+
+    private String name = null;
+
+    @PersistentCollection
+    private Set<String> stringSet = new HashSet();
+
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private TreeSet<ProxiesPC> proxySet = new TreeSet();
+
+    @PersistentMap
+    @KeyColumn(name = "strngkey")
+    private Map<String, String> stringMap = new HashMap();
+
+    //    @PersistentMap
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    @KeyColumn(name = "prxykey")
+    private TreeMap<String, ProxiesPC> proxyMap = new TreeMap();
+
+    @PersistentCollection
+    private List<String> list = new ArrayList();
+
+    @PersistentCollection
+    private Collection<String> comp = new TreeSet(new ComparableComparator());
+
+    @Temporal(TemporalType.DATE)
+    private Date date = null;
+
+    // sql types
+    private java.sql.Date sqlDate = null;
+    private java.sql.Timestamp timestamp = null;
+
+    public ProxiesPC() {
+    }
+
+    public ProxiesPC(String name) {
+        this.name = name;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Set getStringSet() {
+        return stringSet;
+    }
+
+    public void setStringSet(Set stringSet) {
+        this.stringSet = stringSet;
+    }
+
+    public TreeSet getProxySet() {
+        return proxySet;
+    }
+
+    public void setProxySet(TreeSet proxySet) {
+        this.proxySet = proxySet;
+    }
+
+    public Map getStringMap() {
+        return stringMap;
+    }
+
+    public void setStringMap(Map stringMap) {
+        this.stringMap = stringMap;
+    }
+
+    public TreeMap getProxyMap() {
+        return proxyMap;
+    }
+
+    public void setProxyMap(TreeMap proxyMap) {
+        this.proxyMap = proxyMap;
+    }
+
+    public int compareTo(Object other) {
+        return name.compareTo(((ProxiesPC) other).getName());
+    }
+
+    public List getList() {
+        return this.list;
+    }
+
+    public void setList(List list) {
+        this.list = list;
+    }
+
+    public Collection getComp() {
+        return this.comp;
+    }
+
+    public void setComp(Collection comp) {
+        this.comp = comp;
+    }
+
+    public java.sql.Date getSQLDate() {
+        return this.sqlDate;
+    }
+
+    public void setSQLDate(java.sql.Date sqlDate) {
+        this.sqlDate = sqlDate;
+    }
+
+    public java.sql.Timestamp getTimestamp() {
+        return this.timestamp;
+    }
+
+    public void setTimestamp(java.sql.Timestamp timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public Date getDate() {
+        return this.date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RecursivelyEmbeddedPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RecursivelyEmbeddedPC.java
index a30900e..5411d47 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RecursivelyEmbeddedPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RecursivelyEmbeddedPC.java
@@ -1,45 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-
-/**
- * <p>Embedded type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class RecursivelyEmbeddedPC {
-
-    @OneToOne
-    private EmbeddedPC embedded;
-
-    public EmbeddedPC getEmbedded() {
-        return this.embedded;
-    }
-
-    public void setEmbedded(EmbeddedPC embedded) {
-        this.embedded = embedded;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+
+/**
+ * <p>Embedded type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class RecursivelyEmbeddedPC {
+
+    @OneToOne
+    private EmbeddedPC embedded;
+
+    public EmbeddedPC getEmbedded() {
+        return this.embedded;
+    }
+
+    public void setEmbedded(EmbeddedPC embedded) {
+        this.embedded = embedded;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest1.java
index 7b0f228..c1a50d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest1.java
@@ -1,158 +1,158 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import javax.persistence.Transient;
-import javax.persistence.Version;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "rtest1")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class RuntimeTest1 implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @Temporal(TemporalType.DATE)
-    private Date dateField;
-
-    @Transient
-    public static final String someStaticField = "someField";
-
-    private Locale localeField;
-
-    @Id
-    private int intField;
-
-    private int intField1;
-
-    @Column(length = 35)
-    private String stringField;
-
-    // transactional only
-    @Column(length = 35)
-    public String transString;
-
-    // relations
-    //@Transient
-    @OneToOne(fetch = FetchType.LAZY,
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private RuntimeTest1 selfOneOne;
-
-    @OneToMany(mappedBy = "selfOneOne",
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private Set<RuntimeTest1> selfOneMany = new HashSet<RuntimeTest1>();
-
-    @Version
-    private int version;
-
-    public RuntimeTest1() {
-    }
-
-    public RuntimeTest1(int key) {
-        this.intField = key;
-    }
-
-    public RuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-        intField1 = i;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public int getIntField1() {
-        return this.intField1;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public void setIntField1(int intField1) {
-        this.intField1 = intField1;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public RuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-
-    public String toString() {
-        return "IntField: " + intField + ", StringField: " + stringField + " .";
-    }
-
-    public Locale getLocaleField() {
-        return localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-
-    public Date getDateField() {
-        return this.dateField;
-    }
-
-    public void setDateField(Date d) {
-        this.dateField = d;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+import javax.persistence.Version;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "rtest1")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class RuntimeTest1 implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Temporal(TemporalType.DATE)
+    private Date dateField;
+
+    @Transient
+    public static final String someStaticField = "someField";
+
+    private Locale localeField;
+
+    @Id
+    private int intField;
+
+    private int intField1;
+
+    @Column(length = 35)
+    private String stringField;
+
+    // transactional only
+    @Column(length = 35)
+    public String transString;
+
+    // relations
+    //@Transient
+    @OneToOne(fetch = FetchType.LAZY,
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private RuntimeTest1 selfOneOne;
+
+    @OneToMany(mappedBy = "selfOneOne",
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private Set<RuntimeTest1> selfOneMany = new HashSet<RuntimeTest1>();
+
+    @Version
+    private int version;
+
+    public RuntimeTest1() {
+    }
+
+    public RuntimeTest1(int key) {
+        this.intField = key;
+    }
+
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+        intField1 = i;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public int getIntField1() {
+        return this.intField1;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public void setIntField1(int intField1) {
+        this.intField1 = intField1;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+
+    public String toString() {
+        return "IntField: " + intField + ", StringField: " + stringField + " .";
+    }
+
+    public Locale getLocaleField() {
+        return localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+
+    public void setDateField(Date d) {
+        this.dateField = d;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest2.java
index 1251935..a16bf36 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest2.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("RT2")
-public class RuntimeTest2 extends RuntimeTest1 {
-
-    private static final long serialVersionUID = 1L;
-    //@Id
-    private int intField2;
-
-    public RuntimeTest2() {
-    }
-
-    public RuntimeTest2(int key) {
-        super(key);
-    }
-
-    public RuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-
-    public String toString() {
-        return "IntField: " + intField2 + ", StringField: " +
-            super.getStringField() + " .";
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("RT2")
+public class RuntimeTest2 extends RuntimeTest1 {
+
+    private static final long serialVersionUID = 1L;
+    //@Id
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(int key) {
+        super(key);
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+
+    public String toString() {
+        return "IntField: " + intField2 + ", StringField: " +
+            super.getStringField() + " .";
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest3.java
index 953c80d..666530c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest3.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("RT3")
-public class RuntimeTest3
-    extends RuntimeTest2 {
-
-    //@Id
-    private int intField3;
-
-    public RuntimeTest3() {
-    }
-
-    public RuntimeTest3(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField3() {
-        return this.intField3;
-    }
-
-    public void setIntField3(int intField3) {
-        this.intField3 = intField3;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("RT3")
+public class RuntimeTest3
+    extends RuntimeTest2 {
+
+    //@Id
+    private int intField3;
+
+    public RuntimeTest3() {
+    }
+
+    public RuntimeTest3(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField3() {
+        return this.intField3;
+    }
+
+    public void setIntField3(int intField3) {
+        this.intField3 = intField3;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest4.java
index b3d1dae..7ba7ad8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest4.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToMany;
-
-@Entity
-public class RuntimeTest4 {
-
-    private String name;
-
-    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private Collection<RuntimeTest5> runtimeTest5s = new ArrayList();
-
-    public RuntimeTest4(String str) {
-        name = str;
-    }
-
-    public void setName(String val) {
-        name = val;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Collection getRuntimeTest5s() {
-        return runtimeTest5s;
-    }
-
-    public void setRuntimeTest5s(Collection c) {
-        runtimeTest5s = c;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+
+@Entity
+public class RuntimeTest4 {
+
+    private String name;
+
+    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private Collection<RuntimeTest5> runtimeTest5s = new ArrayList();
+
+    public RuntimeTest4(String str) {
+        name = str;
+    }
+
+    public void setName(String val) {
+        name = val;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Collection getRuntimeTest5s() {
+        return runtimeTest5s;
+    }
+
+    public void setRuntimeTest5s(Collection c) {
+        runtimeTest5s = c;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest5.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest5.java
index 8ebb73f..a56c03d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest5.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/RuntimeTest5.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class RuntimeTest5 {
-
-    private String name;
-    private RuntimeTest4 runtimeTest4;
-
-    public RuntimeTest5(String str) {
-        name = str;
-    }
-
-    public void setName(String val) {
-        name = val;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setRuntimeTest4(RuntimeTest4 val) {
-        runtimeTest4 = val;
-    }
-
-    public RuntimeTest4 getRuntimeTest4() {
-        return runtimeTest4;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest5 {
+
+    private String name;
+    private RuntimeTest4 runtimeTest4;
+
+    public RuntimeTest5(String str) {
+        name = str;
+    }
+
+    public void setName(String val) {
+        name = val;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setRuntimeTest4(RuntimeTest4 val) {
+        runtimeTest4 = val;
+    }
+
+    public RuntimeTest4 getRuntimeTest4() {
+        return runtimeTest4;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SCOTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SCOTest.java
index 0c9e9e2..c01c8dd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SCOTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SCOTest.java
@@ -1,291 +1,291 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.PersistentMap;
-
-/**
- * Used in testing; should be enhanced.
- */
-@Entity
-public class SCOTest {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    private int id;
-
-    @PersistentMap
-    @KeyColumn(name = "strintkey")
-    private Map<String, Integer> strIntMap;
-
-    @PersistentMap
-    @KeyColumn(name = "intlngkey")
-    private Map<Integer, Long> intLongMap;
-
-    @PersistentMap
-    @KeyColumn(name = "lngfltkey")
-    private Map<Long, Float> longFloatMap;
-
-    @PersistentMap
-    @KeyColumn(name = "fltbtekey")
-    private Map<Float, Byte> floatByteMap;
-
-    @PersistentMap
-    @KeyColumn(name = "btedbkey")
-    private Map<Byte, Double> byteDoubleMap;
-
-    @PersistentMap
-    @KeyColumn(name = "dbchkey")
-    private Map<Double, Character> doubleCharMap;
-
-    @PersistentMap
-    @KeyColumn(name = "chblkey")
-    private Map<Character, Boolean> charBooleanMap;
-
-    @PersistentMap
-    @KeyColumn(name = "dtstrkey")
-    private Map<Date, String> dateStrMap;
-
-    @PersistentMap
-    @KeyColumn(name = "bgdckey")
-    private Map<BigDecimal, BigInteger> bigDecimalBigIntegerMap;
-
-    @PersistentCollection
-    private Collection<String> cString;
-
-    @PersistentCollection
-    private Collection<Integer> cInteger;
-
-    @PersistentCollection
-    private Collection<Long> cLong;
-
-    @PersistentCollection
-    private Collection<Float> cFloat;
-
-    @PersistentCollection
-    private Collection<Byte> cByte;
-
-    @PersistentCollection
-    private Collection<Double> cDouble;
-
-    @PersistentCollection
-    private Collection<Boolean> cBoolean;
-
-    @PersistentCollection
-    private Collection<Short> cShort;
-
-    @PersistentCollection
-    private Collection<Date> cDate;
-
-    @PersistentCollection
-    private Collection<Character> cCharacter;
-
-    @PersistentCollection
-    private Collection<BigInteger> cBigInteger;
-
-    @PersistentCollection
-    private Collection<BigDecimal> cBigDecimal;
-
-    public SCOTest() {
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public void setBigDecimalBigIntegerMap(Map bigDecimalBigIntegerMap) {
-        this.bigDecimalBigIntegerMap = bigDecimalBigIntegerMap;
-    }
-
-    public Map getBigDecimalBigIntegerMap() {
-        return bigDecimalBigIntegerMap;
-    }
-
-    public void setStrIntMap(Map strIntMap) {
-        this.strIntMap = strIntMap;
-    }
-
-    public Map getStrIntMap() {
-        return strIntMap;
-    }
-
-    public void setIntLongMap(Map intLongMap) {
-        this.intLongMap = intLongMap;
-    }
-
-    public Map getIntLongMap() {
-        return intLongMap;
-    }
-
-    public void setLongFloatMap(Map longFloatMap) {
-        this.longFloatMap = longFloatMap;
-    }
-
-    public Map getLongFloatMap() {
-        return longFloatMap;
-    }
-
-    public void setFloatByteMap(Map floatByteMap) {
-        this.floatByteMap = floatByteMap;
-    }
-
-    public Map getFloatByteMap() {
-        return floatByteMap;
-    }
-
-    public void setByteDoubleMap(Map byteDoubleMap) {
-        this.byteDoubleMap = byteDoubleMap;
-    }
-
-    public Map getByteDoubleMap() {
-        return byteDoubleMap;
-    }
-
-    public void setDoubleCharMap(Map doubleCharMap) {
-        this.doubleCharMap = doubleCharMap;
-    }
-
-    public Map getDoubleCharMap() {
-        return doubleCharMap;
-    }
-
-    public void setCharBooleanMap(Map charBooleanMap) {
-        this.charBooleanMap = charBooleanMap;
-    }
-
-    public Map getCharBooleanMap() {
-        return charBooleanMap;
-    }
-
-    public void setDateStrMap(Map dateStrMap) {
-        this.dateStrMap = dateStrMap;
-    }
-
-    public Map getDateStrMap() {
-        return dateStrMap;
-    }
-
-    public void setCString(Collection cString) {
-        this.cString = cString;
-    }
-
-    public Collection getCString() {
-        return cString;
-    }
-
-    public void setCInteger(Collection cInteger) {
-        this.cInteger = cInteger;
-    }
-
-    public Collection getCInteger() {
-        return cInteger;
-    }
-
-    public void setCLong(Collection cLong) {
-        this.cLong = cLong;
-    }
-
-    public Collection getCLong() {
-        return cLong;
-    }
-
-    public void setCCharacter(Collection cCharacter) {
-        this.cCharacter = cCharacter;
-    }
-
-    public Collection getCCharacter() {
-        return cCharacter;
-    }
-
-    public void setCFloat(Collection cFloat) {
-        this.cFloat = cFloat;
-    }
-
-    public Collection getCFloat() {
-        return cFloat;
-    }
-
-    public void setCByte(Collection cByte) {
-        this.cByte = cByte;
-    }
-
-    public Collection getCByte() {
-        return cByte;
-    }
-
-    public void setCDouble(Collection cDouble) {
-        this.cDouble = cDouble;
-    }
-
-    public Collection getCDouble() {
-        return cDouble;
-    }
-
-    public void setCBoolean(Collection cBoolean) {
-        this.cBoolean = cBoolean;
-    }
-
-    public Collection getCBoolean() {
-        return cBoolean;
-    }
-
-    public void setCShort(Collection cShort) {
-        this.cShort = cShort;
-    }
-
-    public Collection getCShort() {
-        return cShort;
-    }
-
-    public void setCDate(Collection cDate) {
-        this.cDate = cDate;
-    }
-
-    public Collection getCDate() {
-        return cDate;
-    }
-
-    public void setCBigInteger(Collection cBigInteger) {
-        this.cBigInteger = cBigInteger;
-    }
-
-    public Collection getCBigInteger() {
-        return cBigInteger;
-    }
-
-    public void setCBigDecimal(Collection cBigDecimal) {
-        this.cBigDecimal = cBigDecimal;
-    }
-
-    public Collection getCBigDecimal() {
-        return cBigDecimal;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.PersistentMap;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+public class SCOTest {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private int id;
+
+    @PersistentMap
+    @KeyColumn(name = "strintkey")
+    private Map<String, Integer> strIntMap;
+
+    @PersistentMap
+    @KeyColumn(name = "intlngkey")
+    private Map<Integer, Long> intLongMap;
+
+    @PersistentMap
+    @KeyColumn(name = "lngfltkey")
+    private Map<Long, Float> longFloatMap;
+
+    @PersistentMap
+    @KeyColumn(name = "fltbtekey")
+    private Map<Float, Byte> floatByteMap;
+
+    @PersistentMap
+    @KeyColumn(name = "btedbkey")
+    private Map<Byte, Double> byteDoubleMap;
+
+    @PersistentMap
+    @KeyColumn(name = "dbchkey")
+    private Map<Double, Character> doubleCharMap;
+
+    @PersistentMap
+    @KeyColumn(name = "chblkey")
+    private Map<Character, Boolean> charBooleanMap;
+
+    @PersistentMap
+    @KeyColumn(name = "dtstrkey")
+    private Map<Date, String> dateStrMap;
+
+    @PersistentMap
+    @KeyColumn(name = "bgdckey")
+    private Map<BigDecimal, BigInteger> bigDecimalBigIntegerMap;
+
+    @PersistentCollection
+    private Collection<String> cString;
+
+    @PersistentCollection
+    private Collection<Integer> cInteger;
+
+    @PersistentCollection
+    private Collection<Long> cLong;
+
+    @PersistentCollection
+    private Collection<Float> cFloat;
+
+    @PersistentCollection
+    private Collection<Byte> cByte;
+
+    @PersistentCollection
+    private Collection<Double> cDouble;
+
+    @PersistentCollection
+    private Collection<Boolean> cBoolean;
+
+    @PersistentCollection
+    private Collection<Short> cShort;
+
+    @PersistentCollection
+    private Collection<Date> cDate;
+
+    @PersistentCollection
+    private Collection<Character> cCharacter;
+
+    @PersistentCollection
+    private Collection<BigInteger> cBigInteger;
+
+    @PersistentCollection
+    private Collection<BigDecimal> cBigDecimal;
+
+    public SCOTest() {
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public void setBigDecimalBigIntegerMap(Map bigDecimalBigIntegerMap) {
+        this.bigDecimalBigIntegerMap = bigDecimalBigIntegerMap;
+    }
+
+    public Map getBigDecimalBigIntegerMap() {
+        return bigDecimalBigIntegerMap;
+    }
+
+    public void setStrIntMap(Map strIntMap) {
+        this.strIntMap = strIntMap;
+    }
+
+    public Map getStrIntMap() {
+        return strIntMap;
+    }
+
+    public void setIntLongMap(Map intLongMap) {
+        this.intLongMap = intLongMap;
+    }
+
+    public Map getIntLongMap() {
+        return intLongMap;
+    }
+
+    public void setLongFloatMap(Map longFloatMap) {
+        this.longFloatMap = longFloatMap;
+    }
+
+    public Map getLongFloatMap() {
+        return longFloatMap;
+    }
+
+    public void setFloatByteMap(Map floatByteMap) {
+        this.floatByteMap = floatByteMap;
+    }
+
+    public Map getFloatByteMap() {
+        return floatByteMap;
+    }
+
+    public void setByteDoubleMap(Map byteDoubleMap) {
+        this.byteDoubleMap = byteDoubleMap;
+    }
+
+    public Map getByteDoubleMap() {
+        return byteDoubleMap;
+    }
+
+    public void setDoubleCharMap(Map doubleCharMap) {
+        this.doubleCharMap = doubleCharMap;
+    }
+
+    public Map getDoubleCharMap() {
+        return doubleCharMap;
+    }
+
+    public void setCharBooleanMap(Map charBooleanMap) {
+        this.charBooleanMap = charBooleanMap;
+    }
+
+    public Map getCharBooleanMap() {
+        return charBooleanMap;
+    }
+
+    public void setDateStrMap(Map dateStrMap) {
+        this.dateStrMap = dateStrMap;
+    }
+
+    public Map getDateStrMap() {
+        return dateStrMap;
+    }
+
+    public void setCString(Collection cString) {
+        this.cString = cString;
+    }
+
+    public Collection getCString() {
+        return cString;
+    }
+
+    public void setCInteger(Collection cInteger) {
+        this.cInteger = cInteger;
+    }
+
+    public Collection getCInteger() {
+        return cInteger;
+    }
+
+    public void setCLong(Collection cLong) {
+        this.cLong = cLong;
+    }
+
+    public Collection getCLong() {
+        return cLong;
+    }
+
+    public void setCCharacter(Collection cCharacter) {
+        this.cCharacter = cCharacter;
+    }
+
+    public Collection getCCharacter() {
+        return cCharacter;
+    }
+
+    public void setCFloat(Collection cFloat) {
+        this.cFloat = cFloat;
+    }
+
+    public Collection getCFloat() {
+        return cFloat;
+    }
+
+    public void setCByte(Collection cByte) {
+        this.cByte = cByte;
+    }
+
+    public Collection getCByte() {
+        return cByte;
+    }
+
+    public void setCDouble(Collection cDouble) {
+        this.cDouble = cDouble;
+    }
+
+    public Collection getCDouble() {
+        return cDouble;
+    }
+
+    public void setCBoolean(Collection cBoolean) {
+        this.cBoolean = cBoolean;
+    }
+
+    public Collection getCBoolean() {
+        return cBoolean;
+    }
+
+    public void setCShort(Collection cShort) {
+        this.cShort = cShort;
+    }
+
+    public Collection getCShort() {
+        return cShort;
+    }
+
+    public void setCDate(Collection cDate) {
+        this.cDate = cDate;
+    }
+
+    public Collection getCDate() {
+        return cDate;
+    }
+
+    public void setCBigInteger(Collection cBigInteger) {
+        this.cBigInteger = cBigInteger;
+    }
+
+    public Collection getCBigInteger() {
+        return cBigInteger;
+    }
+
+    public void setCBigDecimal(Collection cBigDecimal) {
+        this.cBigDecimal = cBigDecimal;
+    }
+
+    public Collection getCBigDecimal() {
+        return cBigDecimal;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SecondaryTab.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SecondaryTab.java
index 4c18b9b..75e6c2d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SecondaryTab.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SecondaryTab.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.SecondaryTable;
-import javax.persistence.SecondaryTables;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "sectables")
-@SecondaryTables({
-@SecondaryTable(name = "SEC1_TAB"),
-@SecondaryTable(name = "SEC2_TAB")
-    })
-public class SecondaryTab {
-
-    @Id
-    public int id;
-
-    @Basic
-    @Column(name = "strngfld", length = 50)
-    public String stringField;
-
-    public SecondaryTab() {
-    }
-
-    public SecondaryTab(int id) {
-        this.id = id;
-    }
-
-    public int getid() {
-        return id;
-    }
-
-    public void setid(int id) {
-        this.id = id;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "sectables")
+@SecondaryTables({
+@SecondaryTable(name = "SEC1_TAB"),
+@SecondaryTable(name = "SEC2_TAB")
+    })
+public class SecondaryTab {
+
+    @Id
+    public int id;
+
+    @Basic
+    @Column(name = "strngfld", length = 50)
+    public String stringField;
+
+    public SecondaryTab() {
+    }
+
+    public SecondaryTab(int id) {
+        this.id = id;
+    }
+
+    public int getid() {
+        return id;
+    }
+
+    public void setid(int id) {
+        this.id = id;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned.java
index 84e09f5..8a11e70 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned.java
@@ -1,91 +1,91 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "seqAssigned")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@IdClass(SequenceAssigned.SeqId.class)
-public class SequenceAssigned {
-
-    @Id
-    private long pk;
-
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private SequenceAssigned other;
-
-    public SequenceAssigned() {
-    }
-
-    public SequenceAssigned(long pk) {
-        this.pk = pk;
-    }
-
-    public void setPK(long l) {
-        pk = l;
-    }
-
-    public long getPK() {
-        return pk;
-    }
-
-    public void setOther(SequenceAssigned other) {
-        this.other = other;
-    }
-
-    public SequenceAssigned getOther() {
-        return other;
-    }
-
-    @SuppressWarnings("serial")
-    public static class SeqId implements java.io.Serializable {
-
-        public long pk;
-
-        public SeqId() {
-        }
-
-        public SeqId(String str) {
-            pk = Long.parseLong(str);
-        }
-
-        public int hashCode() {
-            return (int) (pk % (long) Integer.MAX_VALUE);
-        }
-
-        public String toString() {
-            return pk + "";
-        }
-
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof SeqId))
-                return false;
-            return pk == ((SeqId) o).pk;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "seqAssigned")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@IdClass(SequenceAssigned.SeqId.class)
+public class SequenceAssigned {
+
+    @Id
+    private long pk;
+
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private SequenceAssigned other;
+
+    public SequenceAssigned() {
+    }
+
+    public SequenceAssigned(long pk) {
+        this.pk = pk;
+    }
+
+    public void setPK(long l) {
+        pk = l;
+    }
+
+    public long getPK() {
+        return pk;
+    }
+
+    public void setOther(SequenceAssigned other) {
+        this.other = other;
+    }
+
+    public SequenceAssigned getOther() {
+        return other;
+    }
+
+    @SuppressWarnings("serial")
+    public static class SeqId implements java.io.Serializable {
+
+        public long pk;
+
+        public SeqId() {
+        }
+
+        public SeqId(String str) {
+            pk = Long.parseLong(str);
+        }
+
+        public int hashCode() {
+            return (int) (pk % (long) Integer.MAX_VALUE);
+        }
+
+        public String toString() {
+            return pk + "";
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof SeqId))
+                return false;
+            return pk == ((SeqId) o).pk;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned2.java
index 1e53681..74a33ea 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned2.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-@Entity
-@DiscriminatorValue("seqAss2")
-public class SequenceAssigned2 extends SequenceAssigned {
-
-    private int foo;
-
-    public SequenceAssigned2(long pk) {
-        super(pk);
-    }
-
-    public int getFoo() {
-        return foo;
-    }
-
-    public void setFoo(int foo) {
-        this.foo = foo;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("seqAss2")
+public class SequenceAssigned2 extends SequenceAssigned {
+
+    private int foo;
+
+    public SequenceAssigned2(long pk) {
+        super(pk);
+    }
+
+    public int getFoo() {
+        return foo;
+    }
+
+    public void setFoo(int foo) {
+        this.foo = foo;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned3.java
index 789f854..c42357e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SequenceAssigned3.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "seqAss3")
-@IdClass(SequenceAssigned3.seq3Id.class)
-public class SequenceAssigned3 {
-
-    @Id
-    private Long pk;
-
-    public SequenceAssigned3() {
-    }
-
-    public SequenceAssigned3(Long pk) {
-        this.pk = pk;
-    }
-
-    public void setPK(Long l) {
-        pk = l;
-    }
-
-    public Long getPK() {
-        return pk;
-    }
-
-    @SuppressWarnings("serial")
-    public static class seq3Id implements java.io.Serializable {
-
-        public Long pk;
-
-        public seq3Id() {
-        }
-
-        public seq3Id(String str) {
-            pk = Long.valueOf(str);
-        }
-
-        public int hashCode() {
-            return (int) (pk == null ? 0 : pk.longValue()
-                % (long) Integer.MAX_VALUE);
-        }
-
-        public String toString() {
-            return pk + "";
-        }
-
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof seq3Id))
-                return false;
-            return pk == ((seq3Id) o).pk;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "seqAss3")
+@IdClass(SequenceAssigned3.seq3Id.class)
+public class SequenceAssigned3 {
+
+    @Id
+    private Long pk;
+
+    public SequenceAssigned3() {
+    }
+
+    public SequenceAssigned3(Long pk) {
+        this.pk = pk;
+    }
+
+    public void setPK(Long l) {
+        pk = l;
+    }
+
+    public Long getPK() {
+        return pk;
+    }
+
+    @SuppressWarnings("serial")
+    public static class seq3Id implements java.io.Serializable {
+
+        public Long pk;
+
+        public seq3Id() {
+        }
+
+        public seq3Id(String str) {
+            pk = Long.valueOf(str);
+        }
+
+        public int hashCode() {
+            return (int) (pk == null ? 0 : pk.longValue()
+                % (long) Integer.MAX_VALUE);
+        }
+
+        public String toString() {
+            return pk + "";
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof seq3Id))
+                return false;
+            return pk == ((seq3Id) o).pk;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleId.java
index 17f9f78..ba30ad1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleId.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleId.java
@@ -1,30 +1,30 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-public interface SingleId {
-
-    public String getPkString();
-
-    public void setString(String s);
-
-    public String getString();
-
-    public boolean correctIdClass(Class oid);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+public interface SingleId {
+
+    public String getPkString();
+
+    public void setString(String s);
+
+    public String getString();
+
+    public boolean correctIdClass(Class oid);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdByte.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdByte.java
index 834d44f..f88fe0e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdByte.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdByte.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.ByteId;
-
-@Entity
-public class SingleIdByte implements SingleId {
-
-    private byte pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return ByteId.class.equals(c);
-    }
-
-    public byte getPk() {
-        return pk;
-    }
-
-    public void setPk(byte i) {
-        pk = i;
-    }
-
-    public String getPkString() {
-        return pk + "";
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.ByteId;
+
+@Entity
+public class SingleIdByte implements SingleId {
+
+    private byte pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return ByteId.class.equals(c);
+    }
+
+    public byte getPk() {
+        return pk;
+    }
+
+    public void setPk(byte i) {
+        pk = i;
+    }
+
+    public String getPkString() {
+        return pk + "";
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdChar.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdChar.java
index 8839927..21ddee6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdChar.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdChar.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.CharId;
-
-@Entity
-public class SingleIdChar implements SingleId {
-
-    private char pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return CharId.class.equals(c);
-    }
-
-    public char getPk() {
-        return pk;
-    }
-
-    public String getPkString() {
-        return pk + "";
-    }
-
-    public void setPk(char i) {
-        pk = i;
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.CharId;
+
+@Entity
+public class SingleIdChar implements SingleId {
+
+    private char pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return CharId.class.equals(c);
+    }
+
+    public char getPk() {
+        return pk;
+    }
+
+    public String getPkString() {
+        return pk + "";
+    }
+
+    public void setPk(char i) {
+        pk = i;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdInt.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdInt.java
index 753de7e..0d3da3e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdInt.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdInt.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.IntId;
-
-@Entity
-public class SingleIdInt implements SingleId {
-
-    private int pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return IntId.class.equals(c);
-    }
-
-    public String getPkString() {
-        return pk + "";
-    }
-
-    public int getPk() {
-        return pk;
-    }
-
-    public void setPk(int i) {
-        pk = i;
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.IntId;
+
+@Entity
+public class SingleIdInt implements SingleId {
+
+    private int pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return IntId.class.equals(c);
+    }
+
+    public String getPkString() {
+        return pk + "";
+    }
+
+    public int getPk() {
+        return pk;
+    }
+
+    public void setPk(int i) {
+        pk = i;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdLong.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdLong.java
index 43a6df6..751462a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdLong.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdLong.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.LongId;
-
-@Entity
-public class SingleIdLong implements SingleId {
-
-    private long pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return LongId.class.equals(c);
-    }
-
-    public String getPkString() {
-        return pk + "";
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setPk(long i) {
-        pk = i;
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.LongId;
+
+@Entity
+public class SingleIdLong implements SingleId {
+
+    private long pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return LongId.class.equals(c);
+    }
+
+    public String getPkString() {
+        return pk + "";
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setPk(long i) {
+        pk = i;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdShort.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdShort.java
index 7006162..608f907 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdShort.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdShort.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.ShortId;
-
-@Entity
-public class SingleIdShort implements SingleId {
-
-    private short pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return ShortId.class.equals(c);
-    }
-
-    public String getPkString() {
-        return pk + "";
-    }
-
-    public short getPk() {
-        return pk;
-    }
-
-    public void setPk(short i) {
-        pk = i;
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.ShortId;
+
+@Entity
+public class SingleIdShort implements SingleId {
+
+    private short pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return ShortId.class.equals(c);
+    }
+
+    public String getPkString() {
+        return pk + "";
+    }
+
+    public short getPk() {
+        return pk;
+    }
+
+    public void setPk(short i) {
+        pk = i;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdString.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdString.java
index 50b3d4e..3c3d7cb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdString.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdString.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.StringId;
-
-@Entity
-public class SingleIdString implements SingleId {
-
-    private String pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return StringId.class.equals(c);
-    }
-
-    public String getPk() {
-        return pk;
-    }
-
-    public String getPkString() {
-        return pk;
-    }
-
-    public void setPk(String i) {
-        pk = i;
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.StringId;
+
+@Entity
+public class SingleIdString implements SingleId {
+
+    private String pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return StringId.class.equals(c);
+    }
+
+    public String getPk() {
+        return pk;
+    }
+
+    public String getPkString() {
+        return pk;
+    }
+
+    public void setPk(String i) {
+        pk = i;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdWrapper.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdWrapper.java
index e3aed6b..494eddc 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdWrapper.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/SingleIdWrapper.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.util.IntId;
-
-@Entity
-public class SingleIdWrapper implements SingleId {
-
-    private Integer pk;
-    private String str;
-
-    public boolean correctIdClass(Class c) {
-        return IntId.class.equals(c);
-    }
-
-    public String getPkString() {
-        return pk == null ? "null" : pk.toString();
-    }
-
-    public int getPk() {
-        return pk.intValue();
-    }
-
-    public void setPk(int i) {
-        pk = new Integer(i);
-    }
-
-    public String getString() {
-        return str;
-    }
-
-    public void setString(String s) {
-        str = s;
-    }
-
-    public static void main(String[] args) {
-        SingleIdWrapper wrap = new SingleIdWrapper();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.util.IntId;
+
+@Entity
+public class SingleIdWrapper implements SingleId {
+
+    private Integer pk;
+    private String str;
+
+    public boolean correctIdClass(Class c) {
+        return IntId.class.equals(c);
+    }
+
+    public String getPkString() {
+        return pk == null ? "null" : pk.toString();
+    }
+
+    public int getPk() {
+        return pk.intValue();
+    }
+
+    public void setPk(int i) {
+        pk = new Integer(i);
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public void setString(String s) {
+        str = s;
+    }
+
+    public static void main(String[] args) {
+        SingleIdWrapper wrap = new SingleIdWrapper();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/TransactionalClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/TransactionalClassPC.java
index f49abad..a5edf61 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/TransactionalClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/TransactionalClassPC.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * <p>Transactional type used in testing.</p>
- *
- * @author Abe White
- */
-public class TransactionalClassPC {
-
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * <p>Transactional type used in testing.</p>
+ *
+ * @author Abe White
+ */
+public class TransactionalClassPC {
+
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/UnAnnotPojo.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/UnAnnotPojo.java
index b3598df..b18820c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/UnAnnotPojo.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/UnAnnotPojo.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-/**
- * <p>Pojo type used in testing.</p>
- *
- * @author Afam Okeke
- */
-public class UnAnnotPojo {
-
-    private String name;
-    private int num;
-
-    public UnAnnotPojo() {
-    }
-
-    public UnAnnotPojo(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public int getNum() {
-        return num;
-    }
-
-    public void setNum(int num) {
-        this.num = num;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+/**
+ * <p>Pojo type used in testing.</p>
+ *
+ * @author Afam Okeke
+ */
+public class UnAnnotPojo {
+
+    private String name;
+    private int num;
+
+    public UnAnnotPojo() {
+    }
+
+    public UnAnnotPojo(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getNum() {
+        return num;
+    }
+
+    public void setNum(int num) {
+        this.num = num;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ValueStrategyPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ValueStrategyPC.java
index 8d67c0f..57e4077 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ValueStrategyPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/ValueStrategyPC.java
@@ -1,132 +1,132 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.kernel.common.apps;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "valstratpc")
-public class ValueStrategyPC {
-
-    @Id
-    private int id;
-
-    @Column(length = 35)
-    private String uuid;
-    @Column(length = 35)
-    private String uuidHex;
-    @Column(length = 35)
-    private String name;
-    @Column(name = "ignupdate")
-    private int ignoreUpdate;
-    @Column(name = "resupdate")
-    private int restrictUpdate;
-    private int version;
-    private int sequence;
-
-    public ValueStrategyPC() {
-    }
-
-    public ValueStrategyPC(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public int getIgnoreUpdate() {
-        return this.ignoreUpdate;
-    }
-
-    public void setIgnoreUpdate(int ignoreUpdate) {
-        this.ignoreUpdate = ignoreUpdate;
-    }
-
-    public int getRestrictUpdate() {
-        return this.restrictUpdate;
-    }
-
-    public void setRestrictUpdate(int restrictUpdate) {
-        this.restrictUpdate = restrictUpdate;
-    }
-
-    public String getUUID() {
-        return this.uuid;
-    }
-
-    public void setUUID(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getUUIDHex() {
-        return this.uuidHex;
-    }
-
-    public void setUUIDHex(String uuidHex) {
-        this.uuidHex = uuidHex;
-    }
-
-    public int getVersion() {
-        return this.version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-
-    public int getSequence() {
-        return this.sequence;
-    }
-
-    public void setSequence(int sequence) {
-        this.sequence = sequence;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getUuidHex() {
-        return uuidHex;
-    }
-
-    public void setUuidHex(String uuidHex) {
-        this.uuidHex = uuidHex;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.kernel.common.apps;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "valstratpc")
+public class ValueStrategyPC {
+
+    @Id
+    private int id;
+
+    @Column(length = 35)
+    private String uuid;
+    @Column(length = 35)
+    private String uuidHex;
+    @Column(length = 35)
+    private String name;
+    @Column(name = "ignupdate")
+    private int ignoreUpdate;
+    @Column(name = "resupdate")
+    private int restrictUpdate;
+    private int version;
+    private int sequence;
+
+    public ValueStrategyPC() {
+    }
+
+    public ValueStrategyPC(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getIgnoreUpdate() {
+        return this.ignoreUpdate;
+    }
+
+    public void setIgnoreUpdate(int ignoreUpdate) {
+        this.ignoreUpdate = ignoreUpdate;
+    }
+
+    public int getRestrictUpdate() {
+        return this.restrictUpdate;
+    }
+
+    public void setRestrictUpdate(int restrictUpdate) {
+        this.restrictUpdate = restrictUpdate;
+    }
+
+    public String getUUID() {
+        return this.uuid;
+    }
+
+    public void setUUID(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getUUIDHex() {
+        return this.uuidHex;
+    }
+
+    public void setUUIDHex(String uuidHex) {
+        this.uuidHex = uuidHex;
+    }
+
+    public int getVersion() {
+        return this.version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public int getSequence() {
+        return this.sequence;
+    }
+
+    public void setSequence(int sequence) {
+        this.sequence = sequence;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getUuidHex() {
+        return uuidHex;
+    }
+
+    public void setUuidHex(String uuidHex) {
+        this.uuidHex = uuidHex;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestMergeAndPersistWithManagedRelation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestMergeAndPersistWithManagedRelation.java
index 2248964..7d95204 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestMergeAndPersistWithManagedRelation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestMergeAndPersistWithManagedRelation.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.lifecycle;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.relations.BidiChild;
-import org.apache.openjpa.persistence.relations.BidiParent;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestMergeAndPersistWithManagedRelation
-    extends SingleEMTestCase {
-
-    private long childId;
-
-    public void setUp() {
-        setUp(BidiParent.class, BidiChild.class, CLEAR_TABLES);
-
-        BidiChild child = new BidiChild();
-        child.setName("child");
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(child);
-        em.getTransaction().commit();
-        childId = child.getId();
-        em.close();
-    }
-
-    public void testPersistWithManagedRelation() {
-        BidiParent parent = new BidiParent();
-        BidiChild child = em.find(BidiChild.class, childId);
-        parent.setOneToOneChild(child);
-        em.getTransaction().begin();
-        em.persist(parent);
-        em.getTransaction().commit();
-        long id = parent.getId();
-        em.close();
-
-        em = emf.createEntityManager();
-        parent = em.find(BidiParent.class, id);
-        assertNotNull(parent);
-    }
-
-    public void testMergeWithManagedRelation() {
-        BidiParent parent = new BidiParent();
-        BidiChild child = em.find(BidiChild.class, childId);
-        parent.setOneToOneChild(child);
-        em.getTransaction().begin();
-        parent = em.merge(parent);
-        em.getTransaction().commit();
-        long id = parent.getId();
-        em.close();
-
-        em = emf.createEntityManager();
-        parent = em.find(BidiParent.class, id);
-        assertNotNull(parent);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.lifecycle;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.relations.BidiChild;
+import org.apache.openjpa.persistence.relations.BidiParent;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestMergeAndPersistWithManagedRelation
+    extends SingleEMTestCase {
+
+    private long childId;
+
+    public void setUp() {
+        setUp(BidiParent.class, BidiChild.class, CLEAR_TABLES);
+
+        BidiChild child = new BidiChild();
+        child.setName("child");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(child);
+        em.getTransaction().commit();
+        childId = child.getId();
+        em.close();
+    }
+
+    public void testPersistWithManagedRelation() {
+        BidiParent parent = new BidiParent();
+        BidiChild child = em.find(BidiChild.class, childId);
+        parent.setOneToOneChild(child);
+        em.getTransaction().begin();
+        em.persist(parent);
+        em.getTransaction().commit();
+        long id = parent.getId();
+        em.close();
+
+        em = emf.createEntityManager();
+        parent = em.find(BidiParent.class, id);
+        assertNotNull(parent);
+    }
+
+    public void testMergeWithManagedRelation() {
+        BidiParent parent = new BidiParent();
+        BidiChild child = em.find(BidiChild.class, childId);
+        parent.setOneToOneChild(child);
+        em.getTransaction().begin();
+        parent = em.merge(parent);
+        em.getTransaction().commit();
+        long id = parent.getId();
+        em.close();
+
+        em = emf.createEntityManager();
+        parent = em.find(BidiParent.class, id);
+        assertNotNull(parent);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestPessimisticPNonTransToPDirty.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestPessimisticPNonTransToPDirty.java
index 684e6b0..6b7ec8d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestPessimisticPNonTransToPDirty.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lifecycle/TestPessimisticPNonTransToPDirty.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.lifecycle;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestPessimisticPNonTransToPDirty
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(UnenhancedPropertyAccess.class, CLEAR_TABLES);
-
-        UnenhancedPropertyAccess o = new UnenhancedPropertyAccess();
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testPNonTransToPDirty() {
-        em.setOptimistic(false);
-        UnenhancedPropertyAccess o = (UnenhancedPropertyAccess)
-            em.createQuery("select o from UnenhancedPropertyAccess o")
-                .getSingleResult();
-        em.getTransaction().begin();
-        try {
-            Broker b = JPAFacadeHelper.toBroker(em);
-            OpenJPAStateManager sm = b.getStateManager(o);
-            assertEquals(PCState.PNONTRANS, sm.getPCState());
-            o.setLazyField("foo");
-            assertEquals(PCState.PDIRTY, sm.getPCState());
-        } finally {
-                em.getTransaction().rollback();
-        }
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.lifecycle;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestPessimisticPNonTransToPDirty
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(UnenhancedPropertyAccess.class, CLEAR_TABLES);
+
+        UnenhancedPropertyAccess o = new UnenhancedPropertyAccess();
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPNonTransToPDirty() {
+        em.setOptimistic(false);
+        UnenhancedPropertyAccess o = (UnenhancedPropertyAccess)
+            em.createQuery("select o from UnenhancedPropertyAccess o")
+                .getSingleResult();
+        em.getTransaction().begin();
+        try {
+            Broker b = JPAFacadeHelper.toBroker(em);
+            OpenJPAStateManager sm = b.getStateManager(o);
+            assertEquals(PCState.PNONTRANS, sm.getPCState());
+            o.setLazyField("foo");
+            assertEquals(PCState.PDIRTY, sm.getPCState());
+        } finally {
+                em.getTransaction().rollback();
+        }
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedIface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedIface.java
index 4103128..08ca30d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedIface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedIface.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import java.util.*;
-
-import javax.persistence.Entity;
-import javax.persistence.Embedded;
-import javax.persistence.OneToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.CascadeType;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.ManagedInterface;
-import org.apache.openjpa.persistence.query.SimpleEntity;
-
-@ManagedInterface
-@Entity
-public interface ManagedIface extends ManagedInterfaceSup {
-    public int getIntField();
-    public void setIntField(int i);
-
-    @Embedded
-    public ManagedInterfaceEmbed getEmbed();
-    public void setEmbed(ManagedInterfaceEmbed embed);
-
-    @OneToOne(cascade=CascadeType.PERSIST)
-    public ManagedIface getSelf();
-    public void setSelf(ManagedIface iface);
-
-    @PersistentCollection
-    public Set<Integer> getSetInteger();
-    public void setSetInteger(Set<Integer> collection);
-
-    @OneToMany(cascade=CascadeType.PERSIST)
-    public Set<SimpleEntity> getSetPC();
-    public void setSetPC(Set<SimpleEntity> collection);
-
-    @OneToMany(cascade=CascadeType.PERSIST)
-    public Set<ManagedIface> getSetI();
-    public void setSetI(Set<ManagedIface> collection);
-
-    @OneToOne(cascade=CascadeType.PERSIST)
-    public SimpleEntity getPC();
-    public void setPC(SimpleEntity pc);
-
-    public void unimplemented();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import java.util.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Embedded;
+import javax.persistence.OneToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.CascadeType;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.ManagedInterface;
+import org.apache.openjpa.persistence.query.SimpleEntity;
+
+@ManagedInterface
+@Entity
+public interface ManagedIface extends ManagedInterfaceSup {
+    public int getIntField();
+    public void setIntField(int i);
+
+    @Embedded
+    public ManagedInterfaceEmbed getEmbed();
+    public void setEmbed(ManagedInterfaceEmbed embed);
+
+    @OneToOne(cascade=CascadeType.PERSIST)
+    public ManagedIface getSelf();
+    public void setSelf(ManagedIface iface);
+
+    @PersistentCollection
+    public Set<Integer> getSetInteger();
+    public void setSetInteger(Set<Integer> collection);
+
+    @OneToMany(cascade=CascadeType.PERSIST)
+    public Set<SimpleEntity> getSetPC();
+    public void setSetPC(Set<SimpleEntity> collection);
+
+    @OneToMany(cascade=CascadeType.PERSIST)
+    public Set<ManagedIface> getSetI();
+    public void setSetI(Set<ManagedIface> collection);
+
+    @OneToOne(cascade=CascadeType.PERSIST)
+    public SimpleEntity getPC();
+    public void setPC(SimpleEntity pc);
+
+    public void unimplemented();
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceEmbed.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceEmbed.java
index 7da20f4..9687be6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceEmbed.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceEmbed.java
@@ -1,31 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.Embeddable;
-import javax.persistence.Basic;
-
-import org.apache.openjpa.persistence.ManagedInterface;
-
-@ManagedInterface
-@Embeddable
-public interface ManagedInterfaceEmbed {
-    public int getEmbedIntField();
-    public void setEmbedIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Basic;
+
+import org.apache.openjpa.persistence.ManagedInterface;
+
+@ManagedInterface
+@Embeddable
+public interface ManagedInterfaceEmbed {
+    public int getEmbedIntField();
+    public void setEmbedIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceOwner.java
index d13080b..1bd4efb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceOwner.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.OneToOne;
-import javax.persistence.Id;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.CascadeType;
-
-@Entity
-public class ManagedInterfaceOwner {
-
-    @Id
-    private int id;
-
-    private int intField;
-
-    @OneToOne(cascade=CascadeType.PERSIST)
-    private ManagedInterfaceSup iface;
-
-    @Embedded
-    private ManagedInterfaceEmbed embed;
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-
-    public ManagedInterfaceSup getIFace() {
-        return iface;
-    }
-
-    public void setIFace(ManagedInterfaceSup iface) {
-        this.iface = iface;
-    }
-
-    public ManagedInterfaceEmbed getEmbed() {
-        return embed;
-    }
-
-    public void setEmbed(ManagedInterfaceEmbed embed) {
-        this.embed = embed;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.OneToOne;
+import javax.persistence.Id;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.CascadeType;
+
+@Entity
+public class ManagedInterfaceOwner {
+
+    @Id
+    private int id;
+
+    private int intField;
+
+    @OneToOne(cascade=CascadeType.PERSIST)
+    private ManagedInterfaceSup iface;
+
+    @Embedded
+    private ManagedInterfaceEmbed embed;
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+
+    public ManagedInterfaceSup getIFace() {
+        return iface;
+    }
+
+    public void setIFace(ManagedInterfaceSup iface) {
+        this.iface = iface;
+    }
+
+    public ManagedInterfaceEmbed getEmbed() {
+        return embed;
+    }
+
+    public void setEmbed(ManagedInterfaceEmbed embed) {
+        this.embed = embed;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceSup.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceSup.java
index 4f53011..d9e553b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceSup.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/ManagedInterfaceSup.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-
-import org.apache.openjpa.persistence.ManagedInterface;
-
-@ManagedInterface
-@Entity
-public interface ManagedInterfaceSup {
-    @Id @GeneratedValue
-    public int getId();
-    public void setId(int id);
-
-    public int getIntFieldSup();
-    public void setIntFieldSup(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+import org.apache.openjpa.persistence.ManagedInterface;
+
+@ManagedInterface
+@Entity
+public interface ManagedInterfaceSup {
+    @Id @GeneratedValue
+    public int getId();
+    public void setId(int id);
+
+    public int getIntFieldSup();
+    public void setIntFieldSup(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterface.java
index 4e5b244..92b2f9f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterface.java
@@ -1,38 +1,38 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.ManagedInterface;
-
-@ManagedInterface
-@Entity
-public interface MixedInterface {
-
-    @Id
-    @GeneratedValue
-    public int getId();
-    public void setId(int id);
-
-    public int getIntField();
-    public void setIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.ManagedInterface;
+
+@ManagedInterface
+@Entity
+public interface MixedInterface {
+
+    @Id
+    @GeneratedValue
+    public int getId();
+    public void setId(int id);
+
+    public int getIntField();
+    public void setIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterfaceImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterfaceImpl.java
index 3bb1283..3c907cf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterfaceImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/MixedInterfaceImpl.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-
-@Entity
-public class MixedInterfaceImpl implements MixedInterface {
-    @Id
-    @GeneratedValue
-    private int id;
-
-    private int intField;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setIntField(int i) {
-        intField = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+@Entity
+public class MixedInterfaceImpl implements MixedInterface {
+    @Id
+    @GeneratedValue
+    private int id;
+
+    private int intField;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setIntField(int i) {
+        intField = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterface.java
index d235c7a..7d11ab7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterface.java
@@ -1,25 +1,25 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-public interface NonMappedInterface {
-    public int getIntField();
-
-    public void setIntField(int i);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+public interface NonMappedInterface {
+    public int getIntField();
+
+    public void setIntField(int i);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterfaceImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterfaceImpl.java
index 183b672..cfd83aa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterfaceImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/NonMappedInterfaceImpl.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.Entity;
-
-@Entity
-public class NonMappedInterfaceImpl
-    implements NonMappedInterface {
-    private int mismatch;
-
-    public int getIntField() {
-        return mismatch;
-    }
-
-    public void setIntField(int i) {
-        mismatch = i;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.Entity;
+
+@Entity
+public class NonMappedInterfaceImpl
+    implements NonMappedInterface {
+    private int mismatch;
+
+    public int getIntField() {
+        return mismatch;
+    }
+
+    public void setIntField(int i) {
+        mismatch = i;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/SimpleManagedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/SimpleManagedInterface.java
index 2a4af53..db606a4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/SimpleManagedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/SimpleManagedInterface.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.Id;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.ManagedInterface;
-
-@ManagedInterface
-@Entity
-public interface SimpleManagedInterface {
-
-    @Id
-    public int getId();
-    public void setId(int id);
-
-    public String getString();
-    public void setString(String s);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.Id;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.ManagedInterface;
+
+@ManagedInterface
+@Entity
+public interface SimpleManagedInterface {
+
+    @Id
+    public int getId();
+    public void setId(int id);
+
+    public String getString();
+    public void setString(String s);
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestManagedInterfaces.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestManagedInterfaces.java
index 5c0db50..e378fe1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestManagedInterfaces.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestManagedInterfaces.java
@@ -1,463 +1,463 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import java.util.Set;
-import java.util.HashSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import javax.persistence.Query;
-import javax.persistence.EntityNotFoundException;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.query.SimpleEntity;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.PersistenceException;
-
-public class TestManagedInterfaces extends SingleEMFTestCase {
-
-    @Override
-    public void setUp() {
-        super.setUp(SimpleEntity.class, ManagedInterfaceEmbed.class,
-            ManagedInterfaceSup.class, ManagedIface.class,
-            ManagedInterfaceOwner.class, MixedInterface.class,
-            MixedInterfaceImpl.class, NonMappedInterfaceImpl.class,
-            CLEAR_TABLES);
-    }
-
-    public void testEmbeddedMetaData() {
-        emf.createEntityManager().close();
-        ClassMetaData ownerMeta = JPAFacadeHelper.getMetaData(emf,
-            ManagedIface.class);
-        ClassMetaData embeddedMeta = ownerMeta.getField("embed")
-            .getDefiningMetaData();
-        assertTrue(embeddedMeta.isManagedInterface());
-        assertTrue(embeddedMeta.isIntercepting());
-
-        ClassMetaData embeddableMeta = JPAFacadeHelper.getMetaData(emf,
-            ManagedInterfaceEmbed.class);
-        assertTrue(embeddableMeta.isManagedInterface());
-        assertTrue(embeddableMeta.isIntercepting());
-    }
-
-    public void testManagedInterface() throws Exception {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        ManagedIface pc = em.createInstance(ManagedIface.class);
-        pc.setIntFieldSup(3);
-        pc.setIntField(4);
-        pc.setEmbed(em.createInstance(ManagedInterfaceEmbed.class));
-
-        pc.getEmbed().setEmbedIntField(5);
-        assertEquals(5, pc.getEmbed().getEmbedIntField());
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        assertEquals(3, pc.getIntFieldSup());
-        assertEquals(4, pc.getIntField());
-        assertEquals(5, pc.getEmbed().getEmbedIntField());
-        em.getTransaction().begin();
-        pc.setIntField(14);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager ();
-        em.getTransaction().begin();
-        Query query = em.createQuery("select o from ManagedIface o " +
-            "where o.intField = 14");
-        pc = (ManagedIface) query.getSingleResult();
-        assertEquals(14, pc.getIntField());
-        em.remove(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        try {
-            assertNull(em.find(ManagedIface.class, oid));
-        } catch (EntityNotFoundException onfe) {}
-
-        em.close();
-    }
-
-    public void testInterfaceOwner() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        ManagedInterfaceOwner pc = new ManagedInterfaceOwner();
-        pc.setIFace(em.createInstance(ManagedInterfaceSup.class));
-        pc.setEmbed(em.createInstance(ManagedInterfaceEmbed.class));
-        pc.getIFace().setIntFieldSup(3);
-        pc.getEmbed().setEmbedIntField(5);
-
-        em.getTransaction().begin();
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        em.getTransaction().commit();
-        pc = em.find(ManagedInterfaceOwner.class, oid);
-        assertEquals(3, pc.getIFace().getIntFieldSup());
-        assertEquals(5, pc.getEmbed().getEmbedIntField());
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedInterfaceOwner.class, oid);
-        assertEquals(3, pc.getIFace().getIntFieldSup());
-        assertEquals(5, pc.getEmbed().getEmbedIntField());
-        em.close();
-
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Query q = em.createQuery("select o from ManagedInterfaceOwner o " +
-            "where o.iface.intFieldSup = 3 and o.embed.embedIntField = 5");
-        pc = (ManagedInterfaceOwner) q.getSingleResult();
-        assertEquals(3, pc.getIFace().getIntFieldSup());
-        assertEquals(5, pc.getEmbed().getEmbedIntField());
-
-        pc.getIFace().setIntFieldSup(13);
-        pc.getEmbed().setEmbedIntField(15);
-        assertEquals(13, pc.getIFace().getIntFieldSup());
-        assertEquals(15, pc.getEmbed().getEmbedIntField());
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedInterfaceOwner.class, oid);
-        assertEquals(13, pc.getIFace().getIntFieldSup());
-        assertEquals(15, pc.getEmbed().getEmbedIntField());
-        em.close();
-    }
-
-    public void testCollection() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        ManagedIface pc = em.createInstance(ManagedIface.class);
-        Set set = new HashSet();
-        set.add(new Integer(3));
-        set.add(new Integer(4));
-        set.add(new Integer(5));
-        pc.setSetInteger(set);
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetInteger();
-        assertEquals(3, set.size());
-        assertTrue(set.contains(new Integer(3)));
-        assertTrue(set.contains(new Integer(4)));
-        assertTrue(set.contains(new Integer(5)));
-        em.getTransaction().begin();
-        set.remove(new Integer(4));
-        set.add(new Integer(14));
-        set.add(new Integer(15));
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetInteger();
-        assertEquals(4, set.size());
-        assertTrue(set.contains(new Integer(3)));
-        assertTrue(set.contains(new Integer(5)));
-        assertTrue(set.contains(new Integer(14)));
-        assertTrue(set.contains(new Integer(15)));
-        em.getTransaction().begin();
-        pc.setSetInteger(null);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetInteger();
-        assertTrue (set == null || set.size() == 0);
-        em.close();
-    }
-
-    public void testCollectionPC() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        ManagedIface pc = em.createInstance(ManagedIface.class);
-        Set set = new HashSet();
-        set.add(new SimpleEntity("a", "3"));
-        set.add(new SimpleEntity("b", "4"));
-        set.add(new SimpleEntity("c", "5"));
-        pc.setSetPC(set);
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetPC();
-        assertEquals(3, set.size());
-        Collection seen = new ArrayList();
-        SimpleEntity rel;
-        SimpleEntity toRem = null;
-        for (Iterator it = set.iterator(); it.hasNext();) {
-            rel = (SimpleEntity) it.next();
-            seen.add(rel.getName());
-            if (rel.getValue().equals("4"))
-                toRem = rel;
-        }
-        assertEquals(3, seen.size());
-        assertTrue(seen.contains("a"));
-        assertTrue(seen.contains("b"));
-        assertTrue(seen.contains("c"));
-        em.getTransaction().begin();
-        assertNotNull(toRem);
-        set.remove(toRem);
-        set.add(new SimpleEntity("x", "14"));
-        set.add(new SimpleEntity("y", "15"));
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetPC();
-        assertEquals(4, set.size());
-        seen.clear();
-        for (Iterator it = set.iterator(); it.hasNext();) {
-            rel = (SimpleEntity) it.next();
-            seen.add(rel.getName());
-        }
-        assertEquals(4, seen.size());
-        assertTrue(seen.contains("a"));
-        assertTrue(seen.contains("c"));
-        assertTrue(seen.contains("x"));
-        assertTrue(seen.contains("y"));
-        em.getTransaction().begin();
-        pc.setSetPC(null);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetPC();
-        assertTrue (set == null || set.size() == 0);
-        em.close();
-    }
-
-    public void testCollectionInterfaces() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        ManagedIface pc = em.createInstance(ManagedIface.class);
-        Set set = new HashSet();
-        set.add(createInstance(em, 3));
-        set.add(createInstance(em, 4));
-        set.add(createInstance(em, 5));
-        pc.setSetI(set);
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetI();
-        assertEquals(3, set.size());
-        Collection seen = new ArrayList();
-        ManagedIface rel = null;
-        ManagedIface toRem = null;
-        for (Iterator it = set.iterator(); it.hasNext();) {
-            rel = (ManagedIface) it.next();
-            seen.add(new Integer(rel.getIntField()));
-            if (rel.getIntField() == 4)
-                toRem = rel;
-        }
-        assertEquals(3, seen.size());
-        assertTrue(seen.contains(new Integer(3)));
-        assertTrue(seen.contains(new Integer(4)));
-        assertTrue(seen.contains(new Integer(5)));
-        em.getTransaction().begin();
-        assertNotNull(toRem);
-        set.remove(toRem);
-        set.add(createInstance(em, 14));
-        set.add(createInstance(em, 15));
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetI();
-        assertEquals(4, set.size());
-        seen.clear();
-        for (Iterator it = set.iterator(); it.hasNext();) {
-            rel = (ManagedIface) it.next();
-            seen.add(new Integer(rel.getIntField()));
-        }
-        assertEquals(4, seen.size());
-        assertTrue(seen.contains(new Integer(3)));
-        assertTrue(seen.contains(new Integer(5)));
-        assertTrue(seen.contains(new Integer(14)));
-        assertTrue(seen.contains(new Integer(15)));
-        em.getTransaction().begin();
-        pc.setSetPC(null);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        set = pc.getSetPC();
-        assertTrue (set == null || set.size() == 0);
-        em.close();
-    }
-
-    public void testMixedQuery() {
-        createMixed();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        Query q = em.createQuery("select o from MixedInterface o " +
-            "where o.intField = 4");
-        Collection c = q.getResultList();
-        Set seen = new HashSet();
-        assertEquals(2, c.size());
-        MixedInterface pc;
-        for (Iterator it = c.iterator(); it.hasNext();) {
-            pc = (MixedInterface) it.next();
-            assertEquals(4, pc.getIntField());
-            seen.add(pc.getClass());
-        }
-        assertEquals(2, seen.size());
-        
-        // Changes of OPENJPA-485 had the positive (but unintended) consequence
-        // of making this case pass, which was failing before as reported in
-        // OPENJPA-481
-    }
-
-    public void testQueryForMixedInterfaceImpls() {
-        createMixed();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        Query q = em.createQuery("select o from MixedInterfaceImpl o " +
-            "where o.intField = 4");
-        MixedInterface pc = (MixedInterface) q.getSingleResult();
-        assertEquals(4, pc.getIntField());
-        assertTrue(pc instanceof MixedInterfaceImpl);
-        em.close();
-    }
-
-    public void testMixedExtent() {
-        createMixed();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        Extent e = em.createExtent(MixedInterface.class, true);
-        Set seen = new HashSet();
-        int size = 0;
-        for (Iterator it = e.iterator(); it.hasNext();) {
-            seen.add(it.next().getClass());
-            size++;
-        }
-        assertEquals(3, size);
-        assertEquals(2, seen.size());
-
-        e = em.createExtent(MixedInterface.class, false);
-        seen = new HashSet();
-        size = 0;
-        for (Iterator it = e.iterator(); it.hasNext();) {
-            seen.add(it.next().getClass());
-            size++;
-        }
-        assertEquals(1, size);
-        assertNotEquals(MixedInterfaceImpl.class, seen.iterator().next());
-        em.close();
-    }
-
-    private void createMixed() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        MixedInterface pc = em.createInstance(MixedInterface.class);
-        pc.setIntField(4);
-        em.persist(pc);
-        pc = new MixedInterfaceImpl();
-        pc.setIntField(4);
-        em.persist(pc);
-        pc = new MixedInterfaceImpl();
-        pc.setIntField(8);
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testUnimplementedThrowsException() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        ManagedIface pc = createInstance(em, 1);
-        try {
-            pc.unimplemented();
-            fail("Exception expected.");
-        } catch (UnsupportedOperationException uoe) {} // good
-        em.close();
-    }
-
-    public void testNonMappedCreateInstanceException() {
-        // OpenJPA's support of non-mapped interfaces differs from JDO support;
-        // there is no special query or relation support for non-mapped
-        // interfaces in OpenJPA at this time.
-        OpenJPAEntityManager em = null;
-        try {
-            em = emf.createEntityManager();
-            em.createInstance(NonMappedInterface.class);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException e) {} // good
-        if (em != null)
-            em.close();
-    }
-
-    public void testDetach() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        ManagedIface pc = createInstance(em, 4);
-        em.persist(pc);
-        Object oid = em.getObjectId(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        ManagedIface pcx = em.find(ManagedIface.class, oid);
-        pc = em.detach(pcx);
-        em.close();
-
-        assertTrue(em.isDetached(pc));
-        pc.setIntField(7);
-
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.merge(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(ManagedIface.class, oid);
-        assertEquals(7, pc.getIntField());
-        em.close();
-    }
-
-    private ManagedIface createInstance(OpenJPAEntityManager em, int i) {
-        ManagedIface pc = em.createInstance(ManagedIface.class);
-        pc.setIntField(i);
-        return pc;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import javax.persistence.Query;
+import javax.persistence.EntityNotFoundException;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.query.SimpleEntity;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.PersistenceException;
+
+public class TestManagedInterfaces extends SingleEMFTestCase {
+
+    @Override
+    public void setUp() {
+        super.setUp(SimpleEntity.class, ManagedInterfaceEmbed.class,
+            ManagedInterfaceSup.class, ManagedIface.class,
+            ManagedInterfaceOwner.class, MixedInterface.class,
+            MixedInterfaceImpl.class, NonMappedInterfaceImpl.class,
+            CLEAR_TABLES);
+    }
+
+    public void testEmbeddedMetaData() {
+        emf.createEntityManager().close();
+        ClassMetaData ownerMeta = JPAFacadeHelper.getMetaData(emf,
+            ManagedIface.class);
+        ClassMetaData embeddedMeta = ownerMeta.getField("embed")
+            .getDefiningMetaData();
+        assertTrue(embeddedMeta.isManagedInterface());
+        assertTrue(embeddedMeta.isIntercepting());
+
+        ClassMetaData embeddableMeta = JPAFacadeHelper.getMetaData(emf,
+            ManagedInterfaceEmbed.class);
+        assertTrue(embeddableMeta.isManagedInterface());
+        assertTrue(embeddableMeta.isIntercepting());
+    }
+
+    public void testManagedInterface() throws Exception {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ManagedIface pc = em.createInstance(ManagedIface.class);
+        pc.setIntFieldSup(3);
+        pc.setIntField(4);
+        pc.setEmbed(em.createInstance(ManagedInterfaceEmbed.class));
+
+        pc.getEmbed().setEmbedIntField(5);
+        assertEquals(5, pc.getEmbed().getEmbedIntField());
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        assertEquals(3, pc.getIntFieldSup());
+        assertEquals(4, pc.getIntField());
+        assertEquals(5, pc.getEmbed().getEmbedIntField());
+        em.getTransaction().begin();
+        pc.setIntField(14);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager ();
+        em.getTransaction().begin();
+        Query query = em.createQuery("select o from ManagedIface o " +
+            "where o.intField = 14");
+        pc = (ManagedIface) query.getSingleResult();
+        assertEquals(14, pc.getIntField());
+        em.remove(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        try {
+            assertNull(em.find(ManagedIface.class, oid));
+        } catch (EntityNotFoundException onfe) {}
+
+        em.close();
+    }
+
+    public void testInterfaceOwner() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        ManagedInterfaceOwner pc = new ManagedInterfaceOwner();
+        pc.setIFace(em.createInstance(ManagedInterfaceSup.class));
+        pc.setEmbed(em.createInstance(ManagedInterfaceEmbed.class));
+        pc.getIFace().setIntFieldSup(3);
+        pc.getEmbed().setEmbedIntField(5);
+
+        em.getTransaction().begin();
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        em.getTransaction().commit();
+        pc = em.find(ManagedInterfaceOwner.class, oid);
+        assertEquals(3, pc.getIFace().getIntFieldSup());
+        assertEquals(5, pc.getEmbed().getEmbedIntField());
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedInterfaceOwner.class, oid);
+        assertEquals(3, pc.getIFace().getIntFieldSup());
+        assertEquals(5, pc.getEmbed().getEmbedIntField());
+        em.close();
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query q = em.createQuery("select o from ManagedInterfaceOwner o " +
+            "where o.iface.intFieldSup = 3 and o.embed.embedIntField = 5");
+        pc = (ManagedInterfaceOwner) q.getSingleResult();
+        assertEquals(3, pc.getIFace().getIntFieldSup());
+        assertEquals(5, pc.getEmbed().getEmbedIntField());
+
+        pc.getIFace().setIntFieldSup(13);
+        pc.getEmbed().setEmbedIntField(15);
+        assertEquals(13, pc.getIFace().getIntFieldSup());
+        assertEquals(15, pc.getEmbed().getEmbedIntField());
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedInterfaceOwner.class, oid);
+        assertEquals(13, pc.getIFace().getIntFieldSup());
+        assertEquals(15, pc.getEmbed().getEmbedIntField());
+        em.close();
+    }
+
+    public void testCollection() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ManagedIface pc = em.createInstance(ManagedIface.class);
+        Set set = new HashSet();
+        set.add(new Integer(3));
+        set.add(new Integer(4));
+        set.add(new Integer(5));
+        pc.setSetInteger(set);
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetInteger();
+        assertEquals(3, set.size());
+        assertTrue(set.contains(new Integer(3)));
+        assertTrue(set.contains(new Integer(4)));
+        assertTrue(set.contains(new Integer(5)));
+        em.getTransaction().begin();
+        set.remove(new Integer(4));
+        set.add(new Integer(14));
+        set.add(new Integer(15));
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetInteger();
+        assertEquals(4, set.size());
+        assertTrue(set.contains(new Integer(3)));
+        assertTrue(set.contains(new Integer(5)));
+        assertTrue(set.contains(new Integer(14)));
+        assertTrue(set.contains(new Integer(15)));
+        em.getTransaction().begin();
+        pc.setSetInteger(null);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetInteger();
+        assertTrue (set == null || set.size() == 0);
+        em.close();
+    }
+
+    public void testCollectionPC() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ManagedIface pc = em.createInstance(ManagedIface.class);
+        Set set = new HashSet();
+        set.add(new SimpleEntity("a", "3"));
+        set.add(new SimpleEntity("b", "4"));
+        set.add(new SimpleEntity("c", "5"));
+        pc.setSetPC(set);
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetPC();
+        assertEquals(3, set.size());
+        Collection seen = new ArrayList();
+        SimpleEntity rel;
+        SimpleEntity toRem = null;
+        for (Iterator it = set.iterator(); it.hasNext();) {
+            rel = (SimpleEntity) it.next();
+            seen.add(rel.getName());
+            if (rel.getValue().equals("4"))
+                toRem = rel;
+        }
+        assertEquals(3, seen.size());
+        assertTrue(seen.contains("a"));
+        assertTrue(seen.contains("b"));
+        assertTrue(seen.contains("c"));
+        em.getTransaction().begin();
+        assertNotNull(toRem);
+        set.remove(toRem);
+        set.add(new SimpleEntity("x", "14"));
+        set.add(new SimpleEntity("y", "15"));
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetPC();
+        assertEquals(4, set.size());
+        seen.clear();
+        for (Iterator it = set.iterator(); it.hasNext();) {
+            rel = (SimpleEntity) it.next();
+            seen.add(rel.getName());
+        }
+        assertEquals(4, seen.size());
+        assertTrue(seen.contains("a"));
+        assertTrue(seen.contains("c"));
+        assertTrue(seen.contains("x"));
+        assertTrue(seen.contains("y"));
+        em.getTransaction().begin();
+        pc.setSetPC(null);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetPC();
+        assertTrue (set == null || set.size() == 0);
+        em.close();
+    }
+
+    public void testCollectionInterfaces() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ManagedIface pc = em.createInstance(ManagedIface.class);
+        Set set = new HashSet();
+        set.add(createInstance(em, 3));
+        set.add(createInstance(em, 4));
+        set.add(createInstance(em, 5));
+        pc.setSetI(set);
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetI();
+        assertEquals(3, set.size());
+        Collection seen = new ArrayList();
+        ManagedIface rel = null;
+        ManagedIface toRem = null;
+        for (Iterator it = set.iterator(); it.hasNext();) {
+            rel = (ManagedIface) it.next();
+            seen.add(new Integer(rel.getIntField()));
+            if (rel.getIntField() == 4)
+                toRem = rel;
+        }
+        assertEquals(3, seen.size());
+        assertTrue(seen.contains(new Integer(3)));
+        assertTrue(seen.contains(new Integer(4)));
+        assertTrue(seen.contains(new Integer(5)));
+        em.getTransaction().begin();
+        assertNotNull(toRem);
+        set.remove(toRem);
+        set.add(createInstance(em, 14));
+        set.add(createInstance(em, 15));
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetI();
+        assertEquals(4, set.size());
+        seen.clear();
+        for (Iterator it = set.iterator(); it.hasNext();) {
+            rel = (ManagedIface) it.next();
+            seen.add(new Integer(rel.getIntField()));
+        }
+        assertEquals(4, seen.size());
+        assertTrue(seen.contains(new Integer(3)));
+        assertTrue(seen.contains(new Integer(5)));
+        assertTrue(seen.contains(new Integer(14)));
+        assertTrue(seen.contains(new Integer(15)));
+        em.getTransaction().begin();
+        pc.setSetPC(null);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        set = pc.getSetPC();
+        assertTrue (set == null || set.size() == 0);
+        em.close();
+    }
+
+    public void testMixedQuery() {
+        createMixed();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        Query q = em.createQuery("select o from MixedInterface o " +
+            "where o.intField = 4");
+        Collection c = q.getResultList();
+        Set seen = new HashSet();
+        assertEquals(2, c.size());
+        MixedInterface pc;
+        for (Iterator it = c.iterator(); it.hasNext();) {
+            pc = (MixedInterface) it.next();
+            assertEquals(4, pc.getIntField());
+            seen.add(pc.getClass());
+        }
+        assertEquals(2, seen.size());
+        
+        // Changes of OPENJPA-485 had the positive (but unintended) consequence
+        // of making this case pass, which was failing before as reported in
+        // OPENJPA-481
+    }
+
+    public void testQueryForMixedInterfaceImpls() {
+        createMixed();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        Query q = em.createQuery("select o from MixedInterfaceImpl o " +
+            "where o.intField = 4");
+        MixedInterface pc = (MixedInterface) q.getSingleResult();
+        assertEquals(4, pc.getIntField());
+        assertTrue(pc instanceof MixedInterfaceImpl);
+        em.close();
+    }
+
+    public void testMixedExtent() {
+        createMixed();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        Extent e = em.createExtent(MixedInterface.class, true);
+        Set seen = new HashSet();
+        int size = 0;
+        for (Iterator it = e.iterator(); it.hasNext();) {
+            seen.add(it.next().getClass());
+            size++;
+        }
+        assertEquals(3, size);
+        assertEquals(2, seen.size());
+
+        e = em.createExtent(MixedInterface.class, false);
+        seen = new HashSet();
+        size = 0;
+        for (Iterator it = e.iterator(); it.hasNext();) {
+            seen.add(it.next().getClass());
+            size++;
+        }
+        assertEquals(1, size);
+        assertNotEquals(MixedInterfaceImpl.class, seen.iterator().next());
+        em.close();
+    }
+
+    private void createMixed() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        MixedInterface pc = em.createInstance(MixedInterface.class);
+        pc.setIntField(4);
+        em.persist(pc);
+        pc = new MixedInterfaceImpl();
+        pc.setIntField(4);
+        em.persist(pc);
+        pc = new MixedInterfaceImpl();
+        pc.setIntField(8);
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testUnimplementedThrowsException() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        ManagedIface pc = createInstance(em, 1);
+        try {
+            pc.unimplemented();
+            fail("Exception expected.");
+        } catch (UnsupportedOperationException uoe) {} // good
+        em.close();
+    }
+
+    public void testNonMappedCreateInstanceException() {
+        // OpenJPA's support of non-mapped interfaces differs from JDO support;
+        // there is no special query or relation support for non-mapped
+        // interfaces in OpenJPA at this time.
+        OpenJPAEntityManager em = null;
+        try {
+            em = emf.createEntityManager();
+            em.createInstance(NonMappedInterface.class);
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException e) {} // good
+        if (em != null)
+            em.close();
+    }
+
+    public void testDetach() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ManagedIface pc = createInstance(em, 4);
+        em.persist(pc);
+        Object oid = em.getObjectId(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        ManagedIface pcx = em.find(ManagedIface.class, oid);
+        pc = em.detach(pcx);
+        em.close();
+
+        assertTrue(em.isDetached(pc));
+        pc.setIntField(7);
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.merge(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(ManagedIface.class, oid);
+        assertEquals(7, pc.getIntField());
+        em.close();
+    }
+
+    private ManagedIface createInstance(OpenJPAEntityManager em, int i) {
+        ManagedIface pc = em.createInstance(ManagedIface.class);
+        pc.setIntField(i);
+        return pc;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestSimpleManagedInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestSimpleManagedInterface.java
index da567bb..1264815 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestSimpleManagedInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/managedinterface/TestSimpleManagedInterface.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.managedinterface;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.query.SimpleEntity;
-import org.apache.openjpa.kernel.AbstractBrokerFactory;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-
-public class TestSimpleManagedInterface
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(SimpleManagedInterface.class, SimpleEntity.class, CLEAR_TABLES);
-    }
-
-    public void testMetaDataRepository() {
-        AbstractBrokerFactory bf =
-            (AbstractBrokerFactory) JPAFacadeHelper.toBrokerFactory(emf);
-        bf.makeReadOnly();
-        MetaDataRepository repos = bf.getConfiguration()
-            .getMetaDataRepositoryInstance();
-        ClassMetaData meta = repos.getMetaData(SimpleManagedInterface.class,
-            null, false);
-        assertNotNull(meta);
-        assertTrue(meta.isManagedInterface());
-        assertEquals(SimpleManagedInterface.class, meta.getDescribedType());
-    }
-
-    public void testInterfaceImplGeneration() {
-        ((AbstractBrokerFactory) JPAFacadeHelper.toBrokerFactory(emf))
-            .makeReadOnly();
-        // load metadata to trigger instance creation
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
-            SimpleManagedInterface.class);
-        assertEquals(SimpleManagedInterface.class, meta.getDescribedType());
-    }
-
-    public void testBasicOperations() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        SimpleManagedInterface pc =
-            em.createInstance(SimpleManagedInterface.class);
-        pc.setId(17);
-        pc.setString("hello!");
-        em.getTransaction().begin();
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        pc = em.find(SimpleManagedInterface.class, 17);
-        assertNotNull(pc);
-        em.getTransaction().begin();
-        pc.setString("updated");
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.remove(em.getReference(SimpleManagedInterface.class, 17));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testJPQL() {
-        EntityManager em = emf.createEntityManager();
-        assertEquals(0, em.createQuery("select o from SimpleManagedInterface o")
-            .getResultList().size());
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.managedinterface;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.query.SimpleEntity;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+
+public class TestSimpleManagedInterface
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(SimpleManagedInterface.class, SimpleEntity.class, CLEAR_TABLES);
+    }
+
+    public void testMetaDataRepository() {
+        AbstractBrokerFactory bf =
+            (AbstractBrokerFactory) JPAFacadeHelper.toBrokerFactory(emf);
+        bf.makeReadOnly();
+        MetaDataRepository repos = bf.getConfiguration()
+            .getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(SimpleManagedInterface.class,
+            null, false);
+        assertNotNull(meta);
+        assertTrue(meta.isManagedInterface());
+        assertEquals(SimpleManagedInterface.class, meta.getDescribedType());
+    }
+
+    public void testInterfaceImplGeneration() {
+        ((AbstractBrokerFactory) JPAFacadeHelper.toBrokerFactory(emf))
+            .makeReadOnly();
+        // load metadata to trigger instance creation
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
+            SimpleManagedInterface.class);
+        assertEquals(SimpleManagedInterface.class, meta.getDescribedType());
+    }
+
+    public void testBasicOperations() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        SimpleManagedInterface pc =
+            em.createInstance(SimpleManagedInterface.class);
+        pc.setId(17);
+        pc.setString("hello!");
+        em.getTransaction().begin();
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(SimpleManagedInterface.class, 17);
+        assertNotNull(pc);
+        em.getTransaction().begin();
+        pc.setString("updated");
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.remove(em.getReference(SimpleManagedInterface.class, 17));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testJPQL() {
+        EntityManager em = emf.createEntityManager();
+        assertEquals(0, em.createQuery("select o from SimpleManagedInterface o")
+            .getResultList().size());
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/TestCascadeOneToManyMerge.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/TestCascadeOneToManyMerge.java
new file mode 100644
index 0000000..87cd9cd
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/TestCascadeOneToManyMerge.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.merge;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.merge.model.Toy;
+import org.apache.openjpa.persistence.merge.model.ToyBox;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestCascadeOneToManyMerge extends SingleEMFTestCase {
+    public void setUp() {
+        setUp(Toy.class, ToyBox.class, CLEAR_TABLES);
+    }
+
+    /**
+     * Create an instance of Toy and Toybox, establish the bidirectional relationship between the two, and call
+     * em.merge() on the instance of Toybox. The merge should cascade across the inverse relationship, adding both
+     * entities to the persistence context. The reference to Toy by the owning side of the relationship should be
+     * updated to point to the managed instance (Toy' because of the merge op).
+     * 
+     */
+    public void testOneToManyCascadeMergeSingleEntity() {
+        EntityManager em = emf.createEntityManager();
+
+        try {
+            // Create toy
+            Toy toy = new Toy(1);
+            toy.setToyName("Toy Train");
+
+            // Create toybox
+            ToyBox toybox = new ToyBox(1);
+            toybox.setOwnerName("Evan");
+
+            // Establish relationship
+            toy.setToybox(toybox);
+            toybox.getToyList().add(toy);
+
+            // Perform the merge
+            em.getTransaction().begin();
+            ToyBox mergedToyBox = em.merge(toybox);
+            assertNotNull("Assert em.merge() didn't return null", mergedToyBox);
+
+            // Verify the merge
+            ToyBox toyboxFind = em.find(ToyBox.class, 1);
+            Toy toyFind = em.find(Toy.class, 1);
+            assertNotNull("Assert em.find() for ToyBox(id=1) did not return null.", toyboxFind);
+            assertNotNull("Assert em.find() for Toy(id=1) did not return null.", toyFind);
+            assertTrue("Assert em.find() returns the ToyBox returned by em.merge()", mergedToyBox == toyboxFind);
+            assertTrue("Assert tahat ToyBox(id=1).toyList is size 1", toyboxFind.getToyList().size() == 1);
+            assertTrue("Assert that ToyBox(id=1).toyList contains the managed Toy(id=1).", toyboxFind.getToyList()
+                .contains(toyFind));
+            assertTrue("Assert that Toy(id=1) references the managed ToyBox(id=1).", toyFind.getToybox() == toyboxFind);
+
+            em.getTransaction().commit();
+
+            // Verify successful save to the database
+            em.clear();
+            assertNotNull("Assert em.find(Toy.class, 1) doesn't return null.", em.find(Toy.class, 1));
+            assertNotNull("Assert em.find(ToyBox.class, 1) doesn't return null.", em.find(ToyBox.class, 1));
+        } finally {
+            if (em != null) {
+                if (em.getTransaction().isActive())
+                    em.getTransaction().rollback();
+                em.close();
+            }
+        }
+    }
+
+    /**
+     * Create an instance of Toys (2) and Toybox, establish the bidirectional relationship between the two, and call
+     * em.merge() on the instance of Toybox. The merge should cascade across the inverse relationship, adding all
+     * entities to the persistence context. The reference to the Toys by the owning side of the relationship should be
+     * updated to point to the managed instance (Toy' because of the merge op).
+     * 
+     */
+    public void testOneToManyCascadeMergeDoubleEntity() {
+        EntityManager em = emf.createEntityManager();
+
+        try {
+            // Create toys
+            Toy toy1 = new Toy(1);
+            toy1.setToyName("Toy Train");
+
+            Toy toy2 = new Toy(2);
+            toy2.setToyName("Toy Plane");
+
+            // Create toybox
+            ToyBox toybox = new ToyBox(1);
+            toybox.setOwnerName("Evan");
+
+            // Establish relationship
+            toy1.setToybox(toybox);
+            toy2.setToybox(toybox);
+            toybox.getToyList().add(toy1);
+            toybox.getToyList().add(toy2);
+
+            // Perform the merge
+            em.getTransaction().begin();
+            ToyBox mergedToyBox = em.merge(toybox);
+            assertNotNull("Assert em.merge() didn't return null", mergedToyBox);
+            em.getTransaction().commit();
+
+            // Verify the merge
+            ToyBox toyboxFind = em.find(ToyBox.class, 1);
+            Toy toy1Find = em.find(Toy.class, 1);
+            Toy toy2Find = em.find(Toy.class, 2);
+            assertNotNull("Assert em.find() for ToyBox(id=1) did not return null.", toyboxFind);
+            assertNotNull("Assert em.find() for Toy(id=1) did not return null.", toy1Find);
+            assertNotNull("Assert em.find() for Toy(id=2) did not return null.", toy2Find);
+            assertTrue("Assert em.find() returns the ToyBox returned by em.merge()", mergedToyBox == toyboxFind);
+            assertTrue("Assert tahat ToyBox(id=1).toyList is size 2", toyboxFind.getToyList().size() == 2);
+            assertTrue("Assert that ToyBox(id=1).toyList contains the managed Toy(id=1).", toyboxFind.getToyList()
+                .contains(toy1Find));
+            assertTrue("Assert that ToyBox(id=1).toyList contains the managed Toy(id=2).", toyboxFind.getToyList()
+                .contains(toy2Find));
+            assertTrue("Assert that Toy(id=1) references the managed ToyBox(id=1).",
+                toy1Find.getToybox() == toyboxFind);
+            assertTrue("Assert that Toy(id=2) references the managed ToyBox(id=1).", 
+                toy2Find.getToybox() == toyboxFind);
+
+            em.clear();
+            assertNotNull("Assert em.find(Toy.class, 1) doesn't return null.", em.find(Toy.class, 1));
+            assertNotNull("Assert em.find(Toy.class, 2) doesn't return null.", em.find(Toy.class, 2));
+            assertNotNull("Assert em.find(ToyBox.class, 1) doesn't return null.", em.find(ToyBox.class, 1));
+        } finally {
+            if (em != null) {
+                if (em.getTransaction().isActive())
+                    em.getTransaction().rollback();
+                em.close();
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/model/Toy.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/model/Toy.java
new file mode 100644
index 0000000..dab4156
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/model/Toy.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.merge.model;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class Toy {
+    @Id
+    private int id;
+
+    private String toyName;
+
+    @ManyToOne(optional = false, fetch = FetchType.LAZY)
+    private ToyBox toybox;
+
+    @Version
+    private long version;
+
+    public Toy() {
+
+    }
+
+    public Toy(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getToyName() {
+        return toyName;
+    }
+
+    public void setToyName(String toyName) {
+        this.toyName = toyName;
+    }
+
+    public ToyBox getToybox() {
+        return toybox;
+    }
+
+    public void setToybox(ToyBox toybox) {
+        this.toybox = toybox;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/model/ToyBox.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/model/ToyBox.java
new file mode 100644
index 0000000..a42027a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/merge/model/ToyBox.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.merge.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Version;
+
+@Entity
+public class ToyBox {
+    @Id
+    private int id;
+
+    @Basic
+    private String ownerName;
+
+    @OneToMany(mappedBy = "toybox", cascade = CascadeType.ALL)
+    private List<Toy> toyList;
+
+    @Version
+    private long version;
+
+    public ToyBox() {
+        toyList = new ArrayList<Toy>();
+    }
+
+    public ToyBox(int id) {
+        this.id = id;
+        toyList = new ArrayList<Toy>();
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getOwnerName() {
+        return ownerName;
+    }
+
+    public void setOwnerName(String ownerName) {
+        this.ownerName = ownerName;
+    }
+
+    public List<Toy> getToyList() {
+        return toyList;
+    }
+
+    public void setToyList(List<Toy> toyList) {
+        this.toyList = toyList;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestClassMetaData.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestClassMetaData.java
index 8300912..b90de89 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestClassMetaData.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestClassMetaData.java
@@ -1,309 +1,309 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-import java.util.Map;
-import javax.persistence.EntityManager;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest1;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest2;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest3;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest5;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest6;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-/**
- * <p>Tests the {@link ClassMetaData} type, and in so doing tests parts of
- * the {@link MetaDataRepository} and {@link FieldMetaData} types.</p>
- *
- * @author Abe White
- */
-public class TestClassMetaData
-    extends AbstractTestCase {
-
-    private MetaDataRepository _repos = null;
-
-    private ClassMetaData _metaTest1 = null;
-    private ClassMetaData _metaTest2 = null;
-    private ClassMetaData _metaTest3 = null;
-    private ClassMetaData _metaTest5 = null;
-    private ClassMetaData _metaTest6 = null;
-
-    public TestClassMetaData(String test) {
-        super(test, "metacactusapp");
-    }
-
-    public void setUp()
-        throws Exception {
-        _repos = getRepository();
-        _metaTest5 = _repos.getMetaData(MetaTest5.class, null, true);
-        _metaTest3 = _repos.getMetaData(MetaTest3.class, null, true);
-        _metaTest2 = _repos.getMetaData(MetaTest2.class, null, true);
-        _metaTest1 = _repos.getMetaData(MetaTest1.class, null, true);
-        _metaTest6 = _repos.getMetaData(MetaTest6.class, null, true);
-    }
-
-    protected MetaDataRepository getRepository()
-        throws Exception {
-        //return new OpenJPAConfigurationImpl().newMetaDataRepositoryInstance();
-        //return getConfiguration().newMetaDataRepositoryInstance();
-        EntityManager em = currentEntityManager();
-        Broker broker = JPAFacadeHelper.toBroker(em);
-        return broker.getConfiguration().newMetaDataRepositoryInstance();
-    }
-
-    /**
-     * Test the class-level defaults.
-     */
-    public void testClassDefaults() {
-        assertEquals(MetaTest1.class.getName(),
-            _metaTest1.getDescribedType().getName());
-        assertNull(_metaTest1.getPCSuperclass());
-        assertEquals(ClassMetaData.ID_DATASTORE,
-            _metaTest1.getIdentityType());
-        assertTrue(_metaTest1.getRequiresExtent());
-    }
-
-    /**
-     * Test non-persistent fields.
-     */
-    public void testDefaultNonPersistentFields() {
-        assertNull(_metaTest1.getField("staticField"));
-        assertNull(_metaTest1.getField("finalfield"));
-        assertNull(_metaTest1.getField("transientfield"));
-        assertNull(_metaTest1.getField("metaTest4Field"));
-        assertNull(_metaTest1.getField("metaTest4ArrayField"));
-        assertNull(_metaTest1.getField("objectField"));
-        assertNull(_metaTest1.getField("longWrapperField"));
-
-        FieldMetaData fmd = _metaTest1.getField("doubleField");
-        assertEquals(FieldMetaData.MANAGE_TRANSACTIONAL, fmd.getManagement());
-    }
-
-    /**
-     * Test basics on persistent fields.
-     */
-    public void testBasicFields() {
-        FieldMetaData fmd;
-        fmd = _metaTest1.getField("stringField");
-        assertEquals(JavaTypes.STRING, fmd.getTypeCode());
-        assertEquals(JavaTypes.STRING, fmd.getDeclaredTypeCode());
-        assertNull(fmd.getTypeMetaData());
-        assertNull(fmd.getDeclaredTypeMetaData());
-        fmd = _metaTest1.getField("intWrapperField");
-        assertEquals(JavaTypes.INT_OBJ, fmd.getTypeCode());
-        assertEquals(JavaTypes.INT_OBJ, fmd.getDeclaredTypeCode());
-        fmd = _metaTest1.getField("intField");
-        assertEquals(JavaTypes.INT, fmd.getTypeCode());
-        assertEquals(JavaTypes.INT, fmd.getDeclaredTypeCode());
-        fmd = _metaTest1.getField("metaTest2Field");
-        assertEquals(JavaTypes.PC, fmd.getTypeCode());
-        assertEquals(JavaTypes.PC, fmd.getDeclaredTypeCode());
-        assertEquals(_metaTest2, fmd.getTypeMetaData());
-        assertEquals(_metaTest2, fmd.getDeclaredTypeMetaData());
-        fmd = _metaTest1.getField("metaTest2ArrayField");
-        assertEquals(JavaTypes.ARRAY, fmd.getTypeCode());
-        assertEquals(JavaTypes.PC, fmd.getElement().getTypeCode());
-        assertEquals(JavaTypes.ARRAY, fmd.getDeclaredTypeCode());
-        assertEquals(JavaTypes.PC,
-            fmd.getElement().getDeclaredTypeCode());
-        fmd = _metaTest1.getField("intArrayField");
-        assertEquals(JavaTypes.ARRAY, fmd.getTypeCode());
-        assertEquals(JavaTypes.INT, fmd.getElement().getTypeCode());
-        assertEquals(JavaTypes.ARRAY, fmd.getDeclaredTypeCode());
-        assertEquals(JavaTypes.INT,
-            fmd.getElement().getDeclaredTypeCode());
-        fmd = _metaTest1.getField("intField");
-        assertEquals(FieldMetaData.NULL_EXCEPTION, fmd.getNullValue());
-        assertTrue(!fmd.isInDefaultFetchGroup());
-        assertTrue(!fmd.isEmbedded());
-        fmd = _metaTest1.getField("stringField");
-        assertEquals(FieldMetaData.NULL_UNSET, fmd.getNullValue());
-        assertTrue(fmd.isInDefaultFetchGroup());
-        assertTrue(fmd.isEmbedded());
-    }
-
-    /**
-     * Test collection and map fields.
-     */
-    public void testCollectionFields() {
-        FieldMetaData fmd;
-        fmd = _metaTest2.getField("collectionField1");
-        assertEquals(JavaTypes.COLLECTION, fmd.getTypeCode());
-        assertEquals(JavaTypes.OBJECT, fmd.getElement().getTypeCode());
-        assertEquals(Object.class, fmd.getElement().getType());
-        assertNull(fmd.getElement().getTypeMetaData());
-        assertEquals(JavaTypes.COLLECTION,
-            fmd.getDeclaredTypeCode());
-        assertEquals(JavaTypes.OBJECT,
-            fmd.getElement().getDeclaredTypeCode());
-        assertEquals(Object.class, fmd.getElement().getDeclaredType());
-        assertNull(fmd.getElement().getTypeMetaData());
-        assertTrue(fmd.getElement().isEmbedded());
-        fmd = _metaTest2.getField("collectionField2");
-        assertEquals(JavaTypes.COLLECTION, fmd.getTypeCode());
-        assertEquals(JavaTypes.PC, fmd.getElement().getTypeCode());
-        assertEquals(MetaTest3.class, fmd.getElement().getType());
-        assertEquals(_metaTest3, fmd.getElement().getTypeMetaData());
-        assertEquals(JavaTypes.COLLECTION,
-            fmd.getDeclaredTypeCode());
-        assertEquals(JavaTypes.PC,
-            fmd.getElement().getDeclaredTypeCode());
-        assertEquals(MetaTest3.class, fmd.getElement().getDeclaredType());
-        assertEquals(_metaTest3, fmd.getElement().getDeclaredTypeMetaData());
-        assertTrue(!fmd.getElement().isEmbedded());
-
-        fmd = _metaTest2.getField("mapField1");
-        assertEquals(JavaTypes.MAP, fmd.getTypeCode());
-        assertEquals(JavaTypes.OBJECT, fmd.getKey().getTypeCode());
-        assertEquals(JavaTypes.OBJECT, fmd.getElement().getTypeCode());
-        assertEquals(Object.class, fmd.getKey().getType());
-        assertNull(fmd.getKey().getTypeMetaData());
-        assertEquals(Object.class, fmd.getElement().getType());
-        assertEquals(JavaTypes.MAP, fmd.getDeclaredTypeCode());
-        assertEquals(JavaTypes.OBJECT, fmd.getKey().getDeclaredTypeCode());
-        assertEquals(JavaTypes.OBJECT,
-            fmd.getElement().getDeclaredTypeCode());
-        assertEquals(Object.class, fmd.getKey().getDeclaredType());
-        assertNull(fmd.getKey().getDeclaredTypeMetaData());
-        assertEquals(Object.class, fmd.getElement().getDeclaredType());
-        assertTrue(fmd.getKey().isEmbedded());
-        assertTrue(fmd.getElement().isEmbedded());
-        fmd = _metaTest2.getField("mapField2");
-        assertEquals(JavaTypes.MAP, fmd.getTypeCode());
-        assertEquals(JavaTypes.STRING, fmd.getKey().getTypeCode());
-        assertEquals(JavaTypes.INT_OBJ, fmd.getElement().getTypeCode());
-        assertEquals(String.class, fmd.getKey().getType());
-        assertEquals(Integer.class, fmd.getElement().getType());
-        assertEquals(JavaTypes.MAP, fmd.getDeclaredTypeCode());
-        assertEquals(JavaTypes.STRING, fmd.getKey().getDeclaredTypeCode());
-        assertEquals(JavaTypes.INT_OBJ,
-            fmd.getElement().getDeclaredTypeCode());
-        assertEquals(String.class, fmd.getKey().getDeclaredType());
-        assertEquals(Integer.class, fmd.getElement().getDeclaredType());
-        assertTrue(fmd.getKey().isEmbedded());
-        assertTrue(!fmd.getElement().isEmbedded());
-    }
-
-    /**
-     * Test the basic class-level meta data.
-     */
-    public void testBasicClass() {
-        assertEquals(_metaTest1, _metaTest2.getPCSuperclassMetaData());
-        assertTrue(!_metaTest2.getRequiresExtent());
-    }
-
-    /**
-     * Test application identity.
-     */
-    public void testApplicationIdentity() {
-        assertEquals(ClassMetaData.ID_APPLICATION,
-            _metaTest5.getIdentityType());
-        assertEquals(MetaTest5.MetaTest5Id.class.getName(),
-            _metaTest5.getObjectIdType().getName());
-        assertEquals(ClassMetaData.ID_APPLICATION,
-            _metaTest6.getIdentityType());
-        assertEquals(MetaTest5.MetaTest5Id.class.getName(),
-            _metaTest6.getObjectIdType().getName());
-    }
-
-    /**
-     * Test absolute field numbering.
-     */
-    public void testAbsoluteFieldNumbering() {
-        assertEquals(0, _metaTest1.getField("doubleField").getIndex());
-        assertEquals(1, _metaTest1.getField("intArrayField").getIndex());
-        assertEquals(2, _metaTest1.getField("intField").getIndex());
-        assertEquals(3, _metaTest1.getField("intWrapperField").getIndex());
-        assertEquals(4, _metaTest1.getField("metaTest2ArrayField").
-            getIndex());
-        assertEquals(5, _metaTest1.getField("metaTest2Field").getIndex());
-        assertEquals(6, _metaTest1.getField("stringField").getIndex());
-        assertEquals(7, _metaTest2.getField("collectionField1").getIndex());
-        assertEquals(8, _metaTest2.getField("collectionField2").getIndex());
-        assertEquals(9, _metaTest2.getField("mapField1").getIndex());
-        assertEquals(10, _metaTest2.getField("mapField2").getIndex());
-    }
-
-    /**
-     * Test the methods to get fields.
-     */
-    public void testGetFields() {
-        FieldMetaData[] fmds = _metaTest2.getFields();
-        assertEquals("doubleField", fmds[0].getName());
-        assertEquals("intField", fmds[2].getName());
-        assertEquals("collectionField2", fmds[8].getName());
-    }
-
-    /**
-     * Test that metadata on inner classes is available.
-     */
-    public void testStaticInnerClasses() {
-        assertNotNull(_repos.getMetaData(MetaTest1.Inner.class, null, true));
-    }
-
-    /**
-     * Test extensions for external values and declared vs external types.
-     */
-    public void testExternalTypes() {
-        // note that below, declared type code is promoted
-        FieldMetaData fmd = _metaTest3.getField("pcField");
-        assertEquals(JavaTypes.PC_UNTYPED, fmd.getTypeCode());
-        assertEquals(JavaTypes.PC_UNTYPED, fmd.getDeclaredTypeCode());
-        assertEquals(PersistenceCapable.class, fmd.getType());
-        assertEquals(Object.class, fmd.getDeclaredType());
-        assertNull(fmd.getDeclaredTypeMetaData());
-        assertNull(fmd.getTypeMetaData());
-
-        // note that below, declared type code is promoted
-        fmd = _metaTest3.getField("metaField");
-        assertEquals(JavaTypes.PC, fmd.getTypeCode());
-        assertEquals(JavaTypes.PC, fmd.getDeclaredTypeCode());
-        assertEquals(MetaTest2.class, fmd.getType());
-        assertEquals(Object.class, fmd.getDeclaredType());
-        assertEquals(_metaTest2, fmd.getDeclaredTypeMetaData());
-        assertEquals(_metaTest2, fmd.getTypeMetaData());
-
-        fmd = _metaTest3.getField("externalField");
-        assertTrue(fmd.isExternalized());
-        assertEquals(JavaTypes.MAP, fmd.getTypeCode());
-        assertEquals(JavaTypes.OBJECT, fmd.getDeclaredTypeCode());
-        assertEquals(Map.class, fmd.getType());
-        assertEquals(Object.class, fmd.getDeclaredType());
-        assertEquals(JavaTypes.STRING, fmd.getKey().getTypeCode());
-        assertEquals(JavaTypes.OBJECT, fmd.getKey().getDeclaredTypeCode());
-        assertEquals(String.class, fmd.getKey().getType());
-        assertEquals(Object.class, fmd.getKey().getDeclaredType());
-        assertEquals(JavaTypes.PC, fmd.getElement().getTypeCode());
-        assertEquals(JavaTypes.OBJECT,
-            fmd.getElement().getDeclaredTypeCode());
-        assertEquals(MetaTest2.class, fmd.getElement().getType());
-        assertEquals(Object.class, fmd.getElement().getDeclaredType());
-        assertEquals(_metaTest2, fmd.getElement().getTypeMetaData());
-        assertNull(fmd.getElement().getDeclaredTypeMetaData());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest1;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest2;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest3;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest5;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest6;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+/**
+ * <p>Tests the {@link ClassMetaData} type, and in so doing tests parts of
+ * the {@link MetaDataRepository} and {@link FieldMetaData} types.</p>
+ *
+ * @author Abe White
+ */
+public class TestClassMetaData
+    extends AbstractTestCase {
+
+    private MetaDataRepository _repos = null;
+
+    private ClassMetaData _metaTest1 = null;
+    private ClassMetaData _metaTest2 = null;
+    private ClassMetaData _metaTest3 = null;
+    private ClassMetaData _metaTest5 = null;
+    private ClassMetaData _metaTest6 = null;
+
+    public TestClassMetaData(String test) {
+        super(test, "metacactusapp");
+    }
+
+    public void setUp()
+        throws Exception {
+        _repos = getRepository();
+        _metaTest5 = _repos.getMetaData(MetaTest5.class, null, true);
+        _metaTest3 = _repos.getMetaData(MetaTest3.class, null, true);
+        _metaTest2 = _repos.getMetaData(MetaTest2.class, null, true);
+        _metaTest1 = _repos.getMetaData(MetaTest1.class, null, true);
+        _metaTest6 = _repos.getMetaData(MetaTest6.class, null, true);
+    }
+
+    protected MetaDataRepository getRepository()
+        throws Exception {
+        //return new OpenJPAConfigurationImpl().newMetaDataRepositoryInstance();
+        //return getConfiguration().newMetaDataRepositoryInstance();
+        EntityManager em = currentEntityManager();
+        Broker broker = JPAFacadeHelper.toBroker(em);
+        return broker.getConfiguration().newMetaDataRepositoryInstance();
+    }
+
+    /**
+     * Test the class-level defaults.
+     */
+    public void testClassDefaults() {
+        assertEquals(MetaTest1.class.getName(),
+            _metaTest1.getDescribedType().getName());
+        assertNull(_metaTest1.getPCSuperclass());
+        assertEquals(ClassMetaData.ID_DATASTORE,
+            _metaTest1.getIdentityType());
+        assertTrue(_metaTest1.getRequiresExtent());
+    }
+
+    /**
+     * Test non-persistent fields.
+     */
+    public void testDefaultNonPersistentFields() {
+        assertNull(_metaTest1.getField("staticField"));
+        assertNull(_metaTest1.getField("finalfield"));
+        assertNull(_metaTest1.getField("transientfield"));
+        assertNull(_metaTest1.getField("metaTest4Field"));
+        assertNull(_metaTest1.getField("metaTest4ArrayField"));
+        assertNull(_metaTest1.getField("objectField"));
+        assertNull(_metaTest1.getField("longWrapperField"));
+
+        FieldMetaData fmd = _metaTest1.getField("doubleField");
+        assertEquals(FieldMetaData.MANAGE_TRANSACTIONAL, fmd.getManagement());
+    }
+
+    /**
+     * Test basics on persistent fields.
+     */
+    public void testBasicFields() {
+        FieldMetaData fmd;
+        fmd = _metaTest1.getField("stringField");
+        assertEquals(JavaTypes.STRING, fmd.getTypeCode());
+        assertEquals(JavaTypes.STRING, fmd.getDeclaredTypeCode());
+        assertNull(fmd.getTypeMetaData());
+        assertNull(fmd.getDeclaredTypeMetaData());
+        fmd = _metaTest1.getField("intWrapperField");
+        assertEquals(JavaTypes.INT_OBJ, fmd.getTypeCode());
+        assertEquals(JavaTypes.INT_OBJ, fmd.getDeclaredTypeCode());
+        fmd = _metaTest1.getField("intField");
+        assertEquals(JavaTypes.INT, fmd.getTypeCode());
+        assertEquals(JavaTypes.INT, fmd.getDeclaredTypeCode());
+        fmd = _metaTest1.getField("metaTest2Field");
+        assertEquals(JavaTypes.PC, fmd.getTypeCode());
+        assertEquals(JavaTypes.PC, fmd.getDeclaredTypeCode());
+        assertEquals(_metaTest2, fmd.getTypeMetaData());
+        assertEquals(_metaTest2, fmd.getDeclaredTypeMetaData());
+        fmd = _metaTest1.getField("metaTest2ArrayField");
+        assertEquals(JavaTypes.ARRAY, fmd.getTypeCode());
+        assertEquals(JavaTypes.PC, fmd.getElement().getTypeCode());
+        assertEquals(JavaTypes.ARRAY, fmd.getDeclaredTypeCode());
+        assertEquals(JavaTypes.PC,
+            fmd.getElement().getDeclaredTypeCode());
+        fmd = _metaTest1.getField("intArrayField");
+        assertEquals(JavaTypes.ARRAY, fmd.getTypeCode());
+        assertEquals(JavaTypes.INT, fmd.getElement().getTypeCode());
+        assertEquals(JavaTypes.ARRAY, fmd.getDeclaredTypeCode());
+        assertEquals(JavaTypes.INT,
+            fmd.getElement().getDeclaredTypeCode());
+        fmd = _metaTest1.getField("intField");
+        assertEquals(FieldMetaData.NULL_EXCEPTION, fmd.getNullValue());
+        assertTrue(!fmd.isInDefaultFetchGroup());
+        assertTrue(!fmd.isEmbedded());
+        fmd = _metaTest1.getField("stringField");
+        assertEquals(FieldMetaData.NULL_UNSET, fmd.getNullValue());
+        assertTrue(fmd.isInDefaultFetchGroup());
+        assertTrue(fmd.isEmbedded());
+    }
+
+    /**
+     * Test collection and map fields.
+     */
+    public void testCollectionFields() {
+        FieldMetaData fmd;
+        fmd = _metaTest2.getField("collectionField1");
+        assertEquals(JavaTypes.COLLECTION, fmd.getTypeCode());
+        assertEquals(JavaTypes.OBJECT, fmd.getElement().getTypeCode());
+        assertEquals(Object.class, fmd.getElement().getType());
+        assertNull(fmd.getElement().getTypeMetaData());
+        assertEquals(JavaTypes.COLLECTION,
+            fmd.getDeclaredTypeCode());
+        assertEquals(JavaTypes.OBJECT,
+            fmd.getElement().getDeclaredTypeCode());
+        assertEquals(Object.class, fmd.getElement().getDeclaredType());
+        assertNull(fmd.getElement().getTypeMetaData());
+        assertTrue(fmd.getElement().isEmbedded());
+        fmd = _metaTest2.getField("collectionField2");
+        assertEquals(JavaTypes.COLLECTION, fmd.getTypeCode());
+        assertEquals(JavaTypes.PC, fmd.getElement().getTypeCode());
+        assertEquals(MetaTest3.class, fmd.getElement().getType());
+        assertEquals(_metaTest3, fmd.getElement().getTypeMetaData());
+        assertEquals(JavaTypes.COLLECTION,
+            fmd.getDeclaredTypeCode());
+        assertEquals(JavaTypes.PC,
+            fmd.getElement().getDeclaredTypeCode());
+        assertEquals(MetaTest3.class, fmd.getElement().getDeclaredType());
+        assertEquals(_metaTest3, fmd.getElement().getDeclaredTypeMetaData());
+        assertTrue(!fmd.getElement().isEmbedded());
+
+        fmd = _metaTest2.getField("mapField1");
+        assertEquals(JavaTypes.MAP, fmd.getTypeCode());
+        assertEquals(JavaTypes.OBJECT, fmd.getKey().getTypeCode());
+        assertEquals(JavaTypes.OBJECT, fmd.getElement().getTypeCode());
+        assertEquals(Object.class, fmd.getKey().getType());
+        assertNull(fmd.getKey().getTypeMetaData());
+        assertEquals(Object.class, fmd.getElement().getType());
+        assertEquals(JavaTypes.MAP, fmd.getDeclaredTypeCode());
+        assertEquals(JavaTypes.OBJECT, fmd.getKey().getDeclaredTypeCode());
+        assertEquals(JavaTypes.OBJECT,
+            fmd.getElement().getDeclaredTypeCode());
+        assertEquals(Object.class, fmd.getKey().getDeclaredType());
+        assertNull(fmd.getKey().getDeclaredTypeMetaData());
+        assertEquals(Object.class, fmd.getElement().getDeclaredType());
+        assertTrue(fmd.getKey().isEmbedded());
+        assertTrue(fmd.getElement().isEmbedded());
+        fmd = _metaTest2.getField("mapField2");
+        assertEquals(JavaTypes.MAP, fmd.getTypeCode());
+        assertEquals(JavaTypes.STRING, fmd.getKey().getTypeCode());
+        assertEquals(JavaTypes.INT_OBJ, fmd.getElement().getTypeCode());
+        assertEquals(String.class, fmd.getKey().getType());
+        assertEquals(Integer.class, fmd.getElement().getType());
+        assertEquals(JavaTypes.MAP, fmd.getDeclaredTypeCode());
+        assertEquals(JavaTypes.STRING, fmd.getKey().getDeclaredTypeCode());
+        assertEquals(JavaTypes.INT_OBJ,
+            fmd.getElement().getDeclaredTypeCode());
+        assertEquals(String.class, fmd.getKey().getDeclaredType());
+        assertEquals(Integer.class, fmd.getElement().getDeclaredType());
+        assertTrue(fmd.getKey().isEmbedded());
+        assertTrue(!fmd.getElement().isEmbedded());
+    }
+
+    /**
+     * Test the basic class-level meta data.
+     */
+    public void testBasicClass() {
+        assertEquals(_metaTest1, _metaTest2.getPCSuperclassMetaData());
+        assertTrue(!_metaTest2.getRequiresExtent());
+    }
+
+    /**
+     * Test application identity.
+     */
+    public void testApplicationIdentity() {
+        assertEquals(ClassMetaData.ID_APPLICATION,
+            _metaTest5.getIdentityType());
+        assertEquals(MetaTest5.MetaTest5Id.class.getName(),
+            _metaTest5.getObjectIdType().getName());
+        assertEquals(ClassMetaData.ID_APPLICATION,
+            _metaTest6.getIdentityType());
+        assertEquals(MetaTest5.MetaTest5Id.class.getName(),
+            _metaTest6.getObjectIdType().getName());
+    }
+
+    /**
+     * Test absolute field numbering.
+     */
+    public void testAbsoluteFieldNumbering() {
+        assertEquals(0, _metaTest1.getField("doubleField").getIndex());
+        assertEquals(1, _metaTest1.getField("intArrayField").getIndex());
+        assertEquals(2, _metaTest1.getField("intField").getIndex());
+        assertEquals(3, _metaTest1.getField("intWrapperField").getIndex());
+        assertEquals(4, _metaTest1.getField("metaTest2ArrayField").
+            getIndex());
+        assertEquals(5, _metaTest1.getField("metaTest2Field").getIndex());
+        assertEquals(6, _metaTest1.getField("stringField").getIndex());
+        assertEquals(7, _metaTest2.getField("collectionField1").getIndex());
+        assertEquals(8, _metaTest2.getField("collectionField2").getIndex());
+        assertEquals(9, _metaTest2.getField("mapField1").getIndex());
+        assertEquals(10, _metaTest2.getField("mapField2").getIndex());
+    }
+
+    /**
+     * Test the methods to get fields.
+     */
+    public void testGetFields() {
+        FieldMetaData[] fmds = _metaTest2.getFields();
+        assertEquals("doubleField", fmds[0].getName());
+        assertEquals("intField", fmds[2].getName());
+        assertEquals("collectionField2", fmds[8].getName());
+    }
+
+    /**
+     * Test that metadata on inner classes is available.
+     */
+    public void testStaticInnerClasses() {
+        assertNotNull(_repos.getMetaData(MetaTest1.Inner.class, null, true));
+    }
+
+    /**
+     * Test extensions for external values and declared vs external types.
+     */
+    public void testExternalTypes() {
+        // note that below, declared type code is promoted
+        FieldMetaData fmd = _metaTest3.getField("pcField");
+        assertEquals(JavaTypes.PC_UNTYPED, fmd.getTypeCode());
+        assertEquals(JavaTypes.PC_UNTYPED, fmd.getDeclaredTypeCode());
+        assertEquals(PersistenceCapable.class, fmd.getType());
+        assertEquals(Object.class, fmd.getDeclaredType());
+        assertNull(fmd.getDeclaredTypeMetaData());
+        assertNull(fmd.getTypeMetaData());
+
+        // note that below, declared type code is promoted
+        fmd = _metaTest3.getField("metaField");
+        assertEquals(JavaTypes.PC, fmd.getTypeCode());
+        assertEquals(JavaTypes.PC, fmd.getDeclaredTypeCode());
+        assertEquals(MetaTest2.class, fmd.getType());
+        assertEquals(Object.class, fmd.getDeclaredType());
+        assertEquals(_metaTest2, fmd.getDeclaredTypeMetaData());
+        assertEquals(_metaTest2, fmd.getTypeMetaData());
+
+        fmd = _metaTest3.getField("externalField");
+        assertTrue(fmd.isExternalized());
+        assertEquals(JavaTypes.MAP, fmd.getTypeCode());
+        assertEquals(JavaTypes.OBJECT, fmd.getDeclaredTypeCode());
+        assertEquals(Map.class, fmd.getType());
+        assertEquals(Object.class, fmd.getDeclaredType());
+        assertEquals(JavaTypes.STRING, fmd.getKey().getTypeCode());
+        assertEquals(JavaTypes.OBJECT, fmd.getKey().getDeclaredTypeCode());
+        assertEquals(String.class, fmd.getKey().getType());
+        assertEquals(Object.class, fmd.getKey().getDeclaredType());
+        assertEquals(JavaTypes.PC, fmd.getElement().getTypeCode());
+        assertEquals(JavaTypes.OBJECT,
+            fmd.getElement().getDeclaredTypeCode());
+        assertEquals(MetaTest2.class, fmd.getElement().getType());
+        assertEquals(Object.class, fmd.getElement().getDeclaredType());
+        assertEquals(_metaTest2, fmd.getElement().getTypeMetaData());
+        assertNull(fmd.getElement().getDeclaredTypeMetaData());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestExternalValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestExternalValues.java
index c6db1d2..2b14f09 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestExternalValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestExternalValues.java
@@ -1,195 +1,195 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-
-import java.util.List;
-import java.util.UUID;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.meta.common.apps.ExternalValues;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.ArgumentException;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-/**
- * <p>Tests the {@link ExternalValuesFieldMapping}.</p>
- *
- * @author Abe White
- * @author Pinaki Poddar (added binding query parameter tests) 
- */
-public class TestExternalValues
-    extends AbstractTestCase {
-    
-    public TestExternalValues(String test) {
-        super(test, "metacactusapp");
-    }
-
-    public void setUp()
-        throws Exception {
-        deleteAll(ExternalValues.class);
-    }
-
-    public void testInsert() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-
-        ExternalValues pc = new ExternalValues();
-        pc.setBooleanToShort(true);
-        pc.setByteToDouble((byte) 4);
-        pc.setIntToFloat(4);
-        pc.setLongToChar(4);
-        pc.setShortToString((short) 4);
-        pc.setFloatToBoolean(4.5f);
-        pc.setDoubleToByte(4.5);
-        pc.setCharToInt('f');
-        pc.setStringToLong("foo");
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ExternalValues) pm.find(ExternalValues.class, oid);
-
-        assertTrue(pc.getBooleanToShort());
-        assertEquals((byte) 4, pc.getByteToDouble());
-        assertEquals(4, pc.getIntToFloat());
-        assertEquals(4, pc.getLongToChar());
-        assertEquals((short) 4, pc.getShortToString());
-        assertTrue(4.5f == pc.getFloatToBoolean());
-        assertTrue(4.5 == pc.getDoubleToByte());
-        assertEquals('f', pc.getCharToInt());
-        assertEquals("foo", pc.getStringToLong());
-
-        endEm(pm);
-    }
-
-    public void testComplexStrings() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-
-        ExternalValues pc = new ExternalValues();
-        pc.setShortToString((short) 3);
-        pc.setStringToLong("long string");
-
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ExternalValues) pm.find(ExternalValues.class, oid);
-        assertEquals(3, pc.getShortToString());
-        endEm(pm);
-    }
-
-    public void testAllNull() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-
-        ExternalValues pc = new ExternalValues();
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ExternalValues) pm.find(ExternalValues.class, oid);
-        endEm(pm);
-    }
-    
-    public void testPositionalBindingQueryParameterEqualsDeclaredType() {
-        UUID uuid = new UUID(1,4);
-        createInstance(uuid);
-        
-        EntityManager em = currentEntityManager();
-        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=?1";
-        List<ExternalValues> result = em.createQuery(jpql)
-                                        .setParameter(1, uuid)
-                                        .getResultList();
-        assertFalse(result.isEmpty());
-        for (ExternalValues x:result) {
-            assertEquals(uuid, x.getUuid());
-        }
-    }
-    
-    public void testNamedBindingQueryParameterEqualsDeclaredType() {
-        UUID uuid = new UUID(2,4);
-        createInstance(uuid);
-        
-        EntityManager em = currentEntityManager();
-        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=:uuid";
-        List<ExternalValues> result = em.createQuery(jpql)
-                                        .setParameter("uuid", uuid)
-                                        .getResultList();
-        assertFalse(result.isEmpty());
-        for (ExternalValues pc:result) {
-            assertEquals(uuid, pc.getUuid());
-        }
-    }
-    
-    public void testPositionalBindingQueryParameterNotEqualsExternalizedType() {
-        UUID uuid = new UUID(1,4);
-        createInstance(uuid);
-        
-        EntityManager em = currentEntityManager();
-        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=?1";
-        Query query = em.createQuery(jpql)
-                        .setParameter(1, uuid.toString());
-                                        
-        try {
-            query.getResultList();
-            fail("Expected ArgumentException");
-       } catch (ArgumentException ex) {
-           // expected
-       }
-    }
-
-    public void testNamedBindingQueryParameterNotEqualsExternalizedType() {
-        UUID uuid = new UUID(2,4);
-        createInstance(uuid);
-        
-        EntityManager em = currentEntityManager();
-        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=:uuid";
-        Query query = em.createQuery(jpql)
-                        .setParameter("uuid", uuid.toString());
-        try {
-             query.getResultList();
-             fail("Expected ArgumentException");
-        } catch (ArgumentException ex) {
-            // expected
-        }
-    }
-    
-    private void createInstance(UUID uuid) {
-        EntityManager em = currentEntityManager();
-        em.getTransaction().begin();
-        ExternalValues pc = new ExternalValues();
-        pc.setUuid(uuid);
-        em.persist(pc);
-        em.getTransaction().commit();
-        em.clear();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.meta.common.apps.ExternalValues;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.ArgumentException;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * <p>Tests the {@link ExternalValuesFieldMapping}.</p>
+ *
+ * @author Abe White
+ * @author Pinaki Poddar (added binding query parameter tests) 
+ */
+public class TestExternalValues
+    extends AbstractTestCase {
+    
+    public TestExternalValues(String test) {
+        super(test, "metacactusapp");
+    }
+
+    public void setUp()
+        throws Exception {
+        deleteAll(ExternalValues.class);
+    }
+
+    public void testInsert() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+
+        ExternalValues pc = new ExternalValues();
+        pc.setBooleanToShort(true);
+        pc.setByteToDouble((byte) 4);
+        pc.setIntToFloat(4);
+        pc.setLongToChar(4);
+        pc.setShortToString((short) 4);
+        pc.setFloatToBoolean(4.5f);
+        pc.setDoubleToByte(4.5);
+        pc.setCharToInt('f');
+        pc.setStringToLong("foo");
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ExternalValues) pm.find(ExternalValues.class, oid);
+
+        assertTrue(pc.getBooleanToShort());
+        assertEquals((byte) 4, pc.getByteToDouble());
+        assertEquals(4, pc.getIntToFloat());
+        assertEquals(4, pc.getLongToChar());
+        assertEquals((short) 4, pc.getShortToString());
+        assertTrue(4.5f == pc.getFloatToBoolean());
+        assertTrue(4.5 == pc.getDoubleToByte());
+        assertEquals('f', pc.getCharToInt());
+        assertEquals("foo", pc.getStringToLong());
+
+        endEm(pm);
+    }
+
+    public void testComplexStrings() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+
+        ExternalValues pc = new ExternalValues();
+        pc.setShortToString((short) 3);
+        pc.setStringToLong("long string");
+
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ExternalValues) pm.find(ExternalValues.class, oid);
+        assertEquals(3, pc.getShortToString());
+        endEm(pm);
+    }
+
+    public void testAllNull() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+
+        ExternalValues pc = new ExternalValues();
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ExternalValues) pm.find(ExternalValues.class, oid);
+        endEm(pm);
+    }
+    
+    public void testPositionalBindingQueryParameterEqualsDeclaredType() {
+        UUID uuid = new UUID(1,4);
+        createInstance(uuid);
+        
+        EntityManager em = currentEntityManager();
+        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=?1";
+        List<ExternalValues> result = em.createQuery(jpql)
+                                        .setParameter(1, uuid)
+                                        .getResultList();
+        assertFalse(result.isEmpty());
+        for (ExternalValues x:result) {
+            assertEquals(uuid, x.getUuid());
+        }
+    }
+    
+    public void testNamedBindingQueryParameterEqualsDeclaredType() {
+        UUID uuid = new UUID(2,4);
+        createInstance(uuid);
+        
+        EntityManager em = currentEntityManager();
+        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=:uuid";
+        List<ExternalValues> result = em.createQuery(jpql)
+                                        .setParameter("uuid", uuid)
+                                        .getResultList();
+        assertFalse(result.isEmpty());
+        for (ExternalValues pc:result) {
+            assertEquals(uuid, pc.getUuid());
+        }
+    }
+    
+    public void testPositionalBindingQueryParameterNotEqualsExternalizedType() {
+        UUID uuid = new UUID(1,4);
+        createInstance(uuid);
+        
+        EntityManager em = currentEntityManager();
+        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=?1";
+        Query query = em.createQuery(jpql)
+                        .setParameter(1, uuid.toString());
+                                        
+        try {
+            query.getResultList();
+            fail("Expected ArgumentException");
+       } catch (ArgumentException ex) {
+           // expected
+       }
+    }
+
+    public void testNamedBindingQueryParameterNotEqualsExternalizedType() {
+        UUID uuid = new UUID(2,4);
+        createInstance(uuid);
+        
+        EntityManager em = currentEntityManager();
+        String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=:uuid";
+        Query query = em.createQuery(jpql)
+                        .setParameter("uuid", uuid.toString());
+        try {
+             query.getResultList();
+             fail("Expected ArgumentException");
+        } catch (ArgumentException ex) {
+            // expected
+        }
+    }
+    
+    private void createInstance(UUID uuid) {
+        EntityManager em = currentEntityManager();
+        em.getTransaction().begin();
+        ExternalValues pc = new ExternalValues();
+        pc.setUuid(uuid);
+        em.persist(pc);
+        em.getTransaction().commit();
+        em.clear();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestFieldDeclarationOrder.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestFieldDeclarationOrder.java
index 1c1c6f4..640eb30 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestFieldDeclarationOrder.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestFieldDeclarationOrder.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.FieldOrderPC;
-import org.apache.openjpa.persistence.meta.common.apps.FieldOrderPCSubclass;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-public class TestFieldDeclarationOrder
-    extends AbstractTestCase {
-
-    public TestFieldDeclarationOrder(String test) {
-        super(test, "metacactusapp");
-    }
-
-    public void testSubclass() {
-        ClassMetaData meta = JPAFacadeHelper
-            .getMetaData(getEmf(),
-                FieldOrderPCSubclass.class);
-        FieldMetaData[] fmds = meta.getFieldsInListingOrder();
-
-        assertEquals(11, fmds.length);
-        assertEquals("firstField", fmds[0].getName());
-        assertEquals("secondField", fmds[1].getName());
-        assertEquals("thirdField", fmds[2].getName());
-        assertEquals("unmanagedField", fmds[3].getName());
-        assertEquals("intField", fmds[4].getName());
-        assertEquals("oneToOneField", fmds[5].getName());
-        assertEquals("sub1", fmds[6].getName());
-        assertEquals("sub2", fmds[7].getName());
-        assertEquals("sub3", fmds[8].getName());
-        assertEquals("unmanagedSubField", fmds[9].getName());
-        assertEquals("undeclaredSubField", fmds[10].getName());
-    }
-
-    public void testSuperclass() {
-        ClassMetaData meta = JPAFacadeHelper
-            .getMetaData(getEmf(),
-                FieldOrderPC.class);
-        FieldMetaData[] fmds = meta.getFieldsInListingOrder();
-
-        assertEquals(6, fmds.length);
-        assertEquals("firstField", fmds[0].getName());
-        assertEquals("secondField", fmds[1].getName());
-        assertEquals("thirdField", fmds[2].getName());
-        assertEquals("unmanagedField", fmds[3].getName());
-        assertEquals("intField", fmds[4].getName());
-        assertEquals("oneToOneField", fmds[5].getName());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.FieldOrderPC;
+import org.apache.openjpa.persistence.meta.common.apps.FieldOrderPCSubclass;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+public class TestFieldDeclarationOrder
+    extends AbstractTestCase {
+
+    public TestFieldDeclarationOrder(String test) {
+        super(test, "metacactusapp");
+    }
+
+    public void testSubclass() {
+        ClassMetaData meta = JPAFacadeHelper
+            .getMetaData(getEmf(),
+                FieldOrderPCSubclass.class);
+        FieldMetaData[] fmds = meta.getFieldsInListingOrder();
+
+        assertEquals(11, fmds.length);
+        assertEquals("firstField", fmds[0].getName());
+        assertEquals("secondField", fmds[1].getName());
+        assertEquals("thirdField", fmds[2].getName());
+        assertEquals("unmanagedField", fmds[3].getName());
+        assertEquals("intField", fmds[4].getName());
+        assertEquals("oneToOneField", fmds[5].getName());
+        assertEquals("sub1", fmds[6].getName());
+        assertEquals("sub2", fmds[7].getName());
+        assertEquals("sub3", fmds[8].getName());
+        assertEquals("unmanagedSubField", fmds[9].getName());
+        assertEquals("undeclaredSubField", fmds[10].getName());
+    }
+
+    public void testSuperclass() {
+        ClassMetaData meta = JPAFacadeHelper
+            .getMetaData(getEmf(),
+                FieldOrderPC.class);
+        FieldMetaData[] fmds = meta.getFieldsInListingOrder();
+
+        assertEquals(6, fmds.length);
+        assertEquals("firstField", fmds[0].getName());
+        assertEquals("secondField", fmds[1].getName());
+        assertEquals("thirdField", fmds[2].getName());
+        assertEquals("unmanagedField", fmds[3].getName());
+        assertEquals("intField", fmds[4].getName());
+        assertEquals("oneToOneField", fmds[5].getName());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestNonPersistentFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestNonPersistentFields.java
index f936014..8d8f134 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestNonPersistentFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestNonPersistentFields.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.NonPersistentFieldsPC;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-
-/**
- * <p>Tests that fields that should not be persistent actually aren't.</p>
- *
- * @author Abe White
- */
-public class TestNonPersistentFields
-    extends AbstractTestCase {
-
-    private ClassMetaData _meta = null;
-
-    public TestNonPersistentFields(String test) {
-        super(test, "metacactusapp");
-    }
-
-    public void setUp() {
-        MetaDataRepository repos = new OpenJPAConfigurationImpl().
-            newMetaDataRepositoryInstance();
-        _meta = repos.getMetaData(NonPersistentFieldsPC.class, null, true);
-    }
-
-    public void testNonPersistentFields() {
-        FieldMetaData[] fmds = _meta.getFields();
-        assertEquals(5, fmds.length);
-        assertEquals("persistentField", fmds[0].getName());
-        assertEquals("persistentInterfaceField", fmds[1].getName());
-        assertEquals("persistentObjectField", fmds[2].getName());
-        assertEquals("persistentUserInterfaceField", fmds[3].getName());
-        assertEquals("persistentUserObjectField", fmds[4].getName());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.NonPersistentFieldsPC;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+
+/**
+ * <p>Tests that fields that should not be persistent actually aren't.</p>
+ *
+ * @author Abe White
+ */
+public class TestNonPersistentFields
+    extends AbstractTestCase {
+
+    private ClassMetaData _meta = null;
+
+    public TestNonPersistentFields(String test) {
+        super(test, "metacactusapp");
+    }
+
+    public void setUp() {
+        MetaDataRepository repos = new OpenJPAConfigurationImpl().
+            newMetaDataRepositoryInstance();
+        _meta = repos.getMetaData(NonPersistentFieldsPC.class, null, true);
+    }
+
+    public void testNonPersistentFields() {
+        FieldMetaData[] fmds = _meta.getFields();
+        assertEquals(5, fmds.length);
+        assertEquals("persistentField", fmds[0].getName());
+        assertEquals("persistentInterfaceField", fmds[1].getName());
+        assertEquals("persistentObjectField", fmds[2].getName());
+        assertEquals("persistentUserInterfaceField", fmds[3].getName());
+        assertEquals("persistentUserObjectField", fmds[4].getName());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestOrderBy.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestOrderBy.java
index 737d1e7..66bb501 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestOrderBy.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestOrderBy.java
@@ -1,283 +1,283 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-import java.util.Arrays;
-import java.util.List;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.OrderByPC;
-import org.apache.openjpa.persistence.meta.common.apps.OrderByPCRel;
-import org.apache.openjpa.persistence.meta.common.apps.OrderByPCRelSub;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.FetchPlan;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-/**
- * <p>Test the <code>order-by</code> field extension.</p>
- *
- * @author Abe White
- */
-public class TestOrderBy
-    extends AbstractTestCase {
-
-    public TestOrderBy(String test) {
-        super(test, "metacactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(OrderByPCRel.class);
-        deleteAll(OrderByPC.class);
-    }
-
-    public void testStringList() {
-        stringListTest(false, false);
-    }
-
-    public void testEagerParallelStringList() {
-        stringListTest(true, true);
-    }
-
-    public void testEagerJoinStringList() {
-        stringListTest(true, false);
-    }
-
-    private void stringListTest(boolean eager, boolean parallel) {
-        String[] strs = new String[]{
-            "9", "0", "5", "1", "3", "7", "8", "2", "6", "4",
-        };
-        OrderByPC pc = new OrderByPC();
-        pc.setId(1L);
-        pc.getStringListAsc().addAll(Arrays.asList(strs));
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        if (eager)
-            ((FetchPlan) pm.getFetchPlan()).addField(OrderByPC.class,
-                "stringListAsc");
-        if (parallel) {
-
-            OpenJPAQuery q = pm.createQuery(
-                "select a FROM " + OrderByPC.class.getSimpleName());
-            List res = (List) q.getResultList();
-            assertEquals(1, res.size());
-            pc = (OrderByPC) res.get(0);
-        } else
-            pc = (OrderByPC) pm.find(OrderByPC.class, oid);
-        List stringList = pc.getStringListAsc();
-        for (int i = 0; i < 10; i++)
-            assertEquals(String.valueOf(i), stringList.get(i));
-        endEm(pm);
-    }
-
-    public void testIntArray() {
-        int[] ints = new int[]{ 9, 0, 5, 1, 3, 7, 8, 2, 6, 4, };
-        OrderByPC pc = new OrderByPC();
-        pc.setId(1L);
-        pc.setIntArrayDesc(ints);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (OrderByPC) pm.find(OrderByPC.class, oid);
-        int[] intArray = pc.getIntArrayDesc();
-        for (int i = 0; i < 10; i++)
-            assertEquals(9 - i, intArray[i]);
-        endEm(pm);
-    }
-
-    public void testOrderByPK() {
-        orderByPKTest(false, false, false);
-    }
-
-    public void testEagerJoinOrderByPK() {
-        orderByPKTest(true, false, false);
-    }
-
-    public void testEagerParallelOrderByPK() {
-        orderByPKTest(true, true, false);
-    }
-
-    public void testOneToManyOrderByPK() {
-        orderByPKTest(false, false, true);
-    }
-
-    public void testEagerJoinOneToManyOrderByPK() {
-        orderByPKTest(true, false, true);
-    }
-
-    public void testEagerParallelOneToManyOrderByPK() {
-        orderByPKTest(true, true, true);
-    }
-
-    private void orderByPKTest(boolean eager, boolean parallel,
-        boolean oneToMany) {
-        long[] ids = new long[]{ 9, 0, 5, 1, 3, 7, 8, 2, 6, 4, };
-        OrderByPC pc = new OrderByPC();
-        pc.setId(1L);
-        OrderByPC pc2 = new OrderByPC();
-        pc2.setId(2L);
-        for (int i = 0; i < ids.length; i++) {
-            OrderByPCRel rel = (i % 2 == 0) ? new OrderByPCRel()
-                : new OrderByPCRelSub();
-            rel.setId(ids[i]);
-            if (oneToMany) {
-                pc.getOneToManyAsc().add(rel);
-                rel.setToOne(pc);
-            } else
-                pc.getOrderByPKAsc().add(rel);
-
-            if (parallel)
-                pc2.getOrderByPKAsc().add(rel);
-        }
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        if (eager)
-            ((FetchPlan) pm.getFetchPlan()).addField(OrderByPC.class,
-                "orderByPKAsc");
-        if (parallel) {
-
-            OpenJPAQuery q = pm.createQuery("select a FROM " +
-                OrderByPC.class.getSimpleName() + " select order by id asc");
-            pc = (OrderByPC) ((List) q.getResultList()).get(0);
-            q.closeAll();
-        } else
-            pc = (OrderByPC) pm.find(OrderByPC.class, oid);
-
-        List orderByPK = (oneToMany) ? pc.getOneToManyAsc()
-            : pc.getOrderByPKAsc();
-        for (int i = 0; i < 10; i++)
-            assertEquals(i, ((OrderByPCRel) orderByPK.get(i)).getId());
-        endEm(pm);
-    }
-
-    public void testOrderByRelatedField() {
-        String[] strs = new String[]{
-            "9", "0", "5", "1", "3", "7", "8", "2", "6", "4",
-        };
-        OrderByPC pc = new OrderByPC();
-        pc.setId(1L);
-        for (int i = 0; i < strs.length; i++) {
-            OrderByPCRel rel = (i % 2 == 0) ? new OrderByPCRel()
-                : new OrderByPCRelSub();
-            rel.setId(i);
-            rel.setString(strs[i]);
-            pc.getOrderByStringDesc().add(rel);
-        }
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (OrderByPC) pm.find(OrderByPC.class, oid);
-        List orderByRelField = pc.getOrderByStringDesc();
-        for (int i = 0; i < 10; i++)
-            assertEquals(String.valueOf(9 - i), ((OrderByPCRel)
-                orderByRelField.get(i)).getString());
-        endEm(pm);
-    }
-
-    public void testOrderByPKAndRelatedField() {
-        orderByPKAndRelatedFieldTest(false, false);
-    }
-
-    public void testEagerJoinOrderByPKAndRelatedField() {
-        orderByPKAndRelatedFieldTest(true, false);
-    }
-
-    public void testEagerParallelOrderByPKAndRelatedField() {
-        orderByPKAndRelatedFieldTest(true, true);
-    }
-
-    private void orderByPKAndRelatedFieldTest(boolean eager, boolean parallel) {
-        OrderByPC pc = new OrderByPC();
-        pc.setId(1L);
-        OrderByPC pc2 = new OrderByPC();
-        pc.setId(2L);
-
-        OrderByPCRel rel1 = new OrderByPCRel();
-        rel1.setId(1L);
-        rel1.setString("1");
-        OrderByPCRel rel2 = new OrderByPCRelSub();
-        rel2.setId(2L);
-        rel2.setString("1");
-        OrderByPCRel rel3 = new OrderByPCRel();
-        rel3.setId(3L);
-        rel3.setString("2");
-        OrderByPCRel rel4 = new OrderByPCRelSub();
-        rel4.setId(4L);
-        rel4.setString("2");
-        pc.getOrderByStringAndPKDesc().addAll(Arrays.asList
-            (new Object[]{ rel1, rel2, rel4, rel3, }));
-        if (parallel)
-            pc2.getOrderByStringAndPKDesc().addAll(Arrays.asList
-                (new Object[]{ rel1, rel2, rel4, rel3, }));
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        if (eager)
-            ((FetchPlan) pm.getFetchPlan()).addField(OrderByPC.class,
-                "orderByStringAndPKDesc");
-        if (parallel) {
-            OpenJPAQuery q = pm.createQuery("select a FROM " +
-                OrderByPC.class.getSimpleName() + " select order by id asc");
-            pc = (OrderByPC) ((List) q.getResultList()).get(0);
-            q.closeAll();
-        } else
-            pc = (OrderByPC) pm.find(OrderByPC.class, oid);
-        List multiOrder = pc.getOrderByStringAndPKDesc();
-        for (int i = 0; i < 4; i++)
-            assertEquals(4 - i, ((OrderByPCRel) multiOrder.get(i)).getId());
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.OrderByPC;
+import org.apache.openjpa.persistence.meta.common.apps.OrderByPCRel;
+import org.apache.openjpa.persistence.meta.common.apps.OrderByPCRelSub;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.FetchPlan;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+/**
+ * <p>Test the <code>order-by</code> field extension.</p>
+ *
+ * @author Abe White
+ */
+public class TestOrderBy
+    extends AbstractTestCase {
+
+    public TestOrderBy(String test) {
+        super(test, "metacactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(OrderByPCRel.class);
+        deleteAll(OrderByPC.class);
+    }
+
+    public void testStringList() {
+        stringListTest(false, false);
+    }
+
+    public void testEagerParallelStringList() {
+        stringListTest(true, true);
+    }
+
+    public void testEagerJoinStringList() {
+        stringListTest(true, false);
+    }
+
+    private void stringListTest(boolean eager, boolean parallel) {
+        String[] strs = new String[]{
+            "9", "0", "5", "1", "3", "7", "8", "2", "6", "4",
+        };
+        OrderByPC pc = new OrderByPC();
+        pc.setId(1L);
+        pc.getStringListAsc().addAll(Arrays.asList(strs));
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        if (eager)
+            ((FetchPlan) pm.getFetchPlan()).addField(OrderByPC.class,
+                "stringListAsc");
+        if (parallel) {
+
+            OpenJPAQuery q = pm.createQuery(
+                "select a FROM " + OrderByPC.class.getSimpleName());
+            List res = (List) q.getResultList();
+            assertEquals(1, res.size());
+            pc = (OrderByPC) res.get(0);
+        } else
+            pc = (OrderByPC) pm.find(OrderByPC.class, oid);
+        List stringList = pc.getStringListAsc();
+        for (int i = 0; i < 10; i++)
+            assertEquals(String.valueOf(i), stringList.get(i));
+        endEm(pm);
+    }
+
+    public void testIntArray() {
+        int[] ints = new int[]{ 9, 0, 5, 1, 3, 7, 8, 2, 6, 4, };
+        OrderByPC pc = new OrderByPC();
+        pc.setId(1L);
+        pc.setIntArrayDesc(ints);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (OrderByPC) pm.find(OrderByPC.class, oid);
+        int[] intArray = pc.getIntArrayDesc();
+        for (int i = 0; i < 10; i++)
+            assertEquals(9 - i, intArray[i]);
+        endEm(pm);
+    }
+
+    public void testOrderByPK() {
+        orderByPKTest(false, false, false);
+    }
+
+    public void testEagerJoinOrderByPK() {
+        orderByPKTest(true, false, false);
+    }
+
+    public void testEagerParallelOrderByPK() {
+        orderByPKTest(true, true, false);
+    }
+
+    public void testOneToManyOrderByPK() {
+        orderByPKTest(false, false, true);
+    }
+
+    public void testEagerJoinOneToManyOrderByPK() {
+        orderByPKTest(true, false, true);
+    }
+
+    public void testEagerParallelOneToManyOrderByPK() {
+        orderByPKTest(true, true, true);
+    }
+
+    private void orderByPKTest(boolean eager, boolean parallel,
+        boolean oneToMany) {
+        long[] ids = new long[]{ 9, 0, 5, 1, 3, 7, 8, 2, 6, 4, };
+        OrderByPC pc = new OrderByPC();
+        pc.setId(1L);
+        OrderByPC pc2 = new OrderByPC();
+        pc2.setId(2L);
+        for (int i = 0; i < ids.length; i++) {
+            OrderByPCRel rel = (i % 2 == 0) ? new OrderByPCRel()
+                : new OrderByPCRelSub();
+            rel.setId(ids[i]);
+            if (oneToMany) {
+                pc.getOneToManyAsc().add(rel);
+                rel.setToOne(pc);
+            } else
+                pc.getOrderByPKAsc().add(rel);
+
+            if (parallel)
+                pc2.getOrderByPKAsc().add(rel);
+        }
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        if (eager)
+            ((FetchPlan) pm.getFetchPlan()).addField(OrderByPC.class,
+                "orderByPKAsc");
+        if (parallel) {
+
+            OpenJPAQuery q = pm.createQuery("select a FROM " +
+                OrderByPC.class.getSimpleName() + " select order by id asc");
+            pc = (OrderByPC) ((List) q.getResultList()).get(0);
+            q.closeAll();
+        } else
+            pc = (OrderByPC) pm.find(OrderByPC.class, oid);
+
+        List orderByPK = (oneToMany) ? pc.getOneToManyAsc()
+            : pc.getOrderByPKAsc();
+        for (int i = 0; i < 10; i++)
+            assertEquals(i, ((OrderByPCRel) orderByPK.get(i)).getId());
+        endEm(pm);
+    }
+
+    public void testOrderByRelatedField() {
+        String[] strs = new String[]{
+            "9", "0", "5", "1", "3", "7", "8", "2", "6", "4",
+        };
+        OrderByPC pc = new OrderByPC();
+        pc.setId(1L);
+        for (int i = 0; i < strs.length; i++) {
+            OrderByPCRel rel = (i % 2 == 0) ? new OrderByPCRel()
+                : new OrderByPCRelSub();
+            rel.setId(i);
+            rel.setString(strs[i]);
+            pc.getOrderByStringDesc().add(rel);
+        }
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (OrderByPC) pm.find(OrderByPC.class, oid);
+        List orderByRelField = pc.getOrderByStringDesc();
+        for (int i = 0; i < 10; i++)
+            assertEquals(String.valueOf(9 - i), ((OrderByPCRel)
+                orderByRelField.get(i)).getString());
+        endEm(pm);
+    }
+
+    public void testOrderByPKAndRelatedField() {
+        orderByPKAndRelatedFieldTest(false, false);
+    }
+
+    public void testEagerJoinOrderByPKAndRelatedField() {
+        orderByPKAndRelatedFieldTest(true, false);
+    }
+
+    public void testEagerParallelOrderByPKAndRelatedField() {
+        orderByPKAndRelatedFieldTest(true, true);
+    }
+
+    private void orderByPKAndRelatedFieldTest(boolean eager, boolean parallel) {
+        OrderByPC pc = new OrderByPC();
+        pc.setId(1L);
+        OrderByPC pc2 = new OrderByPC();
+        pc.setId(2L);
+
+        OrderByPCRel rel1 = new OrderByPCRel();
+        rel1.setId(1L);
+        rel1.setString("1");
+        OrderByPCRel rel2 = new OrderByPCRelSub();
+        rel2.setId(2L);
+        rel2.setString("1");
+        OrderByPCRel rel3 = new OrderByPCRel();
+        rel3.setId(3L);
+        rel3.setString("2");
+        OrderByPCRel rel4 = new OrderByPCRelSub();
+        rel4.setId(4L);
+        rel4.setString("2");
+        pc.getOrderByStringAndPKDesc().addAll(Arrays.asList
+            (new Object[]{ rel1, rel2, rel4, rel3, }));
+        if (parallel)
+            pc2.getOrderByStringAndPKDesc().addAll(Arrays.asList
+                (new Object[]{ rel1, rel2, rel4, rel3, }));
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        if (eager)
+            ((FetchPlan) pm.getFetchPlan()).addField(OrderByPC.class,
+                "orderByStringAndPKDesc");
+        if (parallel) {
+            OpenJPAQuery q = pm.createQuery("select a FROM " +
+                OrderByPC.class.getSimpleName() + " select order by id asc");
+            pc = (OrderByPC) ((List) q.getResultList()).get(0);
+            q.closeAll();
+        } else
+            pc = (OrderByPC) pm.find(OrderByPC.class, oid);
+        List multiOrder = pc.getOrderByStringAndPKDesc();
+        for (int i = 0; i < 4; i++)
+            assertEquals(4 - i, ((OrderByPCRel) multiOrder.get(i)).getId());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestPersistentClasses.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestPersistentClasses.java
index 5a5ad54..9d83833 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestPersistentClasses.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestPersistentClasses.java
@@ -1,111 +1,111 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.openjpa.persistence.meta.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.meta.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.meta.common.apps.RuntimeTest3;
-import org.apache.openjpa.persistence.common.utils.*;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public class TestPersistentClasses
-    extends AbstractTestCase {
-
-    public TestPersistentClasses(String test) {
-        super(test, "metacactusapp");
-    }
-
-    private void assertClass(Class cls, OpenJPAConfiguration conf,
-        boolean shouldExist) {
-        assertClass(cls.getName(), conf, shouldExist);
-    }
-
-    private void assertClass(String clsName, OpenJPAConfiguration conf,
-        boolean shouldExist) {
-
-        Collection names = conf.getMetaDataRepositoryInstance().
-            getPersistentTypeNames(false, null);
-
-        if (shouldExist)
-            assertTrue("expected element " + clsName + " was not found in "
-                + names, names.contains(clsName));
-        else
-            assertTrue("unexpected element " + clsName + " was found in "
-                + names, !names.contains(clsName));
-    }
-
-    public void testNoneConfigured() {
-
-        Map map = new HashMap();
-        map.put("openjpa.MetaDataFactory", "jpa");
-        OpenJPAEntityManagerFactory pmf = getEmf(map);
-
-        assertNull(((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration()
-            .getMetaDataRepositoryInstance().
-
-            getPersistentTypeNames(false, null));
-
-        pmf.close();
-    }
-
-    public void testJPAClasspathScanner() {
-        Map map = new HashMap();
-        map.put("openjpa.MetaDataFactory", "jpa(ClasspathScan=src;jdk1.5-test)");
-        OpenJPAEntityManagerFactory pmf = getEmf(map);
-
-        assertClass(RuntimeTest1.class,
-            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), false);
-
-        assertClass(RuntimeTest2.class,
-            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), false);
-
-        assertClass("openjpa.meta.GenericFields",
-            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), true);
-
-        pmf.close();
-    }
-
-    public void testTypes() {
-
-        Map map = new HashMap();
-
-        map.put("openjpa.MetaDataFactory",
-            "jpa(Types=org.apache.openjpa.persistence.kernel.RuntimeTest1;" +
-                "org.apache.openjpa.persistence.kernel.RuntimeTest2)");
-
-        OpenJPAEntityManagerFactory pmf = getEmf(map);
-        assertClass(RuntimeTest1.class,
-            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), true);
-
-        assertClass(RuntimeTest2.class,
-            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), true);
-
-        assertClass(RuntimeTest3.class,
-            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), false);
-
-        pmf.close();
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.openjpa.persistence.meta.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.meta.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.meta.common.apps.RuntimeTest3;
+import org.apache.openjpa.persistence.common.utils.*;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestPersistentClasses
+    extends AbstractTestCase {
+
+    public TestPersistentClasses(String test) {
+        super(test, "metacactusapp");
+    }
+
+    private void assertClass(Class cls, OpenJPAConfiguration conf,
+        boolean shouldExist) {
+        assertClass(cls.getName(), conf, shouldExist);
+    }
+
+    private void assertClass(String clsName, OpenJPAConfiguration conf,
+        boolean shouldExist) {
+
+        Collection names = conf.getMetaDataRepositoryInstance().
+            getPersistentTypeNames(false, null);
+
+        if (shouldExist)
+            assertTrue("expected element " + clsName + " was not found in "
+                + names, names.contains(clsName));
+        else
+            assertTrue("unexpected element " + clsName + " was found in "
+                + names, !names.contains(clsName));
+    }
+
+    public void testNoneConfigured() {
+
+        Map map = new HashMap();
+        map.put("openjpa.MetaDataFactory", "jpa");
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+
+        assertNull(((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration()
+            .getMetaDataRepositoryInstance().
+
+            getPersistentTypeNames(false, null));
+
+        pmf.close();
+    }
+
+    public void testJPAClasspathScanner() {
+        Map map = new HashMap();
+        map.put("openjpa.MetaDataFactory", "jpa(ClasspathScan=src;jdk1.5-test)");
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+
+        assertClass(RuntimeTest1.class,
+            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), false);
+
+        assertClass(RuntimeTest2.class,
+            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), false);
+
+        assertClass("openjpa.meta.GenericFields",
+            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), true);
+
+        pmf.close();
+    }
+
+    public void testTypes() {
+
+        Map map = new HashMap();
+
+        map.put("openjpa.MetaDataFactory",
+            "jpa(Types=org.apache.openjpa.persistence.kernel.RuntimeTest1;" +
+                "org.apache.openjpa.persistence.kernel.RuntimeTest2)");
+
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+        assertClass(RuntimeTest1.class,
+            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), true);
+
+        assertClass(RuntimeTest2.class,
+            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), true);
+
+        assertClass(RuntimeTest3.class,
+            ((OpenJPAEntityManagerFactorySPI) pmf).getConfiguration(), false);
+
+        pmf.close();
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestSequenceAssigned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestSequenceAssigned.java
index 7834539..ed81e63 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestSequenceAssigned.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestSequenceAssigned.java
@@ -1,172 +1,172 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned;
-import org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned2;
-import org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned3;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestSequenceAssigned
-    extends AbstractTestCase {
-
-    public TestSequenceAssigned(String testName) {
-        super(testName, "metacactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(SequenceAssigned.class);
-        deleteAll(SequenceAssigned3.class);
-    }
-
-    public void testGetObjectId() {
-        SequenceAssigned pc = new SequenceAssigned();
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        SequenceAssigned.Id id = (SequenceAssigned.Id)
-            pm.getObjectId(pc);
-        assertTrue(0 != id.pk);
-        assertTrue(0 != pc.getPK());
-        assertEquals(pc.getPK(), id.pk);
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testGetValue() {
-        SequenceAssigned pc = new SequenceAssigned();
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        assertEquals(0, pc.getPK());
-        pm.persist(pc);
-        assertTrue(0 != pc.getPK());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testPrimitive() {
-        SequenceAssigned pc = new SequenceAssigned();
-        SequenceAssigned pc2 = new SequenceAssigned();
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        pm.flush();
-        assertTrue(0 != pc.getPK());
-        assertTrue(0 != pc2.getPK());
-        assertTrue(pc.getPK() != pc2.getPK());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testManualAssign() {
-        SequenceAssigned pc = new SequenceAssigned();
-        SequenceAssigned3 pc2 = new SequenceAssigned3();
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pc.setPK(-100);
-        pc2.setPK(new Long(-100));
-        pm.persist(pc);
-        pm.persist(pc2);
-        pm.flush();
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        Object oid2 = pm.getObjectId(pc2);
-        endEm(pm);
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (SequenceAssigned) pm.find(SequenceAssigned.class, oid);
-        pc2 = (SequenceAssigned3) pm.find(SequenceAssigned3.class, oid2);
-        assertEquals(-100, pc.getPK());
-        assertEquals(new Long(-100), pc2.getPK());
-        endEm(pm);
-    }
-
-    public void testInheritance() {
-        SequenceAssigned2 pc = new SequenceAssigned2();
-        SequenceAssigned2 pc2 = new SequenceAssigned2();
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        pm.flush();
-        assertTrue(0 != pc.getPK());
-        assertTrue(0 != pc2.getPK());
-        assertTrue(pc.getPK() != pc2.getPK());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testWrapper() {
-        SequenceAssigned3 pc = new SequenceAssigned3();
-        SequenceAssigned3 pc2 = new SequenceAssigned3();
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        pm.flush();
-        assertNotNull(pc.getPK());
-        assertNotNull(pc2.getPK());
-        assertTrue(0 != pc.getPK().longValue());
-        assertTrue(0 != pc2.getPK().longValue());
-        assertNotEquals(pc.getPK(), pc2.getPK());
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testGetObjectById() {
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        SequenceAssigned pc = new SequenceAssigned();
-        pm.persist(pc);
-        Object oid = pm.getObjectId(pc);
-        assertTrue(0 != ((SequenceAssigned.Id) oid).pk);
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pm.find(SequenceAssigned.class, oid);
-        endEm(pm);
-    }
-
-    public void testReachability() {
-        SequenceAssigned pc = new SequenceAssigned();
-        SequenceAssigned pc2 = new SequenceAssigned();
-        pc.setOther(pc2);
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        endTx(pm);
-        SequenceAssigned.Id id = (SequenceAssigned.Id)
-            pm.getObjectId(pc2);
-        assertTrue(0 != id.pk);
-        assertTrue(0 != pc2.getPK());
-        assertEquals(pc2.getPK(), id.pk);
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned;
+import org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned2;
+import org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned3;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestSequenceAssigned
+    extends AbstractTestCase {
+
+    public TestSequenceAssigned(String testName) {
+        super(testName, "metacactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(SequenceAssigned.class);
+        deleteAll(SequenceAssigned3.class);
+    }
+
+    public void testGetObjectId() {
+        SequenceAssigned pc = new SequenceAssigned();
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        SequenceAssigned.Id id = (SequenceAssigned.Id)
+            pm.getObjectId(pc);
+        assertTrue(0 != id.pk);
+        assertTrue(0 != pc.getPK());
+        assertEquals(pc.getPK(), id.pk);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testGetValue() {
+        SequenceAssigned pc = new SequenceAssigned();
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        assertEquals(0, pc.getPK());
+        pm.persist(pc);
+        assertTrue(0 != pc.getPK());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testPrimitive() {
+        SequenceAssigned pc = new SequenceAssigned();
+        SequenceAssigned pc2 = new SequenceAssigned();
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        pm.flush();
+        assertTrue(0 != pc.getPK());
+        assertTrue(0 != pc2.getPK());
+        assertTrue(pc.getPK() != pc2.getPK());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testManualAssign() {
+        SequenceAssigned pc = new SequenceAssigned();
+        SequenceAssigned3 pc2 = new SequenceAssigned3();
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pc.setPK(-100);
+        pc2.setPK(new Long(-100));
+        pm.persist(pc);
+        pm.persist(pc2);
+        pm.flush();
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        Object oid2 = pm.getObjectId(pc2);
+        endEm(pm);
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (SequenceAssigned) pm.find(SequenceAssigned.class, oid);
+        pc2 = (SequenceAssigned3) pm.find(SequenceAssigned3.class, oid2);
+        assertEquals(-100, pc.getPK());
+        assertEquals(new Long(-100), pc2.getPK());
+        endEm(pm);
+    }
+
+    public void testInheritance() {
+        SequenceAssigned2 pc = new SequenceAssigned2();
+        SequenceAssigned2 pc2 = new SequenceAssigned2();
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        pm.flush();
+        assertTrue(0 != pc.getPK());
+        assertTrue(0 != pc2.getPK());
+        assertTrue(pc.getPK() != pc2.getPK());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testWrapper() {
+        SequenceAssigned3 pc = new SequenceAssigned3();
+        SequenceAssigned3 pc2 = new SequenceAssigned3();
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        pm.flush();
+        assertNotNull(pc.getPK());
+        assertNotNull(pc2.getPK());
+        assertTrue(0 != pc.getPK().longValue());
+        assertTrue(0 != pc2.getPK().longValue());
+        assertNotEquals(pc.getPK(), pc2.getPK());
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testGetObjectById() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        SequenceAssigned pc = new SequenceAssigned();
+        pm.persist(pc);
+        Object oid = pm.getObjectId(pc);
+        assertTrue(0 != ((SequenceAssigned.Id) oid).pk);
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pm.find(SequenceAssigned.class, oid);
+        endEm(pm);
+    }
+
+    public void testReachability() {
+        SequenceAssigned pc = new SequenceAssigned();
+        SequenceAssigned pc2 = new SequenceAssigned();
+        pc.setOther(pc2);
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        SequenceAssigned.Id id = (SequenceAssigned.Id)
+            pm.getObjectId(pc2);
+        assertTrue(0 != id.pk);
+        assertTrue(0 != pc2.getPK());
+        assertEquals(pc2.getPK(), id.pk);
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestValueStrategies.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestValueStrategies.java
index 0e4bd76..dce945d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestValueStrategies.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestValueStrategies.java
@@ -1,404 +1,404 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.EntityManagerFactory;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.ValueStrategyPC;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.util.OpenJPAException;
-
-/**
- * <p>Test value and update strategies.  Also tests version fields, which
- * are represented in JDO as a value strategy.</p>
- *
- * @author Abe White
- */
-public class TestValueStrategies
-    extends AbstractTestCase {
-
-    public TestValueStrategies(String test) {
-        super(test, "metacactusapp");
-    }
-
-    public void setUp() {
-        deleteAll(ValueStrategyPC.class);
-    }
-
-    public void testIgnoreUpdate() {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        pc.setName("pc");
-        pc.setIgnoreUpdate(10);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        assertEquals(10, pc.getIgnoreUpdate());
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        //pm = getPM(false, false);
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        assertNotNull(pc);
-        assertEquals(10, pc.getIgnoreUpdate());
-        startTx(pm);
-        pc.setIgnoreUpdate(100);
-        assertFalse(pm.isDirty(pc));
-        pm.transactional(pc, false);
-        endTx(pm);
-        assertEquals(10, pc.getIgnoreUpdate());
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        assertNotNull(pc);
-        assertEquals(10, pc.getIgnoreUpdate());
-        endEm(pm);
-    }
-
-    public void testRestrictUpdate() {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        pc.setName("pc");
-        pc.setRestrictUpdate(10);
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        assertEquals(10, pc.getRestrictUpdate());
-        endTx(pm);
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        //pm = getPM(false, false);
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        assertNotNull(pc);
-        assertEquals(10, pc.getRestrictUpdate());
-        startTx(pm);
-        try {
-            pc.setRestrictUpdate(100);
-            fail("Allowed update of restricted field.");
-        } catch (RuntimeException re) {
-        }
-        endTx(pm);
-        assertEquals(10, pc.getRestrictUpdate());
-        endEm(pm);
-    }
-
-    public void testUUID() {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        ValueStrategyPC pc2 = new ValueStrategyPC();
-        pc.setName("pc");
-        pc2.setName("pc2");
-        assertNull(pc.getUUID());
-        assertNull(pc2.getUUID());
-        assertNull(pc.getUUIDHex());
-        assertNull(pc2.getUUIDHex());
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        pm.setOptimistic(true);
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        String str = pc.getUUID();
-        String hex = pc.getUUIDHex();
-        assertTrue(!pm.isStoreActive());    // no flush needed
-        endTx(pm);
-        String str2 = pc2.getUUID();
-        String hex2 = pc2.getUUIDHex();
-        Object oid = pm.getObjectId(pc);
-        Object oid2 = pm.getObjectId(pc2);
-        endEm(pm);
-
-        assertNotNull(str);
-        assertNotNull(str2);
-        assertTrue(!str.equals(str2));
-        assertNotNull(hex);
-        assertNotNull(hex2);
-        assertTrue(!hex.equals(hex2));
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
-        assertEquals(str, pc.getUUID());
-        assertEquals(str2, pc2.getUUID());
-        assertEquals(hex, pc.getUUIDHex());
-        assertEquals(hex2, pc2.getUUIDHex());
-        startTx(pm);
-        pc.setUUIDHex("foo");
-        pc2.setUUIDHex("bar");
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
-        assertEquals("foo", pc.getUUIDHex());
-        assertEquals("bar", pc2.getUUIDHex());
-        endEm(pm);
-    }
-
-    public void testSequence() {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        ValueStrategyPC pc2 = new ValueStrategyPC();
-        pc.setName("pc");
-        pc2.setName("pc2");
-        assertEquals(0, pc.getSequence());
-        assertEquals(0, pc2.getSequence());
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        pm.setOptimistic(true);
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        int seq = pc.getSequence();
-        assertTrue(!pm.isStoreActive());    // no flush needed
-        endTx(pm);
-        int seq2 = pc2.getSequence();
-        Object oid = pm.getObjectId(pc);
-        Object oid2 = pm.getObjectId(pc2);
-        endEm(pm);
-
-        assertTrue(seq > 0);
-        assertTrue(seq2 > 0);
-        assertTrue(seq != seq2);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
-        assertEquals(seq, pc.getSequence());
-        assertEquals(seq2, pc2.getSequence());
-        startTx(pm);
-        pc.setSequence(99);
-        pc2.setSequence(100);
-        endTx(pm);
-        endEm(pm);
-
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
-        assertEquals(99, pc.getSequence());
-        assertEquals(100, pc2.getSequence());
-        endEm(pm);
-    }
-
-    public void testVersion() {
-        versionTest(getEmf());
-    }
-
-    public void testVersionDataCache() {
-
-        Map map = new HashMap();
-        map.put("openjpa.DataCache", "true");
-        map.put("openjpa.RemoteCommitProvider", "sjvm");
-        versionTest(getEmf(map));
-    }
-
-    private void versionTest(EntityManagerFactory pmf) {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        pc.setName("pc");
-
-        OpenJPAEntityManager pm = (OpenJPAEntityManager)
-            pmf.createEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        ClassMetaData meta = getConfiguration()
-            .getMetaDataRepositoryInstance().
-            getMetaData(pc.getClass(), null, false);
-        assertNotNull(meta.getVersionField());
-        assertEquals("version", meta.getVersionField().getName());
-        assertEquals(0, pc.getVersion());
-        endTx(pm);
-        assertEquals(1, pc.getVersion());
-        Object oid = pm.getObjectId(pc);
-        endEm(pm);
-
-        // do no-op commit
-        pm = (OpenJPAEntityManager) pmf.createEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        assertNotNull(pc);
-        assertEquals(1, pc.getVersion());
-        startTx(pm);
-        try {
-            pc.setVersion(10);
-            fail("Allowed change to version field.");
-        } catch (RuntimeException re) {
-        }
-        endTx(pm);
-        assertEquals(1, pc.getVersion());
-        endEm(pm);
-
-        // do real commit
-        pm = (OpenJPAEntityManager) pmf.createEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        assertNotNull(pc);
-        assertEquals(1, pc.getVersion());
-        startTx(pm);
-        pc.setName("changed");
-        pm.flush();
-        assertEquals(1, pc.getVersion());
-        endTx(pm);
-        assertEquals("changed", pc.getName());
-        assertEquals(2, pc.getVersion());
-        endEm(pm);
-
-        // rollback
-        pm = (OpenJPAEntityManager) pmf.createEntityManager();
-        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
-        assertNotNull(pc);
-        assertEquals(2, pc.getVersion());
-        startTx(pm);
-        pc.setName("changed2");
-        pm.flush();
-        assertEquals(2, pc.getVersion());
-        rollbackTx(pm);
-        assertEquals(2, pc.getVersion());
-        endEm(pm);
-    }
-
-    public void testVersionDetach() {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        ValueStrategyPC pc2 = new ValueStrategyPC();
-        pc.setName("pc");
-        pc2.setName("pc2");
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        pm.persist(pc2);
-        endTx(pm);
-        startTx(pm);
-        pc.setName("changed");
-        pc2.setName("changed2");
-        endTx(pm);
-        assertEquals(2, pc.getVersion());
-        assertEquals(2, pc2.getVersion());
-        ValueStrategyPC detached = (ValueStrategyPC) pm.detach(pc);
-        ValueStrategyPC detached2 = (ValueStrategyPC) pm.detach(pc2);
-        endEm(pm);
-
-        // clean attach
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pc = (ValueStrategyPC) pm.merge(detached);
-        assertEquals(2, pc.getVersion());
-        endTx(pm);
-        assertEquals(2, pc.getVersion());
-        endEm(pm);
-
-        // dirty attach
-        detached.setName("changed-detached");
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pc = (ValueStrategyPC) pm.merge(detached);
-        assertEquals(2, pc.getVersion());
-        endTx(pm);
-        assertEquals(3, pc.getVersion());
-        endEm(pm);
-
-        // stale attach
-        detached.setName("stale");
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        try {
-            pm.merge(detached);
-            endTx(pm);
-            fail("Committed stale version.");
-        } catch (OpenJPAException je) {
-        }
-        if (isActiveTx(pm))
-            rollbackTx(pm);
-        endEm(pm);
-
-        // modify version field in detached; allow either exception or
-        // allow the update to be ignored
-        detached2.setName("changed2-detached");
-        detached2.setVersion(99);
-        pm = (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        try {
-            pc2 = (ValueStrategyPC) pm.merge(detached2);
-            assertEquals(2, pc2.getVersion());
-            endTx(pm);
-            assertEquals(3, pc2.getVersion());
-        } catch (OpenJPAException je) {
-        }
-        if (isActiveTx(pm))
-            rollbackTx(pm);
-        ;
-        endEm(pm);
-    }
-
-    public void testVersionRefresh() {
-        ValueStrategyPC pc = new ValueStrategyPC();
-        pc.setName("pc");
-
-        OpenJPAEntityManager pm =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm);
-        pm.persist(pc);
-        endTx(pm);
-        startTx(pm);
-        pc.setName("changed");
-        endTx(pm);
-        assertEquals(2, pc.getVersion());
-
-        // clean refresh
-        startTx(pm);
-        pm.refresh(pc);
-        assertEquals(2, pc.getVersion());
-
-        // concurrent mod
-        OpenJPAEntityManager pm2 =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(pm2);
-        ValueStrategyPC pc2 = (ValueStrategyPC) pm2.find
-            (ValueStrategyPC.class, pm2.getObjectId(pc));
-        pc2.setName("changed2");
-        endTx(pm2);
-        assertEquals(3, pc2.getVersion());
-        endEm(pm2);
-
-        // stale refresh
-        pm.refresh(pc);
-        assertEquals(3, pc.getVersion());
-
-        // dirty refresh
-        pc.setName("changed-1");
-        pm.refresh(pc);
-        assertEquals(3, pc.getVersion());
-
-        pc.setName("changed-2");
-        endTx(pm);
-        assertEquals(4, pc.getVersion());
-        endEm(pm);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.ValueStrategyPC;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.util.OpenJPAException;
+
+/**
+ * <p>Test value and update strategies.  Also tests version fields, which
+ * are represented in JDO as a value strategy.</p>
+ *
+ * @author Abe White
+ */
+public class TestValueStrategies
+    extends AbstractTestCase {
+
+    public TestValueStrategies(String test) {
+        super(test, "metacactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(ValueStrategyPC.class);
+    }
+
+    public void testIgnoreUpdate() {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        pc.setName("pc");
+        pc.setIgnoreUpdate(10);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        assertEquals(10, pc.getIgnoreUpdate());
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        //pm = getPM(false, false);
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        assertNotNull(pc);
+        assertEquals(10, pc.getIgnoreUpdate());
+        startTx(pm);
+        pc.setIgnoreUpdate(100);
+        assertFalse(pm.isDirty(pc));
+        pm.transactional(pc, false);
+        endTx(pm);
+        assertEquals(10, pc.getIgnoreUpdate());
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        assertNotNull(pc);
+        assertEquals(10, pc.getIgnoreUpdate());
+        endEm(pm);
+    }
+
+    public void testRestrictUpdate() {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        pc.setName("pc");
+        pc.setRestrictUpdate(10);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        assertEquals(10, pc.getRestrictUpdate());
+        endTx(pm);
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        //pm = getPM(false, false);
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        assertNotNull(pc);
+        assertEquals(10, pc.getRestrictUpdate());
+        startTx(pm);
+        try {
+            pc.setRestrictUpdate(100);
+            fail("Allowed update of restricted field.");
+        } catch (RuntimeException re) {
+        }
+        endTx(pm);
+        assertEquals(10, pc.getRestrictUpdate());
+        endEm(pm);
+    }
+
+    public void testUUID() {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        ValueStrategyPC pc2 = new ValueStrategyPC();
+        pc.setName("pc");
+        pc2.setName("pc2");
+        assertNull(pc.getUUID());
+        assertNull(pc2.getUUID());
+        assertNull(pc.getUUIDHex());
+        assertNull(pc2.getUUIDHex());
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        pm.setOptimistic(true);
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        String str = pc.getUUID();
+        String hex = pc.getUUIDHex();
+        assertTrue(!pm.isStoreActive());    // no flush needed
+        endTx(pm);
+        String str2 = pc2.getUUID();
+        String hex2 = pc2.getUUIDHex();
+        Object oid = pm.getObjectId(pc);
+        Object oid2 = pm.getObjectId(pc2);
+        endEm(pm);
+
+        assertNotNull(str);
+        assertNotNull(str2);
+        assertTrue(!str.equals(str2));
+        assertNotNull(hex);
+        assertNotNull(hex2);
+        assertTrue(!hex.equals(hex2));
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
+        assertEquals(str, pc.getUUID());
+        assertEquals(str2, pc2.getUUID());
+        assertEquals(hex, pc.getUUIDHex());
+        assertEquals(hex2, pc2.getUUIDHex());
+        startTx(pm);
+        pc.setUUIDHex("foo");
+        pc2.setUUIDHex("bar");
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
+        assertEquals("foo", pc.getUUIDHex());
+        assertEquals("bar", pc2.getUUIDHex());
+        endEm(pm);
+    }
+
+    public void testSequence() {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        ValueStrategyPC pc2 = new ValueStrategyPC();
+        pc.setName("pc");
+        pc2.setName("pc2");
+        assertEquals(0, pc.getSequence());
+        assertEquals(0, pc2.getSequence());
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        pm.setOptimistic(true);
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        int seq = pc.getSequence();
+        assertTrue(!pm.isStoreActive());    // no flush needed
+        endTx(pm);
+        int seq2 = pc2.getSequence();
+        Object oid = pm.getObjectId(pc);
+        Object oid2 = pm.getObjectId(pc2);
+        endEm(pm);
+
+        assertTrue(seq > 0);
+        assertTrue(seq2 > 0);
+        assertTrue(seq != seq2);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
+        assertEquals(seq, pc.getSequence());
+        assertEquals(seq2, pc2.getSequence());
+        startTx(pm);
+        pc.setSequence(99);
+        pc2.setSequence(100);
+        endTx(pm);
+        endEm(pm);
+
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        pc2 = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid2);
+        assertEquals(99, pc.getSequence());
+        assertEquals(100, pc2.getSequence());
+        endEm(pm);
+    }
+
+    public void testVersion() {
+        versionTest(getEmf());
+    }
+
+    public void testVersionDataCache() {
+
+        Map map = new HashMap();
+        map.put("openjpa.DataCache", "true");
+        map.put("openjpa.RemoteCommitProvider", "sjvm");
+        versionTest(getEmf(map));
+    }
+
+    private void versionTest(EntityManagerFactory pmf) {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        pc.setName("pc");
+
+        OpenJPAEntityManager pm = (OpenJPAEntityManager)
+            pmf.createEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        ClassMetaData meta = getConfiguration()
+            .getMetaDataRepositoryInstance().
+            getMetaData(pc.getClass(), null, false);
+        assertNotNull(meta.getVersionField());
+        assertEquals("version", meta.getVersionField().getName());
+        assertEquals(0, pc.getVersion());
+        endTx(pm);
+        assertEquals(1, pc.getVersion());
+        Object oid = pm.getObjectId(pc);
+        endEm(pm);
+
+        // do no-op commit
+        pm = (OpenJPAEntityManager) pmf.createEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        assertNotNull(pc);
+        assertEquals(1, pc.getVersion());
+        startTx(pm);
+        try {
+            pc.setVersion(10);
+            fail("Allowed change to version field.");
+        } catch (RuntimeException re) {
+        }
+        endTx(pm);
+        assertEquals(1, pc.getVersion());
+        endEm(pm);
+
+        // do real commit
+        pm = (OpenJPAEntityManager) pmf.createEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        assertNotNull(pc);
+        assertEquals(1, pc.getVersion());
+        startTx(pm);
+        pc.setName("changed");
+        pm.flush();
+        assertEquals(1, pc.getVersion());
+        endTx(pm);
+        assertEquals("changed", pc.getName());
+        assertEquals(2, pc.getVersion());
+        endEm(pm);
+
+        // rollback
+        pm = (OpenJPAEntityManager) pmf.createEntityManager();
+        pc = (ValueStrategyPC) pm.find(ValueStrategyPC.class, oid);
+        assertNotNull(pc);
+        assertEquals(2, pc.getVersion());
+        startTx(pm);
+        pc.setName("changed2");
+        pm.flush();
+        assertEquals(2, pc.getVersion());
+        rollbackTx(pm);
+        assertEquals(2, pc.getVersion());
+        endEm(pm);
+    }
+
+    public void testVersionDetach() {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        ValueStrategyPC pc2 = new ValueStrategyPC();
+        pc.setName("pc");
+        pc2.setName("pc2");
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        pm.persist(pc2);
+        endTx(pm);
+        startTx(pm);
+        pc.setName("changed");
+        pc2.setName("changed2");
+        endTx(pm);
+        assertEquals(2, pc.getVersion());
+        assertEquals(2, pc2.getVersion());
+        ValueStrategyPC detached = (ValueStrategyPC) pm.detach(pc);
+        ValueStrategyPC detached2 = (ValueStrategyPC) pm.detach(pc2);
+        endEm(pm);
+
+        // clean attach
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pc = (ValueStrategyPC) pm.merge(detached);
+        assertEquals(2, pc.getVersion());
+        endTx(pm);
+        assertEquals(2, pc.getVersion());
+        endEm(pm);
+
+        // dirty attach
+        detached.setName("changed-detached");
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pc = (ValueStrategyPC) pm.merge(detached);
+        assertEquals(2, pc.getVersion());
+        endTx(pm);
+        assertEquals(3, pc.getVersion());
+        endEm(pm);
+
+        // stale attach
+        detached.setName("stale");
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        try {
+            pm.merge(detached);
+            endTx(pm);
+            fail("Committed stale version.");
+        } catch (OpenJPAException je) {
+        }
+        if (isActiveTx(pm))
+            rollbackTx(pm);
+        endEm(pm);
+
+        // modify version field in detached; allow either exception or
+        // allow the update to be ignored
+        detached2.setName("changed2-detached");
+        detached2.setVersion(99);
+        pm = (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        try {
+            pc2 = (ValueStrategyPC) pm.merge(detached2);
+            assertEquals(2, pc2.getVersion());
+            endTx(pm);
+            assertEquals(3, pc2.getVersion());
+        } catch (OpenJPAException je) {
+        }
+        if (isActiveTx(pm))
+            rollbackTx(pm);
+        ;
+        endEm(pm);
+    }
+
+    public void testVersionRefresh() {
+        ValueStrategyPC pc = new ValueStrategyPC();
+        pc.setName("pc");
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        startTx(pm);
+        pc.setName("changed");
+        endTx(pm);
+        assertEquals(2, pc.getVersion());
+
+        // clean refresh
+        startTx(pm);
+        pm.refresh(pc);
+        assertEquals(2, pc.getVersion());
+
+        // concurrent mod
+        OpenJPAEntityManager pm2 =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm2);
+        ValueStrategyPC pc2 = (ValueStrategyPC) pm2.find
+            (ValueStrategyPC.class, pm2.getObjectId(pc));
+        pc2.setName("changed2");
+        endTx(pm2);
+        assertEquals(3, pc2.getVersion());
+        endEm(pm2);
+
+        // stale refresh
+        pm.refresh(pc);
+        assertEquals(3, pc.getVersion());
+
+        // dirty refresh
+        pc.setName("changed-1");
+        pm.refresh(pc);
+        assertEquals(3, pc.getVersion());
+
+        pc.setName("changed-2");
+        endTx(pm);
+        assertEquals(4, pc.getVersion());
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestXMLPersistenceMetaDataSerializer.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestXMLPersistenceMetaDataSerializer.java
index 4fc2d7c..c0669d5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestXMLPersistenceMetaDataSerializer.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestXMLPersistenceMetaDataSerializer.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-
-
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest1;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest2;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest3;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest5;
-import org.apache.openjpa.persistence.meta.common.apps.MetaTest6;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.XMLPersistenceMetaDataParser;
-import org.apache.openjpa.persistence.XMLPersistenceMetaDataSerializer;
-
-/**
- * <p>Tests the {@link MetaDataSerializer} by parsing all the metadata
- * files, serializing them to a buffer, then deserializing them from the
- * buffer and invoking the tests defined by {@link TestClassMetaData}.</p>
- *
- * @author Abe White
- */
-public class TestXMLPersistenceMetaDataSerializer
-    extends TestClassMetaData {
-
-    public TestXMLPersistenceMetaDataSerializer(String test) {
-        super(test);
-    }
-
-    protected MetaDataRepository getRepository()
-        throws Exception {
-        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
-        MetaDataRepository repos = conf.newMetaDataRepositoryInstance();
-        repos.getMetaData(MetaTest5.class, null, true);
-        repos.getMetaData(MetaTest3.class, null, true);
-        repos.getMetaData(MetaTest2.class, null, true);
-        repos.getMetaData(MetaTest1.class, null, true);
-        repos.getMetaData(MetaTest6.class, null, true);
-
-        XMLPersistenceMetaDataSerializer ser =
-            new XMLPersistenceMetaDataSerializer(conf);
-        ser.addAll(repos);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ser.serialize(new OutputStreamWriter(out), ser.PRETTY);
-        byte[] bytes = out.toByteArray();
-
-        XMLPersistenceMetaDataParser parser =
-            new XMLPersistenceMetaDataParser(conf);
-        parser.parse(new InputStreamReader
-            (new ByteArrayInputStream(bytes)), "bytes");
-        return parser.getRepository();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+
+
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest1;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest2;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest3;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest5;
+import org.apache.openjpa.persistence.meta.common.apps.MetaTest6;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.XMLPersistenceMetaDataParser;
+import org.apache.openjpa.persistence.XMLPersistenceMetaDataSerializer;
+
+/**
+ * <p>Tests the {@link MetaDataSerializer} by parsing all the metadata
+ * files, serializing them to a buffer, then deserializing them from the
+ * buffer and invoking the tests defined by {@link TestClassMetaData}.</p>
+ *
+ * @author Abe White
+ */
+public class TestXMLPersistenceMetaDataSerializer
+    extends TestClassMetaData {
+
+    public TestXMLPersistenceMetaDataSerializer(String test) {
+        super(test);
+    }
+
+    protected MetaDataRepository getRepository()
+        throws Exception {
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
+        MetaDataRepository repos = conf.newMetaDataRepositoryInstance();
+        repos.getMetaData(MetaTest5.class, null, true);
+        repos.getMetaData(MetaTest3.class, null, true);
+        repos.getMetaData(MetaTest2.class, null, true);
+        repos.getMetaData(MetaTest1.class, null, true);
+        repos.getMetaData(MetaTest6.class, null, true);
+
+        XMLPersistenceMetaDataSerializer ser =
+            new XMLPersistenceMetaDataSerializer(conf);
+        ser.addAll(repos);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ser.serialize(new OutputStreamWriter(out), ser.PRETTY);
+        byte[] bytes = out.toByteArray();
+
+        XMLPersistenceMetaDataParser parser =
+            new XMLPersistenceMetaDataParser(conf);
+        parser.parse(new InputStreamReader
+            (new ByteArrayInputStream(bytes)), "bytes");
+        return parser.getRepository();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ExternalValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ExternalValues.java
index 2c2920d..2e1a999 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ExternalValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ExternalValues.java
@@ -1,126 +1,126 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-
-import java.util.UUID;
-
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.Externalizer;
-import org.apache.openjpa.persistence.Factory;
-import org.apache.openjpa.persistence.Persistent;
-
-@Entity
-public class ExternalValues {
-
-    private boolean booleanToShort;
-    private byte byteToDouble;
-    private int intToFloat;
-    private long longToChar;
-    private short shortToString;
-    private float floatToBoolean;
-    private double doubleToByte;
-    private char charToInt;
-    private String stringToLong;
-    @Persistent
-    @Externalizer("toString")        
-    @Factory("UUID.fromString")
-    private UUID    uuid;
-
-    public boolean getBooleanToShort() {
-        return booleanToShort;
-    }
-
-    public void setBooleanToShort(boolean b) {
-        booleanToShort = b;
-    }
-
-    public byte getByteToDouble() {
-        return byteToDouble;
-    }
-
-    public void setByteToDouble(byte b) {
-        byteToDouble = b;
-    }
-
-    public int getIntToFloat() {
-        return intToFloat;
-    }
-
-    public void setIntToFloat(int i) {
-        intToFloat = i;
-    }
-
-    public long getLongToChar() {
-        return longToChar;
-    }
-
-    public void setLongToChar(long l) {
-        longToChar = l;
-    }
-
-    public short getShortToString() {
-        return shortToString;
-    }
-
-    public void setShortToString(short s) {
-        shortToString = s;
-    }
-
-    public double getDoubleToByte() {
-        return doubleToByte;
-    }
-
-    public void setDoubleToByte(double d) {
-        doubleToByte = d;
-    }
-
-    public float getFloatToBoolean() {
-        return floatToBoolean;
-    }
-
-    public void setFloatToBoolean(float f) {
-        floatToBoolean = f;
-    }
-
-    public char getCharToInt() {
-        return charToInt;
-    }
-
-    public void setCharToInt(char c) {
-        charToInt = c;
-    }
-
-    public String getStringToLong() {
-        return stringToLong;
-    }
-
-    public void setStringToLong(String s) {
-        stringToLong = s;
-    }
-
-    public UUID getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(UUID uuid) {
-        this.uuid = uuid;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+
+import java.util.UUID;
+
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.Externalizer;
+import org.apache.openjpa.persistence.Factory;
+import org.apache.openjpa.persistence.Persistent;
+
+@Entity
+public class ExternalValues {
+
+    private boolean booleanToShort;
+    private byte byteToDouble;
+    private int intToFloat;
+    private long longToChar;
+    private short shortToString;
+    private float floatToBoolean;
+    private double doubleToByte;
+    private char charToInt;
+    private String stringToLong;
+    @Persistent
+    @Externalizer("toString")        
+    @Factory("UUID.fromString")
+    private UUID    uuid;
+
+    public boolean getBooleanToShort() {
+        return booleanToShort;
+    }
+
+    public void setBooleanToShort(boolean b) {
+        booleanToShort = b;
+    }
+
+    public byte getByteToDouble() {
+        return byteToDouble;
+    }
+
+    public void setByteToDouble(byte b) {
+        byteToDouble = b;
+    }
+
+    public int getIntToFloat() {
+        return intToFloat;
+    }
+
+    public void setIntToFloat(int i) {
+        intToFloat = i;
+    }
+
+    public long getLongToChar() {
+        return longToChar;
+    }
+
+    public void setLongToChar(long l) {
+        longToChar = l;
+    }
+
+    public short getShortToString() {
+        return shortToString;
+    }
+
+    public void setShortToString(short s) {
+        shortToString = s;
+    }
+
+    public double getDoubleToByte() {
+        return doubleToByte;
+    }
+
+    public void setDoubleToByte(double d) {
+        doubleToByte = d;
+    }
+
+    public float getFloatToBoolean() {
+        return floatToBoolean;
+    }
+
+    public void setFloatToBoolean(float f) {
+        floatToBoolean = f;
+    }
+
+    public char getCharToInt() {
+        return charToInt;
+    }
+
+    public void setCharToInt(char c) {
+        charToInt = c;
+    }
+
+    public String getStringToLong() {
+        return stringToLong;
+    }
+
+    public void setStringToLong(String s) {
+        stringToLong = s;
+    }
+
+    public UUID getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPC.java
index d91d58c..055796e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPC.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class FieldOrderPC {
-
-    private transient String firstField;
-    private static char staticField;
-    private int intField;
-    private int thirdField;
-    private int unmanagedField;
-    private final Long finalField = null;
-    private Double secondField;
-    private FieldOrderPC oneToOneField;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class FieldOrderPC {
+
+    private transient String firstField;
+    private static char staticField;
+    private int intField;
+    private int thirdField;
+    private int unmanagedField;
+    private final Long finalField = null;
+    private Double secondField;
+    private FieldOrderPC oneToOneField;
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPCSubclass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPCSubclass.java
index f08fed3..af78536 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPCSubclass.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/FieldOrderPCSubclass.java
@@ -1,32 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class FieldOrderPCSubclass
-    extends FieldOrderPC {
-
-    private transient String sub1;
-    private int sub2;
-    private Double sub3;
-    private int unmanagedSubField;
-    private int undeclaredSubField;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class FieldOrderPCSubclass
+    extends FieldOrderPC {
+
+    private transient String sub1;
+    private int sub2;
+    private Double sub3;
+    private int unmanagedSubField;
+    private int undeclaredSubField;
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest1.java
index 6f6e024..13a513f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest1.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-
-@Entity
-public class MetaTest1 {
-
-    // these should not be persistent
-    private static int staticField;
-    private final String finalField = null;
-    private transient char transientField;
-    private MetaTest4 metaTest4Field;
-    //@OneToMany(mappedBy="MetaTest4", fetch=FetchType.LAZY)
-    @PersistentCollection
-    private java.util.Set<MetaTest4> metaTest4ArrayField;
-    //private MetaTest4[] metaTest4ArrayField;
-    private Object objectField;
-    private Long longWrapperField;
-    private double doubleField;
-
-    // persistent fields -- see metadata
-    private String stringField;
-    private Integer intWrapperField;
-    private int intField;
-    private MetaTest2 metaTest2Field;
-    //@OneToMany(mappedBy="MetaTest2", fetch=FetchType.LAZY)
-    @PersistentCollection
-    private java.util.Set<MetaTest2> metaTest2ArrayField;
-    //private MetaTest2[] metaTest2ArrayField;
-    @PersistentCollection
-    private int[] intArrayField;
-
-    @Entity
-    @Table(name="MetaTest1_Inner")
-    public static class Inner {
-
-        private long longField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+public class MetaTest1 {
+
+    // these should not be persistent
+    private static int staticField;
+    private final String finalField = null;
+    private transient char transientField;
+    private MetaTest4 metaTest4Field;
+    //@OneToMany(mappedBy="MetaTest4", fetch=FetchType.LAZY)
+    @PersistentCollection
+    private java.util.Set<MetaTest4> metaTest4ArrayField;
+    //private MetaTest4[] metaTest4ArrayField;
+    private Object objectField;
+    private Long longWrapperField;
+    private double doubleField;
+
+    // persistent fields -- see metadata
+    private String stringField;
+    private Integer intWrapperField;
+    private int intField;
+    private MetaTest2 metaTest2Field;
+    //@OneToMany(mappedBy="MetaTest2", fetch=FetchType.LAZY)
+    @PersistentCollection
+    private java.util.Set<MetaTest2> metaTest2ArrayField;
+    //private MetaTest2[] metaTest2ArrayField;
+    @PersistentCollection
+    private int[] intArrayField;
+
+    @Entity
+    @Table(name="MetaTest1_Inner")
+    public static class Inner {
+
+        private long longField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest2.java
index 356e392..10d9405 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest2.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import java.util.Collection;
-import java.util.Map;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToOne;
-
-@Entity
-public class MetaTest2
-    extends MetaTest1 {
-
-    private Collection collectionField1;
-    private Collection collectionField2;
-    private Map mapField1;
-    private Map mapField2;
-    @ManyToOne(fetch = FetchType.LAZY)
-    private MetaTest2 metaTest2Field;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import java.util.Collection;
+import java.util.Map;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class MetaTest2
+    extends MetaTest1 {
+
+    private Collection collectionField1;
+    private Collection collectionField2;
+    private Map mapField1;
+    private Map mapField2;
+    @ManyToOne(fetch = FetchType.LAZY)
+    private MetaTest2 metaTest2Field;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest3.java
index a01c4bc..1917ae9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest3.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import java.util.Map;
-import javax.persistence.Entity;
-
-@Entity
-public class MetaTest3
-    extends MetaTest2 {
-
-    private Object pcField;
-    private Object externalField;
-    private Object metaField;
-
-    public static Map toMap(Object fieldValue) {
-        // dummy method
-        return null;
-    }
-
-    public static Object fromMap(Map externalValue) {
-        // dummy method
-        return null;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import java.util.Map;
+import javax.persistence.Entity;
+
+@Entity
+public class MetaTest3
+    extends MetaTest2 {
+
+    private Object pcField;
+    private Object externalField;
+    private Object metaField;
+
+    public static Map toMap(Object fieldValue) {
+        // dummy method
+        return null;
+    }
+
+    public static Object fromMap(Map externalValue) {
+        // dummy method
+        return null;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest4.java
index dd3f58e..9780cb3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest4.java
@@ -1,26 +1,26 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class MetaTest4 {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class MetaTest4 {
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest5.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest5.java
index f8506d7..b6515b6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest5.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest5.java
@@ -1,57 +1,57 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-/**
- * <p>Persistent type used in the testing of the JDO metadata.</p>
- *
- * @author Abe White
- */
-public abstract class MetaTest5 {
-
-    private long id;
-
-    public static class MetaTest5Id {
-
-        public long id;
-
-        public MetaTest5Id() {
-        }
-
-        public MetaTest5Id(String str) {
-            id = Long.parseLong(str);
-        }
-
-        public String toString() {
-            return String.valueOf(id);
-        }
-
-        public boolean equals(Object other) {
-            return other instanceof MetaTest5Id
-                && ((MetaTest5Id) other).id == id;
-        }
-
-        public int hashCode() {
-            return (int) (id % Integer.MAX_VALUE);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+/**
+ * <p>Persistent type used in the testing of the JDO metadata.</p>
+ *
+ * @author Abe White
+ */
+public abstract class MetaTest5 {
+
+    private long id;
+
+    public static class MetaTest5Id {
+
+        public long id;
+
+        public MetaTest5Id() {
+        }
+
+        public MetaTest5Id(String str) {
+            id = Long.parseLong(str);
+        }
+
+        public String toString() {
+            return String.valueOf(id);
+        }
+
+        public boolean equals(Object other) {
+            return other instanceof MetaTest5Id
+                && ((MetaTest5Id) other).id == id;
+        }
+
+        public int hashCode() {
+            return (int) (id % Integer.MAX_VALUE);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest6.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest6.java
index 5f4c05c..451cb4f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest6.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/MetaTest6.java
@@ -1,28 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class MetaTest6
-    extends MetaTest5 {
-
-    private String name;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class MetaTest6
+    extends MetaTest5 {
+
+    private String name;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/NonPersistentFieldsPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/NonPersistentFieldsPC.java
index 44b7c49..2204e12 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/NonPersistentFieldsPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/NonPersistentFieldsPC.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.meta.ClassMetaData;
-
-@Entity
-public class NonPersistentFieldsPC {
-
-    private String persistentField;
-    private String nonPersistentField;
-    private Object objectField;
-    private Serializable interfaceField;
-    private ClassMetaData userObjectField;
-    private ClassMetaData userInterfaceField;
-    private Object explicitObjectField;
-    private Serializable explicitInterfaceField;
-    private ClassMetaData explicitUserObjectField;
-    private ClassMetaData explicitUserInterfaceField;
-    private Object persistentObjectField;
-    private Serializable persistentInterfaceField;
-    private ClassMetaData persistentUserObjectField;
-    private ClassMetaData persistentUserInterfaceField;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.meta.ClassMetaData;
+
+@Entity
+public class NonPersistentFieldsPC {
+
+    private String persistentField;
+    private String nonPersistentField;
+    private Object objectField;
+    private Serializable interfaceField;
+    private ClassMetaData userObjectField;
+    private ClassMetaData userInterfaceField;
+    private Object explicitObjectField;
+    private Serializable explicitInterfaceField;
+    private ClassMetaData explicitUserObjectField;
+    private ClassMetaData explicitUserInterfaceField;
+    private Object persistentObjectField;
+    private Serializable persistentInterfaceField;
+    private ClassMetaData persistentUserObjectField;
+    private ClassMetaData persistentUserInterfaceField;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPC.java
index a64237b..7e74793 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPC.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Entity;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-
-@Entity
-public class OrderByPC {
-
-    private long id;
-
-    private List stringListAsc = new ArrayList();
-    @PersistentCollection
-    private int[] intArrayDesc;
-    private List orderByPKAsc = new ArrayList();
-    private List orderByStringDesc = new ArrayList();
-    private List orderByStringAndPKDesc = new ArrayList();
-
-    private List oneToManyAsc = new ArrayList();
-
-    public long getId() {
-        return this.id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public List getStringListAsc() {
-        return this.stringListAsc;
-    }
-
-    public int[] getIntArrayDesc() {
-        return this.intArrayDesc;
-    }
-
-    public void setIntArrayDesc(int[] intArrayDesc) {
-        this.intArrayDesc = intArrayDesc;
-    }
-
-    public List getOrderByPKAsc() {
-        return this.orderByPKAsc;
-    }
-
-    public List getOrderByStringDesc() {
-        return this.orderByStringDesc;
-    }
-
-    public List getOrderByStringAndPKDesc() {
-        return this.orderByStringAndPKDesc;
-    }
-
-    public List getOneToManyAsc() {
-        return this.oneToManyAsc;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+public class OrderByPC {
+
+    private long id;
+
+    private List stringListAsc = new ArrayList();
+    @PersistentCollection
+    private int[] intArrayDesc;
+    private List orderByPKAsc = new ArrayList();
+    private List orderByStringDesc = new ArrayList();
+    private List orderByStringAndPKDesc = new ArrayList();
+
+    private List oneToManyAsc = new ArrayList();
+
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public List getStringListAsc() {
+        return this.stringListAsc;
+    }
+
+    public int[] getIntArrayDesc() {
+        return this.intArrayDesc;
+    }
+
+    public void setIntArrayDesc(int[] intArrayDesc) {
+        this.intArrayDesc = intArrayDesc;
+    }
+
+    public List getOrderByPKAsc() {
+        return this.orderByPKAsc;
+    }
+
+    public List getOrderByStringDesc() {
+        return this.orderByStringDesc;
+    }
+
+    public List getOrderByStringAndPKDesc() {
+        return this.orderByStringAndPKDesc;
+    }
+
+    public List getOneToManyAsc() {
+        return this.oneToManyAsc;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRel.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRel.java
index b416bb5..99f6b87 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRel.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRel.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class OrderByPCRel {
-
-    private long id;
-    private String string;
-    private OrderByPC toOne;
-
-    public long getId() {
-        return this.id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getString() {
-        return this.string;
-    }
-
-    public void setString(String string) {
-        this.string = string;
-    }
-
-    public OrderByPC getToOne() {
-        return this.toOne;
-    }
-
-    public void setToOne(OrderByPC toOne) {
-        this.toOne = toOne;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class OrderByPCRel {
+
+    private long id;
+    private String string;
+    private OrderByPC toOne;
+
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getString() {
+        return this.string;
+    }
+
+    public void setString(String string) {
+        this.string = string;
+    }
+
+    public OrderByPC getToOne() {
+        return this.toOne;
+    }
+
+    public void setToOne(OrderByPC toOne) {
+        this.toOne = toOne;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRelSub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRelSub.java
index b3786cb..4cac71a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRelSub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/OrderByPCRelSub.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class OrderByPCRelSub
-    extends OrderByPCRel {
-
-    private int sub;
-
-    public int getSub() {
-        return this.sub;
-    }
-
-    public void setSub(int sub) {
-        this.sub = sub;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class OrderByPCRelSub
+    extends OrderByPCRel {
+
+    private int sub;
+
+    public int getSub() {
+        return this.sub;
+    }
+
+    public void setSub(int sub) {
+        this.sub = sub;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest1.java
index 205b9a0..be93239 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest1.java
@@ -1,268 +1,268 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.Entity;
-
-@Entity
-public class RuntimeTest1
-    implements Serializable {
-
-    public static final String someStaticField = "someField";
-
-    private byte byteField;
-    private boolean booleanField;
-    private char charField;
-    private double doubleField;
-    private float floatField;
-    private int intField;
-    private long longField;
-    private short shortField;
-    private String stringField;
-    private BigInteger bigIntegerField;
-    private BigDecimal bigDecimalField;
-    private Date dateField;
-    private Locale localeField;
-    private Byte byteObjfield;
-    private Boolean booleanObjField;
-    private Character charObjField;
-    private Double doubleObjField;
-    private Float floatObjField;
-    private Integer intObjField;
-    private Long longObjField;
-    private Short shortObjField;
-
-    // transactional only
-    private TransactionalClassPC transField;
-    public String transString;
-
-    // relations
-    private RuntimeTest1 selfOneOne;
-    private Set selfOneMany = new HashSet();
-
-    public RuntimeTest1() {
-    }
-
-    public RuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-        //FIXME Seetha Oct 25,2006
-        //mySQL 0.0 float issue
-        floatField = 1.0f;
-    }
-
-    public byte getByteField() {
-        return this.byteField;
-    }
-
-    public void setByteField(byte byteField) {
-        this.byteField = byteField;
-    }
-
-    public boolean getBooleanField() {
-        return this.booleanField;
-    }
-
-    public void setBooleanField(boolean booleanField) {
-        this.booleanField = booleanField;
-    }
-
-    public char getCharField() {
-        return this.charField;
-    }
-
-    public void setCharField(char charField) {
-        this.charField = charField;
-    }
-
-    public double getDoubleField() {
-        return this.doubleField;
-    }
-
-    public void setDoubleField(double doubleField) {
-        this.doubleField = doubleField;
-    }
-
-    public float getFloatField() {
-        return this.floatField;
-    }
-
-    public void setFloatField(float floatField) {
-        this.floatField = floatField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public long getLongField() {
-        return this.longField;
-    }
-
-    public void setLongField(long longField) {
-        this.longField = longField;
-    }
-
-    public short getShortField() {
-        return this.shortField;
-    }
-
-    public void setShortField(short shortField) {
-        this.shortField = shortField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public BigInteger getBigIntegerField() {
-        return this.bigIntegerField;
-    }
-
-    public void setBigIntegerField(BigInteger bigIntegerField) {
-        this.bigIntegerField = bigIntegerField;
-    }
-
-    public BigDecimal getBigDecimalField() {
-        return this.bigDecimalField;
-    }
-
-    public void setBigDecimalField(BigDecimal bigDecimalField) {
-        this.bigDecimalField = bigDecimalField;
-    }
-
-    public Date getDateField() {
-        return this.dateField;
-    }
-
-    public void setDateField(Date dateField) {
-        this.dateField = dateField;
-    }
-
-    public Locale getLocaleField() {
-        return this.localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-
-    public Byte getByteObjfield() {
-        return this.byteObjfield;
-    }
-
-    public void setByteObjfield(Byte byteObjfield) {
-        this.byteObjfield = byteObjfield;
-    }
-
-    public Boolean getBooleanObjField() {
-        return this.booleanObjField;
-    }
-
-    public void setBooleanObjField(Boolean booleanObjField) {
-        this.booleanObjField = booleanObjField;
-    }
-
-    public Character getCharObjField() {
-        return this.charObjField;
-    }
-
-    public void setCharObjField(Character charObjField) {
-        this.charObjField = charObjField;
-    }
-
-    public Double getDoubleObjField() {
-        return this.doubleObjField;
-    }
-
-    public void setDoubleObjField(Double doubleObjField) {
-        this.doubleObjField = doubleObjField;
-    }
-
-    public Float getFloatObjField() {
-        return this.floatObjField;
-    }
-
-    public void setFloatObjField(Float floatObjField) {
-        this.floatObjField = floatObjField;
-    }
-
-    public Integer getIntObjField() {
-        return this.intObjField;
-    }
-
-    public void setIntObjField(Integer intObjField) {
-        this.intObjField = intObjField;
-    }
-
-    public Long getLongObjField() {
-        return this.longObjField;
-    }
-
-    public void setLongObjField(Long longObjField) {
-        this.longObjField = longObjField;
-    }
-
-    public Short getShortObjField() {
-        return this.shortObjField;
-    }
-
-    public void setShortObjField(Short shortObjField) {
-        this.shortObjField = shortObjField;
-    }
-
-    public TransactionalClassPC getTransField() {
-        return this.transField;
-    }
-
-    public void setTransField(TransactionalClassPC transField) {
-        this.transField = transField;
-    }
-
-    public RuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest1
+    implements Serializable {
+
+    public static final String someStaticField = "someField";
+
+    private byte byteField;
+    private boolean booleanField;
+    private char charField;
+    private double doubleField;
+    private float floatField;
+    private int intField;
+    private long longField;
+    private short shortField;
+    private String stringField;
+    private BigInteger bigIntegerField;
+    private BigDecimal bigDecimalField;
+    private Date dateField;
+    private Locale localeField;
+    private Byte byteObjfield;
+    private Boolean booleanObjField;
+    private Character charObjField;
+    private Double doubleObjField;
+    private Float floatObjField;
+    private Integer intObjField;
+    private Long longObjField;
+    private Short shortObjField;
+
+    // transactional only
+    private TransactionalClassPC transField;
+    public String transString;
+
+    // relations
+    private RuntimeTest1 selfOneOne;
+    private Set selfOneMany = new HashSet();
+
+    public RuntimeTest1() {
+    }
+
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+        //FIXME Seetha Oct 25,2006
+        //mySQL 0.0 float issue
+        floatField = 1.0f;
+    }
+
+    public byte getByteField() {
+        return this.byteField;
+    }
+
+    public void setByteField(byte byteField) {
+        this.byteField = byteField;
+    }
+
+    public boolean getBooleanField() {
+        return this.booleanField;
+    }
+
+    public void setBooleanField(boolean booleanField) {
+        this.booleanField = booleanField;
+    }
+
+    public char getCharField() {
+        return this.charField;
+    }
+
+    public void setCharField(char charField) {
+        this.charField = charField;
+    }
+
+    public double getDoubleField() {
+        return this.doubleField;
+    }
+
+    public void setDoubleField(double doubleField) {
+        this.doubleField = doubleField;
+    }
+
+    public float getFloatField() {
+        return this.floatField;
+    }
+
+    public void setFloatField(float floatField) {
+        this.floatField = floatField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public long getLongField() {
+        return this.longField;
+    }
+
+    public void setLongField(long longField) {
+        this.longField = longField;
+    }
+
+    public short getShortField() {
+        return this.shortField;
+    }
+
+    public void setShortField(short shortField) {
+        this.shortField = shortField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public BigInteger getBigIntegerField() {
+        return this.bigIntegerField;
+    }
+
+    public void setBigIntegerField(BigInteger bigIntegerField) {
+        this.bigIntegerField = bigIntegerField;
+    }
+
+    public BigDecimal getBigDecimalField() {
+        return this.bigDecimalField;
+    }
+
+    public void setBigDecimalField(BigDecimal bigDecimalField) {
+        this.bigDecimalField = bigDecimalField;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+
+    public void setDateField(Date dateField) {
+        this.dateField = dateField;
+    }
+
+    public Locale getLocaleField() {
+        return this.localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+
+    public Byte getByteObjfield() {
+        return this.byteObjfield;
+    }
+
+    public void setByteObjfield(Byte byteObjfield) {
+        this.byteObjfield = byteObjfield;
+    }
+
+    public Boolean getBooleanObjField() {
+        return this.booleanObjField;
+    }
+
+    public void setBooleanObjField(Boolean booleanObjField) {
+        this.booleanObjField = booleanObjField;
+    }
+
+    public Character getCharObjField() {
+        return this.charObjField;
+    }
+
+    public void setCharObjField(Character charObjField) {
+        this.charObjField = charObjField;
+    }
+
+    public Double getDoubleObjField() {
+        return this.doubleObjField;
+    }
+
+    public void setDoubleObjField(Double doubleObjField) {
+        this.doubleObjField = doubleObjField;
+    }
+
+    public Float getFloatObjField() {
+        return this.floatObjField;
+    }
+
+    public void setFloatObjField(Float floatObjField) {
+        this.floatObjField = floatObjField;
+    }
+
+    public Integer getIntObjField() {
+        return this.intObjField;
+    }
+
+    public void setIntObjField(Integer intObjField) {
+        this.intObjField = intObjField;
+    }
+
+    public Long getLongObjField() {
+        return this.longObjField;
+    }
+
+    public void setLongObjField(Long longObjField) {
+        this.longObjField = longObjField;
+    }
+
+    public Short getShortObjField() {
+        return this.shortObjField;
+    }
+
+    public void setShortObjField(Short shortObjField) {
+        this.shortObjField = shortObjField;
+    }
+
+    public TransactionalClassPC getTransField() {
+        return this.transField;
+    }
+
+    public void setTransField(TransactionalClassPC transField) {
+        this.transField = transField;
+    }
+
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest2.java
index 4a87cd8..4f3d441 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest2.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class RuntimeTest2
-    extends RuntimeTest1 {
-
-    private int intField2;
-
-    public RuntimeTest2() {
-    }
-
-    public RuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest2
+    extends RuntimeTest1 {
+
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest3.java
index 8b24fcb..e4b2af8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/RuntimeTest3.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class RuntimeTest3
-    extends RuntimeTest2 {
-
-    private int intField3;
-
-    public RuntimeTest3() {
-    }
-
-    public RuntimeTest3(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField3() {
-        return this.intField3;
-    }
-
-    public void setIntField3(int intField3) {
-        this.intField3 = intField3;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest3
+    extends RuntimeTest2 {
+
+    private int intField3;
+
+    public RuntimeTest3() {
+    }
+
+    public RuntimeTest3(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField3() {
+        return this.intField3;
+    }
+
+    public void setIntField3(int intField3) {
+        this.intField3 = intField3;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned.java
index ae57fab..9329791 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned.java
@@ -1,70 +1,70 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class SequenceAssigned {
-
-    private long pk;
-    private SequenceAssigned other;
-
-    public void setPK(long l) {
-        pk = l;
-    }
-
-    public long getPK() {
-        return pk;
-    }
-
-    public void setOther(SequenceAssigned other) {
-        this.other = other;
-    }
-
-    public SequenceAssigned getOther() {
-        return other;
-    }
-
-    public static class Id implements java.io.Serializable {
-
-        public long pk;
-
-        public Id() {
-        }
-
-        public Id(String str) {
-            pk = Long.parseLong(str);
-        }
-
-        public int hashCode() {
-            return (int) (pk % (long) Integer.MAX_VALUE);
-        }
-
-        public String toString() {
-            return pk + "";
-        }
-
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof Id))
-                return false;
-            return pk == ((Id) o).pk;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class SequenceAssigned {
+
+    private long pk;
+    private SequenceAssigned other;
+
+    public void setPK(long l) {
+        pk = l;
+    }
+
+    public long getPK() {
+        return pk;
+    }
+
+    public void setOther(SequenceAssigned other) {
+        this.other = other;
+    }
+
+    public SequenceAssigned getOther() {
+        return other;
+    }
+
+    public static class Id implements java.io.Serializable {
+
+        public long pk;
+
+        public Id() {
+        }
+
+        public Id(String str) {
+            pk = Long.parseLong(str);
+        }
+
+        public int hashCode() {
+            return (int) (pk % (long) Integer.MAX_VALUE);
+        }
+
+        public String toString() {
+            return pk + "";
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof Id))
+                return false;
+            return pk == ((Id) o).pk;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned2.java
index 603ebe3..be621ba 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned2.java
@@ -1,27 +1,27 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class SequenceAssigned2 extends SequenceAssigned {
-
-    private int foo;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class SequenceAssigned2 extends SequenceAssigned {
+
+    private int foo;
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned3.java
index bc00731..a4d48cb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/SequenceAssigned3.java
@@ -1,62 +1,62 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class SequenceAssigned3 {
-
-    private Long pk;
-
-    public void setPK(Long l) {
-        pk = l;
-    }
-
-    public Long getPK() {
-        return pk;
-    }
-
-    public static class Id implements java.io.Serializable {
-
-        public Long pk;
-
-        public Id() {
-        }
-
-        public Id(String str) {
-            pk = Long.valueOf(str);
-        }
-
-        public int hashCode() {
-            return (int) (pk == null ? 0 : pk.longValue()
-                % (long) Integer.MAX_VALUE);
-        }
-
-        public String toString() {
-            return pk + "";
-        }
-
-        public boolean equals(Object o) {
-            if (o == null || !(o instanceof Id))
-                return false;
-            return pk == ((Id) o).pk;
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class SequenceAssigned3 {
+
+    private Long pk;
+
+    public void setPK(Long l) {
+        pk = l;
+    }
+
+    public Long getPK() {
+        return pk;
+    }
+
+    public static class Id implements java.io.Serializable {
+
+        public Long pk;
+
+        public Id() {
+        }
+
+        public Id(String str) {
+            pk = Long.valueOf(str);
+        }
+
+        public int hashCode() {
+            return (int) (pk == null ? 0 : pk.longValue()
+                % (long) Integer.MAX_VALUE);
+        }
+
+        public String toString() {
+            return pk + "";
+        }
+
+        public boolean equals(Object o) {
+            if (o == null || !(o instanceof Id))
+                return false;
+            return pk == ((Id) o).pk;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/TransactionalClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/TransactionalClassPC.java
index de75a33..47e2576 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/TransactionalClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/TransactionalClassPC.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-
-@Entity
-public class TransactionalClassPC {
-
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+
+@Entity
+public class TransactionalClassPC {
+
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ValueStrategyPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ValueStrategyPC.java
index 7094070..9193f88 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ValueStrategyPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/common/apps/ValueStrategyPC.java
@@ -1,89 +1,89 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.meta.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ValueStrategyPC {
-
-    private String uuid;
-    private String uuidHex;
-    private String name;
-    private int ignoreUpdate;
-    private int restrictUpdate;
-    private int version;
-    private int sequence;
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public int getIgnoreUpdate() {
-        return this.ignoreUpdate;
-    }
-
-    public void setIgnoreUpdate(int ignoreUpdate) {
-        this.ignoreUpdate = ignoreUpdate;
-    }
-
-    public int getRestrictUpdate() {
-        return this.restrictUpdate;
-    }
-
-    public void setRestrictUpdate(int restrictUpdate) {
-        this.restrictUpdate = restrictUpdate;
-    }
-
-    public String getUUID() {
-        return this.uuid;
-    }
-
-    public void setUUID(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getUUIDHex() {
-        return this.uuidHex;
-    }
-
-    public void setUUIDHex(String uuidHex) {
-        this.uuidHex = uuidHex;
-    }
-
-    public int getVersion() {
-        return this.version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-
-    public int getSequence() {
-        return this.sequence;
-    }
-
-    public void setSequence(int sequence) {
-        this.sequence = sequence;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.meta.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ValueStrategyPC {
+
+    private String uuid;
+    private String uuidHex;
+    private String name;
+    private int ignoreUpdate;
+    private int restrictUpdate;
+    private int version;
+    private int sequence;
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getIgnoreUpdate() {
+        return this.ignoreUpdate;
+    }
+
+    public void setIgnoreUpdate(int ignoreUpdate) {
+        this.ignoreUpdate = ignoreUpdate;
+    }
+
+    public int getRestrictUpdate() {
+        return this.restrictUpdate;
+    }
+
+    public void setRestrictUpdate(int restrictUpdate) {
+        this.restrictUpdate = restrictUpdate;
+    }
+
+    public String getUUID() {
+        return this.uuid;
+    }
+
+    public void setUUID(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getUUIDHex() {
+        return this.uuidHex;
+    }
+
+    public void setUUIDHex(String uuidHex) {
+        this.uuidHex = uuidHex;
+    }
+
+    public int getVersion() {
+        return this.version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public int getSequence() {
+        return this.sequence;
+    }
+
+    public void setSequence(int sequence) {
+        this.sequence = sequence;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java
index 4487c80..a64bc76 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/NullValues.java
@@ -1,154 +1,154 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.nullity;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-/**
- * Persistent entity used to test behavior of null constraint on basic fields.
- *  
- * @author Pinaki Poddar
- *
- */
-@Entity
-public class NullValues {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	@Column(nullable=true)
-	private Integer nullable;
-	
-	@Column(nullable=false)
-	private Integer notNullable;
-	
-	@Basic(optional=true)
-	private Integer optional;
-	
-	@Basic(optional=false)
-	private Integer notOptional;
-	
-	@Column(nullable=true)
-	private BlobValue nullableBlob;
-	
-	@Column(nullable=false)
-	private BlobValue notNullableBlob;
-	
-	@Basic(optional=true)
-	private BlobValue optionalBlob;
-	
-	@Basic(optional=false)
-	private BlobValue notOptionalBlob;
-	
-	@Version
-	private int version;
-	
-	
-	/**
-	 * Construct with all fields set to non-null values.
-	 */
-	public NullValues() {
-		setOptional(42);
-		setNotOptional(42);
-		setNotNullable(42);
-		setNullable(42);
-		
-		setNullableBlob(new BlobValue());
-		setNotNullableBlob(new BlobValue());
-		setOptionalBlob(new BlobValue());
-		setNotOptionalBlob(new BlobValue());
-	}
-	
-	public long getId() {
-		return id;
-	}
-	
-	public Integer getNullable() {
-		return nullable;
-	}
-	
-	public void setNullable(Integer nullable) {
-		this.nullable = nullable;
-	}
-	
-	public Integer getNotNullable() {
-		return notNullable;
-	}
-	
-	public void setNotNullable(Integer notNullable) {
-		this.notNullable = notNullable;
-	}
-	
-	public Integer getOptional() {
-		return optional;
-	}
-	
-	public void setOptional(Integer optional) {
-		this.optional = optional;
-	}
-	
-	public Integer getNotOptional() {
-		return notOptional;
-	}
-	
-	public void setNotOptional(Integer notOptional) {
-		this.notOptional = notOptional;
-	}
-
-	public BlobValue getNullableBlob() {
-		return nullableBlob;
-	}
-
-	public void setNullableBlob(BlobValue nullableBlob) {
-		this.nullableBlob = nullableBlob;
-	}
-
-	public BlobValue getNotNullableBlob() {
-		return notNullableBlob;
-	}
-
-	public void setNotNullableBlob(BlobValue notNullableBlob) {
-		this.notNullableBlob = notNullableBlob;
-	}
-
-	public BlobValue getOptionalBlob() {
-		return optionalBlob;
-	}
-
-	public void setOptionalBlob(BlobValue optionalBlob) {
-		this.optionalBlob = optionalBlob;
-	}
-
-	public BlobValue getNotOptionalBlob() {
-		return notOptionalBlob;
-	}
-
-	public void setNotOptionalBlob(BlobValue notOptionalBlob) {
-		this.notOptionalBlob = notOptionalBlob;
-	}
-	
-	public int getVersion() { 
-	    return version;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.nullity;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * Persistent entity used to test behavior of null constraint on basic fields.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class NullValues {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	@Column(nullable=true)
+	private Integer nullable;
+	
+	@Column(nullable=false)
+	private Integer notNullable;
+	
+	@Basic(optional=true)
+	private Integer optional;
+	
+	@Basic(optional=false)
+	private Integer notOptional;
+	
+	@Column(nullable=true)
+	private BlobValue nullableBlob;
+	
+	@Column(nullable=false)
+	private BlobValue notNullableBlob;
+	
+	@Basic(optional=true)
+	private BlobValue optionalBlob;
+	
+	@Basic(optional=false)
+	private BlobValue notOptionalBlob;
+	
+	@Version
+	private int version;
+	
+	
+	/**
+	 * Construct with all fields set to non-null values.
+	 */
+	public NullValues() {
+		setOptional(42);
+		setNotOptional(42);
+		setNotNullable(42);
+		setNullable(42);
+		
+		setNullableBlob(new BlobValue());
+		setNotNullableBlob(new BlobValue());
+		setOptionalBlob(new BlobValue());
+		setNotOptionalBlob(new BlobValue());
+	}
+	
+	public long getId() {
+		return id;
+	}
+	
+	public Integer getNullable() {
+		return nullable;
+	}
+	
+	public void setNullable(Integer nullable) {
+		this.nullable = nullable;
+	}
+	
+	public Integer getNotNullable() {
+		return notNullable;
+	}
+	
+	public void setNotNullable(Integer notNullable) {
+		this.notNullable = notNullable;
+	}
+	
+	public Integer getOptional() {
+		return optional;
+	}
+	
+	public void setOptional(Integer optional) {
+		this.optional = optional;
+	}
+	
+	public Integer getNotOptional() {
+		return notOptional;
+	}
+	
+	public void setNotOptional(Integer notOptional) {
+		this.notOptional = notOptional;
+	}
+
+	public BlobValue getNullableBlob() {
+		return nullableBlob;
+	}
+
+	public void setNullableBlob(BlobValue nullableBlob) {
+		this.nullableBlob = nullableBlob;
+	}
+
+	public BlobValue getNotNullableBlob() {
+		return notNullableBlob;
+	}
+
+	public void setNotNullableBlob(BlobValue notNullableBlob) {
+		this.notNullableBlob = notNullableBlob;
+	}
+
+	public BlobValue getOptionalBlob() {
+		return optionalBlob;
+	}
+
+	public void setOptionalBlob(BlobValue optionalBlob) {
+		this.optionalBlob = optionalBlob;
+	}
+
+	public BlobValue getNotOptionalBlob() {
+		return notOptionalBlob;
+	}
+
+	public void setNotOptionalBlob(BlobValue notOptionalBlob) {
+		this.notOptionalBlob = notOptionalBlob;
+	}
+	
+	public int getVersion() { 
+	    return version;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java
index f1ef9da..0dfbfaa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/nullity/TestBasicFieldNullity.java
@@ -1,117 +1,117 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.nullity;
-
-import javax.persistence.RollbackException;
-
-import org.apache.openjpa.persistence.InvalidStateException;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-
-/**
- * Test @Basic(optional=true|false) and @Column(nullable=true|false) 
- * specification is honored. 
- * Note: null constraint violation manifests as different exception types
- * for option and nullable condition.
- *
- * @author Pinaki Poddar
- */
-public class TestBasicFieldNullity extends AbstractNullityTestCase {
-
-    public void setUp() {
-        setUp(CLEAR_TABLES, NullValues.class);
-    }
-
-    public void testNullOnOptionalFieldIsAllowed() {
-    	NullValues pc = new NullValues();
-    	pc.setOptional(null); 
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNullOnNonOptionalFieldIsDisallowed() {
-    	NullValues pc = new NullValues();
-    	pc.setNotOptional(null);
-    	assertCommitFails(pc, NEW, InvalidStateException.class);
-    }
-    
-    public void testNotNullOnOptionalFieldIsAllowed() {
-    	NullValues pc = new NullValues();
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNotNullOnNonOptionalFieldIsAllowed() {
-    	NullValues pc = new NullValues();
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNullOnNullableColumnAllowed() {
-    	NullValues pc = new NullValues();
-    	pc.setNullable(null);
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNullOnNonNullableColumnIsDisallowed() {
-    	NullValues pc = new NullValues();
-    	pc.setNotNullable(null);
-    	assertCommitFails(pc, NEW, RollbackException.class);
-    }
-    
-    public void testNotNullOnNullableColumnIsAllowed() {
-    	NullValues pc = new NullValues();
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNotNullOnNonNullableColumnIsAllowed() {
-    	NullValues pc = new NullValues();
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNullOnOptionalBlobFieldIsAllowed() {
-    	NullValues pc = new NullValues();
-    	pc.setOptionalBlob(null);
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNullOnNonOptionalBlobFieldIsDisallowed() {
-    	NullValues pc = new NullValues();
-    	pc.setNotOptionalBlob(null);
-    	assertCommitFails(pc, NEW, InvalidStateException.class);
-    }
-    
-    public void testNullOnNullableBlobColumnAllowed() {
-    	NullValues pc = new NullValues();
-    	pc.setNullableBlob(null);
-    	assertCommitSucceeds(pc, NEW);
-    }
-    
-    public void testNullOnNonNullableBlobColumnIsDisallowed() {
-    	NullValues pc = new NullValues();
-    	pc.setNotNullableBlob(null);
-    	assertCommitFails(pc, NEW, RollbackException.class);
-    }
-    
-    public void testX() {
-    	NullValues pc = new NullValues();
-    	assertCommitSucceeds(pc, NEW);
-    	OpenJPAPersistence.getEntityManager(pc).close();
-    	
-    	pc.setNotNullableBlob(null);
-    	assertCommitFails(pc, !NEW, RollbackException.class);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.nullity;
+
+import javax.persistence.RollbackException;
+
+import org.apache.openjpa.persistence.InvalidStateException;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/**
+ * Test @Basic(optional=true|false) and @Column(nullable=true|false) 
+ * specification is honored. 
+ * Note: null constraint violation manifests as different exception types
+ * for option and nullable condition.
+ *
+ * @author Pinaki Poddar
+ */
+public class TestBasicFieldNullity extends AbstractNullityTestCase {
+
+    public void setUp() {
+        setUp(CLEAR_TABLES, NullValues.class);
+    }
+
+    public void testNullOnOptionalFieldIsAllowed() {
+    	NullValues pc = new NullValues();
+    	pc.setOptional(null); 
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNullOnNonOptionalFieldIsDisallowed() {
+    	NullValues pc = new NullValues();
+    	pc.setNotOptional(null);
+    	assertCommitFails(pc, NEW, InvalidStateException.class);
+    }
+    
+    public void testNotNullOnOptionalFieldIsAllowed() {
+    	NullValues pc = new NullValues();
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNotNullOnNonOptionalFieldIsAllowed() {
+    	NullValues pc = new NullValues();
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNullOnNullableColumnAllowed() {
+    	NullValues pc = new NullValues();
+    	pc.setNullable(null);
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNullOnNonNullableColumnIsDisallowed() {
+    	NullValues pc = new NullValues();
+    	pc.setNotNullable(null);
+    	assertCommitFails(pc, NEW, RollbackException.class);
+    }
+    
+    public void testNotNullOnNullableColumnIsAllowed() {
+    	NullValues pc = new NullValues();
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNotNullOnNonNullableColumnIsAllowed() {
+    	NullValues pc = new NullValues();
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNullOnOptionalBlobFieldIsAllowed() {
+    	NullValues pc = new NullValues();
+    	pc.setOptionalBlob(null);
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNullOnNonOptionalBlobFieldIsDisallowed() {
+    	NullValues pc = new NullValues();
+    	pc.setNotOptionalBlob(null);
+    	assertCommitFails(pc, NEW, InvalidStateException.class);
+    }
+    
+    public void testNullOnNullableBlobColumnAllowed() {
+    	NullValues pc = new NullValues();
+    	pc.setNullableBlob(null);
+    	assertCommitSucceeds(pc, NEW);
+    }
+    
+    public void testNullOnNonNullableBlobColumnIsDisallowed() {
+    	NullValues pc = new NullValues();
+    	pc.setNotNullableBlob(null);
+    	assertCommitFails(pc, NEW, RollbackException.class);
+    }
+    
+    public void testX() {
+    	NullValues pc = new NullValues();
+    	assertCommitSucceeds(pc, NEW);
+    	OpenJPAPersistence.getEntityManager(pc).close();
+    	
+    	pc.setNotNullableBlob(null);
+    	assertCommitFails(pc, !NEW, RollbackException.class);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/BaseQueryTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/BaseQueryTest.java
index 350ed33..e4fc151 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/BaseQueryTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/BaseQueryTest.java
@@ -1,146 +1,146 @@
-/*
- * BaseKernelTest.java
- *
- * Created on October 9, 2006, 12:56 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import javax.persistence.EntityManager;
-
-
-
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public abstract class BaseQueryTest extends org.apache.openjpa.persistence.common.utils.AbstractTestCase {
-
-    private static Map _sysprops = new HashMap();
-
-    /**
-     * Creates a new instance of BaseQueryTest
-     */
-    public BaseQueryTest(String name) {
-        super(name, "querycactusapp");
-    }
-
-    protected OpenJPAEntityManager getEM() {
-        return (OpenJPAEntityManager) currentEntityManager();
-    }
-
-    protected OpenJPAEntityManager getEM(boolean optimistic,
-        boolean retainValues) {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        em.setNontransactionalRead(true);
-        em.setRetainState(retainValues);
-        em.setOptimistic(optimistic);
-        return em;
-    }
-
-    /**
-     * Delete all instances of the given class.
-     */
-    protected int deleteAll(Broker broker, Class clazz,
-        boolean subclasses) {
-        final boolean useDeleteByQuery = false;
-
-        if (useDeleteByQuery) {
-            org.apache.openjpa.kernel.Query query = broker.newQuery(
-                JPQLParser.LANG_JPQL, clazz, "");
-            query.setCandidateType(clazz, subclasses);
-            return (int) query.deleteAll();
-        } else {
-            org.apache.openjpa.kernel.Extent extent =
-                broker.newExtent(clazz, subclasses);
-            List list = extent.list();
-            int size = list.size();
-            broker.deleteAll(list, null);
-            return size;
-        }
-    }
-
-    protected Object persist(Object ob) {
-        Broker broker = getBrokerFactory().newBroker();
-        broker.begin();
-        broker.persist(ob, null);
-        Object id = broker.getObjectId(ob);
-        broker.commit();
-        broker.close();
-        return id;
-    }
-
-    protected Properties getProperties() {
-        return getProperties(null);
-    }
-
-    /**
-     * Return the runtime properties, optionally overriding or setting
-     * some via the given array, which should be in the form
-     * { key, val, key, val, ... }.
-     */
-    protected synchronized Properties getProperties(String[] props) {
-        Properties p = new Properties(System.getProperties());
-        String str = p.getProperty("openjpa.properties", "kodo.properties");
-        if (str != null && str.length() > 0) {
-            // cache system properties to reduce load on file system
-            Properties loaded = (Properties) _sysprops.get(str);
-            if (loaded == null) {
-                loaded = new Properties();
-                ConfigurationProvider cp =
-                    (ConfigurationProvider) Configurations
-                        .getProperty(str, null);
-                if (cp != null)
-                    loaded.putAll(cp.getProperties());
-                _sysprops.put(str, loaded);
-            }
-            p.putAll(loaded);
-        }
-
-        for (int i = 0; props != null && i < props.length; i += 2) {
-            if (props[i + 1] != null) {
-                // remove any duplicate kodo/openjpa property so we don't clash
-                if (props[i].startsWith("openjpa."))
-                    p.remove("openjpa." + props[i].substring(5));
-                else if (props[i].startsWith("openjpa."))
-                    p.remove("openjpa." + props[i].substring(8));
-
-                p.setProperty(props[i], props[i + 1]);
-            } else {
-                p.remove(props[i]);
-            }
-        }
-        return p;
-    }
-}
+/*
+ * BaseKernelTest.java
+ *
+ * Created on October 9, 2006, 12:56 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import javax.persistence.EntityManager;
+
+
+
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public abstract class BaseQueryTest extends org.apache.openjpa.persistence.common.utils.AbstractTestCase {
+
+    private static Map _sysprops = new HashMap();
+
+    /**
+     * Creates a new instance of BaseQueryTest
+     */
+    public BaseQueryTest(String name) {
+        super(name, "querycactusapp");
+    }
+
+    protected OpenJPAEntityManager getEM() {
+        return (OpenJPAEntityManager) currentEntityManager();
+    }
+
+    protected OpenJPAEntityManager getEM(boolean optimistic,
+        boolean retainValues) {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        em.setNontransactionalRead(true);
+        em.setRetainState(retainValues);
+        em.setOptimistic(optimistic);
+        return em;
+    }
+
+    /**
+     * Delete all instances of the given class.
+     */
+    protected int deleteAll(Broker broker, Class clazz,
+        boolean subclasses) {
+        final boolean useDeleteByQuery = false;
+
+        if (useDeleteByQuery) {
+            org.apache.openjpa.kernel.Query query = broker.newQuery(
+                JPQLParser.LANG_JPQL, clazz, "");
+            query.setCandidateType(clazz, subclasses);
+            return (int) query.deleteAll();
+        } else {
+            org.apache.openjpa.kernel.Extent extent =
+                broker.newExtent(clazz, subclasses);
+            List list = extent.list();
+            int size = list.size();
+            broker.deleteAll(list, null);
+            return size;
+        }
+    }
+
+    protected Object persist(Object ob) {
+        Broker broker = getBrokerFactory().newBroker();
+        broker.begin();
+        broker.persist(ob, null);
+        Object id = broker.getObjectId(ob);
+        broker.commit();
+        broker.close();
+        return id;
+    }
+
+    protected Properties getProperties() {
+        return getProperties(null);
+    }
+
+    /**
+     * Return the runtime properties, optionally overriding or setting
+     * some via the given array, which should be in the form
+     * { key, val, key, val, ... }.
+     */
+    protected synchronized Properties getProperties(String[] props) {
+        Properties p = new Properties(System.getProperties());
+        String str = p.getProperty("openjpa.properties", "kodo.properties");
+        if (str != null && str.length() > 0) {
+            // cache system properties to reduce load on file system
+            Properties loaded = (Properties) _sysprops.get(str);
+            if (loaded == null) {
+                loaded = new Properties();
+                ConfigurationProvider cp =
+                    (ConfigurationProvider) Configurations
+                        .getProperty(str, null);
+                if (cp != null)
+                    loaded.putAll(cp.getProperties());
+                _sysprops.put(str, loaded);
+            }
+            p.putAll(loaded);
+        }
+
+        for (int i = 0; props != null && i < props.length; i += 2) {
+            if (props[i + 1] != null) {
+                // remove any duplicate kodo/openjpa property so we don't clash
+                if (props[i].startsWith("openjpa."))
+                    p.remove("openjpa." + props[i].substring(5));
+                else if (props[i].startsWith("openjpa."))
+                    p.remove("openjpa." + props[i].substring(8));
+
+                p.setProperty(props[i], props[i + 1]);
+            } else {
+                p.remove(props[i]);
+            }
+        }
+        return p;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Employee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Employee.java
index e8321a1..0e3b55e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Employee.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Employee.java
@@ -20,8 +20,16 @@
 
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 
+@NamedQueries( { 
+    @NamedQuery(name = "Employee.findByName", 
+        query = "Select e from Employee e where e.name LIKE :name") ,
+    @NamedQuery(name = "Employee.findByNameEscaped", 
+        query = "Select e from Employee e where e.name LIKE :name ESCAPE '\\'")
+    })
 @Entity
 @Table(name="SUBQ_EMPLOYEE")
 public class Employee {
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java
index 988ea3a..30fdeb6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java
@@ -1,296 +1,296 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.*;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.ArgumentException;
-
-/**
- * <p>Tests grouping and having capabilities.</p>
- *
- * @author Abe White
- */
-public abstract class GroupingTestCase
-    extends SingleEMTestCase {
-
-    protected abstract void prepareQuery(Query q);
-
-    public void setUp() {
-        super.setUp(AllFieldTypes.class, CLEAR_TABLES,
-            "openjpa.Compatibility", "JPQL=warn");
-
-        AllFieldTypes pc1 = new AllFieldTypes();
-        AllFieldTypes pc2 = new AllFieldTypes();
-        AllFieldTypes pc3 = new AllFieldTypes();
-        AllFieldTypes pc4 = new AllFieldTypes();
-
-        // pc1 and pc2, pc3 and pc4 grouped on intField, shortField
-        pc1.setIntField(1);
-        pc1.setShortField((short) -1);
-        pc2.setIntField(1);
-        pc2.setShortField((short) -1);
-        pc3.setIntField(2);
-        pc3.setShortField((short) -2);
-        pc4.setIntField(2);
-        pc4.setShortField((short) -2);
-
-        // pc1 and pc2 grouped on stringField
-        pc1.setStringField("abc");
-        pc2.setStringField("acd");
-        pc3.setStringField("def");
-        pc4.setStringField("efg");
-
-        // pc2 and pc3 grouped on byteField
-        pc2.setByteField((byte) 1);
-        pc3.setByteField((byte) 1);
-        pc1.setByteField((byte) 0);
-        pc4.setByteField((byte) 2);
-
-        // longField is unique id
-        pc1.setLongField(1L);
-        pc2.setLongField(2L);
-        pc3.setLongField(3L);
-        pc4.setLongField(4L);
-
-        // set up some relations
-        pc1.setSelfOneOne(pc4);
-        pc2.setSelfOneOne(pc3);
-        pc3.setSelfOneOne(pc2);
-        pc4.setSelfOneOne(pc1);
-
-        // if variable testing, set up some 1-Ms instead of the 1-1s above
-        if (getName().startsWith("testVariable")) {
-            pc1.setSelfOneOne(pc1);
-            pc2.setSelfOneOne(pc1);
-            pc1.getSelfOneMany().add(pc1);
-            pc1.getSelfOneMany().add(pc2);
-
-            pc3.setSelfOneOne(pc3);
-            pc4.setSelfOneOne(pc3);
-            pc3.getSelfOneMany().add(pc3);
-            pc3.getSelfOneMany().add(pc4);
-        }
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(pc1);
-        em.persist(pc2);
-        em.persist(pc3);
-        em.persist(pc4);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testSimpleGroup() {
-        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
-            "group by o.intField order by o.intField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Integer(1), itr.next());
-        assertEquals(new Integer(2), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testOrderByAggregate() {
-        // this is an extension of JPQL
-        Query q = em.createQuery("select sum(o.shortField) " +
-            "from AllFieldTypes o"
-            + " group by o.intField order by sum(o.shortField) asc");
-        prepareQuery(q);
-        // this might fail in MySQL
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Long(-4), itr.next());
-        assertEquals(new Long(-2), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testCompoundGroupSame() {
-        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
-            "group by o.intField, o.shortField order by o.shortField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Integer(2), itr.next());
-        assertEquals(new Integer(1), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testCompoundGroupDifferent() {
-        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
-            "group by o.intField, o.byteField order by o.intField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(4, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Integer(1), itr.next());
-        assertEquals(new Integer(1), itr.next());
-        assertEquals(new Integer(2), itr.next());
-        assertEquals(new Integer(2), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testDifferentGroupLengths() {
-        Query q = em.createQuery("select o.byteField from AllFieldTypes o"
-            + " group by o.byteField order by o.byteField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(3, res.size());
-        Iterator itr = res.iterator();
-        assertEquals((byte) 0, itr.next());
-        assertEquals((byte) 1, itr.next());
-        assertEquals((byte) 2, itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testGroupRelationField() {
-        Query q = em.createQuery("select o.selfOneOne.intField " +
-            "from AllFieldTypes o group by o.selfOneOne.intField " +
-            "order by o.selfOneOne.intField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Integer(1), itr.next());
-        assertEquals(new Integer(2), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testSubstringInGroupBy() {
-        // this is an extension of JPQL
-        Query q = em.createQuery("select substring(o.stringField, 1, 1), " +
-            "count(o) from AllFieldTypes o " +
-            "group by substring(o.stringField, 1, 1)");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(3, res.size());
-
-        q = em.createQuery("select substring(o.stringField, 1, 2), count(o) " +
-            "from AllFieldTypes o group by substring(o.stringField, 1, 2)");
-        prepareQuery(q);
-        res = q.getResultList();
-        assertEquals(4, res.size());
-    }
-
-    public void testGroupedAggregate() {
-        Query q = em.createQuery("select count(o) from AllFieldTypes o " +
-            "group by o.byteField order by o.byteField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(3, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Long(1), itr.next());
-        assertEquals(new Long(2), itr.next());
-        assertEquals(new Long(1), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testGroupedRelationAggregate() {
-        Query q = em.createQuery("select count(o), max(o.selfOneOne.longField)"
-            + " from AllFieldTypes o group by o.intField"
-            + " order by o.intField asc");
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        Object[] o = (Object[]) itr.next();
-        assertEquals(new Long(2), o[0]);
-        assertEquals(new Long(4), o[1]);
-        o = (Object[]) itr.next();
-        assertEquals(new Long(2), o[0]);
-        assertEquals(new Long(2), o[1]);
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testGroupedMixedProjection() {
-        Query q = em.createQuery("select count(o), o.shortField " +
-            "from AllFieldTypes o group by o.intField, o.shortField " +
-            "order by o.intField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        Object[] o = (Object[]) itr.next();
-        assertEquals(new Long(2), o[0]);
-        assertEquals(new Short((short) -1), o[1]);
-        o = (Object[]) itr.next();
-        assertEquals(new Long(2), o[0]);
-        assertEquals(new Short((short) -2), o[1]);
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testSimpleHaving() {
-        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
-            "group by o.intField having o.intField < 2");
-        prepareQuery(q);
-        assertEquals(new Integer(1), q.getSingleResult());
-    }
-
-    public void testAggregateHaving() {
-        Query q = em.createQuery("select o.byteField from AllFieldTypes o " +
-            "group by o.byteField having count(o) > 1");
-        prepareQuery(q);
-        assertEquals(new Byte((byte) 1), q.getSingleResult());
-    }
-
-    public void testMixedHaving() {
-        Query q = em.createQuery("select o.byteField from AllFieldTypes o " +
-            "group by o.byteField having count(o) > 1 or o.byteField = 0 " +
-            "order by o.byteField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Byte((byte) 0), itr.next());
-        assertEquals(new Byte((byte) 1), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testVariableGroup() {
-        Query q = em.createQuery("select max(other.longField) " +
-            "from AllFieldTypes o, AllFieldTypes other " +
-            "where other member of o.selfOneMany " +
-            "group by other.intField order by other.intField asc");
-        prepareQuery(q);
-        List res = q.getResultList();
-        assertEquals(2, res.size());
-        Iterator itr = res.iterator();
-        assertEquals(new Long(2), itr.next());
-        assertEquals(new Long(4), itr.next());
-        assertTrue(!itr.hasNext());
-    }
-
-    public void testVariableHaving() {
-        Query q = em.createQuery("select max(o.longField), other.byteField " +
-            "from AllFieldTypes o, AllFieldTypes other " +
-            "where other member of o.selfOneMany " +
-            "group by other.byteField having sum(other.intField) = 2");
-        prepareQuery(q);
-        assertEquals(new Long(3), ((Object[])q.getSingleResult())[0]);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.*;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.ArgumentException;
+
+/**
+ * <p>Tests grouping and having capabilities.</p>
+ *
+ * @author Abe White
+ */
+public abstract class GroupingTestCase
+    extends SingleEMTestCase {
+
+    protected abstract void prepareQuery(Query q);
+
+    public void setUp() {
+        super.setUp(AllFieldTypes.class, CLEAR_TABLES,
+            "openjpa.Compatibility", "JPQL=warn");
+
+        AllFieldTypes pc1 = new AllFieldTypes();
+        AllFieldTypes pc2 = new AllFieldTypes();
+        AllFieldTypes pc3 = new AllFieldTypes();
+        AllFieldTypes pc4 = new AllFieldTypes();
+
+        // pc1 and pc2, pc3 and pc4 grouped on intField, shortField
+        pc1.setIntField(1);
+        pc1.setShortField((short) -1);
+        pc2.setIntField(1);
+        pc2.setShortField((short) -1);
+        pc3.setIntField(2);
+        pc3.setShortField((short) -2);
+        pc4.setIntField(2);
+        pc4.setShortField((short) -2);
+
+        // pc1 and pc2 grouped on stringField
+        pc1.setStringField("abc");
+        pc2.setStringField("acd");
+        pc3.setStringField("def");
+        pc4.setStringField("efg");
+
+        // pc2 and pc3 grouped on byteField
+        pc2.setByteField((byte) 1);
+        pc3.setByteField((byte) 1);
+        pc1.setByteField((byte) 0);
+        pc4.setByteField((byte) 2);
+
+        // longField is unique id
+        pc1.setLongField(1L);
+        pc2.setLongField(2L);
+        pc3.setLongField(3L);
+        pc4.setLongField(4L);
+
+        // set up some relations
+        pc1.setSelfOneOne(pc4);
+        pc2.setSelfOneOne(pc3);
+        pc3.setSelfOneOne(pc2);
+        pc4.setSelfOneOne(pc1);
+
+        // if variable testing, set up some 1-Ms instead of the 1-1s above
+        if (getName().startsWith("testVariable")) {
+            pc1.setSelfOneOne(pc1);
+            pc2.setSelfOneOne(pc1);
+            pc1.getSelfOneMany().add(pc1);
+            pc1.getSelfOneMany().add(pc2);
+
+            pc3.setSelfOneOne(pc3);
+            pc4.setSelfOneOne(pc3);
+            pc3.getSelfOneMany().add(pc3);
+            pc3.getSelfOneMany().add(pc4);
+        }
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(pc1);
+        em.persist(pc2);
+        em.persist(pc3);
+        em.persist(pc4);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testSimpleGroup() {
+        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
+            "group by o.intField order by o.intField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Integer(1), itr.next());
+        assertEquals(new Integer(2), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testOrderByAggregate() {
+        // this is an extension of JPQL
+        Query q = em.createQuery("select sum(o.shortField) " +
+            "from AllFieldTypes o"
+            + " group by o.intField order by sum(o.shortField) asc");
+        prepareQuery(q);
+        // this might fail in MySQL
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Long(-4), itr.next());
+        assertEquals(new Long(-2), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testCompoundGroupSame() {
+        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
+            "group by o.intField, o.shortField order by o.shortField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Integer(2), itr.next());
+        assertEquals(new Integer(1), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testCompoundGroupDifferent() {
+        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
+            "group by o.intField, o.byteField order by o.intField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(4, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Integer(1), itr.next());
+        assertEquals(new Integer(1), itr.next());
+        assertEquals(new Integer(2), itr.next());
+        assertEquals(new Integer(2), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testDifferentGroupLengths() {
+        Query q = em.createQuery("select o.byteField from AllFieldTypes o"
+            + " group by o.byteField order by o.byteField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(3, res.size());
+        Iterator itr = res.iterator();
+        assertEquals((byte) 0, itr.next());
+        assertEquals((byte) 1, itr.next());
+        assertEquals((byte) 2, itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testGroupRelationField() {
+        Query q = em.createQuery("select o.selfOneOne.intField " +
+            "from AllFieldTypes o group by o.selfOneOne.intField " +
+            "order by o.selfOneOne.intField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Integer(1), itr.next());
+        assertEquals(new Integer(2), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testSubstringInGroupBy() {
+        // this is an extension of JPQL
+        Query q = em.createQuery("select substring(o.stringField, 1, 1), " +
+            "count(o) from AllFieldTypes o " +
+            "group by substring(o.stringField, 1, 1)");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(3, res.size());
+
+        q = em.createQuery("select substring(o.stringField, 1, 2), count(o) " +
+            "from AllFieldTypes o group by substring(o.stringField, 1, 2)");
+        prepareQuery(q);
+        res = q.getResultList();
+        assertEquals(4, res.size());
+    }
+
+    public void testGroupedAggregate() {
+        Query q = em.createQuery("select count(o) from AllFieldTypes o " +
+            "group by o.byteField order by o.byteField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(3, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Long(1), itr.next());
+        assertEquals(new Long(2), itr.next());
+        assertEquals(new Long(1), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testGroupedRelationAggregate() {
+        Query q = em.createQuery("select count(o), max(o.selfOneOne.longField)"
+            + " from AllFieldTypes o group by o.intField"
+            + " order by o.intField asc");
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        Object[] o = (Object[]) itr.next();
+        assertEquals(new Long(2), o[0]);
+        assertEquals(new Long(4), o[1]);
+        o = (Object[]) itr.next();
+        assertEquals(new Long(2), o[0]);
+        assertEquals(new Long(2), o[1]);
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testGroupedMixedProjection() {
+        Query q = em.createQuery("select count(o), o.shortField " +
+            "from AllFieldTypes o group by o.intField, o.shortField " +
+            "order by o.intField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        Object[] o = (Object[]) itr.next();
+        assertEquals(new Long(2), o[0]);
+        assertEquals(new Short((short) -1), o[1]);
+        o = (Object[]) itr.next();
+        assertEquals(new Long(2), o[0]);
+        assertEquals(new Short((short) -2), o[1]);
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testSimpleHaving() {
+        Query q = em.createQuery("select o.intField from AllFieldTypes o " +
+            "group by o.intField having o.intField < 2");
+        prepareQuery(q);
+        assertEquals(new Integer(1), q.getSingleResult());
+    }
+
+    public void testAggregateHaving() {
+        Query q = em.createQuery("select o.byteField from AllFieldTypes o " +
+            "group by o.byteField having count(o) > 1");
+        prepareQuery(q);
+        assertEquals(new Byte((byte) 1), q.getSingleResult());
+    }
+
+    public void testMixedHaving() {
+        Query q = em.createQuery("select o.byteField from AllFieldTypes o " +
+            "group by o.byteField having count(o) > 1 or o.byteField = 0 " +
+            "order by o.byteField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Byte((byte) 0), itr.next());
+        assertEquals(new Byte((byte) 1), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testVariableGroup() {
+        Query q = em.createQuery("select max(other.longField) " +
+            "from AllFieldTypes o, AllFieldTypes other " +
+            "where other member of o.selfOneMany " +
+            "group by other.intField order by other.intField asc");
+        prepareQuery(q);
+        List res = q.getResultList();
+        assertEquals(2, res.size());
+        Iterator itr = res.iterator();
+        assertEquals(new Long(2), itr.next());
+        assertEquals(new Long(4), itr.next());
+        assertTrue(!itr.hasNext());
+    }
+
+    public void testVariableHaving() {
+        Query q = em.createQuery("select max(o.longField), other.byteField " +
+            "from AllFieldTypes o, AllFieldTypes other " +
+            "where other member of o.selfOneMany " +
+            "group by other.byteField having sum(other.intField) = 2");
+        prepareQuery(q);
+        assertEquals(new Long(3), ((Object[])q.getSingleResult())[0]);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java
index 0eb1832..b580beb 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.io.Serializable;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class ManyOneEntity implements Serializable {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @ManyToOne(cascade=CascadeType.ALL)
-    private ManyOneEntity rel;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public ManyOneEntity getRel() {
-        return rel; 
-    }
-
-    public void setRel(ManyOneEntity rel) {
-        this.rel = rel;
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.io.Serializable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class ManyOneEntity implements Serializable {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @ManyToOne(cascade=CascadeType.ALL)
+    private ManyOneEntity rel;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public ManyOneEntity getRel() {
+        return rel; 
+    }
+
+    public void setRel(ManyOneEntity rel) {
+        this.rel = rel;
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntitySub.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntitySub.java
index 6c414d1..b13cfcb 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntitySub.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntitySub.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.Entity;
-
-@Entity
-public class ManyOneEntitySub 
-    extends ManyOneEntity {
-
-    private int subInt;
-
-    public int getSubInt() { 
-        return subInt; 
-    }
-
-    public void setSubInt(int subInt) { 
-        this.subInt = subInt; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.Entity;
+
+@Entity
+public class ManyOneEntitySub 
+    extends ManyOneEntity {
+
+    private int subInt;
+
+    public int getSubInt() { 
+        return subInt; 
+    }
+
+    public void setSubInt(int subInt) { 
+        this.subInt = subInt; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/NamedQueryEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/NamedQueryEntity.java
index f9a97c5..43773aa 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/NamedQueryEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/NamedQueryEntity.java
@@ -1,42 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.NamedQuery;
-
-@Entity
-@NamedQuery(name="NamedQueryEntity.namedQuery",
-    query="select o from NamedQueryEntity o where o.stringField = 'foo'")
-public class NamedQueryEntity {
-    @Id @GeneratedValue
-    private Integer id;
-
-    private String stringField;
-
-    public NamedQueryEntity(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public NamedQueryEntity() {
-        // for JPA
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+
+@Entity
+@NamedQuery(name="NamedQueryEntity.namedQuery",
+    query="select o from NamedQueryEntity o where o.stringField = 'foo'")
+public class NamedQueryEntity {
+    @Id @GeneratedValue
+    private Integer id;
+
+    private String stringField;
+
+    public NamedQueryEntity(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public NamedQueryEntity() {
+        // for JPA
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
index 81b85f5..973d915 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.FieldResult;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.NamedNativeQueries;
-import javax.persistence.NamedNativeQuery;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-
-@NamedQuery(name="FindXTwo", query="select s from simple s where s.name = :fname")
-
-@NamedQueries( {
-    @NamedQuery(name="FindOne", query="select s from simple s where s.name = :fname"),
-    @NamedQuery(name="FindOne", query="select s from simple s where s.name = :fname"),
-    @NamedQuery(name="FindAll", query="select s from simple s")
-})
-
-@NamedNativeQueries( { 
-    @NamedNativeQuery(name = "findSimpleEntitites",
-        query = "SELECT ID, NAME, VALUE FROM SIMPLE_ENTITY", 
-        resultSetMapping = "simpleEntitiesResult") })
-
-@SqlResultSetMapping(name = "simpleEntitiesResult",
-    entities = @EntityResult(
-    entityClass = org.apache.openjpa.persistence.query.SimpleEntity.class, 
-    fields = {@FieldResult(name = "id", column = "ID"),
-        @FieldResult(name = "name", column = "NAME"),
-        @FieldResult(name = "value", column = "VALUE") }))
-@Entity(name = "simple")
-@Table(name = "SIMPLE_ENTITY")
-public class SimpleEntity implements Serializable {
-
-    @Id
-    @GeneratedValue
-    @Column(name = "ID")
-    private long id;
-
-    @Basic
-    @Column(name = "NAME")
-    private String name;
-
-    @Basic
-    @Column(name = "VALUE")
-    private String value;
-
-    public SimpleEntity() {
-    }
-
-    public SimpleEntity(String name, String value) {
-        this();
-        this.name = name;
-        this.value = value;
-    }
-
-    public long getId() {
-        return this.id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.FieldResult;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+
+@NamedQuery(name="FindXTwo", query="select s from simple s where s.name = :fname")
+
+@NamedQueries( {
+    @NamedQuery(name="FindOne", query="select s from simple s where s.name = :fname"),
+    @NamedQuery(name="FindOne", query="select s from simple s where s.name = :fname"),
+    @NamedQuery(name="FindAll", query="select s from simple s")
+})
+
+@NamedNativeQueries( { 
+    @NamedNativeQuery(name = "findSimpleEntitites",
+        query = "SELECT ID, NAME, VALUE FROM SIMPLE_ENTITY", 
+        resultSetMapping = "simpleEntitiesResult") })
+
+@SqlResultSetMapping(name = "simpleEntitiesResult",
+    entities = @EntityResult(
+    entityClass = org.apache.openjpa.persistence.query.SimpleEntity.class, 
+    fields = {@FieldResult(name = "id", column = "ID"),
+        @FieldResult(name = "name", column = "NAME"),
+        @FieldResult(name = "value", column = "VALUE") }))
+@Entity(name = "simple")
+@Table(name = "SIMPLE_ENTITY")
+public class SimpleEntity implements Serializable {
+
+    @Id
+    @GeneratedValue
+    @Column(name = "ID")
+    private long id;
+
+    @Basic
+    @Column(name = "NAME")
+    private String name;
+
+    @Basic
+    @Column(name = "VALUE")
+    private String value;
+
+    public SimpleEntity() {
+    }
+
+    public SimpleEntity(String name, String value) {
+        this();
+        this.name = name;
+        this.value = value;
+    }
+
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity2.java
index 920fd2a..fc38904 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity2.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-
-@NamedQuery(name="FindXTwo", query="select s from simple2 s where s.name = :fname")
-
-@NamedQueries( {
-    @NamedQuery(name="FindOne", query="select s from simple2 s where s.name = :fname"),
-    @NamedQuery(name="Find2One", query="select s from simple2 s where s.name = :fname"),
-    @NamedQuery(name="Find2All", query="select s from simple2 s")
-})
-
-@Entity(name = "simple2")
-@Table(name = "SIMPLE_ENTITY2")
-public class SimpleEntity2 {
-
-    @Id
-    @GeneratedValue
-    @Column(name = "ID")
-    private long id;
-
-    @Basic
-    @Column(name = "NAME")
-    private String name;
-
-    @Basic
-    @Column(name = "VALUE")
-    private String value;
-
-    public SimpleEntity2() {
-    }
-
-    public SimpleEntity2(String name, String value) {
-        this();
-        this.name = name;
-        this.value = value;
-    }
-
-    public long getId() {
-        return this.id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+@NamedQuery(name="FindXTwo", query="select s from simple2 s where s.name = :fname")
+
+@NamedQueries( {
+    @NamedQuery(name="FindOne", query="select s from simple2 s where s.name = :fname"),
+    @NamedQuery(name="Find2One", query="select s from simple2 s where s.name = :fname"),
+    @NamedQuery(name="Find2All", query="select s from simple2 s")
+})
+
+@Entity(name = "simple2")
+@Table(name = "SIMPLE_ENTITY2")
+public class SimpleEntity2 {
+
+    @Id
+    @GeneratedValue
+    @Column(name = "ID")
+    private long id;
+
+    @Basic
+    @Column(name = "NAME")
+    private String name;
+
+    @Basic
+    @Column(name = "VALUE")
+    private String value;
+
+    public SimpleEntity2() {
+    }
+
+    public SimpleEntity2(String name, String value) {
+        this();
+        this.name = name;
+        this.value = value;
+    }
+
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestAccessPathsOfSubqueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestAccessPathsOfSubqueries.java
index 0e1027a..a0a2f5b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestAccessPathsOfSubqueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestAccessPathsOfSubqueries.java
@@ -1,90 +1,90 @@
-/*
- * TestAccessPathsOfSubqueries.java
- *
- * Created on October 17, 2006, 2:51 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest4;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest5;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.Query;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.meta.ClassMetaData;
-
-public class TestAccessPathsOfSubqueries extends BaseQueryTest {
-
-    /**
-     * Creates a new instance of TestAccessPathsOfSubqueries
-     */
-
-    public TestAccessPathsOfSubqueries(String name) {
-        super(name);
-    }
-
-    public void testSimpleSubqueryAccessPath() {
-        Broker broker = getBrokerFactory().newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
-            "SELECT o FROM RuntimeTest1 o WHERE EXISTS (SELECT rt5.name FROM RuntimeTest5 rt5 WHERE rt5.name IS NOT NULL)");
-        ClassMetaData[] metas = q.getAccessPathMetaDatas();
-        Collection c = Arrays.asList(metas);
-        ClassMetaData rt1 = broker.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(RuntimeTest1.class,
-            broker.getClassLoader(), true);
-        ClassMetaData rt5 = broker.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(RuntimeTest5.class,
-            broker.getClassLoader(), true);
-        assertTrue(c.contains(rt1));
-        assertTrue(c.contains(rt5));
-        assertEquals(2, c.size());
-    }
-
-    public void testRelationTraversalSubqueryAccessPath() {
-        Broker broker = getBrokerFactory().newBroker();
-        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
-            "SELECT o FROM RuntimeTest1 o WHERE EXISTS (SELECT rt5.runtimeTest4.name FROM RuntimeTest5 rt5 WHERE rt5.name IS NOT NULL)");
-
-        ClassMetaData[] metas = q.getAccessPathMetaDatas();
-        Collection c = Arrays.asList(metas);
-        ClassMetaData rt1 = broker.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(RuntimeTest1.class,
-            broker.getClassLoader(), true);
-        ClassMetaData rt4 = broker.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(RuntimeTest4.class,
-            broker.getClassLoader(), true);
-        ClassMetaData rt5 = broker.getConfiguration().
-            getMetaDataRepositoryInstance().getMetaData(RuntimeTest5.class,
-            broker.getClassLoader(), true);
-        assertTrue(c.contains(rt1));
-        assertTrue(c.contains(rt4));
-        assertTrue(c.contains(rt5));
-        assertEquals(3, c.size());
-    }
-}
+/*
+ * TestAccessPathsOfSubqueries.java
+ *
+ * Created on October 17, 2006, 2:51 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest4;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest5;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.meta.ClassMetaData;
+
+public class TestAccessPathsOfSubqueries extends BaseQueryTest {
+
+    /**
+     * Creates a new instance of TestAccessPathsOfSubqueries
+     */
+
+    public TestAccessPathsOfSubqueries(String name) {
+        super(name);
+    }
+
+    public void testSimpleSubqueryAccessPath() {
+        Broker broker = getBrokerFactory().newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
+            "SELECT o FROM RuntimeTest1 o WHERE EXISTS (SELECT rt5.name FROM RuntimeTest5 rt5 WHERE rt5.name IS NOT NULL)");
+        ClassMetaData[] metas = q.getAccessPathMetaDatas();
+        Collection c = Arrays.asList(metas);
+        ClassMetaData rt1 = broker.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(RuntimeTest1.class,
+            broker.getClassLoader(), true);
+        ClassMetaData rt5 = broker.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(RuntimeTest5.class,
+            broker.getClassLoader(), true);
+        assertTrue(c.contains(rt1));
+        assertTrue(c.contains(rt5));
+        assertEquals(2, c.size());
+    }
+
+    public void testRelationTraversalSubqueryAccessPath() {
+        Broker broker = getBrokerFactory().newBroker();
+        Query q = broker.newQuery(JPQLParser.LANG_JPQL,
+            "SELECT o FROM RuntimeTest1 o WHERE EXISTS (SELECT rt5.runtimeTest4.name FROM RuntimeTest5 rt5 WHERE rt5.name IS NOT NULL)");
+
+        ClassMetaData[] metas = q.getAccessPathMetaDatas();
+        Collection c = Arrays.asList(metas);
+        ClassMetaData rt1 = broker.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(RuntimeTest1.class,
+            broker.getClassLoader(), true);
+        ClassMetaData rt4 = broker.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(RuntimeTest4.class,
+            broker.getClassLoader(), true);
+        ClassMetaData rt5 = broker.getConfiguration().
+            getMetaDataRepositoryInstance().getMetaData(RuntimeTest5.class,
+            broker.getClassLoader(), true);
+        assertTrue(c.contains(rt1));
+        assertTrue(c.contains(rt4));
+        assertTrue(c.contains(rt5));
+        assertEquals(3, c.size());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestComplexQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestComplexQueries.java
index a935b8b..c5024e2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestComplexQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestComplexQueries.java
@@ -1,292 +1,292 @@
-/*
- * TestComplexQueries.java
- *
- * Created on October 17, 2006, 2:59 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-
-import java.util.List;
-
-import org.apache.openjpa.persistence.query.common.apps.ComplexA;
-import org.apache.openjpa.persistence.query.common.apps.ComplexB;
-import org.apache.openjpa.persistence.query.common.apps.ComplexC;
-import org.apache.openjpa.persistence.query.common.apps.ComplexD;
-import org.apache.openjpa.persistence.query.common.apps.ComplexE;
-import org.apache.openjpa.persistence.query.common.apps.ComplexF;
-import org.apache.openjpa.persistence.query.common.apps.ComplexG;
-import junit.framework.AssertionFailedError;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestComplexQueries extends BaseQueryTest {
-
-    /**
-     * Creates a new instance of TestComplexQueries
-     */
-
-    public TestComplexQueries(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        clear();
-    }
-
-    public void clear() {
-        deleteAll(ComplexA.class);
-        deleteAll(ComplexB.class);
-        deleteAll(ComplexC.class);
-        deleteAll(ComplexD.class);
-        deleteAll(ComplexE.class);
-        deleteAll(ComplexF.class);
-        deleteAll(ComplexG.class);
-    }
-
-    public void complexQuery(int size, Object ob, String filter, Class c) {
-
-//        PersistenceManager pm = getPM();
-        Broker broker = getBrokerFactory().newBroker();
-        broker.setIgnoreChanges(false);
-        broker.begin();
-
-        broker.persist(ob, null);
-        // test in-memory
-        // assertSize (size, pm.newQuery (c, filter));
-        broker.commit();
-
-        broker.begin();
-        // test against database
-//        OpenJPAQuery q = pm.createQuery("SELECT o FROM "+c.getSimpleName()+"o WHERE o."+filter);
-        String qstrng =
-            "SELECT o FROM " + c.getSimpleName() + " o WHERE o." + filter;
-        assertSize(size,
-            (List) broker.newQuery(JPQLParser.LANG_JPQL, c, qstrng).execute());
-
-        broker.commit();
-        broker.close();
-
-        broker = getBrokerFactory().newBroker();
-        broker.begin();
-        // test again against a new PM, for good measure
-        assertSize(size,
-            (List) broker.newQuery(JPQLParser.LANG_JPQL, c, qstrng).execute());
-        broker.rollback();
-
-        broker.close();
-    }
-
-    public void testComplex1() {
-        complexQuery(1,
-            new ComplexA("test", 0, null, null),
-            "stringA = \'test\'",
-            ComplexA.class);
-    }
-
-    public void testComplex2() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "stringG = \'testg\'",
-            ComplexG.class);
-    }
-
-    public void testComplex3() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'",
-            ComplexG.class);
-    }
-
-    public void testComplex4() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'"
-                + " AND o.f.e.d.c.b.stringB = \'testb\'",
-            ComplexG.class);
-    }
-
-    public void testComplex5() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'"
-                + " AND o.f.e.d.c.b.stringB = \'testb\'"
-                + " AND o.f.e.d.c.stringC = \'testc\'",
-            ComplexG.class);
-    }
-
-    public void testComplex6() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'"
-                + " AND o.f.e.d.c.b.stringB = \'testb\'"
-                + " AND o.f.e.d.c.stringC = \'testc\'"
-                + " AND o.f.e.d.stringD = \'testd\'",
-            ComplexG.class);
-    }
-
-    public void testComplex7() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'"
-                + " AND o.f.e.d.c.b.stringB = \'testb\'"
-                + " AND o.f.e.d.c.stringC = \'testc\'"
-                + " AND o.f.e.d.stringD = \'testd\'"
-                + " AND o.f.e.stringE = \'teste\'",
-            ComplexG.class);
-    }
-
-    public void testComplex8() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'"
-                + " AND o.f.e.d.c.b.stringB = \'testb\'"
-                + " AND o.f.e.d.c.stringC = \'testc\'"
-                + " AND o.f.e.d.stringD = \'testd\'"
-                + " AND o.f.e.stringE = \'teste\'"
-                + " AND o.f.stringF = \'testf\'",
-            ComplexG.class);
-    }
-
-    public void testComplex9() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.e.d.c.b.a.stringA = \'testa\'"
-                + " AND o.f.e.d.c.b.stringB = \'testb\'"
-                + " AND o.f.e.d.c.stringC = \'testc\'"
-                + " AND o.f.e.d.stringD = \'testd\'"
-                + " AND o.f.e.stringE = \'teste\'"
-                + " AND o.f.stringF = \'testf\'"
-                + " AND o.f.e.d.intD < 1"
-                + " AND o.f.e.d.intD > -1",
-            ComplexG.class);
-    }
-
-    public void testComplex10() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.stringF = \'testf\'",
-            ComplexG.class);
-    }
-
-    public void testComplex11() {
-        complexQuery(1,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.stringF = \'testf\' AND o.stringG = \'testg\'",
-            ComplexG.class);
-    }
-
-    public void testComplex12() {
-        try {
-            complexQuery(1,
-                new ComplexG("testg", 0, null,
-                    new ComplexF("testf", 0, null, null,
-                        new ComplexE("teste", 0, null, null,
-                            new ComplexD("testd", 0, null, null,
-                                new ComplexC("testc", 0, null, null,
-                                    new ComplexB("testb", 0, null, null,
-                                        new ComplexA("testa", 0, null,
-                                            null))))))),
-                "f.stringF = \'testf\'OR o.stringG = \'testg\'",
-                ComplexG.class);
-        } catch (junit.framework.AssertionFailedError afe) {
-            bug(449, afe, "ORs and relational queries");
-        }
-    }
-
-    public void testComplex13() {
-        complexQuery(0,
-            new ComplexG("testg", 0, null,
-                new ComplexF("testf", 0, null, null,
-                    new ComplexE("teste", 0, null, null,
-                        new ComplexD("testd", 0, null, null,
-                            new ComplexC("testc", 0, null, null,
-                                new ComplexB("testb", 0, null, null,
-                                    new ComplexA("testa", 0, null, null))))))),
-            "f.stringF = \'testfXXX\'",
-            ComplexG.class);
-    }
-}
+/*
+ * TestComplexQueries.java
+ *
+ * Created on October 17, 2006, 2:59 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+
+import java.util.List;
+
+import org.apache.openjpa.persistence.query.common.apps.ComplexA;
+import org.apache.openjpa.persistence.query.common.apps.ComplexB;
+import org.apache.openjpa.persistence.query.common.apps.ComplexC;
+import org.apache.openjpa.persistence.query.common.apps.ComplexD;
+import org.apache.openjpa.persistence.query.common.apps.ComplexE;
+import org.apache.openjpa.persistence.query.common.apps.ComplexF;
+import org.apache.openjpa.persistence.query.common.apps.ComplexG;
+import junit.framework.AssertionFailedError;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestComplexQueries extends BaseQueryTest {
+
+    /**
+     * Creates a new instance of TestComplexQueries
+     */
+
+    public TestComplexQueries(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        clear();
+    }
+
+    public void clear() {
+        deleteAll(ComplexA.class);
+        deleteAll(ComplexB.class);
+        deleteAll(ComplexC.class);
+        deleteAll(ComplexD.class);
+        deleteAll(ComplexE.class);
+        deleteAll(ComplexF.class);
+        deleteAll(ComplexG.class);
+    }
+
+    public void complexQuery(int size, Object ob, String filter, Class c) {
+
+//        PersistenceManager pm = getPM();
+        Broker broker = getBrokerFactory().newBroker();
+        broker.setIgnoreChanges(false);
+        broker.begin();
+
+        broker.persist(ob, null);
+        // test in-memory
+        // assertSize (size, pm.newQuery (c, filter));
+        broker.commit();
+
+        broker.begin();
+        // test against database
+//        OpenJPAQuery q = pm.createQuery("SELECT o FROM "+c.getSimpleName()+"o WHERE o."+filter);
+        String qstrng =
+            "SELECT o FROM " + c.getSimpleName() + " o WHERE o." + filter;
+        assertSize(size,
+            (List) broker.newQuery(JPQLParser.LANG_JPQL, c, qstrng).execute());
+
+        broker.commit();
+        broker.close();
+
+        broker = getBrokerFactory().newBroker();
+        broker.begin();
+        // test again against a new PM, for good measure
+        assertSize(size,
+            (List) broker.newQuery(JPQLParser.LANG_JPQL, c, qstrng).execute());
+        broker.rollback();
+
+        broker.close();
+    }
+
+    public void testComplex1() {
+        complexQuery(1,
+            new ComplexA("test", 0, null, null),
+            "stringA = \'test\'",
+            ComplexA.class);
+    }
+
+    public void testComplex2() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "stringG = \'testg\'",
+            ComplexG.class);
+    }
+
+    public void testComplex3() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'",
+            ComplexG.class);
+    }
+
+    public void testComplex4() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'"
+                + " AND o.f.e.d.c.b.stringB = \'testb\'",
+            ComplexG.class);
+    }
+
+    public void testComplex5() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'"
+                + " AND o.f.e.d.c.b.stringB = \'testb\'"
+                + " AND o.f.e.d.c.stringC = \'testc\'",
+            ComplexG.class);
+    }
+
+    public void testComplex6() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'"
+                + " AND o.f.e.d.c.b.stringB = \'testb\'"
+                + " AND o.f.e.d.c.stringC = \'testc\'"
+                + " AND o.f.e.d.stringD = \'testd\'",
+            ComplexG.class);
+    }
+
+    public void testComplex7() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'"
+                + " AND o.f.e.d.c.b.stringB = \'testb\'"
+                + " AND o.f.e.d.c.stringC = \'testc\'"
+                + " AND o.f.e.d.stringD = \'testd\'"
+                + " AND o.f.e.stringE = \'teste\'",
+            ComplexG.class);
+    }
+
+    public void testComplex8() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'"
+                + " AND o.f.e.d.c.b.stringB = \'testb\'"
+                + " AND o.f.e.d.c.stringC = \'testc\'"
+                + " AND o.f.e.d.stringD = \'testd\'"
+                + " AND o.f.e.stringE = \'teste\'"
+                + " AND o.f.stringF = \'testf\'",
+            ComplexG.class);
+    }
+
+    public void testComplex9() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.e.d.c.b.a.stringA = \'testa\'"
+                + " AND o.f.e.d.c.b.stringB = \'testb\'"
+                + " AND o.f.e.d.c.stringC = \'testc\'"
+                + " AND o.f.e.d.stringD = \'testd\'"
+                + " AND o.f.e.stringE = \'teste\'"
+                + " AND o.f.stringF = \'testf\'"
+                + " AND o.f.e.d.intD < 1"
+                + " AND o.f.e.d.intD > -1",
+            ComplexG.class);
+    }
+
+    public void testComplex10() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.stringF = \'testf\'",
+            ComplexG.class);
+    }
+
+    public void testComplex11() {
+        complexQuery(1,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.stringF = \'testf\' AND o.stringG = \'testg\'",
+            ComplexG.class);
+    }
+
+    public void testComplex12() {
+        try {
+            complexQuery(1,
+                new ComplexG("testg", 0, null,
+                    new ComplexF("testf", 0, null, null,
+                        new ComplexE("teste", 0, null, null,
+                            new ComplexD("testd", 0, null, null,
+                                new ComplexC("testc", 0, null, null,
+                                    new ComplexB("testb", 0, null, null,
+                                        new ComplexA("testa", 0, null,
+                                            null))))))),
+                "f.stringF = \'testf\'OR o.stringG = \'testg\'",
+                ComplexG.class);
+        } catch (junit.framework.AssertionFailedError afe) {
+            bug(449, afe, "ORs and relational queries");
+        }
+    }
+
+    public void testComplex13() {
+        complexQuery(0,
+            new ComplexG("testg", 0, null,
+                new ComplexF("testf", 0, null, null,
+                    new ComplexE("teste", 0, null, null,
+                        new ComplexD("testd", 0, null, null,
+                            new ComplexC("testc", 0, null, null,
+                                new ComplexB("testb", 0, null, null,
+                                    new ComplexA("testa", 0, null, null))))))),
+            "f.stringF = \'testfXXX\'",
+            ComplexG.class);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDataStoreActions.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDataStoreActions.java
index 5b603ed..43b22bf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDataStoreActions.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDataStoreActions.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-
-public class TestDataStoreActions
-    extends SingleEMTestCase {
-
-    @Override
-    public void setUp() {
-        setUp(AllFieldTypes.class);
-    }
-
-    public void testDataStoreActions() {
-        OpenJPAQuery q = em.createQuery("select o from AllFieldTypes o");
-        String[] sql = q.getDataStoreActions(null);
-        assertEquals(1, sql.length);
-        assertTrue(sql[0].startsWith("SELECT"));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+public class TestDataStoreActions
+    extends SingleEMTestCase {
+
+    @Override
+    public void setUp() {
+        setUp(AllFieldTypes.class);
+    }
+
+    public void testDataStoreActions() {
+        OpenJPAQuery q = em.createQuery("select o from AllFieldTypes o");
+        String[] sql = q.getDataStoreActions(null);
+        assertEquals(1, sql.length);
+        assertTrue(sql[0].startsWith("SELECT"));
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDistinctQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDistinctQueries.java
index 2f8bcb5..8fb0a38 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDistinctQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestDistinctQueries.java
@@ -1,98 +1,98 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-import org.apache.openjpa.persistence.models.company.fetchlazy.ProductOrder;
-import org.apache.openjpa.persistence.models.company.fetchlazy.LineItem;
-import org.apache.openjpa.persistence.models.company.fetchlazy.Product;
-import org.apache.openjpa.persistence.models.company.fetchlazy.Customer;
-import org.apache.openjpa.persistence.models.company.fetchlazy.Address;
-import org.apache.openjpa.persistence.models.company.fetchlazy.Company;
-import org.apache.openjpa.persistence.models.company.fetchlazy.Employee;
-import org.apache.openjpa.persistence.models.company.fetchlazy.PartTimeEmployee;
-import org.apache.openjpa.persistence.models.company.fetchlazy.FullTimeEmployee;
-import org.apache.openjpa.persistence.models.company.fetchlazy.Person;
-
-public class TestDistinctQueries extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(Address.class, Company.class, Customer.class, Employee.class,
-            FullTimeEmployee.class, LineItem.class, PartTimeEmployee.class,
-            Person.class, Product.class, ProductOrder.class, CLEAR_TABLES);
-
-        ProductOrder order = new ProductOrder();
-        LineItem item0 = new LineItem();
-        LineItem item1 = new LineItem();
-        LineItem item2 = new LineItem();
-        order.getItems().add(item0);
-        order.getItems().add(item1);
-        order.getItems().add(item2);
-
-        em.getTransaction().begin();
-        em.persist(order);
-        em.persist(item0);
-        em.persist(item1);
-        em.persist(item2);
-        em.getTransaction().commit();
-    }
-
-    public void testDuplicateResultsInNonDistinctJoinFetchQuery() {
-        List l = em.createQuery("select o from LAZ_ProductOrder o " +
-            "left join fetch o.items").getResultList();
-        assertEquals(3, l.size());
-    }
-
-    public void testDuplicateResultsInNonDistinctJoinQuery() {
-        List l = em.createQuery("select o from LAZ_ProductOrder o " +
-            "left join o.items item").getResultList();
-        assertEquals(3, l.size());
-    }
-
-    public void testNoDuplicateResultsInDistinctQuery() {
-        List l = em.createQuery("select distinct o from LAZ_ProductOrder o " +
-            "left join o.items item").getResultList();
-        assertEquals(1, l.size());
-    }
-
-    public void testDuplicateResultsInNonDistinctConstructorJoinQuery() {
-        List l = em.createQuery("select new " +
-            "org.apache.openjpa.persistence.query.TestDistinctQueries$Holder(" +
-            "o.id) from LAZ_ProductOrder o " +
-            "left join o.items item").getResultList();
-        assertEquals(3, l.size());
-    }
-
-    public void testNoDuplicateResultsInDistinctConstructorQuery()
-        throws NoSuchMethodException {
-        List l = em.createQuery("select distinct new " +
-            "org.apache.openjpa.persistence.query.TestDistinctQueries$Holder(" +
-            "o.id) from LAZ_ProductOrder o " +
-            "left join o.items item").getResultList();
-        assertEquals(1, l.size());
-    }
-
-    public static class Holder {
-        public Holder(long id) {
-            // we don't actually do anything with the returned data
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.models.company.fetchlazy.ProductOrder;
+import org.apache.openjpa.persistence.models.company.fetchlazy.LineItem;
+import org.apache.openjpa.persistence.models.company.fetchlazy.Product;
+import org.apache.openjpa.persistence.models.company.fetchlazy.Customer;
+import org.apache.openjpa.persistence.models.company.fetchlazy.Address;
+import org.apache.openjpa.persistence.models.company.fetchlazy.Company;
+import org.apache.openjpa.persistence.models.company.fetchlazy.Employee;
+import org.apache.openjpa.persistence.models.company.fetchlazy.PartTimeEmployee;
+import org.apache.openjpa.persistence.models.company.fetchlazy.FullTimeEmployee;
+import org.apache.openjpa.persistence.models.company.fetchlazy.Person;
+
+public class TestDistinctQueries extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(Address.class, Company.class, Customer.class, Employee.class,
+            FullTimeEmployee.class, LineItem.class, PartTimeEmployee.class,
+            Person.class, Product.class, ProductOrder.class, CLEAR_TABLES);
+
+        ProductOrder order = new ProductOrder();
+        LineItem item0 = new LineItem();
+        LineItem item1 = new LineItem();
+        LineItem item2 = new LineItem();
+        order.getItems().add(item0);
+        order.getItems().add(item1);
+        order.getItems().add(item2);
+
+        em.getTransaction().begin();
+        em.persist(order);
+        em.persist(item0);
+        em.persist(item1);
+        em.persist(item2);
+        em.getTransaction().commit();
+    }
+
+    public void testDuplicateResultsInNonDistinctJoinFetchQuery() {
+        List l = em.createQuery("select o from LAZ_ProductOrder o " +
+            "left join fetch o.items").getResultList();
+        assertEquals(3, l.size());
+    }
+
+    public void testDuplicateResultsInNonDistinctJoinQuery() {
+        List l = em.createQuery("select o from LAZ_ProductOrder o " +
+            "left join o.items item").getResultList();
+        assertEquals(3, l.size());
+    }
+
+    public void testNoDuplicateResultsInDistinctQuery() {
+        List l = em.createQuery("select distinct o from LAZ_ProductOrder o " +
+            "left join o.items item").getResultList();
+        assertEquals(1, l.size());
+    }
+
+    public void testDuplicateResultsInNonDistinctConstructorJoinQuery() {
+        List l = em.createQuery("select new " +
+            "org.apache.openjpa.persistence.query.TestDistinctQueries$Holder(" +
+            "o.id) from LAZ_ProductOrder o " +
+            "left join o.items item").getResultList();
+        assertEquals(3, l.size());
+    }
+
+    public void testNoDuplicateResultsInDistinctConstructorQuery()
+        throws NoSuchMethodException {
+        List l = em.createQuery("select distinct new " +
+            "org.apache.openjpa.persistence.query.TestDistinctQueries$Holder(" +
+            "o.id) from LAZ_ProductOrder o " +
+            "left join o.items item").getResultList();
+        assertEquals(1, l.size());
+    }
+
+    public static class Holder {
+        public Holder(long id) {
+            // we don't actually do anything with the returned data
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBDeleteUpdateImpl.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBDeleteUpdateImpl.java
index fd17024..8bef284 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBDeleteUpdateImpl.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBDeleteUpdateImpl.java
@@ -1,197 +1,197 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.Query;
-
-
-import org.apache.openjpa.persistence.query.common.apps.Entity1;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-
-public class TestEJBDeleteUpdateImpl extends BaseQueryTest {
-
-    RuntimeTest1 runt1;
-    RuntimeTest2 runt2;
-    Entity1 ent;
-
-    public TestEJBDeleteUpdateImpl(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-        deleteAll(Entity1.class);
-
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        runt1 = new RuntimeTest1(1);
-        runt1.setStringField("runt1");
-        runt1.setSelfOneOne(new RuntimeTest1(2));
-        runt2 = new RuntimeTest2(3);
-        runt2.setStringField("runt2");
-
-        ent = new Entity1(23, "UPDATEST", 100);
-
-        em.persist(runt1);
-        em.persist(runt2);
-        em.persist(ent);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testUpdate1() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 ret = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-
-        assertNotNull(ret);
-        assertEquals("runt1", ret.getStringField());
-        assertNotNull(ret.getSelfOneOne());
-
-        String ejbqlUpdate =
-            "UPDATE RuntimeTest1 x SET x.stringField = :strngfld WHERE x.stringField = :stdfield";
-        int updatedEntities = em.createQuery(ejbqlUpdate)
-            .setParameter("strngfld", "runner13")
-            .setParameter("stdfield", "runt1")
-            .executeUpdate();
-
-        assertEquals(1, updatedEntities);
-
-        endTx(em);
-
-        RuntimeTest1 ret2 = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-        em.refresh(ret2);
-
-        assertNotNull(ret2);
-        assertEquals("runner13", ret2.getStringField());
-
-        endEm(em);
-    }
-
-    public void testUpdate2() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 run = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-        assertNotNull(run);
-        assertEquals("runt1", run.getStringField());
-        assertNotNull(run.getSelfOneOne());
-
-        String ejbqlUpdate = "UPDATE RuntimeTest1 x " +
-            "SET x.stringField = :strngfld " +
-            "WHERE x.stringField = :field";
-        int upEntities = em.createQuery(ejbqlUpdate)
-            .setParameter("strngfld", "upd")
-            .setParameter("field", "runt1")
-            .executeUpdate();
-
-        assertEquals(1, upEntities);
-
-        endTx(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 inst = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-        em.refresh(inst);
-
-        assertNotNull(inst);
-        assertEquals("upd", inst.getStringField());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testDelete1() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 run = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-        assertNotNull(run);
-        assertEquals("runt1", run.getStringField());
-        assertNotNull(run.getSelfOneOne());
-
-        String ejbdelUpdate = "DELETE  FROM RuntimeTest1 s " +
-            "WHERE s.stringField = :strngfld";
-        int delEntity = em.createQuery(ejbdelUpdate)
-            .setParameter("strngfld", "runt1")
-            .executeUpdate();
-
-        assertEquals(1, delEntity);
-
-        RuntimeTest1 del = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-        assertNull(del);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testDelete2() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        RuntimeTest1 run = em.find(RuntimeTest1.class, em.getObjectId(runt1));
-        assertNotNull(run);
-        assertEquals("runt1", run.getStringField());
-        assertNotNull(run.getSelfOneOne());
-
-        String ejbdelUpdate =
-            "DELETE  FROM RuntimeTest1 r WHERE r.stringField = ?1";
-        Query query = em.createQuery(ejbdelUpdate);
-
-        query.setParameter(1, "runt1");
-        int ok = query.executeUpdate();
-
-        assertEquals(1, ok);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testUpdate3() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        Entity1 ent = em.find(Entity1.class, 23);
-
-        assertNotNull(ent);
-        assertEquals("UPDATEST", ent.getStringField());
-
-        int upd = em.createQuery(
-            "UPDATE Entity1 e SET e.stringField = \'UPDATEFAILED\' WHERE " +
-                "e.pk = 23").executeUpdate();
-
-        assertEquals(1, upd);
-
-        endTx(em);
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.Query;
+
+
+import org.apache.openjpa.persistence.query.common.apps.Entity1;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+public class TestEJBDeleteUpdateImpl extends BaseQueryTest {
+
+    RuntimeTest1 runt1;
+    RuntimeTest2 runt2;
+    Entity1 ent;
+
+    public TestEJBDeleteUpdateImpl(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+        deleteAll(Entity1.class);
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        runt1 = new RuntimeTest1(1);
+        runt1.setStringField("runt1");
+        runt1.setSelfOneOne(new RuntimeTest1(2));
+        runt2 = new RuntimeTest2(3);
+        runt2.setStringField("runt2");
+
+        ent = new Entity1(23, "UPDATEST", 100);
+
+        em.persist(runt1);
+        em.persist(runt2);
+        em.persist(ent);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testUpdate1() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 ret = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+
+        assertNotNull(ret);
+        assertEquals("runt1", ret.getStringField());
+        assertNotNull(ret.getSelfOneOne());
+
+        String ejbqlUpdate =
+            "UPDATE RuntimeTest1 x SET x.stringField = :strngfld WHERE x.stringField = :stdfield";
+        int updatedEntities = em.createQuery(ejbqlUpdate)
+            .setParameter("strngfld", "runner13")
+            .setParameter("stdfield", "runt1")
+            .executeUpdate();
+
+        assertEquals(1, updatedEntities);
+
+        endTx(em);
+
+        RuntimeTest1 ret2 = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+        em.refresh(ret2);
+
+        assertNotNull(ret2);
+        assertEquals("runner13", ret2.getStringField());
+
+        endEm(em);
+    }
+
+    public void testUpdate2() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 run = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+        assertNotNull(run);
+        assertEquals("runt1", run.getStringField());
+        assertNotNull(run.getSelfOneOne());
+
+        String ejbqlUpdate = "UPDATE RuntimeTest1 x " +
+            "SET x.stringField = :strngfld " +
+            "WHERE x.stringField = :field";
+        int upEntities = em.createQuery(ejbqlUpdate)
+            .setParameter("strngfld", "upd")
+            .setParameter("field", "runt1")
+            .executeUpdate();
+
+        assertEquals(1, upEntities);
+
+        endTx(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 inst = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+        em.refresh(inst);
+
+        assertNotNull(inst);
+        assertEquals("upd", inst.getStringField());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testDelete1() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 run = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+        assertNotNull(run);
+        assertEquals("runt1", run.getStringField());
+        assertNotNull(run.getSelfOneOne());
+
+        String ejbdelUpdate = "DELETE  FROM RuntimeTest1 s " +
+            "WHERE s.stringField = :strngfld";
+        int delEntity = em.createQuery(ejbdelUpdate)
+            .setParameter("strngfld", "runt1")
+            .executeUpdate();
+
+        assertEquals(1, delEntity);
+
+        RuntimeTest1 del = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+        assertNull(del);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testDelete2() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        RuntimeTest1 run = em.find(RuntimeTest1.class, em.getObjectId(runt1));
+        assertNotNull(run);
+        assertEquals("runt1", run.getStringField());
+        assertNotNull(run.getSelfOneOne());
+
+        String ejbdelUpdate =
+            "DELETE  FROM RuntimeTest1 r WHERE r.stringField = ?1";
+        Query query = em.createQuery(ejbdelUpdate);
+
+        query.setParameter(1, "runt1");
+        int ok = query.executeUpdate();
+
+        assertEquals(1, ok);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testUpdate3() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        Entity1 ent = em.find(Entity1.class, 23);
+
+        assertNotNull(ent);
+        assertEquals("UPDATEST", ent.getStringField());
+
+        int upd = em.createQuery(
+            "UPDATE Entity1 e SET e.stringField = \'UPDATEFAILED\' WHERE " +
+                "e.pk = 23").executeUpdate();
+
+        assertEquals(1, upd);
+
+        endTx(em);
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBPolymorphicQuery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBPolymorphicQuery.java
index c7020e6..343ad59 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBPolymorphicQuery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBPolymorphicQuery.java
@@ -1,88 +1,88 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-
-
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
-
-public class TestEJBPolymorphicQuery extends BaseQueryTest {
-
-    public TestEJBPolymorphicQuery(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        deleteAll(RuntimeTest2.class);
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        int run1 = 10;
-        int run2 = 15;
-
-        for (int i = 0; i < run1; i++) {
-            RuntimeTest1 rt = new RuntimeTest1(i);
-            rt.setStringField("foo " + i);
-            em.persist(rt);
-        }
-
-        for (int i = 10; i < run2; i++) {
-            em.persist(new RuntimeTest2(i));
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    /**
-     * Ensures that when a select query is ran against an entity at the top of the hierarchy
-     * that the result is its instances and that of all its subclass.
-     */
-    public void testPolymorphicSelect() {
-        EntityManager em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from RuntimeTest1 o")
-            .getResultList();
-
-        assertNotNull(l);
-        assertEquals(15, l.size());
-
-        endEm(em);
-    }
-
-    public void testPolymorphicDelete() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        int l = em.createQuery("Delete from RuntimeTest1")
-            .executeUpdate();
-
-        assertNotNull(l);
-        assertEquals(15, l);
-
-        endTx(em);
-        endEm(em);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+
+
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
+
+public class TestEJBPolymorphicQuery extends BaseQueryTest {
+
+    public TestEJBPolymorphicQuery(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        deleteAll(RuntimeTest2.class);
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        int run1 = 10;
+        int run2 = 15;
+
+        for (int i = 0; i < run1; i++) {
+            RuntimeTest1 rt = new RuntimeTest1(i);
+            rt.setStringField("foo " + i);
+            em.persist(rt);
+        }
+
+        for (int i = 10; i < run2; i++) {
+            em.persist(new RuntimeTest2(i));
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    /**
+     * Ensures that when a select query is ran against an entity at the top of the hierarchy
+     * that the result is its instances and that of all its subclass.
+     */
+    public void testPolymorphicSelect() {
+        EntityManager em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from RuntimeTest1 o")
+            .getResultList();
+
+        assertNotNull(l);
+        assertEquals(15, l.size());
+
+        endEm(em);
+    }
+
+    public void testPolymorphicDelete() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        int l = em.createQuery("Delete from RuntimeTest1")
+            .executeUpdate();
+
+        assertNotNull(l);
+        assertEquals(15, l);
+
+        endTx(em);
+        endEm(em);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBQueryInterface.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBQueryInterface.java
index 1c5fc57..72abb76 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBQueryInterface.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEJBQueryInterface.java
@@ -1,151 +1,151 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-
-
-
-import org.apache.openjpa.persistence.query.common.apps.Entity1;
-import org.apache.openjpa.persistence.query.common.apps.Entity2;
-
-public class TestEJBQueryInterface extends BaseQueryTest {
-
-    public TestEJBQueryInterface(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(Entity1.class);
-
-        int instNum = 10;
-
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        //create and persist multiple entity1 instances
-        for (int i = 0; i < instNum; i++) {
-            Entity1 ent = new Entity1(i, "string" + i, i + 2);
-            Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
-            ent.setEntity2Field(ent2);
-            em.persist(ent);
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testResultList() {
-        EntityManager em = currentEntityManager();
-        List list = em.createQuery("Select object(o) from Entity1 o")
-            .getResultList();
-
-        assertEquals(10, list.size());
-
-        endEm(em);
-    }
-
-    public void testGetSingleList() {
-        EntityManager em = currentEntityManager();
-
-        Entity1 ret =
-            (Entity1) em.createQuery("SELECT o FROM Entity1 o WHERE o.pk = 2")
-                .getSingleResult();
-
-        assertNotNull(ret);
-        assertEquals("string2", ret.getStringField());
-        assertEquals(4, ret.getIntField());
-
-        endEm(em);
-    }
-
-    public void testExecuteUpdate() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-        int ret = em.createQuery("DELETE FROM Entity1 o WHERE o.pk = 2")
-            .executeUpdate();
-
-        assertEquals(ret, 1);
-
-        int ret2 = em.createQuery("DELETE FROM Entity1 o WHERE o.pk = 22")
-            .executeUpdate();
-
-        assertEquals(ret2, 0);
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testSetMaxResults() {
-        EntityManager em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from Entity1 o")
-            .setMaxResults(5)
-            .getResultList();
-
-        assertNotNull(l);
-        assertEquals(5, l.size());
-
-        endEm(em);
-    }
-
-    public void testSetFirstResults() {
-        EntityManager em = currentEntityManager();
-
-        List l = em.createQuery("Select object(o) from Entity1 o order by o.pk")
-            .setFirstResult(3)
-            .getResultList();
-
-        Entity1 ent = (Entity1) l.get(0);
-
-        assertNotNull(ent);
-        assertEquals("string3", ent.getStringField());
-        assertEquals(5, ent.getIntField());
-
-        endEm(em);
-    }
-
-    // Tests Binding an argument to a named parameter.
-    // pk, the named parameter --Not working yet--
-    public void testSetParameter1() {
-        EntityManager em = currentEntityManager();
-        startTx(em);
-
-        List ret =
-            em.createQuery("SELECT o FROM Entity1 o WHERE o.stringField = :fld")
-                .setParameter("fld", "string1")
-                .getResultList();
-
-        assertNotNull(ret);
-        assertEquals(1, ret.size());
-
-        ret = em.createNamedQuery("setParam1")
-            .setParameter("fld", "string1")
-            .getResultList();
-
-        assertNotNull(ret);
-        assertEquals(1, ret.size());
-
-        endTx(em);
-        endEm(em);
-    }
-
-    //rest of the interface is tested by the CTS
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+
+
+import org.apache.openjpa.persistence.query.common.apps.Entity1;
+import org.apache.openjpa.persistence.query.common.apps.Entity2;
+
+public class TestEJBQueryInterface extends BaseQueryTest {
+
+    public TestEJBQueryInterface(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(Entity1.class);
+
+        int instNum = 10;
+
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        //create and persist multiple entity1 instances
+        for (int i = 0; i < instNum; i++) {
+            Entity1 ent = new Entity1(i, "string" + i, i + 2);
+            Entity2 ent2 = new Entity2(i * 2, "ent2" + i, i);
+            ent.setEntity2Field(ent2);
+            em.persist(ent);
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testResultList() {
+        EntityManager em = currentEntityManager();
+        List list = em.createQuery("Select object(o) from Entity1 o")
+            .getResultList();
+
+        assertEquals(10, list.size());
+
+        endEm(em);
+    }
+
+    public void testGetSingleList() {
+        EntityManager em = currentEntityManager();
+
+        Entity1 ret =
+            (Entity1) em.createQuery("SELECT o FROM Entity1 o WHERE o.pk = 2")
+                .getSingleResult();
+
+        assertNotNull(ret);
+        assertEquals("string2", ret.getStringField());
+        assertEquals(4, ret.getIntField());
+
+        endEm(em);
+    }
+
+    public void testExecuteUpdate() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+        int ret = em.createQuery("DELETE FROM Entity1 o WHERE o.pk = 2")
+            .executeUpdate();
+
+        assertEquals(ret, 1);
+
+        int ret2 = em.createQuery("DELETE FROM Entity1 o WHERE o.pk = 22")
+            .executeUpdate();
+
+        assertEquals(ret2, 0);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testSetMaxResults() {
+        EntityManager em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from Entity1 o")
+            .setMaxResults(5)
+            .getResultList();
+
+        assertNotNull(l);
+        assertEquals(5, l.size());
+
+        endEm(em);
+    }
+
+    public void testSetFirstResults() {
+        EntityManager em = currentEntityManager();
+
+        List l = em.createQuery("Select object(o) from Entity1 o order by o.pk")
+            .setFirstResult(3)
+            .getResultList();
+
+        Entity1 ent = (Entity1) l.get(0);
+
+        assertNotNull(ent);
+        assertEquals("string3", ent.getStringField());
+        assertEquals(5, ent.getIntField());
+
+        endEm(em);
+    }
+
+    // Tests Binding an argument to a named parameter.
+    // pk, the named parameter --Not working yet--
+    public void testSetParameter1() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        List ret =
+            em.createQuery("SELECT o FROM Entity1 o WHERE o.stringField = :fld")
+                .setParameter("fld", "string1")
+                .getResultList();
+
+        assertNotNull(ret);
+        assertEquals(1, ret.size());
+
+        ret = em.createNamedQuery("setParam1")
+            .setParameter("fld", "string1")
+            .getResultList();
+
+        assertNotNull(ret);
+        assertEquals(1, ret.size());
+
+        endTx(em);
+        endEm(em);
+    }
+
+    //rest of the interface is tested by the CTS
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEscapedSingleQuotesInJPQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEscapedSingleQuotesInJPQL.java
index 2aff935..46a7bba 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEscapedSingleQuotesInJPQL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestEscapedSingleQuotesInJPQL.java
@@ -1,55 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Collection;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestEscapedSingleQuotesInJPQL
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AllFieldTypes.class, CLEAR_TABLES);
-
-        AllFieldTypes aft = new AllFieldTypes();
-        aft.setStringField("foo'bar");
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(aft);
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testEscapedSingleQuotesInJPQL() {
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAQuery q = em.createQuery("select count(o) " +
-            "from AllFieldTypes o where o.stringField = 'foo''bar'");
-        assertEquals(1, ((Number) q.getSingleResult()).longValue());
-
-        Collection all = em.createQuery("select o from AllFieldTypes o")
-            .getResultList();
-        q.setCandidateCollection(all);
-        assertEquals(1, ((Number) q.getSingleResult()).longValue());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Collection;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestEscapedSingleQuotesInJPQL
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AllFieldTypes.class, CLEAR_TABLES);
+
+        AllFieldTypes aft = new AllFieldTypes();
+        aft.setStringField("foo'bar");
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(aft);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testEscapedSingleQuotesInJPQL() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAQuery q = em.createQuery("select count(o) " +
+            "from AllFieldTypes o where o.stringField = 'foo''bar'");
+        assertEquals(1, ((Number) q.getSingleResult()).longValue());
+
+        Collection all = em.createQuery("select o from AllFieldTypes o")
+            .getResultList();
+        q.setCandidateCollection(all);
+        assertEquals(1, ((Number) q.getSingleResult()).longValue());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestInMemoryQueryMatchEscapes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestInMemoryQueryMatchEscapes.java
index 7263bed..702292d 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestInMemoryQueryMatchEscapes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestInMemoryQueryMatchEscapes.java
@@ -1,69 +1,69 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.FlushModeType;
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-public class TestInMemoryQueryMatchEscapes
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(AllFieldTypes.class);
-    }
-    
-    public void testDatabaseEscape() {
-        OpenJPAQuery q = escapeHelper(false);
-        q.setFlushMode(FlushModeType.AUTO);
-        q.getEntityManager().flush();
-        AllFieldTypes aft = (AllFieldTypes) q.getSingleResult();
-        assertEquals("foo_bar", aft.getStringField());
-        q.getEntityManager().getTransaction().rollback();
-    }
-    
-    public void testInMemoryEscape() {
-        OpenJPAQuery q = escapeHelper(true);
-        q.setFlushMode(FlushModeType.COMMIT);
-        try {
-            q.getSingleResult();
-            fail("OpenJPA doesn't support escape syntax for in-mem queries");
-        } catch (Exception e) {
-            // expected
-        }
-    }
-    
-    private OpenJPAQuery escapeHelper(boolean inMem) {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AllFieldTypes aft = new AllFieldTypes();
-        aft.setStringField("foo_bar");
-        em.persist(aft);
-        aft = new AllFieldTypes();
-        aft.setStringField("foozbar");
-        em.persist(aft);
-
-        return (OpenJPAQuery) em.createQuery(
-            "select e from AllFieldTypes e where e.stringField " +
-            "like 'foox_bar' escape 'x'");
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.FlushModeType;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestInMemoryQueryMatchEscapes
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(AllFieldTypes.class);
+    }
+    
+    public void testDatabaseEscape() {
+        OpenJPAQuery q = escapeHelper(false);
+        q.setFlushMode(FlushModeType.AUTO);
+        q.getEntityManager().flush();
+        AllFieldTypes aft = (AllFieldTypes) q.getSingleResult();
+        assertEquals("foo_bar", aft.getStringField());
+        q.getEntityManager().getTransaction().rollback();
+    }
+    
+    public void testInMemoryEscape() {
+        OpenJPAQuery q = escapeHelper(true);
+        q.setFlushMode(FlushModeType.COMMIT);
+        try {
+            q.getSingleResult();
+            fail("OpenJPA doesn't support escape syntax for in-mem queries");
+        } catch (Exception e) {
+            // expected
+        }
+    }
+    
+    private OpenJPAQuery escapeHelper(boolean inMem) {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AllFieldTypes aft = new AllFieldTypes();
+        aft.setStringField("foo_bar");
+        em.persist(aft);
+        aft = new AllFieldTypes();
+        aft.setStringField("foozbar");
+        em.persist(aft);
+
+        return (OpenJPAQuery) em.createQuery(
+            "select e from AllFieldTypes e where e.stringField " +
+            "like 'foox_bar' escape 'x'");
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPAQuerySubclassFunc.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPAQuerySubclassFunc.java
index 9f545dc..c2c3660 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPAQuerySubclassFunc.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPAQuerySubclassFunc.java
@@ -1,91 +1,91 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-
-
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest3;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestJPAQuerySubclassFunc extends BaseQueryTest {
-
-    public TestJPAQuerySubclassFunc(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager pm = getEM();
-        startTx(pm);
-
-        pm.persist(new RuntimeTest1("TestQueryResults1", 10));
-        pm.persist(new RuntimeTest1("TestQueryResults3", 10));
-        pm.persist(new RuntimeTest1("TestQueryResults5", 10));
-
-        pm.persist(new RuntimeTest3("TestQueryResults2", 10));
-        pm.persist(new RuntimeTest3("TestQueryResults4", 10));
-        pm.persist(new RuntimeTest3("TestQueryResults6", 10));
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testSubClassIsTrueFunction() {
-        OpenJPAEntityManager pm = getEM();
-        startTx(pm);
-
-        OpenJPAQuery query =
-            pm.createQuery("SELECT r.stringField FROM RuntimeTest1 r");
-        query.setSubclasses(true);
-
-        List list = query.getResultList();
-
-        assertEquals("I expect size to be 6 since subclasses are included", 6,
-            list.size());
-        assertTrue(list.contains("TestQueryResults1"));
-        assertTrue(list.contains("TestQueryResults2"));
-
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testSubClassIsFalseFunction() {
-        OpenJPAEntityManager pm = getEM();
-        startTx(pm);
-
-        OpenJPAQuery query =
-            pm.createQuery("SELECT r.stringField FROM RuntimeTest1 r");
-        query.setSubclasses(false);
-
-        List list = query.getResultList();
-
-        assertEquals("I expect size to be 3 since subclasses are not included",
-            3, list.size());
-        assertTrue(list.contains("TestQueryResults1"));
-        assertTrue(list.contains("TestQueryResults3"));
-        assertTrue(list.contains("TestQueryResults5"));
-
-        endTx(pm);
-        endEm(pm);
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest3;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestJPAQuerySubclassFunc extends BaseQueryTest {
+
+    public TestJPAQuerySubclassFunc(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager pm = getEM();
+        startTx(pm);
+
+        pm.persist(new RuntimeTest1("TestQueryResults1", 10));
+        pm.persist(new RuntimeTest1("TestQueryResults3", 10));
+        pm.persist(new RuntimeTest1("TestQueryResults5", 10));
+
+        pm.persist(new RuntimeTest3("TestQueryResults2", 10));
+        pm.persist(new RuntimeTest3("TestQueryResults4", 10));
+        pm.persist(new RuntimeTest3("TestQueryResults6", 10));
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testSubClassIsTrueFunction() {
+        OpenJPAEntityManager pm = getEM();
+        startTx(pm);
+
+        OpenJPAQuery query =
+            pm.createQuery("SELECT r.stringField FROM RuntimeTest1 r");
+        query.setSubclasses(true);
+
+        List list = query.getResultList();
+
+        assertEquals("I expect size to be 6 since subclasses are included", 6,
+            list.size());
+        assertTrue(list.contains("TestQueryResults1"));
+        assertTrue(list.contains("TestQueryResults2"));
+
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testSubClassIsFalseFunction() {
+        OpenJPAEntityManager pm = getEM();
+        startTx(pm);
+
+        OpenJPAQuery query =
+            pm.createQuery("SELECT r.stringField FROM RuntimeTest1 r");
+        query.setSubclasses(false);
+
+        List list = query.getResultList();
+
+        assertEquals("I expect size to be 3 since subclasses are not included",
+            3, list.size());
+        assertTrue(list.contains("TestQueryResults1"));
+        assertTrue(list.contains("TestQueryResults3"));
+        assertTrue(list.contains("TestQueryResults5"));
+
+        endTx(pm);
+        endEm(pm);
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPQLWithoutIdentificationVariable.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPQLWithoutIdentificationVariable.java
index ff3f306..99de6d7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPQLWithoutIdentificationVariable.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestJPQLWithoutIdentificationVariable.java
@@ -1,40 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestJPQLWithoutIdentificationVariable extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(ManyOneEntity.class, ManyOneEntitySub.class);
-    }
-
-    public void testJPQLWithoutIdentificationVariable() {
-        try {
-            em.createQuery("select o from ManyOneEntity o " +
-                "where rel.name = :name").compile();
-        } catch (RuntimeException e) {
-            assertTrue(e.getMessage().contains(
-                "Perhaps you forgot to prefix the path"));
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestJPQLWithoutIdentificationVariable extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(ManyOneEntity.class, ManyOneEntitySub.class);
+    }
+
+    public void testJPQLWithoutIdentificationVariable() {
+        try {
+            em.createQuery("select o from ManyOneEntity o " +
+                "where rel.name = :name").compile();
+        } catch (RuntimeException e) {
+            assertTrue(e.getMessage().contains(
+                "Perhaps you forgot to prefix the path"));
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMathQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMathQueries.java
index 0eadbb5..9681e4e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMathQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMathQueries.java
@@ -1,86 +1,86 @@
-/*
- * TestMathQueries.java
- *
- * Created on October 18, 2006, 1:06 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-
-
-import org.apache.openjpa.persistence.query.common.apps.QueryTest1;
-import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestMathQueries extends BaseQueryTest {
-
-    /**
-     * Creates a new instance of TestMathQueries
-     */
-
-    public TestMathQueries(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(QueryTest1.class);
-        OpenJPAEntityManager pm = getEM();
-        startTx(pm);
-
-        for (int i = 0; i <= 100; i++) {
-            QueryTest1 ob = new QueryTest1();
-            ob.setNum(i);
-            pm.persist(ob);
-        }
-        endTx(pm);
-
-        for (long i = 0; i < 100; i++) {
-            OpenJPAQuery q =
-                pm.createQuery("SELECT q FROM QueryTest1 q WHERE q.numb = :ind")
-                    .setParameter("ind", i);
-            List l = q.getResultList();
-            assertSize(1, l);
-        }
-    }
-
-    public void testMultipleQuery() {
-        try {
-
-            OpenJPAQuery q1, q2;
-            q1 = getEM().createQuery(
-                "SELECT q FROM QueryTest1 q WHERE q.numb * q.numb = 25");
-            q2 = getEM().createQuery(
-                "SELECT q FROM QueryTest1 q WHERE q.numb * q.numb > 25");
-
-            assertSize(95, q2.getResultList());
-            assertSize(1, q1.getResultList());
-        }
-        catch (Exception e) {
-            bug(AbstractTestCase.Platform.EMPRESS, 890, e,
-                "Empress cannot handle certain "
-                    + "aggregate functions");
-        }
-    }
-}
+/*
+ * TestMathQueries.java
+ *
+ * Created on October 18, 2006, 1:06 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+
+import org.apache.openjpa.persistence.query.common.apps.QueryTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestMathQueries extends BaseQueryTest {
+
+    /**
+     * Creates a new instance of TestMathQueries
+     */
+
+    public TestMathQueries(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(QueryTest1.class);
+        OpenJPAEntityManager pm = getEM();
+        startTx(pm);
+
+        for (int i = 0; i <= 100; i++) {
+            QueryTest1 ob = new QueryTest1();
+            ob.setNum(i);
+            pm.persist(ob);
+        }
+        endTx(pm);
+
+        for (long i = 0; i < 100; i++) {
+            OpenJPAQuery q =
+                pm.createQuery("SELECT q FROM QueryTest1 q WHERE q.numb = :ind")
+                    .setParameter("ind", i);
+            List l = q.getResultList();
+            assertSize(1, l);
+        }
+    }
+
+    public void testMultipleQuery() {
+        try {
+
+            OpenJPAQuery q1, q2;
+            q1 = getEM().createQuery(
+                "SELECT q FROM QueryTest1 q WHERE q.numb * q.numb = 25");
+            q2 = getEM().createQuery(
+                "SELECT q FROM QueryTest1 q WHERE q.numb * q.numb > 25");
+
+            assertSize(95, q2.getResultList());
+            assertSize(1, q1.getResultList());
+        }
+        catch (Exception e) {
+            bug(AbstractTestCase.Platform.EMPRESS, 890, e,
+                "Empress cannot handle certain "
+                    + "aggregate functions");
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMethodQLQuery.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMethodQLQuery.java
index f47412b..d0cdbdd 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMethodQLQuery.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestMethodQLQuery.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Map;
-import java.util.ArrayList;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.QueryImpl;
-import org.apache.openjpa.persistence.ArgumentException;
-import org.apache.openjpa.kernel.QueryLanguages;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.lib.rop.ListResultObjectProvider;
-
-public class TestMethodQLQuery
-    extends SingleEMTestCase {
-
-    @Override
-    public void setUp() {
-        setUp(SimpleEntity.class);
-    }
-
-    public void testMethodQLWithoutParametersDeclared() {
-        OpenJPAQuery q = em.createQuery(QueryLanguages.LANG_METHODQL,
-            getClass().getName() + ".echo");
-        ((QueryImpl) q).getDelegate().setCandidateType(
-            SimpleEntity.class, true);
-        q.setParameter("param", 5);
-        ((QueryImpl) q).getDelegate().declareParameters("Integer param");
-        assertEquals(5, q.getResultList().get(0));
-    }
-
-    public void testInvalidMethodReturnType() {
-        OpenJPAQuery q = em.createQuery(QueryLanguages.LANG_METHODQL,
-            getClass().getName() + ".invalidReturnMeth");
-        ((QueryImpl) q).getDelegate().setCandidateType(
-            SimpleEntity.class, true);
-        try {
-            q.getResultList().get(0);
-            fail("should have gotten an exception since method is invalid");
-        } catch (ArgumentException ae) {
-            // expected
-        }
-    }
-
-    public void testVoidMethodReturnType() {
-        OpenJPAQuery q = em.createQuery(QueryLanguages.LANG_METHODQL,
-            getClass().getName() + ".voidMeth");
-        ((QueryImpl) q).getDelegate().setCandidateType(
-            SimpleEntity.class, true);
-        try {
-            q.getResultList().get(0);
-            fail("should have gotten an exception since method is invalid");
-        } catch (ArgumentException ae) {
-            // expected
-        }
-    }
-
-    public static ResultObjectProvider echo(StoreContext ctx,
-        ClassMetaData meta, boolean subs, Map params, FetchConfiguration conf) {
-        return new ListResultObjectProvider(new ArrayList(params.values()));
-    }
-
-    public static void voidMeth(StoreContext ctx,
-        ClassMetaData meta, boolean subs, Map params, FetchConfiguration conf) {
-    }
-
-    public static Object invalidReturnMeth(StoreContext ctx,
-        ClassMetaData meta, boolean subs, Map params, FetchConfiguration conf) {
-        return null;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Map;
+import java.util.ArrayList;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.QueryImpl;
+import org.apache.openjpa.persistence.ArgumentException;
+import org.apache.openjpa.kernel.QueryLanguages;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.rop.ListResultObjectProvider;
+
+public class TestMethodQLQuery
+    extends SingleEMTestCase {
+
+    @Override
+    public void setUp() {
+        setUp(SimpleEntity.class);
+    }
+
+    public void testMethodQLWithoutParametersDeclared() {
+        OpenJPAQuery q = em.createQuery(QueryLanguages.LANG_METHODQL,
+            getClass().getName() + ".echo");
+        ((QueryImpl) q).getDelegate().setCandidateType(
+            SimpleEntity.class, true);
+        q.setParameter("param", 5);
+        ((QueryImpl) q).getDelegate().declareParameters("Integer param");
+        assertEquals(5, q.getResultList().get(0));
+    }
+
+    public void testInvalidMethodReturnType() {
+        OpenJPAQuery q = em.createQuery(QueryLanguages.LANG_METHODQL,
+            getClass().getName() + ".invalidReturnMeth");
+        ((QueryImpl) q).getDelegate().setCandidateType(
+            SimpleEntity.class, true);
+        try {
+            q.getResultList().get(0);
+            fail("should have gotten an exception since method is invalid");
+        } catch (ArgumentException ae) {
+            // expected
+        }
+    }
+
+    public void testVoidMethodReturnType() {
+        OpenJPAQuery q = em.createQuery(QueryLanguages.LANG_METHODQL,
+            getClass().getName() + ".voidMeth");
+        ((QueryImpl) q).getDelegate().setCandidateType(
+            SimpleEntity.class, true);
+        try {
+            q.getResultList().get(0);
+            fail("should have gotten an exception since method is invalid");
+        } catch (ArgumentException ae) {
+            // expected
+        }
+    }
+
+    public static ResultObjectProvider echo(StoreContext ctx,
+        ClassMetaData meta, boolean subs, Map params, FetchConfiguration conf) {
+        return new ListResultObjectProvider(new ArrayList(params.values()));
+    }
+
+    public static void voidMeth(StoreContext ctx,
+        ClassMetaData meta, boolean subs, Map params, FetchConfiguration conf) {
+    }
+
+    public static Object invalidReturnMeth(StoreContext ctx,
+        ClassMetaData meta, boolean subs, Map params, FetchConfiguration conf) {
+        return null;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNamedQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNamedQueries.java
index 0b12633..127e6f6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNamedQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNamedQueries.java
@@ -1,114 +1,114 @@
-/*
- * TestNamedQueries.java
- *
- * Created on October 18, 2006, 1:17 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Collection;
-
-
-
-import org.apache.openjpa.persistence.query.common.apps.QueryTest1;
-
-import org.apache.openjpa.meta.QueryMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestNamedQueries extends BaseQueryTest {
-
-    /**
-     * Creates a new instance of TestNamedQueries
-     */
-
-    public TestNamedQueries(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        deleteAll(QueryTest1.class);
-
-        OpenJPAEntityManager pm = getEM();
-        startTx(pm);
-        QueryTest1 pc = null;
-        for (int i = 0; i < 10; i++) {
-            pc = new QueryTest1();
-            if (i < 5)
-                pc.setNum(4);
-            else
-                pc.setNum(i + 10);
-            pm.persist(pc);
-        }
-        endTx(pm);
-        endEm(pm);
-    }
-
-    public void testNamedClassQuery() {
-        OpenJPAEntityManager pm = getEM();
-
-        OpenJPAQuery query = pm.createQuery("SELECT o FROM QueryTest1 o");
-        query.setResultClass(QueryTest1.class);
-
-        assertEquals(QueryTest1.class, query.getResultClass());
-        assertEquals("SELECT o FROM QueryTest1 o", query.getQueryString());
-        assertEquals(QueryTest1.class, query.getResultClass());
-        //FIXME jthomas
-        /*
-        assertEquals("import java.util.*", query.getImports());
-        assertEquals("int pnum", query.getParameters());
-        assertEquals("QueryTest4 v4", query.getVariables());
-        assertEquals("sum(num)", query.getResult());
-        assertEquals("num", query.getGrouping());
-        */
-        QueryMetaData meta = ((OpenJPAEntityManagerSPI) pm).getConfiguration().
-            getMetaDataRepositoryInstance().getQueryMetaData(null,
-            "named", pm.getClassLoader(), true);
-        assertNotNull(meta);
-        assertEquals("SELECT o FROM QueryTest1 o", meta.getQueryString());
-        assertEquals(null, meta.getResultType());
-
-        endEm(pm);
-    }
-
-    public void testNamespace() {
-        OpenJPAEntityManager pm = getEM();
-        OpenJPAQuery query = (OpenJPAQuery) pm.createNamedQuery("named");
-        assertEquals("SELECT o FROM QueryTest1 o", query.getQueryString());
-        query.closeAll();
-        endEm(pm);
-    }
-
-    public void testSystemJDOQL() {
-        // make sure local query metadata is parsed
-        OpenJPAEntityManager pm = getEM();
-
-        OpenJPAQuery query = (OpenJPAQuery) pm.createNamedQuery("named");
-        assertEquals("SELECT o FROM QueryTest1 o", query.getQueryString());
-        assertEquals(QueryTest1.class, query.getResultClass());
-        assertEquals(10, ((Collection) query.getResultList()).size());
-        query.closeAll();
-        endEm(pm);
-    }
-}
+/*
+ * TestNamedQueries.java
+ *
+ * Created on October 18, 2006, 1:17 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Collection;
+
+
+
+import org.apache.openjpa.persistence.query.common.apps.QueryTest1;
+
+import org.apache.openjpa.meta.QueryMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestNamedQueries extends BaseQueryTest {
+
+    /**
+     * Creates a new instance of TestNamedQueries
+     */
+
+    public TestNamedQueries(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        deleteAll(QueryTest1.class);
+
+        OpenJPAEntityManager pm = getEM();
+        startTx(pm);
+        QueryTest1 pc = null;
+        for (int i = 0; i < 10; i++) {
+            pc = new QueryTest1();
+            if (i < 5)
+                pc.setNum(4);
+            else
+                pc.setNum(i + 10);
+            pm.persist(pc);
+        }
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testNamedClassQuery() {
+        OpenJPAEntityManager pm = getEM();
+
+        OpenJPAQuery query = pm.createQuery("SELECT o FROM QueryTest1 o");
+        query.setResultClass(QueryTest1.class);
+
+        assertEquals(QueryTest1.class, query.getResultClass());
+        assertEquals("SELECT o FROM QueryTest1 o", query.getQueryString());
+        assertEquals(QueryTest1.class, query.getResultClass());
+        //FIXME jthomas
+        /*
+        assertEquals("import java.util.*", query.getImports());
+        assertEquals("int pnum", query.getParameters());
+        assertEquals("QueryTest4 v4", query.getVariables());
+        assertEquals("sum(num)", query.getResult());
+        assertEquals("num", query.getGrouping());
+        */
+        QueryMetaData meta = ((OpenJPAEntityManagerSPI) pm).getConfiguration().
+            getMetaDataRepositoryInstance().getQueryMetaData(null,
+            "named", pm.getClassLoader(), true);
+        assertNotNull(meta);
+        assertEquals("SELECT o FROM QueryTest1 o", meta.getQueryString());
+        assertEquals(null, meta.getResultType());
+
+        endEm(pm);
+    }
+
+    public void testNamespace() {
+        OpenJPAEntityManager pm = getEM();
+        OpenJPAQuery query = (OpenJPAQuery) pm.createNamedQuery("named");
+        assertEquals("SELECT o FROM QueryTest1 o", query.getQueryString());
+        query.closeAll();
+        endEm(pm);
+    }
+
+    public void testSystemJDOQL() {
+        // make sure local query metadata is parsed
+        OpenJPAEntityManager pm = getEM();
+
+        OpenJPAQuery query = (OpenJPAQuery) pm.createNamedQuery("named");
+        assertEquals("SELECT o FROM QueryTest1 o", query.getQueryString());
+        assertEquals(QueryTest1.class, query.getResultClass());
+        assertEquals(10, ((Collection) query.getResultList()).size());
+        query.closeAll();
+        endEm(pm);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNewEntityAsQueryParameter.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNewEntityAsQueryParameter.java
index def0a03..012d1a2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNewEntityAsQueryParameter.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestNewEntityAsQueryParameter.java
@@ -1,133 +1,133 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.openjpa.persistence.query.common.apps.Osoba;
-import org.apache.openjpa.persistence.query.common.apps.Projekt;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Tests that managed, unmanaged or even transient Entity can be used as a 
- * query parameter.
- * 
- * Originally raised as a JIRA Issue
- * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-187">OPENJPA-187</A>
- * 
- * @author Pinaki Poddar
- *
- */
-public class TestNewEntityAsQueryParameter extends SingleEMFTestCase {
-	
-	public static final String ID_PROJEKT1 = "OpenJPA";
-	public static final String ID_PROJEKT2 = "Tomcat";
-	
-	public static final int MEMBER_COUNT_PROJEKT1 = 6;
-	public static final int MEMBER_COUNT_PROJEKT2 = 4;
-	public static final int MEMBER_COUNT_TOTAL    = 8;
-	
-	public void setUp() throws Exception {
-		super.setUp(CLEAR_TABLES, Osoba.class, Projekt.class,
-				"openjpa.Log", "SQL=TRACE");
-		createData();
-	}
-	
-	private void createData() {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		
-		Osoba[] osoby = new Osoba[MEMBER_COUNT_TOTAL];
-		for (int i=0; i<MEMBER_COUNT_TOTAL; i++) {
-			osoby[i] = new Osoba("Osoba-"+(i+1), 20+i);
-			em.persist(osoby[i]);
-		}
-		
-		
-		Projekt projekt1 = new Projekt(ID_PROJEKT1);
-		Projekt projekt2 = new Projekt(ID_PROJEKT2);
-		em.persist(projekt1);
-		em.persist(projekt2);
-		
-		for (int i=0; i<MEMBER_COUNT_PROJEKT1; i++)
-			link(osoby[i], projekt1);
-		for (int i=0; i<MEMBER_COUNT_PROJEKT2; i++)
-			link(osoby[osoby.length-i-1], projekt2);
-				
-		em.getTransaction().commit();
-		em.clear();
-	}
-
-	public void tearDown() throws Exception {
-		super.tearDown();
-	}
-	
-	public void testQueryWithTransientInstanceAsParameter() {
-		Projekt projekt1 = new Projekt(ID_PROJEKT1);
-		Projekt projekt2 = new Projekt(ID_PROJEKT2);
-		
-		EntityManager em = emf.createEntityManager();
-		queryWithParameter(em, projekt1, projekt2);
-	}
-	
-	public void testQueryWithUnmanagedPersistentInstanceAsParameter() {
-		EntityManager em = emf.createEntityManager();
-		Projekt projekt1 = em.find(Projekt.class, ID_PROJEKT1);
-		Projekt projekt2 = em.find(Projekt.class, ID_PROJEKT2);
-		em.clear();
-		assertFalse(em.contains(projekt1));
-		assertFalse(em.contains(projekt2));
-		
-		queryWithParameter(em, projekt1, projekt2);
-	}
-
-	public void testQueryWithManagedPersistentInstanceAsParameter() {
-		EntityManager em = emf.createEntityManager();
-		Projekt projekt1 = em.find(Projekt.class, ID_PROJEKT1);
-		Projekt projekt2 = em.find(Projekt.class, ID_PROJEKT2);
-		assertTrue(em.contains(projekt1));
-		assertTrue(em.contains(projekt2));
-		
-		queryWithParameter(em, projekt1, projekt2);
-	}
-	
-	void queryWithParameter(EntityManager em, Projekt projekt1, Projekt projekt2) {
-		String jpql = "SELECT DISTINCT o FROM Osoba o WHERE :projekt MEMBER OF o.projekty";
-		em.getTransaction().begin();
-		Query query = em.createQuery(jpql);
-		
-		query.setParameter("projekt", projekt1);
-		List<Osoba> osoby = query.getResultList();
-		assertEquals(MEMBER_COUNT_PROJEKT1, osoby.size()); 
-		
-		query.setParameter("projekt", projekt2);
-		osoby = query.getResultList();
-		assertEquals(MEMBER_COUNT_PROJEKT2, osoby.size());
-		em.getTransaction().rollback();
-	}
-	
-	void link(Osoba o, Projekt p) {
-		o.addProjekty(p);
-		p.addOsoba(o);
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.query.common.apps.Osoba;
+import org.apache.openjpa.persistence.query.common.apps.Projekt;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests that managed, unmanaged or even transient Entity can be used as a 
+ * query parameter.
+ * 
+ * Originally raised as a JIRA Issue
+ * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-187">OPENJPA-187</A>
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestNewEntityAsQueryParameter extends SingleEMFTestCase {
+	
+	public static final String ID_PROJEKT1 = "OpenJPA";
+	public static final String ID_PROJEKT2 = "Tomcat";
+	
+	public static final int MEMBER_COUNT_PROJEKT1 = 6;
+	public static final int MEMBER_COUNT_PROJEKT2 = 4;
+	public static final int MEMBER_COUNT_TOTAL    = 8;
+	
+	public void setUp() throws Exception {
+		super.setUp(CLEAR_TABLES, Osoba.class, Projekt.class,
+				"openjpa.Log", "SQL=TRACE");
+		createData();
+	}
+	
+	private void createData() {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		
+		Osoba[] osoby = new Osoba[MEMBER_COUNT_TOTAL];
+		for (int i=0; i<MEMBER_COUNT_TOTAL; i++) {
+			osoby[i] = new Osoba("Osoba-"+(i+1), 20+i);
+			em.persist(osoby[i]);
+		}
+		
+		
+		Projekt projekt1 = new Projekt(ID_PROJEKT1);
+		Projekt projekt2 = new Projekt(ID_PROJEKT2);
+		em.persist(projekt1);
+		em.persist(projekt2);
+		
+		for (int i=0; i<MEMBER_COUNT_PROJEKT1; i++)
+			link(osoby[i], projekt1);
+		for (int i=0; i<MEMBER_COUNT_PROJEKT2; i++)
+			link(osoby[osoby.length-i-1], projekt2);
+				
+		em.getTransaction().commit();
+		em.clear();
+	}
+
+	public void tearDown() throws Exception {
+		super.tearDown();
+	}
+	
+	public void testQueryWithTransientInstanceAsParameter() {
+		Projekt projekt1 = new Projekt(ID_PROJEKT1);
+		Projekt projekt2 = new Projekt(ID_PROJEKT2);
+		
+		EntityManager em = emf.createEntityManager();
+		queryWithParameter(em, projekt1, projekt2);
+	}
+	
+	public void testQueryWithUnmanagedPersistentInstanceAsParameter() {
+		EntityManager em = emf.createEntityManager();
+		Projekt projekt1 = em.find(Projekt.class, ID_PROJEKT1);
+		Projekt projekt2 = em.find(Projekt.class, ID_PROJEKT2);
+		em.clear();
+		assertFalse(em.contains(projekt1));
+		assertFalse(em.contains(projekt2));
+		
+		queryWithParameter(em, projekt1, projekt2);
+	}
+
+	public void testQueryWithManagedPersistentInstanceAsParameter() {
+		EntityManager em = emf.createEntityManager();
+		Projekt projekt1 = em.find(Projekt.class, ID_PROJEKT1);
+		Projekt projekt2 = em.find(Projekt.class, ID_PROJEKT2);
+		assertTrue(em.contains(projekt1));
+		assertTrue(em.contains(projekt2));
+		
+		queryWithParameter(em, projekt1, projekt2);
+	}
+	
+	void queryWithParameter(EntityManager em, Projekt projekt1, Projekt projekt2) {
+		String jpql = "SELECT DISTINCT o FROM Osoba o WHERE :projekt MEMBER OF o.projekty";
+		em.getTransaction().begin();
+		Query query = em.createQuery(jpql);
+		
+		query.setParameter("projekt", projekt1);
+		List<Osoba> osoby = query.getResultList();
+		assertEquals(MEMBER_COUNT_PROJEKT1, osoby.size()); 
+		
+		query.setParameter("projekt", projekt2);
+		osoby = query.getResultList();
+		assertEquals(MEMBER_COUNT_PROJEKT2, osoby.size());
+		em.getTransaction().rollback();
+	}
+	
+	void link(Osoba o, Projekt p) {
+		o.addProjekty(p);
+		p.addOsoba(o);
+	}
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java
index c305aee..16ba10b 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java
@@ -1,109 +1,109 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.jdbc.common.apps.UnidirectionalOneToOneOwned;
-import org.apache.openjpa.persistence.jdbc.common.apps.UnidirectionalOneToOneOwner;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-
-/**
- * The query uses projection and result contains the same instance once as
- * a direct projection and again as a fetch group of the other projection.
- * Does the query return two separate instances or one identical instance?
- * 
- * Originally reported as two different failures:
- * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-209">OPENJPA-209</A>
- * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-210">OPENJPA-210</A> 
- * 
- * @author Pinaki Poddar
- */
-public class TestProjectionQueryWithIdenticalResult extends SingleEMFTestCase {
-	private static boolean USE_TXN = true; 
-    public void setUp() {
-        setUp(CLEAR_TABLES,
-        	  UnidirectionalOneToOneOwned.class, 
-        	  UnidirectionalOneToOneOwner.class);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        UnidirectionalOneToOneOwner owner = new UnidirectionalOneToOneOwner();
-        owner.setMarker("Owner");
-        UnidirectionalOneToOneOwned owned = new UnidirectionalOneToOneOwned();
-        owned.setMarker("Owned");
-        owner.setOwned(owned);
-        em.persist(owner);
-        em.getTransaction().commit();
-        em.close();
-    }
-    
-	public void testDuplicateResultInProjection1() {
-		String jpql = "SELECT p.owned, p FROM UnidirectionalOneToOneOwner p";
-		List<Object[]> result = executeQuery(jpql, USE_TXN);
-		for (Object[] row : result) {
-			assertTrue(row[0] instanceof UnidirectionalOneToOneOwned);
-			assertTrue(row[1] instanceof UnidirectionalOneToOneOwner);
-			assertTrue(((UnidirectionalOneToOneOwner)row[1]).getOwned() == row[0]);
-		}
-	}
-	
-	public void testDuplicateResultInProjection2() {
-		String jpql = "SELECT p, p.owned FROM UnidirectionalOneToOneOwner p";
-		List<Object[]> result = executeQuery(jpql, USE_TXN);
-		for (Object[] row : result) {
-			assertTrue(row[1] instanceof UnidirectionalOneToOneOwned);
-			assertTrue(row[0] instanceof UnidirectionalOneToOneOwner);
-			assertTrue(((UnidirectionalOneToOneOwner)row[0]).getOwned() == row[1]);
-		}
-	}
-	
-	public void testDuplicateResultInProjection3() {
-		String jpql = "SELECT p, q FROM UnidirectionalOneToOneOwner p, " +
-						"UnidirectionalOneToOneOwned q WHERE p.owned = q";
-		List<Object[]> result = executeQuery(jpql, USE_TXN);
-		for (Object[] row : result) {
-			assertTrue(row[0] instanceof UnidirectionalOneToOneOwner);
-			assertTrue(row[1] instanceof UnidirectionalOneToOneOwned);
-			assertTrue(((UnidirectionalOneToOneOwner)row[0]).getOwned() == row[1]);
-		}
-	}
-	
-	public void testDuplicateResultInProjection4() {
-		String jpql = "SELECT q, p FROM UnidirectionalOneToOneOwner p, " +
-					    "UnidirectionalOneToOneOwned q WHERE p.owned = q";
-		List<Object[]> result = executeQuery(jpql, USE_TXN);
-		for (Object[] row : result) {
-			assertTrue(row[0] instanceof UnidirectionalOneToOneOwned);
-			assertTrue(row[1] instanceof UnidirectionalOneToOneOwner);
-			assertTrue(((UnidirectionalOneToOneOwner)row[1]).getOwned() == row[0]);
-		}
-	}
-	
-	private List executeQuery(String jpql, boolean useTxn) {
-		EntityManager em = emf.createEntityManager();
-		em.getTransaction().begin();
-		List result = em.createQuery(jpql).getResultList();
-		em.getTransaction().rollback();
-		return result;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.jdbc.common.apps.UnidirectionalOneToOneOwned;
+import org.apache.openjpa.persistence.jdbc.common.apps.UnidirectionalOneToOneOwner;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+
+/**
+ * The query uses projection and result contains the same instance once as
+ * a direct projection and again as a fetch group of the other projection.
+ * Does the query return two separate instances or one identical instance?
+ * 
+ * Originally reported as two different failures:
+ * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-209">OPENJPA-209</A>
+ * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-210">OPENJPA-210</A> 
+ * 
+ * @author Pinaki Poddar
+ */
+public class TestProjectionQueryWithIdenticalResult extends SingleEMFTestCase {
+	private static boolean USE_TXN = true; 
+    public void setUp() {
+        setUp(CLEAR_TABLES,
+        	  UnidirectionalOneToOneOwned.class, 
+        	  UnidirectionalOneToOneOwner.class);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        UnidirectionalOneToOneOwner owner = new UnidirectionalOneToOneOwner();
+        owner.setMarker("Owner");
+        UnidirectionalOneToOneOwned owned = new UnidirectionalOneToOneOwned();
+        owned.setMarker("Owned");
+        owner.setOwned(owned);
+        em.persist(owner);
+        em.getTransaction().commit();
+        em.close();
+    }
+    
+	public void testDuplicateResultInProjection1() {
+		String jpql = "SELECT p.owned, p FROM UnidirectionalOneToOneOwner p";
+		List<Object[]> result = executeQuery(jpql, USE_TXN);
+		for (Object[] row : result) {
+			assertTrue(row[0] instanceof UnidirectionalOneToOneOwned);
+			assertTrue(row[1] instanceof UnidirectionalOneToOneOwner);
+			assertTrue(((UnidirectionalOneToOneOwner)row[1]).getOwned() == row[0]);
+		}
+	}
+	
+	public void testDuplicateResultInProjection2() {
+		String jpql = "SELECT p, p.owned FROM UnidirectionalOneToOneOwner p";
+		List<Object[]> result = executeQuery(jpql, USE_TXN);
+		for (Object[] row : result) {
+			assertTrue(row[1] instanceof UnidirectionalOneToOneOwned);
+			assertTrue(row[0] instanceof UnidirectionalOneToOneOwner);
+			assertTrue(((UnidirectionalOneToOneOwner)row[0]).getOwned() == row[1]);
+		}
+	}
+	
+	public void testDuplicateResultInProjection3() {
+		String jpql = "SELECT p, q FROM UnidirectionalOneToOneOwner p, " +
+						"UnidirectionalOneToOneOwned q WHERE p.owned = q";
+		List<Object[]> result = executeQuery(jpql, USE_TXN);
+		for (Object[] row : result) {
+			assertTrue(row[0] instanceof UnidirectionalOneToOneOwner);
+			assertTrue(row[1] instanceof UnidirectionalOneToOneOwned);
+			assertTrue(((UnidirectionalOneToOneOwner)row[0]).getOwned() == row[1]);
+		}
+	}
+	
+	public void testDuplicateResultInProjection4() {
+		String jpql = "SELECT q, p FROM UnidirectionalOneToOneOwner p, " +
+					    "UnidirectionalOneToOneOwned q WHERE p.owned = q";
+		List<Object[]> result = executeQuery(jpql, USE_TXN);
+		for (Object[] row : result) {
+			assertTrue(row[0] instanceof UnidirectionalOneToOneOwned);
+			assertTrue(row[1] instanceof UnidirectionalOneToOneOwner);
+			assertTrue(((UnidirectionalOneToOneOwner)row[1]).getOwned() == row[0]);
+		}
+	}
+	
+	private List executeQuery(String jpql, boolean useTxn) {
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		List result = em.createQuery(jpql).getResultList();
+		em.getTransaction().rollback();
+		return result;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryEscapeCharacters.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryEscapeCharacters.java
new file mode 100644
index 0000000..c7b3595
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryEscapeCharacters.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestQueryEscapeCharacters
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Employee.class, CLEAR_TABLES);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        Employee e = new Employee();
+        e.setName("Mike Dick");
+        e.setEmpId(1);
+        em.persist(e);
+
+        e = new Employee();
+        e.setName("Mike Jones");
+        e.setEmpId(2);
+        em.persist(e);
+
+        e = new Employee();
+        e.setName("Mike Smith");
+        e.setEmpId(3);
+        em.persist(e);
+        
+        e = new Employee();
+        e.setName("M%ke Smith");
+        e.setEmpId(4);
+        em.persist(e);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void tearDown() throws Exception {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.createQuery("Delete from Employee").executeUpdate();
+        em.getTransaction().commit();
+        em.close();
+        super.tearDown();
+    }
+    
+    public void testNormalQuery() {
+        performFind ("Employee.findByName", "%Dick", 1);
+    }
+
+    public void testMultiResultQuery() {
+        performFind ("Employee.findByName", "Mike%", 3);
+    }
+
+    public void testEscapedQuery() {
+        performFind ("Employee.findByNameEscaped", 
+                "M\\%%", 1);
+    }
+
+    public void testDoubleEscapedQuery() {
+        performFind ("Employee.findByName", "\\\\", 0);
+    }
+
+    public void testWrongEscape() {
+        performFind ("Employee.findByName", "M|%%", 0);
+    }
+
+    public void testDoubleSlashQuery() {
+        // get the Dictionary and check the alwaysAddSearchString flag
+        OpenJPAEntityManagerFactorySPI ojpaEmf = 
+            (OpenJPAEntityManagerFactorySPI) emf;
+        JDBCConfiguration conf = (JDBCConfiguration)ojpaEmf.getConfiguration();
+        
+        if (conf.getDBDictionaryInstance().
+                requiresSearchStringEscapeForLike == true) {
+            return;
+        }
+
+        performFind ("Employee.findByName", "\\", 0);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void testDifferentEscapeCharacter () {
+        OpenJPAEntityManagerFactorySPI ojpaEmf = 
+            (OpenJPAEntityManagerFactorySPI) emf;
+        JDBCConfiguration conf = (JDBCConfiguration)ojpaEmf.getConfiguration();
+
+        // Would be nice to just pass a map to the createEntityManager, but
+        // seems like it would be too much trouble to get the proper DB type
+        // and then build the string for the map.
+        conf.getDBDictionaryInstance().requiresSearchStringEscapeForLike = true;
+        conf.getDBDictionaryInstance().searchStringEscape = "|";
+        EntityManager em = emf.createEntityManager();
+
+        Query q = em.createNamedQuery("Employee.findByName");
+        q.setParameter("name", "M|%%");
+        List<Employee> emps = (List<Employee>) q.getResultList();
+        assertEquals(1, emps.size());
+
+        String unnamedQuery =
+            "Select e from Employee e where e.name LIKE :name";
+
+        q = em.createQuery(unnamedQuery);
+        q.setParameter("name", "M|%%");
+        emps = (List<Employee>) q.getResultList();
+        assertEquals(1, emps.size());
+        em.close();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void performFind (String namedQuery, String parameter,
+            int expected) {
+        EntityManager em = emf.createEntityManager();
+
+        Query q = em.createNamedQuery(namedQuery);
+        q.setParameter("name", parameter);
+        List<Employee> emps = (List<Employee>) q.getResultList();
+        assertEquals(expected, emps.size());
+
+        String unnamedQuery =
+            "Select e from Employee e where e.name LIKE :name";
+        if (namedQuery.equals("Employee.findByNameEscaped")) {
+            unnamedQuery =
+                "Select e from Employee e where e.name LIKE :name ESCAPE '\\'";
+        }
+        q = em.createQuery(unnamedQuery);
+        q.setParameter("name", parameter);
+        emps = (List<Employee>) q.getResultList();
+        assertEquals(expected, emps.size());
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryExpressionSplit.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryExpressionSplit.java
index c9471a7..f17c9f2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryExpressionSplit.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryExpressionSplit.java
@@ -1,80 +1,80 @@
-/*
- * TestQueryExpressionSplit.java
- *
- * Created on October 18, 2006, 1:57 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Arrays;
-import java.util.List;
-
-
-
-
-import org.apache.openjpa.kernel.Filters;
-
-public class TestQueryExpressionSplit extends BaseQueryTest {
-
-    /**
-     * Creates a new instance of TestQueryExpressionSplit
-     */
-
-    public TestQueryExpressionSplit(String test) {
-        super(test);
-    }
-
-    public void testSimple() {
-        assertEquals(new String[]{ "foo() bar(boo)" },
-            Filters.splitExpressions("foo() bar(boo)", ',', 3));
-        assertEquals(new String[]{ "foo() bar(boo)", "biz()", "baz(boo)" },
-            Filters.splitExpressions("foo() bar(boo), biz(), baz(boo)",
-                ',', 3));
-    }
-
-    public void testCommaInString() {
-        assertEquals(new String[]{ "foo \"bar(),biz)\"" },
-            Filters.splitExpressions("foo \"bar(),biz)\"", ',', 3));
-        assertEquals(new String[]{ "foo 'bar(),\"biz)'", "boo" },
-            Filters.splitExpressions("foo 'bar(),\"biz)', boo", ',', 3));
-    }
-
-    public void testCommaInFunction() {
-        assertEquals(new String[]{ "(foo(bar, biz))",
-            "boo(biz, baz('xxx,yyy'))" },
-            Filters.splitExpressions("(foo(bar, biz)), "
-                + "boo(biz, baz('xxx,yyy'))", ',', 3));
-    }
-
-    public void testEscapedString() {
-        assertEquals(new String[]{ "foo \"bar\\\", biz(\"",
-            "\"baz\\\", boo\"" },
-            Filters.splitExpressions("foo \"bar\\\", biz(\", "
-                + "\"baz\\\", boo\"", ',', 3));
-    }
-
-    private void assertEquals(String[] ans, List test) {
-        List l = Arrays.asList(ans);
-        assertEquals(l + " != " + test, l, test);
-    }
-}
+/*
+ * TestQueryExpressionSplit.java
+ *
+ * Created on October 18, 2006, 1:57 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+
+
+import org.apache.openjpa.kernel.Filters;
+
+public class TestQueryExpressionSplit extends BaseQueryTest {
+
+    /**
+     * Creates a new instance of TestQueryExpressionSplit
+     */
+
+    public TestQueryExpressionSplit(String test) {
+        super(test);
+    }
+
+    public void testSimple() {
+        assertEquals(new String[]{ "foo() bar(boo)" },
+            Filters.splitExpressions("foo() bar(boo)", ',', 3));
+        assertEquals(new String[]{ "foo() bar(boo)", "biz()", "baz(boo)" },
+            Filters.splitExpressions("foo() bar(boo), biz(), baz(boo)",
+                ',', 3));
+    }
+
+    public void testCommaInString() {
+        assertEquals(new String[]{ "foo \"bar(),biz)\"" },
+            Filters.splitExpressions("foo \"bar(),biz)\"", ',', 3));
+        assertEquals(new String[]{ "foo 'bar(),\"biz)'", "boo" },
+            Filters.splitExpressions("foo 'bar(),\"biz)', boo", ',', 3));
+    }
+
+    public void testCommaInFunction() {
+        assertEquals(new String[]{ "(foo(bar, biz))",
+            "boo(biz, baz('xxx,yyy'))" },
+            Filters.splitExpressions("(foo(bar, biz)), "
+                + "boo(biz, baz('xxx,yyy'))", ',', 3));
+    }
+
+    public void testEscapedString() {
+        assertEquals(new String[]{ "foo \"bar\\\", biz(\"",
+            "\"baz\\\", boo\"" },
+            Filters.splitExpressions("foo \"bar\\\", biz(\", "
+                + "\"baz\\\", boo\"", ',', 3));
+    }
+
+    private void assertEquals(String[] ans, List test) {
+        List l = Arrays.asList(ans);
+        assertEquals(l + " != " + test, l, test);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryResults.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryResults.java
index 6e7095f..f990667 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryResults.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryResults.java
@@ -1,625 +1,625 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest3;
-import org.apache.openjpa.persistence.Extent;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.jdbc.FetchMode;
-import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
-
-/**
- * Test that ResultList objects behaver correctly.
- *
- * @author Marc Prud'hommeaux
- */
-public class TestQueryResults extends BaseQueryTest {
-
-    public TestQueryResults(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        em.persist(new RuntimeTest1("TestQueryResults1", 10));
-        em.persist(new RuntimeTest1("TestQueryResults3", 10));
-        em.persist(new RuntimeTest1("TestQueryResults5", 10));
-        em.persist(new RuntimeTest3("TestQueryResults2", 10));
-        em.persist(new RuntimeTest3("TestQueryResults4", 10));
-        em.persist(new RuntimeTest3("TestQueryResults6", 10));
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testQueryIteratorsReturnFalseForClosedQuery() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o");
-        List c = q.getResultList();
-        Iterator i = c.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-
-        if (i.hasNext())
-            fail("Iterator obtained from Query should return false "
-                + "for hasNext() after Query has been closed");
-    }
-
-    public void testQueryIteratorsThrowExceptionForClosedQuery() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o");
-        List c = q.getResultList();
-        Iterator i = c.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-
-        try {
-            i.next();
-            fail("Iterator.next() should have thrown Exception "
-                + "after query.closeAll() was called");
-        }
-        catch (Exception e) {
-            //
-        }
-    }
-
-    public void testLazyQueryIteratorsReturnFalseForClosedem() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        String query = "SELECT o FROM RuntimeTest1 o";
-        OpenJPAQuery q = em.createQuery(query);
-        q.getFetchPlan().setFetchBatchSize(5);
-        List c = q.getResultList();
-
-        Iterator i = c.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        endTx(em);
-        endEm(em);
-
-        if (i.hasNext())
-            fail("Lazy result iterator obtained from Query should return "
-                + "false for hasNext() after em has been closed");
-    }
-
-    public void testEagerQueryIteratorsWorkForClosedem() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        String query = "SELECT o FROM RuntimeTest1 o";
-        OpenJPAQuery q = em.createQuery(query);
-        q.getFetchPlan().setFetchBatchSize(-1);
-
-        List c = q.getResultList();
-
-        Iterator i = c.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        endTx(em);
-        endEm(em);
-
-        if (!i.hasNext())
-            fail("Eager result iterator obtained from Query should return "
-                + "true for hasNext() after em has been closed");
-    }
-
-    public void testQueryResultIsList() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        String query = "SELECT o FROM RuntimeTest1 o";
-
-        Collection c = (Collection) em.createQuery(query).getResultList();
-        if (!(c instanceof List))
-            fail("Collection (" + c.getClass() + ") should have "
-                + "been a List instance");
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testQueryResultSizeIsCorrect() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        em.persist(new RuntimeTest2("TestQueryResults1", 10));
-        endTx(em);
-        endEm(em);
-
-        em = (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        String query =
-            "SELECT r FROM RuntimeTest2 r WHERE r.stringField = \'TestQueryResults1\'";
-        List c = em.createQuery(query).getResultList();
-
-        assertEquals(1, c.size());
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testExtentIteratorsReturnFalseForClosedExtent() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        Extent extent = em.createExtent(RuntimeTest1.class, true);
-
-        Iterator i = extent.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        extent.closeAll();
-
-        if (i.hasNext())
-            fail("Iterator obtained from Extent should return false "
-                + "for hasNext() after Extent has been closed");
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testExtentIteratorsThrowExceptionForClosedExtent() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        Extent extent = em.createExtent(RuntimeTest1.class, true);
-
-        Iterator i = extent.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        extent.closeAll();
-
-        try {
-            i.next();
-            fail("Iterator.next() should have thrown Exception "
-                + "after Extent.closeAll() was called");
-        } catch (Exception e) {
-            // this is a *good* thing.
-        }
-
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testExtentIteratorsReturnFalseForClosedem() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        Extent extent = em.createExtent(RuntimeTest1.class, true);
-        Iterator i = extent.iterator();
-        if (!(i.hasNext()))
-            fail("Iterator should have had next()");
-        endTx(em);
-        endEm(em);
-
-        if (i.hasNext())
-            fail("Iterator obtained from Extent should return false "
-                + "for hasNext() after em has been closed");
-    }
-
-    public void testUniqueReturnsSingleResult() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        String query =
-            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'TestQueryResults1\'";
-        Object obj = em.createQuery(query).getSingleResult();
-
-        assertTrue(obj instanceof RuntimeTest1);
-
-        query =
-            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'xxxx\'";
-        OpenJPAQuery q = em.createQuery(query);
-        List l = q.getResultList();
-        assertNotNull(
-            "expecting l to be null since there is no RuntimeTest1 instance with stringfield=xxxx",
-            l);
-
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testUniqueThrowsExceptionIfMultipleResults() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        String query = "SELECT DISTINCT r FROM RuntimeTest1 r";
-        OpenJPAQuery q = em.createQuery(query);
-
-        try {
-            Object l = q.getSingleResult();
-            fail("Unique query matched multiple results.");
-        }
-        catch (Exception jue) {
-        }
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testImpossibleRangeReturnsEmptyList() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-        String query = "SELECT r FROM RuntimeTest1 r";
-        OpenJPAQuery q = em.createQuery(query);
-        q.setFirstResult(2);
-        q.setMaxResults(0);
-
-        List results = q.getResultList();
-
-        assertEquals(0, results.size());
-        assertFalse(results.iterator().hasNext());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testImpossibleUniqueRangeReturnsNull() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'TestQueryResults1\'");
-        q.setFirstResult(2);
-        q.setMaxResults(0);
-        assertTrue(
-            "resultlist is not null its size is: " + q.getResultList().size(),
-            q.getResultList().isEmpty());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testSingleResultUniqueRange() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'TestQueryResults1\'");
-        q.setFirstResult(1);
-        q.setMaxResults(1000000);
-
-        assertTrue("resultlist is not empty", (q.getResultList()).isEmpty());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testMultiResultUniqueRange() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-        q.setFirstResult(1);
-        q.setMaxResults(2);
-
-        assertEquals("TestQueryResults2",
-            ((RuntimeTest1) q.getResultList().get(0)).getStringField());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    /* This test is being commented because it was supposed to be a converted test complementing the original JDO test
-      * which uses the setUnique() method available in JDO Query. OpenJPAQuery does not have such a method and hence this test
-      * does not make sense.
-      public void testUniqueThrowsExceptionIfNonUniqueRange()
-     {
-         OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
-         startTx(em);
-
-         OpenJPAQuery q = em.createQuery("SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-         q.setFirstResult(1);
-         q.setMaxResults(3);
-
-         try
-         {
-             q.getResultList();
-             fail("Unique allowed non-unique range.");
-         }
-         catch (Exception jue)
-         {
-         }
-         q.closeAll();
-         endTx(em);
-         endEm(em);
-     }
-     */
-    public void testFullRange() {
-        try {
-            OpenJPAEntityManager em =
-                (OpenJPAEntityManager) currentEntityManager();
-            startTx(em);
-
-            OpenJPAQuery q = em.createQuery(
-                "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC");
-            q.setSubclasses(false);
-            q.setFirstResult(0);
-            Long l = new Long(Long.MAX_VALUE);
-            q.setMaxResults(l.intValue());
-
-            List res = (List) q.getResultList();
-            assertEquals(3, res.size());
-            for (int i = 0; i < res.size(); i++)
-                assertEquals("TestQueryResults" + (i * 2 + 1),
-                    ((RuntimeTest1) res.get(i)).getStringField());
-            q.closeAll();
-            endTx(em);
-            endEm(em);
-        }
-        catch (Exception uoe) {
-            //FIXME:AFAM -- Figure out JPA Equivalence of createExtent(class, false) ie how to restrict the query result to the base entity and
-            //not the subclasses
-        }
-    }
-
-    public void testFullRangeSubs() {
-        try {
-            OpenJPAEntityManager em =
-                (OpenJPAEntityManager) currentEntityManager();
-            startTx(em);
-
-            OpenJPAQuery q = em.createQuery(
-                "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC");
-            q.setFirstResult(0);
-            Long l = new Long(Long.MAX_VALUE);
-            q.setMaxResults(l.intValue());
-
-            List res = (List) q.getResultList();
-            assertEquals(6, res.size());
-            for (int i = 0; i < res.size(); i++)
-                assertEquals("TestQueryResults" + (i + 1),
-                    ((RuntimeTest1) res.get(i)).getStringField());
-            q.closeAll();
-            endTx(em);
-            endEm(em);
-        }
-        catch (Exception uoe) {
-        }
-    }
-
-    public void testBeginRange() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-        q.setSubclasses(false);
-        for (int i = 0; i < 4; i++) {
-            q.setFirstResult(i);
-            q.setMaxResults(100000);
-
-            List res = (List) q.getResultList();
-            assertEquals("they are not equal", 3 - i, res.size());
-            int idx = 0;
-
-            // try both random acess and iteration
-            for (int j = 0; j < res.size(); j++)
-                assertEquals("TestQueryResults" + (j * 2 + 1 + i * 2),
-                    (((RuntimeTest1) res.get(j)).getStringField()));
-            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
-                assertEquals("TestQueryResults" + (idx * 2 + 1 + i * 2),
-                    ((RuntimeTest1) itr.next()).getStringField());
-        }
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testBeginRangeSubs() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-
-        for (int i = 0; i < 7; i++) {
-            q.setFirstResult(i);
-            Long l = new Long(Long.MAX_VALUE);
-            q.setMaxResults(100000);
-
-            List res = (List) q.getResultList();
-            assertEquals(6 - i, res.size());
-            int idx = 0;
-
-            // try both random acess and iteration
-            for (int j = 0; j < res.size(); j++)
-                assertEquals("TestQueryResults" + (j + 1 + i),
-                    ((RuntimeTest1) res.get(j)).getStringField());
-            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
-                assertEquals("TestQueryResults" + (idx + 1 + i),
-                    ((RuntimeTest1) itr.next()).getStringField());
-        }
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testEndRange() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-        q.setSubclasses(false);
-
-        for (int i = 0; i < 4; i++) {
-            q.setFirstResult(0);
-            q.setMaxResults(i);
-
-            List res = (List) q.getResultList();
-            assertEquals(i, res.size());
-            int idx = 0;
-
-            // try both random acess and iteration
-            for (int j = 0; j < res.size(); j++)
-                assertEquals("TestQueryResults" + (j * 2 + 1),
-                    ((RuntimeTest1) res.get(j)).getStringField());
-            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
-                assertEquals("TestQueryResults" + (idx * 2 + 1),
-                    ((RuntimeTest1) itr.next()).getStringField());
-        }
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testEndRangeSubs() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-
-        for (int i = 0; i < 7; i++) {
-            q.setFirstResult(0);
-            q.setMaxResults(i);
-            List res = (List) q.getResultList();
-            assertEquals(i, res.size());
-            int idx = 0;
-
-            // try both random acess and iteration
-            for (int j = 0; j < res.size(); j++)
-                assertEquals("TestQueryResults" + (j + 1),
-                    ((RuntimeTest1) res.get(j)).getStringField());
-            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
-                assertEquals("TestQueryResults" + (idx + 1),
-                    ((RuntimeTest1) itr.next()).getStringField());
-        }
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testMidRange() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-        q.setSubclasses(false);
-
-        q.setFirstResult(1);
-        q.setMaxResults(3);
-        List res = (List) q.getResultList();
-        assertEquals(2, res.size());
-        for (int i = 0; i < res.size(); i++)
-            assertEquals("TestQueryResults" + (i * 2 + 1 + 2),
-                ((RuntimeTest1) res.get(i)).getStringField());
-        int idx = 0;
-        for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
-            assertEquals("TestQueryResults" + (idx * 2 + 1 + 2),
-                ((RuntimeTest1) itr.next()).getStringField());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testMidRangeSubs() {
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-        q.setFirstResult(1);
-        q.setMaxResults(3);
-
-        List res = (List) q.getResultList();
-        assertEquals(3, res.size());
-        for (int i = 0; i < res.size(); i++)
-            assertEquals("TestQueryResults" + (i + 1 + 1),
-                ((RuntimeTest1) res.get(i)).getStringField());
-        int idx = 0;
-        for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
-            assertEquals("TestQueryResults" + (idx + 1 + 1),
-                ((RuntimeTest1) itr.next()).getStringField());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-
-    public void testPessimisticOrderedRange() {
-        // test to make sure whatever machinations we do to get a range doesn't
-        // interfere with FOR UPDATE
-        OpenJPAEntityManager em =
-            (OpenJPAEntityManager) currentEntityManager();
-        startTx(em);
-
-        OpenJPAQuery q = em.createQuery(
-            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
-        q.setSubclasses(false);
-        q.setFirstResult(0);
-        q.setMaxResults(2);
-
-        ((JDBCFetchPlan) q.getFetchPlan()).setEagerFetchMode(FetchMode.NONE);
-
-        List res = (List) q.getResultList();
-        assertEquals(2, res.size());
-        assertEquals("TestQueryResults1",
-            ((RuntimeTest1) res.get(0)).getStringField());
-        assertEquals("TestQueryResults3",
-            ((RuntimeTest1) res.get(1)).getStringField());
-        q.closeAll();
-        endTx(em);
-        endEm(em);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest3;
+import org.apache.openjpa.persistence.Extent;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.jdbc.FetchMode;
+import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
+
+/**
+ * Test that ResultList objects behaver correctly.
+ *
+ * @author Marc Prud'hommeaux
+ */
+public class TestQueryResults extends BaseQueryTest {
+
+    public TestQueryResults(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persist(new RuntimeTest1("TestQueryResults1", 10));
+        em.persist(new RuntimeTest1("TestQueryResults3", 10));
+        em.persist(new RuntimeTest1("TestQueryResults5", 10));
+        em.persist(new RuntimeTest3("TestQueryResults2", 10));
+        em.persist(new RuntimeTest3("TestQueryResults4", 10));
+        em.persist(new RuntimeTest3("TestQueryResults6", 10));
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testQueryIteratorsReturnFalseForClosedQuery() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o");
+        List c = q.getResultList();
+        Iterator i = c.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+
+        if (i.hasNext())
+            fail("Iterator obtained from Query should return false "
+                + "for hasNext() after Query has been closed");
+    }
+
+    public void testQueryIteratorsThrowExceptionForClosedQuery() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o");
+        List c = q.getResultList();
+        Iterator i = c.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+
+        try {
+            i.next();
+            fail("Iterator.next() should have thrown Exception "
+                + "after query.closeAll() was called");
+        }
+        catch (Exception e) {
+            //
+        }
+    }
+
+    public void testLazyQueryIteratorsReturnFalseForClosedem() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        String query = "SELECT o FROM RuntimeTest1 o";
+        OpenJPAQuery q = em.createQuery(query);
+        q.getFetchPlan().setFetchBatchSize(5);
+        List c = q.getResultList();
+
+        Iterator i = c.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        endTx(em);
+        endEm(em);
+
+        if (i.hasNext())
+            fail("Lazy result iterator obtained from Query should return "
+                + "false for hasNext() after em has been closed");
+    }
+
+    public void testEagerQueryIteratorsWorkForClosedem() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        String query = "SELECT o FROM RuntimeTest1 o";
+        OpenJPAQuery q = em.createQuery(query);
+        q.getFetchPlan().setFetchBatchSize(-1);
+
+        List c = q.getResultList();
+
+        Iterator i = c.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        endTx(em);
+        endEm(em);
+
+        if (!i.hasNext())
+            fail("Eager result iterator obtained from Query should return "
+                + "true for hasNext() after em has been closed");
+    }
+
+    public void testQueryResultIsList() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        String query = "SELECT o FROM RuntimeTest1 o";
+
+        Collection c = (Collection) em.createQuery(query).getResultList();
+        if (!(c instanceof List))
+            fail("Collection (" + c.getClass() + ") should have "
+                + "been a List instance");
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testQueryResultSizeIsCorrect() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        em.persist(new RuntimeTest2("TestQueryResults1", 10));
+        endTx(em);
+        endEm(em);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        String query =
+            "SELECT r FROM RuntimeTest2 r WHERE r.stringField = \'TestQueryResults1\'";
+        List c = em.createQuery(query).getResultList();
+
+        assertEquals(1, c.size());
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testExtentIteratorsReturnFalseForClosedExtent() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        Extent extent = em.createExtent(RuntimeTest1.class, true);
+
+        Iterator i = extent.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        extent.closeAll();
+
+        if (i.hasNext())
+            fail("Iterator obtained from Extent should return false "
+                + "for hasNext() after Extent has been closed");
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testExtentIteratorsThrowExceptionForClosedExtent() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        Extent extent = em.createExtent(RuntimeTest1.class, true);
+
+        Iterator i = extent.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        extent.closeAll();
+
+        try {
+            i.next();
+            fail("Iterator.next() should have thrown Exception "
+                + "after Extent.closeAll() was called");
+        } catch (Exception e) {
+            // this is a *good* thing.
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testExtentIteratorsReturnFalseForClosedem() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        Extent extent = em.createExtent(RuntimeTest1.class, true);
+        Iterator i = extent.iterator();
+        if (!(i.hasNext()))
+            fail("Iterator should have had next()");
+        endTx(em);
+        endEm(em);
+
+        if (i.hasNext())
+            fail("Iterator obtained from Extent should return false "
+                + "for hasNext() after em has been closed");
+    }
+
+    public void testUniqueReturnsSingleResult() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        String query =
+            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'TestQueryResults1\'";
+        Object obj = em.createQuery(query).getSingleResult();
+
+        assertTrue(obj instanceof RuntimeTest1);
+
+        query =
+            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'xxxx\'";
+        OpenJPAQuery q = em.createQuery(query);
+        List l = q.getResultList();
+        assertNotNull(
+            "expecting l to be null since there is no RuntimeTest1 instance with stringfield=xxxx",
+            l);
+
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testUniqueThrowsExceptionIfMultipleResults() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        String query = "SELECT DISTINCT r FROM RuntimeTest1 r";
+        OpenJPAQuery q = em.createQuery(query);
+
+        try {
+            Object l = q.getSingleResult();
+            fail("Unique query matched multiple results.");
+        }
+        catch (Exception jue) {
+        }
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testImpossibleRangeReturnsEmptyList() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        String query = "SELECT r FROM RuntimeTest1 r";
+        OpenJPAQuery q = em.createQuery(query);
+        q.setFirstResult(2);
+        q.setMaxResults(0);
+
+        List results = q.getResultList();
+
+        assertEquals(0, results.size());
+        assertFalse(results.iterator().hasNext());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testImpossibleUniqueRangeReturnsNull() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'TestQueryResults1\'");
+        q.setFirstResult(2);
+        q.setMaxResults(0);
+        assertTrue(
+            "resultlist is not null its size is: " + q.getResultList().size(),
+            q.getResultList().isEmpty());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testSingleResultUniqueRange() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = \'TestQueryResults1\'");
+        q.setFirstResult(1);
+        q.setMaxResults(1000000);
+
+        assertTrue("resultlist is not empty", (q.getResultList()).isEmpty());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testMultiResultUniqueRange() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+        q.setFirstResult(1);
+        q.setMaxResults(2);
+
+        assertEquals("TestQueryResults2",
+            ((RuntimeTest1) q.getResultList().get(0)).getStringField());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    /* This test is being commented because it was supposed to be a converted test complementing the original JDO test
+      * which uses the setUnique() method available in JDO Query. OpenJPAQuery does not have such a method and hence this test
+      * does not make sense.
+      public void testUniqueThrowsExceptionIfNonUniqueRange()
+     {
+         OpenJPAEntityManager em = (OpenJPAEntityManager) currentEntityManager();
+         startTx(em);
+
+         OpenJPAQuery q = em.createQuery("SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+         q.setFirstResult(1);
+         q.setMaxResults(3);
+
+         try
+         {
+             q.getResultList();
+             fail("Unique allowed non-unique range.");
+         }
+         catch (Exception jue)
+         {
+         }
+         q.closeAll();
+         endTx(em);
+         endEm(em);
+     }
+     */
+    public void testFullRange() {
+        try {
+            OpenJPAEntityManager em =
+                (OpenJPAEntityManager) currentEntityManager();
+            startTx(em);
+
+            OpenJPAQuery q = em.createQuery(
+                "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC");
+            q.setSubclasses(false);
+            q.setFirstResult(0);
+            Long l = new Long(Long.MAX_VALUE);
+            q.setMaxResults(l.intValue());
+
+            List res = (List) q.getResultList();
+            assertEquals(3, res.size());
+            for (int i = 0; i < res.size(); i++)
+                assertEquals("TestQueryResults" + (i * 2 + 1),
+                    ((RuntimeTest1) res.get(i)).getStringField());
+            q.closeAll();
+            endTx(em);
+            endEm(em);
+        }
+        catch (Exception uoe) {
+            //FIXME:AFAM -- Figure out JPA Equivalence of createExtent(class, false) ie how to restrict the query result to the base entity and
+            //not the subclasses
+        }
+    }
+
+    public void testFullRangeSubs() {
+        try {
+            OpenJPAEntityManager em =
+                (OpenJPAEntityManager) currentEntityManager();
+            startTx(em);
+
+            OpenJPAQuery q = em.createQuery(
+                "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC");
+            q.setFirstResult(0);
+            Long l = new Long(Long.MAX_VALUE);
+            q.setMaxResults(l.intValue());
+
+            List res = (List) q.getResultList();
+            assertEquals(6, res.size());
+            for (int i = 0; i < res.size(); i++)
+                assertEquals("TestQueryResults" + (i + 1),
+                    ((RuntimeTest1) res.get(i)).getStringField());
+            q.closeAll();
+            endTx(em);
+            endEm(em);
+        }
+        catch (Exception uoe) {
+        }
+    }
+
+    public void testBeginRange() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+        q.setSubclasses(false);
+        for (int i = 0; i < 4; i++) {
+            q.setFirstResult(i);
+            q.setMaxResults(100000);
+
+            List res = (List) q.getResultList();
+            assertEquals("they are not equal", 3 - i, res.size());
+            int idx = 0;
+
+            // try both random acess and iteration
+            for (int j = 0; j < res.size(); j++)
+                assertEquals("TestQueryResults" + (j * 2 + 1 + i * 2),
+                    (((RuntimeTest1) res.get(j)).getStringField()));
+            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
+                assertEquals("TestQueryResults" + (idx * 2 + 1 + i * 2),
+                    ((RuntimeTest1) itr.next()).getStringField());
+        }
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testBeginRangeSubs() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+
+        for (int i = 0; i < 7; i++) {
+            q.setFirstResult(i);
+            Long l = new Long(Long.MAX_VALUE);
+            q.setMaxResults(100000);
+
+            List res = (List) q.getResultList();
+            assertEquals(6 - i, res.size());
+            int idx = 0;
+
+            // try both random acess and iteration
+            for (int j = 0; j < res.size(); j++)
+                assertEquals("TestQueryResults" + (j + 1 + i),
+                    ((RuntimeTest1) res.get(j)).getStringField());
+            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
+                assertEquals("TestQueryResults" + (idx + 1 + i),
+                    ((RuntimeTest1) itr.next()).getStringField());
+        }
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testEndRange() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+        q.setSubclasses(false);
+
+        for (int i = 0; i < 4; i++) {
+            q.setFirstResult(0);
+            q.setMaxResults(i);
+
+            List res = (List) q.getResultList();
+            assertEquals(i, res.size());
+            int idx = 0;
+
+            // try both random acess and iteration
+            for (int j = 0; j < res.size(); j++)
+                assertEquals("TestQueryResults" + (j * 2 + 1),
+                    ((RuntimeTest1) res.get(j)).getStringField());
+            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
+                assertEquals("TestQueryResults" + (idx * 2 + 1),
+                    ((RuntimeTest1) itr.next()).getStringField());
+        }
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testEndRangeSubs() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+
+        for (int i = 0; i < 7; i++) {
+            q.setFirstResult(0);
+            q.setMaxResults(i);
+            List res = (List) q.getResultList();
+            assertEquals(i, res.size());
+            int idx = 0;
+
+            // try both random acess and iteration
+            for (int j = 0; j < res.size(); j++)
+                assertEquals("TestQueryResults" + (j + 1),
+                    ((RuntimeTest1) res.get(j)).getStringField());
+            for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
+                assertEquals("TestQueryResults" + (idx + 1),
+                    ((RuntimeTest1) itr.next()).getStringField());
+        }
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testMidRange() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+        q.setSubclasses(false);
+
+        q.setFirstResult(1);
+        q.setMaxResults(3);
+        List res = (List) q.getResultList();
+        assertEquals(2, res.size());
+        for (int i = 0; i < res.size(); i++)
+            assertEquals("TestQueryResults" + (i * 2 + 1 + 2),
+                ((RuntimeTest1) res.get(i)).getStringField());
+        int idx = 0;
+        for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
+            assertEquals("TestQueryResults" + (idx * 2 + 1 + 2),
+                ((RuntimeTest1) itr.next()).getStringField());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testMidRangeSubs() {
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+        q.setFirstResult(1);
+        q.setMaxResults(3);
+
+        List res = (List) q.getResultList();
+        assertEquals(3, res.size());
+        for (int i = 0; i < res.size(); i++)
+            assertEquals("TestQueryResults" + (i + 1 + 1),
+                ((RuntimeTest1) res.get(i)).getStringField());
+        int idx = 0;
+        for (Iterator itr = res.iterator(); itr.hasNext(); idx++)
+            assertEquals("TestQueryResults" + (idx + 1 + 1),
+                ((RuntimeTest1) itr.next()).getStringField());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testPessimisticOrderedRange() {
+        // test to make sure whatever machinations we do to get a range doesn't
+        // interfere with FOR UPDATE
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+
+        OpenJPAQuery q = em.createQuery(
+            "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC");
+        q.setSubclasses(false);
+        q.setFirstResult(0);
+        q.setMaxResults(2);
+
+        ((JDBCFetchPlan) q.getFetchPlan()).setEagerFetchMode(FetchMode.NONE);
+
+        List res = (List) q.getResultList();
+        assertEquals(2, res.size());
+        assertEquals("TestQueryResults1",
+            ((RuntimeTest1) res.get(0)).getStringField());
+        assertEquals("TestQueryResults3",
+            ((RuntimeTest1) res.get(1)).getStringField());
+        q.closeAll();
+        endTx(em);
+        endEm(em);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQuotedNumbersInFilters2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQuotedNumbersInFilters2.java
index 4b151e4..9955ee8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQuotedNumbersInFilters2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQuotedNumbersInFilters2.java
@@ -1,198 +1,198 @@
-/*
- * TestQuotedNumbersInFilters.java
- *
- * Created on October 18, 2006, 2:29 PM
- *
- * To change this template, choose Tools | Template Manager
- * and open the template in the editor.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.Query;
-
-
-import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-
-public class TestQuotedNumbersInFilters2 extends BaseQueryTest {
-
-    public TestQuotedNumbersInFilters2(String name) {
-        super(name);
-    }
-
-    public void setUp() {
-        deleteAll(RuntimeTest1.class);
-        OpenJPAEntityManager pm = getEM();
-        startTx(pm);
-        pm.persist(new RuntimeTest1("foo", 3));
-        pm.persist(new RuntimeTest1("bar", 15));
-        pm.persist(new RuntimeTest1("baz", -8));
-        pm.persist(new RuntimeTest1("baz2", 45)); // 45 is '-'
-        pm.persist(new RuntimeTest1("3", (int) '4'));
-        endTx(pm);
-        endEm(pm);
-
-        // make sure everything is working as expected for the base case.
-        assertEquals(1, helper("intField = -8"));
-        assertEquals(1, helper("intField = 15"));
-        assertEquals(1, helper("intField = 3"));
-        assertEquals(0, helper("intField = 51")); // the int value of '3'
-        assertEquals(0, helper("intField = 4"));
-        assertEquals(1, helper("intField = 52")); // the int value of '4'
-        assertEquals(1, helper("stringField = \'foo\'"));
-        assertEquals(1, helper("stringField = \'bar\'"));
-    }
-
-    public void testUnquotedNumbersWithExtraPrecision() {
-        assertEquals(1, helper("intField = 15"));
-        assertEquals(1, helper("intField = -8"));
-        assertEquals(1, helper("intField = 3"));
-        assertEquals(1, helper("intField = 45"));
-
-//    try {
-//        // test without casting ... some DBs don't like this
-////        assertEquals(1, helper("intField = 15.0"));
-////        assertEquals(1, helper("intField = -8.0"));
-//        assertEquals(1, helper("intField = 3.0"));
-//        assertEquals(1, helper("intField = 45.0"));
-//    } catch (Exception jdoe) {
-//        bug(AbstractTestCase.Platform.HYPERSONIC, 414, jdoe,
-//            "Some databases require explicit casts");
-//    }
-    }
-
-    public void testSingleQuotedStrings() {
-        assertEquals(1, helper("stringField = 'foo'"));
-        assertEquals(1, helper("stringField = '3'"));
-    }
-
-    public void testDoubleQuotedStrings() {
-        assertEquals(1, helper("stringField = \'foo\'"));
-        assertEquals(1, helper("stringField = \'3\'"));
-    }
-
-    /**
-     * Kodo 3.1 and prior treated single-quoted numbers as character literals,
-     * to the degree that prepared statement setInt() calls were made.
-     * Only the first digit of multiple-digit single-quoted numbers was used.
-     * FIX ME: aokeke - commenting this --> applies to kodo 3.1 and prior
-     */
-    public void testKodo31SingleQuotedMultipleCharacterBehavior() {
-        assertEquals(0, helper31("intField = '15'", true)); // looks like '1'
-        assertEquals(0, helper31("intField = '52'", true)); // looks like '5'
-        assertEquals(1, helper31("intField = '49'", true)); // looks like '4'
-        assertEquals(1, helper31("intField = '-8'", true)); // looks like '-'
-
-        assertEquals(0, helper31("intField = '15'", false));
-        assertEquals(0, helper31("intField = '52'", false));
-    }
-
-    /**
-     * Kodo 3.1 and prior did not match negative numbers of different types
-     * in in-mem queries.
-     */
-    public void testKodo31UnquotedInMemBehavior() {
-        assertEquals(1, helper31("intField = 3", false));
-        assertEquals(1, helper31("intField = -8", false));
-        assertEquals(1, helper31("intField = 15", false));
-        assertEquals(1, helper31("intField = 45", false));
-    }
-
-    public void testKodo31UnquotedDatastoreBehavior() {
-        assertEquals(1, helper31("intField = 3", false));
-        assertEquals(1, helper31("intField = -8", false));
-        assertEquals(1, helper31("intField = 15", false));
-        assertEquals(1, helper31("intField = 45", false));
-    }
-
-    /**
-     * Returns the # of matches to the query.
-     */
-    private long helper(String filter) {
-        return helper(filter, false);
-    }
-
-    /**
-     * Returns the # of matches to the query. Returns -1 if shouldFail
-     * is true and the query raised an exception in both in-mem and datastore
-     * queries.
-     */
-    private long helper(String filter, boolean shouldFail) {
-        OpenJPAEntityManager pm = getEM();
-
-        OpenJPAQuery q =
-            pm.createQuery("SELECT r FROM RuntimeTest1 r WHERE r." + filter);
-
-        long datastore = getResults(q, shouldFail);
-
-        q.setCandidateCollection((Collection) q.getResultList());
-        long inmem = getResults(q, shouldFail);
-
-        if (datastore != inmem)
-            fail("datastore query returned " + datastore + " values; " +
-                "inmem query returned " + inmem);
-
-        endEm(pm);
-        return datastore;
-    }
-
-    /**
-     * Returns the # of matches to the query. Performs the query in datastore
-     * or memory as appropriate.
-     */
-    private long helper31(String filter, boolean datastore) {
-        Map props = new HashMap();
-        props.put("openjpa.Compatibility", "QuotedNumbersInQueries=true");
-        OpenJPAEntityManager pm = getEmf(props).createEntityManager();
-
-        try {
-            OpenJPAQuery q = pm.createQuery(
-                "SELECT r FROM RuntimeTest1 r WHERE r." + filter);
-
-            if (!datastore)
-                q.setCandidateCollection((Collection) q.getResultList());
-            return getResults(q, false);
-        }
-        finally {
-            endEm(pm);
-        }
-    }
-
-    private long getResults(Query q, boolean shouldFail) {
-        try {
-
-            Integer result = new Integer(q.getResultList().size());
-            if (shouldFail) {
-                fail("should have failed");
-            }
-
-            return ((Number) result).longValue();
-        } catch (IllegalArgumentException e) {
-            if (!shouldFail)
-                throw e;
-            return -1;
-        }
-    }
-}
+/*
+ * TestQuotedNumbersInFilters.java
+ *
+ * Created on October 18, 2006, 2:29 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.Query;
+
+
+import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+public class TestQuotedNumbersInFilters2 extends BaseQueryTest {
+
+    public TestQuotedNumbersInFilters2(String name) {
+        super(name);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        OpenJPAEntityManager pm = getEM();
+        startTx(pm);
+        pm.persist(new RuntimeTest1("foo", 3));
+        pm.persist(new RuntimeTest1("bar", 15));
+        pm.persist(new RuntimeTest1("baz", -8));
+        pm.persist(new RuntimeTest1("baz2", 45)); // 45 is '-'
+        pm.persist(new RuntimeTest1("3", (int) '4'));
+        endTx(pm);
+        endEm(pm);
+
+        // make sure everything is working as expected for the base case.
+        assertEquals(1, helper("intField = -8"));
+        assertEquals(1, helper("intField = 15"));
+        assertEquals(1, helper("intField = 3"));
+        assertEquals(0, helper("intField = 51")); // the int value of '3'
+        assertEquals(0, helper("intField = 4"));
+        assertEquals(1, helper("intField = 52")); // the int value of '4'
+        assertEquals(1, helper("stringField = \'foo\'"));
+        assertEquals(1, helper("stringField = \'bar\'"));
+    }
+
+    public void testUnquotedNumbersWithExtraPrecision() {
+        assertEquals(1, helper("intField = 15"));
+        assertEquals(1, helper("intField = -8"));
+        assertEquals(1, helper("intField = 3"));
+        assertEquals(1, helper("intField = 45"));
+
+//    try {
+//        // test without casting ... some DBs don't like this
+////        assertEquals(1, helper("intField = 15.0"));
+////        assertEquals(1, helper("intField = -8.0"));
+//        assertEquals(1, helper("intField = 3.0"));
+//        assertEquals(1, helper("intField = 45.0"));
+//    } catch (Exception jdoe) {
+//        bug(AbstractTestCase.Platform.HYPERSONIC, 414, jdoe,
+//            "Some databases require explicit casts");
+//    }
+    }
+
+    public void testSingleQuotedStrings() {
+        assertEquals(1, helper("stringField = 'foo'"));
+        assertEquals(1, helper("stringField = '3'"));
+    }
+
+    public void testDoubleQuotedStrings() {
+        assertEquals(1, helper("stringField = \'foo\'"));
+        assertEquals(1, helper("stringField = \'3\'"));
+    }
+
+    /**
+     * Kodo 3.1 and prior treated single-quoted numbers as character literals,
+     * to the degree that prepared statement setInt() calls were made.
+     * Only the first digit of multiple-digit single-quoted numbers was used.
+     * FIX ME: aokeke - commenting this --> applies to kodo 3.1 and prior
+     */
+    public void testKodo31SingleQuotedMultipleCharacterBehavior() {
+        assertEquals(0, helper31("intField = '15'", true)); // looks like '1'
+        assertEquals(0, helper31("intField = '52'", true)); // looks like '5'
+        assertEquals(1, helper31("intField = '49'", true)); // looks like '4'
+        assertEquals(1, helper31("intField = '-8'", true)); // looks like '-'
+
+        assertEquals(0, helper31("intField = '15'", false));
+        assertEquals(0, helper31("intField = '52'", false));
+    }
+
+    /**
+     * Kodo 3.1 and prior did not match negative numbers of different types
+     * in in-mem queries.
+     */
+    public void testKodo31UnquotedInMemBehavior() {
+        assertEquals(1, helper31("intField = 3", false));
+        assertEquals(1, helper31("intField = -8", false));
+        assertEquals(1, helper31("intField = 15", false));
+        assertEquals(1, helper31("intField = 45", false));
+    }
+
+    public void testKodo31UnquotedDatastoreBehavior() {
+        assertEquals(1, helper31("intField = 3", false));
+        assertEquals(1, helper31("intField = -8", false));
+        assertEquals(1, helper31("intField = 15", false));
+        assertEquals(1, helper31("intField = 45", false));
+    }
+
+    /**
+     * Returns the # of matches to the query.
+     */
+    private long helper(String filter) {
+        return helper(filter, false);
+    }
+
+    /**
+     * Returns the # of matches to the query. Returns -1 if shouldFail
+     * is true and the query raised an exception in both in-mem and datastore
+     * queries.
+     */
+    private long helper(String filter, boolean shouldFail) {
+        OpenJPAEntityManager pm = getEM();
+
+        OpenJPAQuery q =
+            pm.createQuery("SELECT r FROM RuntimeTest1 r WHERE r." + filter);
+
+        long datastore = getResults(q, shouldFail);
+
+        q.setCandidateCollection((Collection) q.getResultList());
+        long inmem = getResults(q, shouldFail);
+
+        if (datastore != inmem)
+            fail("datastore query returned " + datastore + " values; " +
+                "inmem query returned " + inmem);
+
+        endEm(pm);
+        return datastore;
+    }
+
+    /**
+     * Returns the # of matches to the query. Performs the query in datastore
+     * or memory as appropriate.
+     */
+    private long helper31(String filter, boolean datastore) {
+        Map props = new HashMap();
+        props.put("openjpa.Compatibility", "QuotedNumbersInQueries=true");
+        OpenJPAEntityManager pm = getEmf(props).createEntityManager();
+
+        try {
+            OpenJPAQuery q = pm.createQuery(
+                "SELECT r FROM RuntimeTest1 r WHERE r." + filter);
+
+            if (!datastore)
+                q.setCandidateCollection((Collection) q.getResultList());
+            return getResults(q, false);
+        }
+        finally {
+            endEm(pm);
+        }
+    }
+
+    private long getResults(Query q, boolean shouldFail) {
+        try {
+
+            Integer result = new Integer(q.getResultList().size());
+            if (shouldFail) {
+                fail("should have failed");
+            }
+
+            return ((Number) result).longValue();
+        } catch (IllegalArgumentException e) {
+            if (!shouldFail)
+                throw e;
+            return -1;
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSimple.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSimple.java
index d0a90c3..bae923d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSimple.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSimple.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query;
-
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-
-import org.apache.openjpa.persistence.query.common.apps.Entity1;
-
-public class TestSimple extends BaseQueryTest {
-
-    private Query q = null;
-
-    public TestSimple(String test) {
-        super(test);
-    }
-
-    public void setUp() {
-        deleteAll(Entity1.class);
-    }
-
-    public void testSimple() throws java.io.IOException {
-        // test create
-        {
-            EntityManager em = currentEntityManager();
-            startTx(em);
-            em.persist(new Entity1(0, "testSimple", 12));
-            endTx(em);
-            endEm(em);
-        }
-
-        // test Query
-        {
-            EntityManager em = currentEntityManager();
-            startTx(em);
-            List l = em.createQuery("SELECT o FROM Entity1 o "
-                + "WHERE o.stringField = 'testSimple'").getResultList();
-            assertSize(1, l);
-            endTx(em);
-            endEm(em);
-        }
-
-        // test Update
-        {
-            EntityManager em = currentEntityManager();
-            startTx(em);
-            ((Entity1) em.createQuery("SELECT o FROM Entity1 o "
-                + "WHERE o.stringField = 'testSimple'").getSingleResult())
-                .setStringField("testSimple2");
-            endTx(em);
-            endEm(em);
-
-            em = currentEntityManager();
-            startTx(em);
-            q = em.createQuery("SELECT o FROM Entity1 o "
-                + "WHERE o.stringField = 'testSimple'");
-            assertSize(0, q);
-            q = em.createQuery("SELECT o FROM Entity1 o "
-                + "WHERE o.stringField = 'testSimple2'");
-            assertSize(1, q);
-            endTx(em);
-            endEm(em);
-        }
-
-        // test delete
-        {
-            EntityManager em = currentEntityManager();
-            startTx(em);
-            em.remove(em.createQuery("SELECT o FROM Entity1 o "
-                + "WHERE o.stringField = 'testSimple2'").getSingleResult());
-            endTx(em);
-            endEm(em);
-
-            em = currentEntityManager();
-            startTx(em);
-
-            q = em.createQuery("SELECT o FROM Entity1 o "
-                + "WHERE o.stringField = 'testSimple2'");
-            assertSize(0, q);
-            endTx(em);
-            endEm(em);
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+
+import org.apache.openjpa.persistence.query.common.apps.Entity1;
+
+public class TestSimple extends BaseQueryTest {
+
+    private Query q = null;
+
+    public TestSimple(String test) {
+        super(test);
+    }
+
+    public void setUp() {
+        deleteAll(Entity1.class);
+    }
+
+    public void testSimple() throws java.io.IOException {
+        // test create
+        {
+            EntityManager em = currentEntityManager();
+            startTx(em);
+            em.persist(new Entity1(0, "testSimple", 12));
+            endTx(em);
+            endEm(em);
+        }
+
+        // test Query
+        {
+            EntityManager em = currentEntityManager();
+            startTx(em);
+            List l = em.createQuery("SELECT o FROM Entity1 o "
+                + "WHERE o.stringField = 'testSimple'").getResultList();
+            assertSize(1, l);
+            endTx(em);
+            endEm(em);
+        }
+
+        // test Update
+        {
+            EntityManager em = currentEntityManager();
+            startTx(em);
+            ((Entity1) em.createQuery("SELECT o FROM Entity1 o "
+                + "WHERE o.stringField = 'testSimple'").getSingleResult())
+                .setStringField("testSimple2");
+            endTx(em);
+            endEm(em);
+
+            em = currentEntityManager();
+            startTx(em);
+            q = em.createQuery("SELECT o FROM Entity1 o "
+                + "WHERE o.stringField = 'testSimple'");
+            assertSize(0, q);
+            q = em.createQuery("SELECT o FROM Entity1 o "
+                + "WHERE o.stringField = 'testSimple2'");
+            assertSize(1, q);
+            endTx(em);
+            endEm(em);
+        }
+
+        // test delete
+        {
+            EntityManager em = currentEntityManager();
+            startTx(em);
+            em.remove(em.createQuery("SELECT o FROM Entity1 o "
+                + "WHERE o.stringField = 'testSimple2'").getSingleResult());
+            endTx(em);
+            endEm(em);
+
+            em = currentEntityManager();
+            startTx(em);
+
+            q = em.createQuery("SELECT o FROM Entity1 o "
+                + "WHERE o.stringField = 'testSimple2'");
+            assertSize(0, q);
+            endTx(em);
+            endEm(em);
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java
index d643ae5..fda1219 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java
@@ -1,62 +1,62 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.query;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestSubstring extends SingleEMTestCase {
-
-    public void setUp() {
-        super.setUp(SimpleEntity.class, CLEAR_TABLES,
-            "openjpa.Compatibility", "JPQL=extended");
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(new SimpleEntity("foo", "bar"));
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testSingleCharacterSubstringInWhere() {
-        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
-            "where substring(o.value, 1, 1) = 'b'").getSingleResult());
-        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
-            "where substring(o.value, 2, 1) = 'a'").getSingleResult());
-        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
-            "where substring(o.value, 3, 1) = 'r'").getSingleResult());
-    }
-
-    public void testMultiCharacterSubstringInWhere() {
-        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
-            "where substring(o.value, 1, 2) = 'ba'").getSingleResult());
-        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
-            "where substring(o.value, 2, 2) = 'ar'").getSingleResult());
-    }
-
-    public void testSubstringInSelect() {
-        assertEquals("b", em.createQuery("select substring(o.value, 1, 1) " +
-            "from simple o").getSingleResult());
-        assertEquals("a", em.createQuery("select substring(o.value, 2, 1) " +
-            "from simple o").getSingleResult());
-        assertEquals("r", em.createQuery("select substring(o.value, 3, 1) " +
-            "from simple o").getSingleResult());
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.query;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestSubstring extends SingleEMTestCase {
+
+    public void setUp() {
+        super.setUp(SimpleEntity.class, CLEAR_TABLES,
+            "openjpa.Compatibility", "JPQL=extended");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(new SimpleEntity("foo", "bar"));
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testSingleCharacterSubstringInWhere() {
+        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
+            "where substring(o.value, 1, 1) = 'b'").getSingleResult());
+        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
+            "where substring(o.value, 2, 1) = 'a'").getSingleResult());
+        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
+            "where substring(o.value, 3, 1) = 'r'").getSingleResult());
+    }
+
+    public void testMultiCharacterSubstringInWhere() {
+        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
+            "where substring(o.value, 1, 2) = 'ba'").getSingleResult());
+        assertEquals((long) 1, em.createQuery("select count(o) from simple o " +
+            "where substring(o.value, 2, 2) = 'ar'").getSingleResult());
+    }
+
+    public void testSubstringInSelect() {
+        assertEquals("b", em.createQuery("select substring(o.value, 1, 1) " +
+            "from simple o").getSingleResult());
+        assertEquals("a", em.createQuery("select substring(o.value, 2, 1) " +
+            "from simple o").getSingleResult());
+        assertEquals("r", em.createQuery("select substring(o.value, 3, 1) " +
+            "from simple o").getSingleResult());
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC.java
index 60ae06b..b439aea 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-
-import javax.persistence.Entity;
-
-@Entity
-public class CircularFKPC {
-
-    private String stringField;
-    private CircularFKPC2 fkField;
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public CircularFKPC2 getFKField() {
-        return this.fkField;
-    }
-
-    public void setFKField(CircularFKPC2 fkField) {
-        this.fkField = fkField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+
+import javax.persistence.Entity;
+
+@Entity
+public class CircularFKPC {
+
+    private String stringField;
+    private CircularFKPC2 fkField;
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public CircularFKPC2 getFKField() {
+        return this.fkField;
+    }
+
+    public void setFKField(CircularFKPC2 fkField) {
+        this.fkField = fkField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC2.java
index 16bc673..d7bd261 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CircularFKPC2.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-/**
- * <p>Persistent type used in testing.</p>
- *
- * @author Abe White
- */
-
-import javax.persistence.Entity;
-
-@Entity
-public class CircularFKPC2 {
-
-    private String stringField;
-    private CircularFKPC fkField;
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public CircularFKPC getFKField() {
-        return this.fkField;
-    }
-
-    public void setFKField(CircularFKPC fkField) {
-        this.fkField = fkField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+/**
+ * <p>Persistent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+
+import javax.persistence.Entity;
+
+@Entity
+public class CircularFKPC2 {
+
+    private String stringField;
+    private CircularFKPC fkField;
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public CircularFKPC getFKField() {
+        return this.fkField;
+    }
+
+    public void setFKField(CircularFKPC fkField) {
+        this.fkField = fkField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexA.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexA.java
index ad57a9e..713af3f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexA.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexA.java
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedList;
-import javax.persistence.Entity;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexA {
-
-    private String stringA;
-    private int intA;
-    @Temporal(TemporalType.DATE)
-    private Date dateA;
-    private Collection bs = new LinkedList();
-
-    public ComplexA() {
-
-    }
-
-    public ComplexA(String stringA, int intA, Date dateA, ComplexB[] bs) {
-        this.stringA = stringA;
-        this.intA = intA;
-        this.dateA = dateA;
-        if (bs != null)
-            this.bs.addAll(Arrays.asList(bs));
-    }
-
-    public void setStringA(String stringA) {
-        this.stringA = stringA;
-    }
-
-    public String getStringA() {
-        return this.stringA;
-    }
-
-    public void setIntA(int intA) {
-        this.intA = intA;
-    }
-
-    public int getIntA() {
-        return this.intA;
-    }
-
-    public void setDateA(Date dateA) {
-        this.dateA = dateA;
-    }
-
-    public Date getDateA() {
-        return this.dateA;
-    }
-
-    public void setBs(Collection bs) {
-        this.bs = bs;
-    }
-
-    public Collection getBs() {
-        return this.bs;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import javax.persistence.Entity;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexA {
+
+    private String stringA;
+    private int intA;
+    @Temporal(TemporalType.DATE)
+    private Date dateA;
+    private Collection bs = new LinkedList();
+
+    public ComplexA() {
+
+    }
+
+    public ComplexA(String stringA, int intA, Date dateA, ComplexB[] bs) {
+        this.stringA = stringA;
+        this.intA = intA;
+        this.dateA = dateA;
+        if (bs != null)
+            this.bs.addAll(Arrays.asList(bs));
+    }
+
+    public void setStringA(String stringA) {
+        this.stringA = stringA;
+    }
+
+    public String getStringA() {
+        return this.stringA;
+    }
+
+    public void setIntA(int intA) {
+        this.intA = intA;
+    }
+
+    public int getIntA() {
+        return this.intA;
+    }
+
+    public void setDateA(Date dateA) {
+        this.dateA = dateA;
+    }
+
+    public Date getDateA() {
+        return this.dateA;
+    }
+
+    public void setBs(Collection bs) {
+        this.bs = bs;
+    }
+
+    public Collection getBs() {
+        return this.bs;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexB.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexB.java
index 5fd7930..1c00962 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexB.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexB.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexB
-    extends ComplexA {
-
-    private String stringB;
-    private int intB;
-    @Temporal(TemporalType.DATE)
-    private Date dateB;
-    private Collection cs = new ArrayList();
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ComplexA a;
-
-    public ComplexB() {
-
-    }
-
-    public ComplexB(String stringB, int intB, Date dateB, ComplexC[] cs,
-        ComplexA a) {
-        this.stringB = stringB;
-        this.intB = intB;
-        this.dateB = dateB;
-        if (cs != null)
-            this.cs.addAll(Arrays.asList(cs));
-        this.a = a;
-    }
-
-    public void setStringB(String stringB) {
-        this.stringB = stringB;
-    }
-
-    public String getStringB() {
-        return this.stringB;
-    }
-
-    public void setIntB(int intB) {
-        this.intB = intB;
-    }
-
-    public int getIntB() {
-        return this.intB;
-    }
-
-    public void setDateB(Date dateB) {
-        this.dateB = dateB;
-    }
-
-    public Date getDateB() {
-        return this.dateB;
-    }
-
-    public void setCs(Collection cs) {
-        this.cs = cs;
-    }
-
-    public Collection getCs() {
-        return this.cs;
-    }
-
-    public void setA(ComplexA a) {
-        this.a = a;
-    }
-
-    public ComplexA getA() {
-        return this.a;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexB
+    extends ComplexA {
+
+    private String stringB;
+    private int intB;
+    @Temporal(TemporalType.DATE)
+    private Date dateB;
+    private Collection cs = new ArrayList();
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ComplexA a;
+
+    public ComplexB() {
+
+    }
+
+    public ComplexB(String stringB, int intB, Date dateB, ComplexC[] cs,
+        ComplexA a) {
+        this.stringB = stringB;
+        this.intB = intB;
+        this.dateB = dateB;
+        if (cs != null)
+            this.cs.addAll(Arrays.asList(cs));
+        this.a = a;
+    }
+
+    public void setStringB(String stringB) {
+        this.stringB = stringB;
+    }
+
+    public String getStringB() {
+        return this.stringB;
+    }
+
+    public void setIntB(int intB) {
+        this.intB = intB;
+    }
+
+    public int getIntB() {
+        return this.intB;
+    }
+
+    public void setDateB(Date dateB) {
+        this.dateB = dateB;
+    }
+
+    public Date getDateB() {
+        return this.dateB;
+    }
+
+    public void setCs(Collection cs) {
+        this.cs = cs;
+    }
+
+    public Collection getCs() {
+        return this.cs;
+    }
+
+    public void setA(ComplexA a) {
+        this.a = a;
+    }
+
+    public ComplexA getA() {
+        return this.a;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexC.java
index ab5f519..dfc0ab9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexC.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexC
-    extends ComplexB {
-
-    private String stringC;
-    private int intC;
-    @Temporal(TemporalType.DATE)
-    private Date dateC;
-    private Set ds = new HashSet();
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ComplexB b;
-
-    public ComplexC() {
-
-    }
-
-    public ComplexC(String stringC, int intC, Date dateC, ComplexD[] ds,
-        ComplexB b) {
-        this.stringC = stringC;
-        this.intC = intC;
-        this.dateC = dateC;
-        if (ds != null)
-            this.ds.addAll(Arrays.asList(ds));
-        this.b = b;
-    }
-
-    public void setStringC(String stringC) {
-        this.stringC = stringC;
-    }
-
-    public String getStringC() {
-        return this.stringC;
-    }
-
-    public void setIntC(int intC) {
-        this.intC = intC;
-    }
-
-    public int getIntC() {
-        return this.intC;
-    }
-
-    public void setDateC(Date dateC) {
-        this.dateC = dateC;
-    }
-
-    public Date getDateC() {
-        return this.dateC;
-    }
-
-    public void setDs(Set ds) {
-        this.ds = ds;
-    }
-
-    public Set getDs() {
-        return this.ds;
-    }
-
-    public void setB(ComplexB b) {
-        this.b = b;
-    }
-
-    public ComplexB getB() {
-        return this.b;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexC
+    extends ComplexB {
+
+    private String stringC;
+    private int intC;
+    @Temporal(TemporalType.DATE)
+    private Date dateC;
+    private Set ds = new HashSet();
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ComplexB b;
+
+    public ComplexC() {
+
+    }
+
+    public ComplexC(String stringC, int intC, Date dateC, ComplexD[] ds,
+        ComplexB b) {
+        this.stringC = stringC;
+        this.intC = intC;
+        this.dateC = dateC;
+        if (ds != null)
+            this.ds.addAll(Arrays.asList(ds));
+        this.b = b;
+    }
+
+    public void setStringC(String stringC) {
+        this.stringC = stringC;
+    }
+
+    public String getStringC() {
+        return this.stringC;
+    }
+
+    public void setIntC(int intC) {
+        this.intC = intC;
+    }
+
+    public int getIntC() {
+        return this.intC;
+    }
+
+    public void setDateC(Date dateC) {
+        this.dateC = dateC;
+    }
+
+    public Date getDateC() {
+        return this.dateC;
+    }
+
+    public void setDs(Set ds) {
+        this.ds = ds;
+    }
+
+    public Set getDs() {
+        return this.ds;
+    }
+
+    public void setB(ComplexB b) {
+        this.b = b;
+    }
+
+    public ComplexB getB() {
+        return this.b;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexD.java
index 1ac2e03..f779867 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexD.java
@@ -1,96 +1,96 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexD {
-
-    private String stringD;
-    private int intD;
-    @Temporal(TemporalType.DATE)
-    private Date dateD;
-    private Set es = new TreeSet();
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ComplexC c;
-
-    public ComplexD() {
-
-    }
-
-    public ComplexD(String stringD, int intD, Date dateD, ComplexE[] es,
-        ComplexC c) {
-        this.stringD = stringD;
-        this.intD = intD;
-        this.dateD = dateD;
-        if (es != null)
-            this.es.addAll(Arrays.asList(es));
-        this.c = c;
-    }
-
-    public void setStringD(String stringD) {
-        this.stringD = stringD;
-    }
-
-    public String getStringD() {
-        return this.stringD;
-    }
-
-    public void setIntD(int intD) {
-        this.intD = intD;
-    }
-
-    public int getIntD() {
-        return this.intD;
-    }
-
-    public void setDateD(Date dateD) {
-        this.dateD = dateD;
-    }
-
-    public Date getDateD() {
-        return this.dateD;
-    }
-
-    public void setEs(Set es) {
-        this.es = es;
-    }
-
-    public Set getEs() {
-        return this.es;
-    }
-
-    public void setC(ComplexC c) {
-        this.c = c;
-    }
-
-    public ComplexC getC() {
-        return this.c;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexD {
+
+    private String stringD;
+    private int intD;
+    @Temporal(TemporalType.DATE)
+    private Date dateD;
+    private Set es = new TreeSet();
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ComplexC c;
+
+    public ComplexD() {
+
+    }
+
+    public ComplexD(String stringD, int intD, Date dateD, ComplexE[] es,
+        ComplexC c) {
+        this.stringD = stringD;
+        this.intD = intD;
+        this.dateD = dateD;
+        if (es != null)
+            this.es.addAll(Arrays.asList(es));
+        this.c = c;
+    }
+
+    public void setStringD(String stringD) {
+        this.stringD = stringD;
+    }
+
+    public String getStringD() {
+        return this.stringD;
+    }
+
+    public void setIntD(int intD) {
+        this.intD = intD;
+    }
+
+    public int getIntD() {
+        return this.intD;
+    }
+
+    public void setDateD(Date dateD) {
+        this.dateD = dateD;
+    }
+
+    public Date getDateD() {
+        return this.dateD;
+    }
+
+    public void setEs(Set es) {
+        this.es = es;
+    }
+
+    public Set getEs() {
+        return this.es;
+    }
+
+    public void setC(ComplexC c) {
+        this.c = c;
+    }
+
+    public ComplexC getC() {
+        return this.c;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexE.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexE.java
index 61e964c..388aa1f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexE.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexE.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedList;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexE
-    extends ComplexD {
-
-    private String stringE;
-    private int intE;
-    @Temporal(TemporalType.DATE)
-    private Date dateE;
-    private Collection fs = new LinkedList();
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ComplexD d;
-
-    public ComplexE() {
-
-    }
-
-    public ComplexE(String stringE, int intE, Date dateE, ComplexF[] fs,
-        ComplexD d) {
-        this.stringE = stringE;
-        this.intE = intE;
-        this.dateE = dateE;
-        if (fs != null)
-            this.fs.addAll(Arrays.asList(fs));
-        this.d = d;
-    }
-
-    public void setStringE(String stringE) {
-        this.stringE = stringE;
-    }
-
-    public String getStringE() {
-        return this.stringE;
-    }
-
-    public void setIntE(int intE) {
-        this.intE = intE;
-    }
-
-    public int getIntE() {
-        return this.intE;
-    }
-
-    public void setDateE(Date dateE) {
-        this.dateE = dateE;
-    }
-
-    public Date getDateE() {
-        return this.dateE;
-    }
-
-    public void setFs(Collection fs) {
-        this.fs = fs;
-    }
-
-    public Collection getFs() {
-        return this.fs;
-    }
-
-    public void setD(ComplexD d) {
-        this.d = d;
-    }
-
-    public ComplexD getD() {
-        return this.d;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexE
+    extends ComplexD {
+
+    private String stringE;
+    private int intE;
+    @Temporal(TemporalType.DATE)
+    private Date dateE;
+    private Collection fs = new LinkedList();
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ComplexD d;
+
+    public ComplexE() {
+
+    }
+
+    public ComplexE(String stringE, int intE, Date dateE, ComplexF[] fs,
+        ComplexD d) {
+        this.stringE = stringE;
+        this.intE = intE;
+        this.dateE = dateE;
+        if (fs != null)
+            this.fs.addAll(Arrays.asList(fs));
+        this.d = d;
+    }
+
+    public void setStringE(String stringE) {
+        this.stringE = stringE;
+    }
+
+    public String getStringE() {
+        return this.stringE;
+    }
+
+    public void setIntE(int intE) {
+        this.intE = intE;
+    }
+
+    public int getIntE() {
+        return this.intE;
+    }
+
+    public void setDateE(Date dateE) {
+        this.dateE = dateE;
+    }
+
+    public Date getDateE() {
+        return this.dateE;
+    }
+
+    public void setFs(Collection fs) {
+        this.fs = fs;
+    }
+
+    public Collection getFs() {
+        return this.fs;
+    }
+
+    public void setD(ComplexD d) {
+        this.d = d;
+    }
+
+    public ComplexD getD() {
+        return this.d;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexF.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexF.java
index 0c50bbc..39217b2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexF.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexF.java
@@ -1,97 +1,97 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexF
-    extends ComplexE {
-
-    private String stringF;
-    private int intF;
-    @Temporal(TemporalType.DATE)
-    private Date dateF;
-    private Collection gs = new HashSet();
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ComplexE e;
-
-    public ComplexF() {
-
-    }
-
-    public ComplexF(String stringF, int intF, Date dateF, ComplexG[] gs,
-        ComplexE e) {
-        this.stringF = stringF;
-        this.intF = intF;
-        this.dateF = dateF;
-        if (gs != null)
-            this.gs.addAll(Arrays.asList(gs));
-        this.e = e;
-    }
-
-    public void setStringF(String stringF) {
-        this.stringF = stringF;
-    }
-
-    public String getStringF() {
-        return this.stringF;
-    }
-
-    public void setIntF(int intF) {
-        this.intF = intF;
-    }
-
-    public int getIntF() {
-        return this.intF;
-    }
-
-    public void setDateF(Date dateF) {
-        this.dateF = dateF;
-    }
-
-    public Date getDateF() {
-        return this.dateF;
-    }
-
-    public void setGs(Collection gs) {
-        this.gs = gs;
-    }
-
-    public Collection getGs() {
-        return this.gs;
-    }
-
-    public void setE(ComplexE e) {
-        this.e = e;
-    }
-
-    public ComplexE getE() {
-        return this.e;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexF
+    extends ComplexE {
+
+    private String stringF;
+    private int intF;
+    @Temporal(TemporalType.DATE)
+    private Date dateF;
+    private Collection gs = new HashSet();
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ComplexE e;
+
+    public ComplexF() {
+
+    }
+
+    public ComplexF(String stringF, int intF, Date dateF, ComplexG[] gs,
+        ComplexE e) {
+        this.stringF = stringF;
+        this.intF = intF;
+        this.dateF = dateF;
+        if (gs != null)
+            this.gs.addAll(Arrays.asList(gs));
+        this.e = e;
+    }
+
+    public void setStringF(String stringF) {
+        this.stringF = stringF;
+    }
+
+    public String getStringF() {
+        return this.stringF;
+    }
+
+    public void setIntF(int intF) {
+        this.intF = intF;
+    }
+
+    public int getIntF() {
+        return this.intF;
+    }
+
+    public void setDateF(Date dateF) {
+        this.dateF = dateF;
+    }
+
+    public Date getDateF() {
+        return this.dateF;
+    }
+
+    public void setGs(Collection gs) {
+        this.gs = gs;
+    }
+
+    public Collection getGs() {
+        return this.gs;
+    }
+
+    public void setE(ComplexE e) {
+        this.e = e;
+    }
+
+    public ComplexE getE() {
+        return this.e;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexG.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexG.java
index 98eac8c..c1283f5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexG.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ComplexG.java
@@ -1,82 +1,82 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Date;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-public class ComplexG
-    extends ComplexE {
-
-    private String stringG;
-    private int intG;
-    @Temporal(TemporalType.DATE)
-    private Date dateG;
-    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ComplexF f;
-
-    public ComplexG() {
-
-    }
-
-    public ComplexG(String stringG, int intG, Date dateG, ComplexF f) {
-        this.stringG = stringG;
-        this.intG = intG;
-        this.dateG = dateG;
-        this.f = f;
-    }
-
-    public void setStringG(String stringG) {
-        this.stringG = stringG;
-    }
-
-    public String getStringG() {
-        return this.stringG;
-    }
-
-    public void setIntG(int intG) {
-        this.intG = intG;
-    }
-
-    public int getIntG() {
-        return this.intG;
-    }
-
-    public void setDateG(Date dateG) {
-        this.dateG = dateG;
-    }
-
-    public Date getDateG() {
-        return this.dateG;
-    }
-
-    public void setF(ComplexF f) {
-        this.f = f;
-    }
-
-    public ComplexF getF() {
-        return this.f;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Date;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+public class ComplexG
+    extends ComplexE {
+
+    private String stringG;
+    private int intG;
+    @Temporal(TemporalType.DATE)
+    private Date dateG;
+    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ComplexF f;
+
+    public ComplexG() {
+
+    }
+
+    public ComplexG(String stringG, int intG, Date dateG, ComplexF f) {
+        this.stringG = stringG;
+        this.intG = intG;
+        this.dateG = dateG;
+        this.f = f;
+    }
+
+    public void setStringG(String stringG) {
+        this.stringG = stringG;
+    }
+
+    public String getStringG() {
+        return this.stringG;
+    }
+
+    public void setIntG(int intG) {
+        this.intG = intG;
+    }
+
+    public int getIntG() {
+        return this.intG;
+    }
+
+    public void setDateG(Date dateG) {
+        this.dateG = dateG;
+    }
+
+    public Date getDateG() {
+        return this.dateG;
+    }
+
+    public void setF(ComplexF f) {
+        this.f = f;
+    }
+
+    public ComplexF getF() {
+        return this.f;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CompoundAppIdPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CompoundAppIdPC.java
index 96592f0..b8a0755 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CompoundAppIdPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/CompoundAppIdPC.java
@@ -1,111 +1,111 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-
-/**
- * <p>Application identity type with a compound primary key.</p>
- *
- * @author Abe White
- */
-
-@Entity
-@IdClass(CompoundAppIdPC.Idkey.class)
-public class CompoundAppIdPC {
-
-    @Id
-    private String pk1;
-
-    @Id
-    private int pk2;
-
-    private int intField;
-
-    public String getPk1() {
-        return this.pk1;
-    }
-
-    public void setPk1(String pk1) {
-        this.pk1 = pk1;
-    }
-
-    public int getPk2() {
-        return this.pk2;
-    }
-
-    public void setPk2(int pk2) {
-        this.pk2 = pk2;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public static class Idkey implements Serializable {
-
-        public String pk1;
-        public int pk2;
-
-        public Idkey() {
-        }
-
-        public Idkey(String str) {
-            int index = str.indexOf("/");
-            if (index != -1) {
-                pk2 = Integer.parseInt(str.substring(0, index));
-                pk1 = str.substring(index + 1);
-            }
-        }
-
-        public String toString() {
-            return pk2 + "/" + pk1;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof Idkey))
-                return false;
-
-            Idkey id = (Idkey) other;
-            if (pk1 == null && id.pk1 != null)
-                return false;
-            if (pk1 != null && id.pk1 == null)
-                return false;
-            if (!(pk1 == id.pk1))
-                return false;
-            if (!(pk1.equals(id.pk1)))
-                return false;
-
-            return true;
-        }
-
-        @Override
-        public int hashCode() {
-            return (pk2 + pk1).hashCode();
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+
+/**
+ * <p>Application identity type with a compound primary key.</p>
+ *
+ * @author Abe White
+ */
+
+@Entity
+@IdClass(CompoundAppIdPC.Idkey.class)
+public class CompoundAppIdPC {
+
+    @Id
+    private String pk1;
+
+    @Id
+    private int pk2;
+
+    private int intField;
+
+    public String getPk1() {
+        return this.pk1;
+    }
+
+    public void setPk1(String pk1) {
+        this.pk1 = pk1;
+    }
+
+    public int getPk2() {
+        return this.pk2;
+    }
+
+    public void setPk2(int pk2) {
+        this.pk2 = pk2;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public static class Idkey implements Serializable {
+
+        public String pk1;
+        public int pk2;
+
+        public Idkey() {
+        }
+
+        public Idkey(String str) {
+            int index = str.indexOf("/");
+            if (index != -1) {
+                pk2 = Integer.parseInt(str.substring(0, index));
+                pk1 = str.substring(index + 1);
+            }
+        }
+
+        public String toString() {
+            return pk2 + "/" + pk1;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof Idkey))
+                return false;
+
+            Idkey id = (Idkey) other;
+            if (pk1 == null && id.pk1 != null)
+                return false;
+            if (pk1 != null && id.pk1 == null)
+                return false;
+            if (!(pk1 == id.pk1))
+                return false;
+            if (!(pk1.equals(id.pk1)))
+                return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return (pk2 + pk1).hashCode();
+        }
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity1.java
index b14ce31..33df25f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity1.java
@@ -1,104 +1,104 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EntityResult;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToOne;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name = "entity_1")
-@Inheritance(strategy = InheritanceType.JOINED)
-@SqlResultSetMapping(name = "NativeTestResult",
-    entities = @EntityResult(entityClass = Entity1.class))
-@NamedQuery(name = "setParam1",
-    query = "SELECT o FROM Entity1 o WHERE o.stringField = :fld")
-public class Entity1 implements Serializable {
-
-    private static final long serialVersionUID = 2882935803066041165L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
-    protected Entity2 entity2Field;
-
-    @Version
-    protected int versionField;
-
-    public Entity1() {
-    }
-
-    public Entity1(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public void setEntity2Field(Entity2 val) {
-        entity2Field = val;
-    }
-
-    public Entity2 getEntity2Field() {
-        return entity2Field;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "entity_1")
+@Inheritance(strategy = InheritanceType.JOINED)
+@SqlResultSetMapping(name = "NativeTestResult",
+    entities = @EntityResult(entityClass = Entity1.class))
+@NamedQuery(name = "setParam1",
+    query = "SELECT o FROM Entity1 o WHERE o.stringField = :fld")
+public class Entity1 implements Serializable {
+
+    private static final long serialVersionUID = 2882935803066041165L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
+    protected Entity2 entity2Field;
+
+    @Version
+    protected int versionField;
+
+    public Entity1() {
+    }
+
+    public Entity1(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public void setEntity2Field(Entity2 val) {
+        entity2Field = val;
+    }
+
+    public Entity2 getEntity2Field() {
+        return entity2Field;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity2.java
index a92e7b1..fe0dc96 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Entity2.java
@@ -1,86 +1,86 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.io.Serializable;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-//@Entity(name="entity2ExplicitName")
-
-//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-/**
- * FIX-ME
- * <p/>
- * It should complain if i uncomment the above strategies...but it does
- */
-@Entity
-public class Entity2 implements Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 4723739219953167343L;
-
-    @Id
-    protected long pk;
-
-    @Basic
-    @Column(length = 35)
-    protected String stringField;
-
-    @Basic
-    protected int intField;
-
-    public Entity2() {
-    }
-
-    public Entity2(long pk, String stringField, int intField) {
-        this.pk = pk;
-        this.stringField = stringField;
-        this.intField = intField;
-    }
-
-    public long getPk() {
-        return pk;
-    }
-
-    public void setStringField(String val) {
-        stringField = val;
-    }
-
-    public String getStringField() {
-        return stringField;
-    }
-
-    public void setIntField(int val) {
-        intField = val;
-    }
-
-    public int getIntField() {
-        return intField;
-    }
-
-    public String toString() {
-        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
-            intField);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+//@Entity(name="entity2ExplicitName")
+
+//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+/**
+ * FIX-ME
+ * <p/>
+ * It should complain if i uncomment the above strategies...but it does
+ */
+@Entity
+public class Entity2 implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4723739219953167343L;
+
+    @Id
+    protected long pk;
+
+    @Basic
+    @Column(length = 35)
+    protected String stringField;
+
+    @Basic
+    protected int intField;
+
+    public Entity2() {
+    }
+
+    public Entity2(long pk, String stringField, int intField) {
+        this.pk = pk;
+        this.stringField = stringField;
+        this.intField = intField;
+    }
+
+    public long getPk() {
+        return pk;
+    }
+
+    public void setStringField(String val) {
+        stringField = val;
+    }
+
+    public String getStringField() {
+        return stringField;
+    }
+
+    public void setIntField(int val) {
+        intField = val;
+    }
+
+    public int getIntField() {
+        return intField;
+    }
+
+    public String toString() {
+        return ("PK: " + pk + " StringField: " + stringField + " IntField: " +
+            intField);
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest1.java
index 0f81c3e..df562ce 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest1.java
@@ -1,124 +1,124 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@Table(name = "mrtest1")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-public class ModRuntimeTest1 implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @Transient
-    public static final String someStaticField = "someField";
-
-    private Locale localeField;
-
-    @Id
-    private int intField;
-
-    @Column(length = 35)
-    private String stringField;
-
-    @Column(length = 35)
-    public String transString;
-
-    @OneToOne(fetch = FetchType.LAZY,
-        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
-    private ModRuntimeTest1 selfOneOne;
-
-    @Transient
-    private Set selfOneMany = new HashSet();
-
-    public ModRuntimeTest1() {
-    }
-
-    public ModRuntimeTest1(int key) {
-        this.intField = key;
-    }
-
-    public ModRuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public ModRuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(ModRuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-
-    public String toString() {
-        return "IntField: " + intField + ", StringField: " + stringField + " .";
-    }
-
-    public Locale getLocaleField() {
-        return localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@Table(name = "mrtest1")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+public class ModRuntimeTest1 implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Transient
+    public static final String someStaticField = "someField";
+
+    private Locale localeField;
+
+    @Id
+    private int intField;
+
+    @Column(length = 35)
+    private String stringField;
+
+    @Column(length = 35)
+    public String transString;
+
+    @OneToOne(fetch = FetchType.LAZY,
+        cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
+    private ModRuntimeTest1 selfOneOne;
+
+    @Transient
+    private Set selfOneMany = new HashSet();
+
+    public ModRuntimeTest1() {
+    }
+
+    public ModRuntimeTest1(int key) {
+        this.intField = key;
+    }
+
+    public ModRuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public ModRuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(ModRuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+
+    public String toString() {
+        return "IntField: " + intField + ", StringField: " + stringField + " .";
+    }
+
+    public Locale getLocaleField() {
+        return localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest2.java
index 4683463..1631d12 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/ModRuntimeTest2.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("mRT2")
-public class ModRuntimeTest2 extends ModRuntimeTest1 {
-
-    private static final long serialVersionUID = 1L;
-    private int intField2;
-
-    public ModRuntimeTest2(int key) {
-        super(key);
-    }
-
-    public ModRuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-
-    public String toString() {
-        return "IntField: " + intField2 + ", StringField: " +
-            super.getStringField() + " .";
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("mRT2")
+public class ModRuntimeTest2 extends ModRuntimeTest1 {
+
+    private static final long serialVersionUID = 1L;
+    private int intField2;
+
+    public ModRuntimeTest2(int key) {
+        super(key);
+    }
+
+    public ModRuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+
+    public String toString() {
+        return "IntField: " + intField2 + ", StringField: " +
+            super.getStringField() + " .";
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Osoba.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Osoba.java
index 14710cc..fdbd2e2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Osoba.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Osoba.java
@@ -1,80 +1,80 @@
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-@Entity
-public class Osoba {
-	@Id
-	@GeneratedValue
-	private long id;
-	
-	private String name;
-	private int age;
-	
-	protected Osoba() {
-		this("?", 0);
-	}
-	
-	public Osoba(String name, int age) {
-		super();
-		this.name = name;
-		this.age = age;
-	}
-	
-	@ManyToMany
-	private List<Projekt> projekty;
-	
-	public String getName() {
-		return name;
-	}
-	
-	public long getId() {
-		return id;
-	}
-	
-	public List<Projekt> getProjekty() {
-		return projekty;
-	}
-	
-	public void addProjekty(Projekt projekt) {
-		if (projekty == null)
-			projekty = new ArrayList<Projekt>();
-		projekty.add(projekt);
-	}
-	
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	public int getAge() {
-		return age;
-	}
-	
-	public void setAge(int age) {
-		this.age = age;
-	}
-}
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+@Entity
+public class Osoba {
+	@Id
+	@GeneratedValue
+	private long id;
+	
+	private String name;
+	private int age;
+	
+	protected Osoba() {
+		this("?", 0);
+	}
+	
+	public Osoba(String name, int age) {
+		super();
+		this.name = name;
+		this.age = age;
+	}
+	
+	@ManyToMany
+	private List<Projekt> projekty;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public long getId() {
+		return id;
+	}
+	
+	public List<Projekt> getProjekty() {
+		return projekty;
+	}
+	
+	public void addProjekty(Projekt projekt) {
+		if (projekty == null)
+			projekty = new ArrayList<Projekt>();
+		projekty.add(projekt);
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public int getAge() {
+		return age;
+	}
+	
+	public void setAge(int age) {
+		this.age = age;
+	}
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Projekt.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Projekt.java
index ae5edf6..5cea02f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Projekt.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/Projekt.java
@@ -1,62 +1,62 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-
-@Entity
-public class Projekt {
-	@Id
-	private String name;
-	
-	@ManyToMany
-	private List<Osoba> osoby;
-
-	protected Projekt() {
-		this("?");
-	}
-	
-	public Projekt(String name) {
-		super();
-		this.name = name;
-	}
-	
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public List<Osoba> getOsoby() {
-		return osoby;
-	}
-
-	public void addOsoba(Osoba osoba) {
-		if (osoby ==null)
-			osoby = new ArrayList<Osoba>();
-		osoby.add(osoba);
-	}	
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+
+@Entity
+public class Projekt {
+	@Id
+	private String name;
+	
+	@ManyToMany
+	private List<Osoba> osoby;
+
+	protected Projekt() {
+		this("?");
+	}
+	
+	public Projekt(String name) {
+		super();
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<Osoba> getOsoby() {
+		return osoby;
+	}
+
+	public void addOsoba(Osoba osoba) {
+		if (osoby ==null)
+			osoby = new ArrayList<Osoba>();
+		osoby.add(osoba);
+	}	
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest1.java
index ccdeb19..6d13ac1 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest1.java
@@ -1,149 +1,149 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Date;
-import java.util.List;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-
-/**
- * <p>Used in testing; should be enhanced.</p>
- *
- * @author Abe White
- */
-@Entity
-@NamedQueries({
-@NamedQuery(name = "named",
-    query = "SELECT o FROM QueryTest1 o"),
-@NamedQuery(name = "sql",
-    query = "select * from foo"),
-@NamedQuery(name = "systemsql",
-    query = "select * from foo"),
-@NamedQuery(name = "systemjdoql",
-    query = "select o FROM QueryTest1 where o.numb == 4")
-    })
-public class QueryTest1 {
-
-    /*
-      * Changed Variable names : Afam Okeke
-      * Reason: The old var names are reserved my some DB's namely MYSQL.
-      */
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    public int id;
-
-    public static final long FIVE = 5L;
-
-    private long numb = 0L;
-    private String strong = null;
-
-    @Column(length = -1)
-    private String cField = null;
-    private boolean boolt = false;
-    private float decar = 1.0f;
-    private char chart = ' ';
-    private Date datum = null;
-
-    @ManyToMany(mappedBy = "manyToMany3")
-    private List<QueryTest4> manyToMany = null;
-
-    public QueryTest1() {
-        decar = 1.0f;
-    }
-
-    public QueryTest1(int id) {
-        decar = 1.0f;
-        this.id = id;
-    }
-
-    public long getNum() {
-        return numb;
-    }
-
-    public void setNum(long val) {
-        numb = val;
-    }
-
-    public String getString() {
-        return strong;
-    }
-
-    public void setString(String val) {
-        strong = val;
-    }
-
-    public String getClob() {
-        return cField;
-    }
-
-    public void setClob(String val) {
-        cField = val;
-    }
-
-    public boolean getBool() {
-        return boolt;
-    }
-
-    public void setBool(boolean val) {
-        boolt = val;
-    }
-
-    public float getDecimal() {
-        return decar;
-    }
-
-    public void setDecimal(float val) {
-        decar = val;
-    }
-
-    public char getCharacter() {
-        return chart;
-    }
-
-    public void setCharacter(char val) {
-        chart = val;
-    }
-
-    public void setDate(Date val) {
-        datum = val;
-    }
-
-    public Date getDate() {
-        return datum;
-    }
-
-    public List<QueryTest4> getManyToMany() {
-        return manyToMany;
-    }
-
-    public void setManyToMany(List<QueryTest4> val) {
-        manyToMany = val;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Date;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+/**
+ * <p>Used in testing; should be enhanced.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@NamedQueries({
+@NamedQuery(name = "named",
+    query = "SELECT o FROM QueryTest1 o"),
+@NamedQuery(name = "sql",
+    query = "select * from foo"),
+@NamedQuery(name = "systemsql",
+    query = "select * from foo"),
+@NamedQuery(name = "systemjdoql",
+    query = "select o FROM QueryTest1 where o.numb == 4")
+    })
+public class QueryTest1 {
+
+    /*
+      * Changed Variable names : Afam Okeke
+      * Reason: The old var names are reserved my some DB's namely MYSQL.
+      */
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    public int id;
+
+    public static final long FIVE = 5L;
+
+    private long numb = 0L;
+    private String strong = null;
+
+    @Column(length = -1)
+    private String cField = null;
+    private boolean boolt = false;
+    private float decar = 1.0f;
+    private char chart = ' ';
+    private Date datum = null;
+
+    @ManyToMany(mappedBy = "manyToMany3")
+    private List<QueryTest4> manyToMany = null;
+
+    public QueryTest1() {
+        decar = 1.0f;
+    }
+
+    public QueryTest1(int id) {
+        decar = 1.0f;
+        this.id = id;
+    }
+
+    public long getNum() {
+        return numb;
+    }
+
+    public void setNum(long val) {
+        numb = val;
+    }
+
+    public String getString() {
+        return strong;
+    }
+
+    public void setString(String val) {
+        strong = val;
+    }
+
+    public String getClob() {
+        return cField;
+    }
+
+    public void setClob(String val) {
+        cField = val;
+    }
+
+    public boolean getBool() {
+        return boolt;
+    }
+
+    public void setBool(boolean val) {
+        boolt = val;
+    }
+
+    public float getDecimal() {
+        return decar;
+    }
+
+    public void setDecimal(float val) {
+        decar = val;
+    }
+
+    public char getCharacter() {
+        return chart;
+    }
+
+    public void setCharacter(char val) {
+        chart = val;
+    }
+
+    public void setDate(Date val) {
+        datum = val;
+    }
+
+    public Date getDate() {
+        return datum;
+    }
+
+    public List<QueryTest4> getManyToMany() {
+        return manyToMany;
+    }
+
+    public void setManyToMany(List<QueryTest4> val) {
+        manyToMany = val;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest2.java
index 50e33e3..8cee808 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest2.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.jdbc.KeyColumn;
-
-/**
- * <p>Used in testing; should be enhanced.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("query2")
-public class QueryTest2 extends QueryTest1 {
-
-    @OneToOne(cascade = { CascadeType.ALL })
-    private QueryTest2 oneToOne = null;
-
-    @PersistentCollection
-    private List<String> stringCollection = null;
-
-    @OneToMany(cascade = { CascadeType.ALL })
-    private List<QueryTest2> oneToMany = null;
-
-    @PersistentMap
-    @KeyColumn(name = "SMAP")
-    private Map<String, String> stringMap = null;
-
-    @OneToMany(cascade = { CascadeType.ALL })
-    @KeyColumn(name = "QT2")
-    private Map<String, QueryTest2> stringToManyMap = null;
-
-    public QueryTest2() {
-    }
-
-    public QueryTest2(int id) {
-        super(id);
-    }
-
-    public QueryTest2 getOneToOne() {
-        return oneToOne;
-    }
-
-    public void setOneToOne(QueryTest2 val) {
-        oneToOne = val;
-    }
-
-    public Collection getStringCollection() {
-        return stringCollection;
-    }
-
-    public void setStringCollection(List<String> val) {
-        stringCollection = val;
-    }
-
-    public Collection getOneToMany() {
-        return oneToMany;
-    }
-
-    public void setOneToMany(List<QueryTest2> val) {
-        oneToMany = val;
-    }
-
-    public Map getStringMap() {
-        return stringMap;
-    }
-
-    public void setStringMap(Map val) {
-        stringMap = val;
-    }
-
-    public Map getStringToManyMap() {
-        return stringToManyMap;
-    }
-
-    public void setStringToManyMap(Map val) {
-        stringToManyMap = val;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+
+/**
+ * <p>Used in testing; should be enhanced.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("query2")
+public class QueryTest2 extends QueryTest1 {
+
+    @OneToOne(cascade = { CascadeType.ALL })
+    private QueryTest2 oneToOne = null;
+
+    @PersistentCollection
+    private List<String> stringCollection = null;
+
+    @OneToMany(cascade = { CascadeType.ALL })
+    private List<QueryTest2> oneToMany = null;
+
+    @PersistentMap
+    @KeyColumn(name = "SMAP")
+    private Map<String, String> stringMap = null;
+
+    @OneToMany(cascade = { CascadeType.ALL })
+    @KeyColumn(name = "QT2")
+    private Map<String, QueryTest2> stringToManyMap = null;
+
+    public QueryTest2() {
+    }
+
+    public QueryTest2(int id) {
+        super(id);
+    }
+
+    public QueryTest2 getOneToOne() {
+        return oneToOne;
+    }
+
+    public void setOneToOne(QueryTest2 val) {
+        oneToOne = val;
+    }
+
+    public Collection getStringCollection() {
+        return stringCollection;
+    }
+
+    public void setStringCollection(List<String> val) {
+        stringCollection = val;
+    }
+
+    public Collection getOneToMany() {
+        return oneToMany;
+    }
+
+    public void setOneToMany(List<QueryTest2> val) {
+        oneToMany = val;
+    }
+
+    public Map getStringMap() {
+        return stringMap;
+    }
+
+    public void setStringMap(Map val) {
+        stringMap = val;
+    }
+
+    public Map getStringToManyMap() {
+        return stringToManyMap;
+    }
+
+    public void setStringToManyMap(Map val) {
+        stringToManyMap = val;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest3.java
index 0eaeb05..2963bed 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest3.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.Entity;
-
-/**
- * <p>Used in testing; should be enhanced.</p>
- *
- * @author Abe White
- */
-@Entity
-public class QueryTest3 extends QueryTest2 {
-
-    private int num2 = 0;
-
-    public QueryTest3() {
-    }
-
-    public QueryTest3(int id) {
-        super(id);
-    }
-
-    public void setNum2(int val) {
-        num2 = val;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.Entity;
+
+/**
+ * <p>Used in testing; should be enhanced.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class QueryTest3 extends QueryTest2 {
+
+    private int num2 = 0;
+
+    public QueryTest3() {
+    }
+
+    public QueryTest3(int id) {
+        super(id);
+    }
+
+    public void setNum2(int val) {
+        num2 = val;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest4.java
index e7a6a38..df456a3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/QueryTest4.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.Collection;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.ManyToMany;
-import javax.persistence.OneToOne;
-
-/**
- * <p>Used in testing; should be enhanced.</p>
- *
- * @author Abe White
- */
-@Entity
-public class QueryTest4 {
-
-    public int num3 = 0;
-    @OneToOne(cascade = { CascadeType.ALL })
-    public QueryTest2 oneToOne2 = null;
-
-    @OneToOne(cascade = { CascadeType.ALL })
-    public QueryTest2 oneToOne3 = null;
-
-    @ManyToMany(cascade = { CascadeType.ALL })
-    public Collection<QueryTest2> manyToMany3 = null;
-
-    public int getNum3() {
-        return num3;
-    }
-
-    public void setNum3(int val) {
-        num3 = val;
-    }
-
-    public void setOneToOne2(QueryTest2 qt2) {
-        oneToOne2 = qt2;
-    }
-
-    public void setOneToOne3(QueryTest2 qt2) {
-        oneToOne3 = qt2;
-    }
-
-    public void setManyToMany3(Collection<QueryTest2> val) {
-        manyToMany3 = val;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.Collection;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+
+/**
+ * <p>Used in testing; should be enhanced.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class QueryTest4 {
+
+    public int num3 = 0;
+    @OneToOne(cascade = { CascadeType.ALL })
+    public QueryTest2 oneToOne2 = null;
+
+    @OneToOne(cascade = { CascadeType.ALL })
+    public QueryTest2 oneToOne3 = null;
+
+    @ManyToMany(cascade = { CascadeType.ALL })
+    public Collection<QueryTest2> manyToMany3 = null;
+
+    public int getNum3() {
+        return num3;
+    }
+
+    public void setNum3(int val) {
+        num3 = val;
+    }
+
+    public void setOneToOne2(QueryTest2 qt2) {
+        oneToOne2 = qt2;
+    }
+
+    public void setOneToOne3(QueryTest2 qt2) {
+        oneToOne3 = qt2;
+    }
+
+    public void setManyToMany3(Collection<QueryTest2> val) {
+        manyToMany3 = val;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest1.java
index 8eaaa5a..95c5f19 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest1.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest1.java
@@ -1,283 +1,283 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("RT1")
-public class RuntimeTest1 implements Serializable {
-
-    public static final String someStaticField = "someField";
-
-    private byte byteField;
-    private boolean booleanField;
-    private char charField;
-    private double doubleField;
-    private float floatField;
-    private int intField;
-    private long longField;
-    private short shortField;
-    private String stringField;
-    private BigInteger bigIntegerField;
-    private BigDecimal bigDecimalField;
-    private Date dateField;
-    private Locale localeField;
-    private Byte byteObjfield;
-    private Boolean booleanObjField;
-    private Character charObjField;
-    private Double doubleObjField;
-    private Float floatObjField;
-    private Integer intObjField;
-    private Long longObjField;
-    private Short shortObjField;
-
-    // transactional only
-    private TransactionalClassPC transField;
-    public String transString;
-
-    // relations
-    @OneToOne(cascade = { CascadeType.ALL })
-    private RuntimeTest1 selfOneOne;
-    @PersistentCollection
-    private Set selfOneMany = new HashSet();
-
-    public RuntimeTest1() {
-    }
-
-    public RuntimeTest1(int key) {
-        this.intField = key;
-        floatField = 1.0f;
-    }
-
-    public RuntimeTest1(String str, int i) {
-        stringField = str;
-        intField = i;
-        floatField = 1.0f;
-    }
-
-    public byte getByteField() {
-        return this.byteField;
-    }
-
-    public void setByteField(byte byteField) {
-        this.byteField = byteField;
-    }
-
-    public boolean getBooleanField() {
-        return this.booleanField;
-    }
-
-    public void setBooleanField(boolean booleanField) {
-        this.booleanField = booleanField;
-    }
-
-    public char getCharField() {
-        return this.charField;
-    }
-
-    public void setCharField(char charField) {
-        this.charField = charField;
-    }
-
-    public double getDoubleField() {
-        return this.doubleField;
-    }
-
-    public void setDoubleField(double doubleField) {
-        this.doubleField = doubleField;
-    }
-
-    public float getFloatField() {
-        return this.floatField;
-    }
-
-    public void setFloatField(float floatField) {
-        this.floatField = floatField;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-
-    public long getLongField() {
-        return this.longField;
-    }
-
-    public void setLongField(long longField) {
-        this.longField = longField;
-    }
-
-    public short getShortField() {
-        return this.shortField;
-    }
-
-    public void setShortField(short shortField) {
-        this.shortField = shortField;
-    }
-
-    public String getStringField() {
-        return this.stringField;
-    }
-
-    public void setStringField(String stringField) {
-        this.stringField = stringField;
-    }
-
-    public BigInteger getBigIntegerField() {
-        return this.bigIntegerField;
-    }
-
-    public void setBigIntegerField(BigInteger bigIntegerField) {
-        this.bigIntegerField = bigIntegerField;
-    }
-
-    public BigDecimal getBigDecimalField() {
-        return this.bigDecimalField;
-    }
-
-    public void setBigDecimalField(BigDecimal bigDecimalField) {
-        this.bigDecimalField = bigDecimalField;
-    }
-
-    public Date getDateField() {
-        return this.dateField;
-    }
-
-    public void setDateField(Date dateField) {
-        this.dateField = dateField;
-    }
-
-    public Locale getLocaleField() {
-        return this.localeField;
-    }
-
-    public void setLocaleField(Locale localeField) {
-        this.localeField = localeField;
-    }
-
-    public Byte getByteObjfield() {
-        return this.byteObjfield;
-    }
-
-    public void setByteObjfield(Byte byteObjfield) {
-        this.byteObjfield = byteObjfield;
-    }
-
-    public Boolean getBooleanObjField() {
-        return this.booleanObjField;
-    }
-
-    public void setBooleanObjField(Boolean booleanObjField) {
-        this.booleanObjField = booleanObjField;
-    }
-
-    public Character getCharObjField() {
-        return this.charObjField;
-    }
-
-    public void setCharObjField(Character charObjField) {
-        this.charObjField = charObjField;
-    }
-
-    public Double getDoubleObjField() {
-        return this.doubleObjField;
-    }
-
-    public void setDoubleObjField(Double doubleObjField) {
-        this.doubleObjField = doubleObjField;
-    }
-
-    public Float getFloatObjField() {
-        return this.floatObjField;
-    }
-
-    public void setFloatObjField(Float floatObjField) {
-        this.floatObjField = floatObjField;
-    }
-
-    public Integer getIntObjField() {
-        return this.intObjField;
-    }
-
-    public void setIntObjField(Integer intObjField) {
-        this.intObjField = intObjField;
-    }
-
-    public Long getLongObjField() {
-        return this.longObjField;
-    }
-
-    public void setLongObjField(Long longObjField) {
-        this.longObjField = longObjField;
-    }
-
-    public Short getShortObjField() {
-        return this.shortObjField;
-    }
-
-    public void setShortObjField(Short shortObjField) {
-        this.shortObjField = shortObjField;
-    }
-
-    public TransactionalClassPC getTransField() {
-        return this.transField;
-    }
-
-    public void setTransField(TransactionalClassPC transField) {
-        this.transField = transField;
-    }
-
-    public RuntimeTest1 getSelfOneOne() {
-        return this.selfOneOne;
-    }
-
-    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
-        this.selfOneOne = selfOneOne;
-    }
-
-    public Set getSelfOneMany() {
-        return this.selfOneMany;
-    }
-
-    public void setSelfOneMany(Set selfOneMany) {
-        this.selfOneMany = selfOneMany;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("RT1")
+public class RuntimeTest1 implements Serializable {
+
+    public static final String someStaticField = "someField";
+
+    private byte byteField;
+    private boolean booleanField;
+    private char charField;
+    private double doubleField;
+    private float floatField;
+    private int intField;
+    private long longField;
+    private short shortField;
+    private String stringField;
+    private BigInteger bigIntegerField;
+    private BigDecimal bigDecimalField;
+    private Date dateField;
+    private Locale localeField;
+    private Byte byteObjfield;
+    private Boolean booleanObjField;
+    private Character charObjField;
+    private Double doubleObjField;
+    private Float floatObjField;
+    private Integer intObjField;
+    private Long longObjField;
+    private Short shortObjField;
+
+    // transactional only
+    private TransactionalClassPC transField;
+    public String transString;
+
+    // relations
+    @OneToOne(cascade = { CascadeType.ALL })
+    private RuntimeTest1 selfOneOne;
+    @PersistentCollection
+    private Set selfOneMany = new HashSet();
+
+    public RuntimeTest1() {
+    }
+
+    public RuntimeTest1(int key) {
+        this.intField = key;
+        floatField = 1.0f;
+    }
+
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+        floatField = 1.0f;
+    }
+
+    public byte getByteField() {
+        return this.byteField;
+    }
+
+    public void setByteField(byte byteField) {
+        this.byteField = byteField;
+    }
+
+    public boolean getBooleanField() {
+        return this.booleanField;
+    }
+
+    public void setBooleanField(boolean booleanField) {
+        this.booleanField = booleanField;
+    }
+
+    public char getCharField() {
+        return this.charField;
+    }
+
+    public void setCharField(char charField) {
+        this.charField = charField;
+    }
+
+    public double getDoubleField() {
+        return this.doubleField;
+    }
+
+    public void setDoubleField(double doubleField) {
+        this.doubleField = doubleField;
+    }
+
+    public float getFloatField() {
+        return this.floatField;
+    }
+
+    public void setFloatField(float floatField) {
+        this.floatField = floatField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public long getLongField() {
+        return this.longField;
+    }
+
+    public void setLongField(long longField) {
+        this.longField = longField;
+    }
+
+    public short getShortField() {
+        return this.shortField;
+    }
+
+    public void setShortField(short shortField) {
+        this.shortField = shortField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public BigInteger getBigIntegerField() {
+        return this.bigIntegerField;
+    }
+
+    public void setBigIntegerField(BigInteger bigIntegerField) {
+        this.bigIntegerField = bigIntegerField;
+    }
+
+    public BigDecimal getBigDecimalField() {
+        return this.bigDecimalField;
+    }
+
+    public void setBigDecimalField(BigDecimal bigDecimalField) {
+        this.bigDecimalField = bigDecimalField;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+
+    public void setDateField(Date dateField) {
+        this.dateField = dateField;
+    }
+
+    public Locale getLocaleField() {
+        return this.localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+
+    public Byte getByteObjfield() {
+        return this.byteObjfield;
+    }
+
+    public void setByteObjfield(Byte byteObjfield) {
+        this.byteObjfield = byteObjfield;
+    }
+
+    public Boolean getBooleanObjField() {
+        return this.booleanObjField;
+    }
+
+    public void setBooleanObjField(Boolean booleanObjField) {
+        this.booleanObjField = booleanObjField;
+    }
+
+    public Character getCharObjField() {
+        return this.charObjField;
+    }
+
+    public void setCharObjField(Character charObjField) {
+        this.charObjField = charObjField;
+    }
+
+    public Double getDoubleObjField() {
+        return this.doubleObjField;
+    }
+
+    public void setDoubleObjField(Double doubleObjField) {
+        this.doubleObjField = doubleObjField;
+    }
+
+    public Float getFloatObjField() {
+        return this.floatObjField;
+    }
+
+    public void setFloatObjField(Float floatObjField) {
+        this.floatObjField = floatObjField;
+    }
+
+    public Integer getIntObjField() {
+        return this.intObjField;
+    }
+
+    public void setIntObjField(Integer intObjField) {
+        this.intObjField = intObjField;
+    }
+
+    public Long getLongObjField() {
+        return this.longObjField;
+    }
+
+    public void setLongObjField(Long longObjField) {
+        this.longObjField = longObjField;
+    }
+
+    public Short getShortObjField() {
+        return this.shortObjField;
+    }
+
+    public void setShortObjField(Short shortObjField) {
+        this.shortObjField = shortObjField;
+    }
+
+    public TransactionalClassPC getTransField() {
+        return this.transField;
+    }
+
+    public void setTransField(TransactionalClassPC transField) {
+        this.transField = transField;
+    }
+
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest2.java
index 93c1d16..60d6bdb 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest2.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest2.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("RT2")
-public class RuntimeTest2 extends RuntimeTest1 {
-
-    private static final long serialVersionUID = 1L;
-    private int intField2;
-
-    public RuntimeTest2() {
-    }
-
-    public RuntimeTest2(int key) {
-        super(key);
-    }
-
-    public RuntimeTest2(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField2() {
-        return this.intField2;
-    }
-
-    public void setIntField2(int intField2) {
-        this.intField2 = intField2;
-    }
-
-    public String toString() {
-        return "IntField: " + intField2 + ", StringField: " +
-            super.getStringField() + " .";
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("RT2")
+public class RuntimeTest2 extends RuntimeTest1 {
+
+    private static final long serialVersionUID = 1L;
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(int key) {
+        super(key);
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+
+    public String toString() {
+        return "IntField: " + intField2 + ", StringField: " +
+            super.getStringField() + " .";
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest3.java
index 35c633f..a36dd9a 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest3.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * <p>Persitent type used in testing.</p>
- *
- * @author Abe White
- */
-@Entity
-@DiscriminatorValue("RT3")
-public class RuntimeTest3 extends RuntimeTest2 {
-
-    private int intField3;
-
-    public RuntimeTest3() {
-    }
-
-    public RuntimeTest3(String str, int i) {
-        super(str, i);
-    }
-
-    public int getIntField3() {
-        return this.intField3;
-    }
-
-    public void setIntField3(int intField3) {
-        this.intField3 = intField3;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+@DiscriminatorValue("RT3")
+public class RuntimeTest3 extends RuntimeTest2 {
+
+    private int intField3;
+
+    public RuntimeTest3() {
+    }
+
+    public RuntimeTest3(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField3() {
+        return this.intField3;
+    }
+
+    public void setIntField3(int intField3) {
+        this.intField3 = intField3;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest4.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest4.java
index 353f283..7cd6d0f 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest4.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest4.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.persistence.Entity;
-
-@Entity
-public class RuntimeTest4 {
-
-    private String name;
-    private Collection runtimeTest5s = new ArrayList();
-
-    public RuntimeTest4(String str) {
-        name = str;
-    }
-
-    public void setName(String val) {
-        name = val;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Collection getRuntimeTest5s() {
-        return runtimeTest5s;
-    }
-
-    public void setRuntimeTest5s(Collection c) {
-        runtimeTest5s = c;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest4 {
+
+    private String name;
+    private Collection runtimeTest5s = new ArrayList();
+
+    public RuntimeTest4(String str) {
+        name = str;
+    }
+
+    public void setName(String val) {
+        name = val;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Collection getRuntimeTest5s() {
+        return runtimeTest5s;
+    }
+
+    public void setRuntimeTest5s(Collection c) {
+        runtimeTest5s = c;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest5.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest5.java
index ac0a6ab..ddeb217 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest5.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/RuntimeTest5.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.OneToOne;
-
-@Entity
-public class RuntimeTest5 {
-
-    private String name;
-
-    @OneToOne(cascade = { CascadeType.ALL })
-    private RuntimeTest4 runtimeTest4;
-
-    public RuntimeTest5(String str) {
-        name = str;
-    }
-
-    public void setName(String val) {
-        name = val;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setRuntimeTest4(RuntimeTest4 val) {
-        runtimeTest4 = val;
-    }
-
-    public RuntimeTest4 getRuntimeTest4() {
-        return runtimeTest4;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+
+@Entity
+public class RuntimeTest5 {
+
+    private String name;
+
+    @OneToOne(cascade = { CascadeType.ALL })
+    private RuntimeTest4 runtimeTest4;
+
+    public RuntimeTest5(String str) {
+        name = str;
+    }
+
+    public void setName(String val) {
+        name = val;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setRuntimeTest4(RuntimeTest4 val) {
+        runtimeTest4 = val;
+    }
+
+    public RuntimeTest4 getRuntimeTest4() {
+        return runtimeTest4;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/SimpleAppIdPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/SimpleAppIdPC.java
index 7cd82b4..e5053e8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/SimpleAppIdPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/SimpleAppIdPC.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-/**
- * <p>Single-field application identity class.</p>
- *
- * @author Abe White
- */
-@Entity
-public class SimpleAppIdPC {
-
-    @Id
-    private String pk;
-
-    private int intField;
-
-    public String getPk() {
-        return this.pk;
-    }
-
-    public void setPk(String pk) {
-        this.pk = pk;
-    }
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * <p>Single-field application identity class.</p>
+ *
+ * @author Abe White
+ */
+@Entity
+public class SimpleAppIdPC {
+
+    @Id
+    private String pk;
+
+    private int intField;
+
+    public String getPk() {
+        return this.pk;
+    }
+
+    public void setPk(String pk) {
+        this.pk = pk;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/TransactionalClassPC.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/TransactionalClassPC.java
index eb59d5f..70ce969 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/TransactionalClassPC.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/common/apps/TransactionalClassPC.java
@@ -1,35 +1,35 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.query.common.apps;
-
-import javax.persistence.Entity;
-
-@Entity
-public class TransactionalClassPC {
-
-    private int intField;
-
-    public int getIntField() {
-        return this.intField;
-    }
-
-    public void setIntField(int intField) {
-        this.intField = intField;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.query.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class TransactionalClassPC {
+
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java
index c988f07..13aa958 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BasicEntity.java
@@ -1,61 +1,61 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-@Entity
-public class BasicEntity {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @ManyToOne
-    private BasicEntity rel;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public BasicEntity getRel() { 
-        return rel; 
-    }
-
-    public void setRel(BasicEntity rel) { 
-        this.rel = rel; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class BasicEntity {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @ManyToOne
+    private BasicEntity rel;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public BasicEntity getRel() { 
+        return rel; 
+    }
+
+    public void setRel(BasicEntity rel) { 
+        this.rel = rel; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyChild.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyChild.java
index 1365b8f..4a50af7 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyChild.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyChild.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-
-@Entity
-public class CascadingOneManyChild {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @ManyToOne(optional=false)
-    @JoinColumn(name="PARENT_ID", nullable=false)
-    @ForeignKey
-    private CascadingOneManyParent parent;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public CascadingOneManyParent getParent() { 
-        return parent; 
-    }
-
-    public void setParent(CascadingOneManyParent parent) { 
-        this.parent = parent; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+
+@Entity
+public class CascadingOneManyChild {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @ManyToOne(optional=false)
+    @JoinColumn(name="PARENT_ID", nullable=false)
+    @ForeignKey
+    private CascadingOneManyParent parent;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public CascadingOneManyParent getParent() { 
+        return parent; 
+    }
+
+    public void setParent(CascadingOneManyParent parent) { 
+        this.parent = parent; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyParent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyParent.java
index 4fd5213..f61fce2 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyParent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/CascadingOneManyParent.java
@@ -1,69 +1,69 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.OrderBy;
-import javax.persistence.Version;
-
-@Entity
-public class CascadingOneManyParent {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
-    @OrderBy("name ASC")
-    private List<CascadingOneManyChild> children = 
-        new ArrayList<CascadingOneManyChild>();
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public List<CascadingOneManyChild> getChildren() { 
-        return children; 
-    }
-
-    public void addChild(CascadingOneManyChild child) {
-        child.setParent(this);
-        children.add(child);
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import javax.persistence.Version;
+
+@Entity
+public class CascadingOneManyParent {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
+    @OrderBy("name ASC")
+    private List<CascadingOneManyChild> children = 
+        new ArrayList<CascadingOneManyChild>();
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public List<CascadingOneManyChild> getChildren() { 
+        return children; 
+    }
+
+    public void addChild(CascadingOneManyChild child) {
+        child.setParent(this);
+        children.add(child);
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Customer.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Customer.java
index e7a1f21..509804e 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Customer.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Customer.java
@@ -1,122 +1,122 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.*;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.ArrayList;
-@Entity
-public class Customer {
-
-    @Embeddable
-    public static class CustomerKey implements Serializable {
-        public String countryCode;
-        public int id;
-
-        public CustomerKey(){}
-
-        public  CustomerKey(String cc, int id){
-            countryCode=cc;
-            this.id=id;
-        }
-
-        public String toString() {
-            return countryCode+"/"+id;
-        }
-        
-        @Override
-        public boolean equals(Object obj){
-            if (obj==this) return true;
-            if ( ! (obj instanceof CustomerKey) ) return false;
-            CustomerKey key = (CustomerKey)obj;
-            if (key.countryCode.equals(this.countryCode) && 
-                    key.id==this.id) return true;
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return this.countryCode.hashCode()
-            ^ this.id;
-        }
-    }
-
-    public enum CreditRating { POOR, GOOD, EXCELLENT };
-
-    @EmbeddedId
-    CustomerKey cid;
-    @Column(length=30)
-    @Basic(fetch=FetchType.LAZY)
-    String name;
-    @Enumerated
-    @Basic(fetch=FetchType.LAZY)
-    CreditRating creditRating;
-    @Version
-    long version;
-
-    @OneToMany(fetch=FetchType.LAZY, mappedBy="customer")
-    private Collection<Order> orders = new ArrayList<Order>();
-
-    public Customer() {}
-
-    public Customer(CustomerKey cid, String name, CreditRating rating){
-        this.cid=cid;
-        this.name=name;
-        this.creditRating=rating;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public CreditRating getRating() {
-        return creditRating;
-    }
-
-    public void setRating(CreditRating rating) {
-        this.creditRating = rating;
-    }
-
-    public Collection<Order> getOrders() {
-        return orders;
-    }
-    
-    public void setOrders(Collection<Order> orders) {
-        this.orders = orders;
-    }
-    
-    public String toString() {
-        return "Customer:"+cid+" name:"+name; 
-    }
-
-    public CustomerKey getCid() {
-        return cid;
-    }
-
-    public void setCid(CustomerKey cid) {
-        this.cid = cid;
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.*;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.ArrayList;
+@Entity
+public class Customer {
+
+    @Embeddable
+    public static class CustomerKey implements Serializable {
+        public String countryCode;
+        public int id;
+
+        public CustomerKey(){}
+
+        public  CustomerKey(String cc, int id){
+            countryCode=cc;
+            this.id=id;
+        }
+
+        public String toString() {
+            return countryCode+"/"+id;
+        }
+        
+        @Override
+        public boolean equals(Object obj){
+            if (obj==this) return true;
+            if ( ! (obj instanceof CustomerKey) ) return false;
+            CustomerKey key = (CustomerKey)obj;
+            if (key.countryCode.equals(this.countryCode) && 
+                    key.id==this.id) return true;
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return this.countryCode.hashCode()
+            ^ this.id;
+        }
+    }
+
+    public enum CreditRating { POOR, GOOD, EXCELLENT };
+
+    @EmbeddedId
+    CustomerKey cid;
+    @Column(length=30)
+    @Basic(fetch=FetchType.LAZY)
+    String name;
+    @Enumerated
+    @Basic(fetch=FetchType.LAZY)
+    CreditRating creditRating;
+    @Version
+    long version;
+
+    @OneToMany(fetch=FetchType.LAZY, mappedBy="customer")
+    private Collection<Order> orders = new ArrayList<Order>();
+
+    public Customer() {}
+
+    public Customer(CustomerKey cid, String name, CreditRating rating){
+        this.cid=cid;
+        this.name=name;
+        this.creditRating=rating;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public CreditRating getRating() {
+        return creditRating;
+    }
+
+    public void setRating(CreditRating rating) {
+        this.creditRating = rating;
+    }
+
+    public Collection<Order> getOrders() {
+        return orders;
+    }
+    
+    public void setOrders(Collection<Order> orders) {
+        this.orders = orders;
+    }
+    
+    public String toString() {
+        return "Customer:"+cid+" name:"+name; 
+    }
+
+    public CustomerKey getCid() {
+        return cid;
+    }
+
+    public void setCid(CustomerKey cid) {
+        this.cid = cid;
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java
index d28ec62..88b94bd 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreBasicEntity.java
@@ -1,54 +1,54 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-import org.apache.openjpa.persistence.DataStoreId;
-
-@Entity
-@DataStoreId
-public class DataStoreBasicEntity {
-
-    private String name;
-
-    @ManyToOne
-    private BasicEntity rel;
-
-    @Version
-    private Integer optLock;
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public BasicEntity getRel() { 
-        return rel; 
-    }
-
-    public void setRel(BasicEntity rel) { 
-        this.rel = rel; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.DataStoreId;
+
+@Entity
+@DataStoreId
+public class DataStoreBasicEntity {
+
+    private String name;
+
+    @ManyToOne
+    private BasicEntity rel;
+
+    @Version
+    private Integer optLock;
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public BasicEntity getRel() { 
+        return rel; 
+    }
+
+    public void setRel(BasicEntity rel) { 
+        this.rel = rel; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreManyOneIdOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreManyOneIdOwner.java
index 260ec35..bf5128c 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreManyOneIdOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/DataStoreManyOneIdOwner.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-@Entity
-public class DataStoreManyOneIdOwner {
-
-    @Id
-    @ManyToOne
-    private DataStoreBasicEntity id;
-
-    private String name;
-
-    @ManyToOne
-    private DataStoreManyOneIdOwner selfRel;
-
-    @Version
-    private Integer optLock;
-
-    public DataStoreBasicEntity getId() { 
-        return id; 
-    }
-
-    public void setId(DataStoreBasicEntity id) { 
-        this.id = id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public DataStoreManyOneIdOwner getSelfRel() { 
-        return selfRel; 
-    }
-
-    public void setSelfRel(DataStoreManyOneIdOwner selfRel) { 
-        this.selfRel = selfRel; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class DataStoreManyOneIdOwner {
+
+    @Id
+    @ManyToOne
+    private DataStoreBasicEntity id;
+
+    private String name;
+
+    @ManyToOne
+    private DataStoreManyOneIdOwner selfRel;
+
+    @Version
+    private Integer optLock;
+
+    public DataStoreBasicEntity getId() { 
+        return id; 
+    }
+
+    public void setId(DataStoreBasicEntity id) { 
+        this.id = id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public DataStoreManyOneIdOwner getSelfRel() { 
+        return selfRel; 
+    }
+
+    public void setSelfRel(DataStoreManyOneIdOwner selfRel) { 
+        this.selfRel = selfRel; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EmbeddableWithRelation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EmbeddableWithRelation.java
index 61935c9..8906e9f 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EmbeddableWithRelation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EmbeddableWithRelation.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Embeddable;
-import javax.persistence.CascadeType;
-import javax.persistence.ManyToOne;
-
-@Embeddable
-public class EmbeddableWithRelation {
-
-    private String name;
-
-    @ManyToOne(cascade=CascadeType.ALL)
-    private MultipleSameTypedEmbedded rel;
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public MultipleSameTypedEmbedded getRel() { 
-        return rel; 
-    }
-
-    public void setRel(MultipleSameTypedEmbedded rel) { 
-        this.rel = rel; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Embeddable;
+import javax.persistence.CascadeType;
+import javax.persistence.ManyToOne;
+
+@Embeddable
+public class EmbeddableWithRelation {
+
+    private String name;
+
+    @ManyToOne(cascade=CascadeType.ALL)
+    private MultipleSameTypedEmbedded rel;
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public MultipleSameTypedEmbedded getRel() { 
+        return rel; 
+    }
+
+    public void setRel(MultipleSameTypedEmbedded rel) { 
+        this.rel = rel; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA1InverseEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA1InverseEager.java
index b0d5c37..6e09d11 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA1InverseEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA1InverseEager.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
-
-@Entity
-@DiscriminatorValue("A1")
-public class EntityA1InverseEager extends EntityAInverseEager {
-    private String name1;
-
-	@OneToMany(fetch=FetchType.EAGER, mappedBy="entityA")
-	private List<EntityBInverseEager> listB = new ArrayList<EntityBInverseEager>();
-	
-	public EntityA1InverseEager() {}
-	
-	public EntityA1InverseEager(String name) {
-	    super(name);
-	    this.name1 = name;
-	}
-
-	public String getName1() {
-        return name1;
-    }
-    
-    public void setName1(String name1) {
-        this.name1 = name1;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
+
+@Entity
+@DiscriminatorValue("A1")
+public class EntityA1InverseEager extends EntityAInverseEager {
+    private String name1;
+
+	@OneToMany(fetch=FetchType.EAGER, mappedBy="entityA")
+	private List<EntityBInverseEager> listB = new ArrayList<EntityBInverseEager>();
+	
+	public EntityA1InverseEager() {}
+	
+	public EntityA1InverseEager(String name) {
+	    super(name);
+	    this.name1 = name;
+	}
+
+	public String getName1() {
+        return name1;
+    }
+    
+    public void setName1(String name1) {
+        this.name1 = name1;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA2InverseEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA2InverseEager.java
index 14b0c54..b3591f5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA2InverseEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityA2InverseEager.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
-
-@Entity
-@DiscriminatorValue("A2")
-public class EntityA2InverseEager extends EntityAInverseEager {
-    private String name2;
-
-	@OneToMany(fetch=FetchType.EAGER, mappedBy="entityA")
-	private List<EntityBInverseEager> listB = new ArrayList<EntityBInverseEager>();
-	
-	public EntityA2InverseEager() {}
-	
-	public EntityA2InverseEager(String name) {
-	    super(name);
-	    this.name2 = name;
-	}
-
-	public String getName2() {
-        return name2;
-    }
-    
-    public void setName2(String name2) {
-        this.name2 = name2;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
+
+@Entity
+@DiscriminatorValue("A2")
+public class EntityA2InverseEager extends EntityAInverseEager {
+    private String name2;
+
+	@OneToMany(fetch=FetchType.EAGER, mappedBy="entityA")
+	private List<EntityBInverseEager> listB = new ArrayList<EntityBInverseEager>();
+	
+	public EntityA2InverseEager() {}
+	
+	public EntityA2InverseEager(String name) {
+	    super(name);
+	    this.name2 = name;
+	}
+
+	public String getName2() {
+        return name2;
+    }
+    
+    public void setName2(String name2) {
+        this.name2 = name2;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityAInverseEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityAInverseEager.java
index 3fac446..24b37cf 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityAInverseEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityAInverseEager.java
@@ -1,71 +1,71 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.OneToMany;
-
-@Entity
-@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-@DiscriminatorColumn(name="TYPE")
-public class EntityAInverseEager  {
-	@GeneratedValue
-	@Id private int id;
-    
-    private String name;
-
-	@OneToMany(fetch=FetchType.EAGER, mappedBy="entityA")
-	private List<EntityBInverseEager> listB = new ArrayList<EntityBInverseEager>();
-	
-	public EntityAInverseEager() {}
-	
-	public EntityAInverseEager(String name) {
-	    this.name = name;
-	}
-	
-	public List<EntityBInverseEager> getListB() {
-		return listB;
-	}
-	
-	public List addB(EntityBInverseEager entityB) {
-		listB.add(entityB);
-		return listB;
-	}
-	
-	public int getId() {
-		return id;
-	}
-	
-    public String getName() {
-        return name;
-    }
-    
-    public void setName(String name) {
-        this.name = name;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+
+@Entity
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name="TYPE")
+public class EntityAInverseEager  {
+	@GeneratedValue
+	@Id private int id;
+    
+    private String name;
+
+	@OneToMany(fetch=FetchType.EAGER, mappedBy="entityA")
+	private List<EntityBInverseEager> listB = new ArrayList<EntityBInverseEager>();
+	
+	public EntityAInverseEager() {}
+	
+	public EntityAInverseEager(String name) {
+	    this.name = name;
+	}
+	
+	public List<EntityBInverseEager> getListB() {
+		return listB;
+	}
+	
+	public List addB(EntityBInverseEager entityB) {
+		listB.add(entityB);
+		return listB;
+	}
+	
+	public int getId() {
+		return id;
+	}
+	
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityBInverseEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityBInverseEager.java
index 01c303f..42c36f6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityBInverseEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityBInverseEager.java
@@ -1,67 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-
-@Entity
-public class EntityBInverseEager  {
-	@GeneratedValue
-	@Id private int id;
-    
-    private String name;
-
-	@ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
-	private EntityAInverseEager entityA;
-	
-    public EntityBInverseEager() {}
-    
-    public EntityBInverseEager(String name) {
-        this.name = name;
-    }
-    
-    public EntityAInverseEager getA() {
-		return entityA;
-	}
-	
-	public void setA(EntityAInverseEager entityA) {
-		this.entityA = entityA;
-	}
-	
-    public int getId() {
-		return id;
-	}
-	
-    public String getName() {
-        return name;
-    }
-    
-    public void setName(String name) {
-        this.name = name;
-    }
-    
-    
-	
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class EntityBInverseEager  {
+	@GeneratedValue
+	@Id private int id;
+    
+    private String name;
+
+	@ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
+	private EntityAInverseEager entityA;
+	
+    public EntityBInverseEager() {}
+    
+    public EntityBInverseEager(String name) {
+        this.name = name;
+    }
+    
+    public EntityAInverseEager getA() {
+		return entityA;
+	}
+	
+	public void setA(EntityAInverseEager entityA) {
+		this.entityA = entityA;
+	}
+	
+    public int getId() {
+		return id;
+	}
+	
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    
+	
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityCInverseEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityCInverseEager.java
index 6ff3966..25efaee 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityCInverseEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityCInverseEager.java
@@ -1,88 +1,88 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-
-@Entity
-
-public class EntityCInverseEager  {
-	@GeneratedValue
-	@Id private int id;
-    
-    private String name;
-    
-    private int age;
-    
-    private int balance;
-    
-	@OneToOne(fetch=FetchType.EAGER, mappedBy="entityC")
-	private EntityDInverseEager entityD = null;
-	
-	public EntityCInverseEager() {}
-	
-	public EntityCInverseEager(String name, int age, int balance) {
-	    this.name = name;
-	    this.age = age;
-	    this.balance = balance;
-	}
-	
-	public EntityDInverseEager getD() {
-		return entityD;
-	}
-	
-	public void setD(EntityDInverseEager entityD) {
-		this.entityD = entityD;
-	}
-	
-	public int getId() {
-		return id;
-	}
-	
-    public String getName() {
-        return name;
-    }
-    
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public int getAge() {
-        return age;
-    }
-    
-    public void setAge(int age) {
-        this.age = age;
-    }
-
-    public int getBalance() {
-        return balance;
-    }
-    
-    public void setBalance(int balance) {
-        this.balance = balance;
-    }
-    
-    
-    
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+
+@Entity
+
+public class EntityCInverseEager  {
+	@GeneratedValue
+	@Id private int id;
+    
+    private String name;
+    
+    private int age;
+    
+    private int balance;
+    
+	@OneToOne(fetch=FetchType.EAGER, mappedBy="entityC")
+	private EntityDInverseEager entityD = null;
+	
+	public EntityCInverseEager() {}
+	
+	public EntityCInverseEager(String name, int age, int balance) {
+	    this.name = name;
+	    this.age = age;
+	    this.balance = balance;
+	}
+	
+	public EntityDInverseEager getD() {
+		return entityD;
+	}
+	
+	public void setD(EntityDInverseEager entityD) {
+		this.entityD = entityD;
+	}
+	
+	public int getId() {
+		return id;
+	}
+	
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+    
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public int getBalance() {
+        return balance;
+    }
+    
+    public void setBalance(int balance) {
+        this.balance = balance;
+    }
+    
+    
+    
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityDInverseEager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityDInverseEager.java
index 609fab0..7bc2337 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityDInverseEager.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/EntityDInverseEager.java
@@ -1,98 +1,98 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.OneToOne;
-
-@Entity
-
-public class EntityDInverseEager  {
-	@GeneratedValue
-	@Id private int id;
-    
-    private String name;
-    
-    private int loginCount;
-    
-    private int logoutCount;
-    
-    private String email;
-    
-
-	@OneToOne(fetch=FetchType.EAGER)
-	private EntityCInverseEager entityC = null;
-	
-	public EntityDInverseEager() {}
-	
-	public EntityDInverseEager(String name, String email, int loginCount, 
-	    int logoutCount) {
-	    this.name = name;
-	    this.email = email;
-	    this.loginCount = loginCount;
-	    this.logoutCount = logoutCount;
-    
-	}
-	
-	public EntityCInverseEager getC() {
-		return entityC;
-	}
-	
-	public void setC(EntityCInverseEager entityC) {
-		this.entityC = entityC;
-	}
-	
-	public int getId() {
-		return id;
-	}
-	
-    public String getName() {
-        return name;
-    }
-    
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-    
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public int getLoginCount() {
-        return loginCount;
-    }
-    
-    public void setLoginCount(int loginCount) {
-        this.loginCount = loginCount;
-    }
-
-    public int getLogoutCount() {
-        return logoutCount;
-    }
-    
-    public void setLogoutCount(int logoutCount) {
-        this.logoutCount = logoutCount;
-    }}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+
+@Entity
+
+public class EntityDInverseEager  {
+	@GeneratedValue
+	@Id private int id;
+    
+    private String name;
+    
+    private int loginCount;
+    
+    private int logoutCount;
+    
+    private String email;
+    
+
+	@OneToOne(fetch=FetchType.EAGER)
+	private EntityCInverseEager entityC = null;
+	
+	public EntityDInverseEager() {}
+	
+	public EntityDInverseEager(String name, String email, int loginCount, 
+	    int logoutCount) {
+	    this.name = name;
+	    this.email = email;
+	    this.loginCount = loginCount;
+	    this.logoutCount = logoutCount;
+    
+	}
+	
+	public EntityCInverseEager getC() {
+		return entityC;
+	}
+	
+	public void setC(EntityCInverseEager entityC) {
+		this.entityC = entityC;
+	}
+	
+	public int getId() {
+		return id;
+	}
+	
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+    
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public int getLoginCount() {
+        return loginCount;
+    }
+    
+    public void setLoginCount(int loginCount) {
+        this.loginCount = loginCount;
+    }
+
+    public int getLogoutCount() {
+        return logoutCount;
+    }
+    
+    public void setLogoutCount(int logoutCount) {
+        this.logoutCount = logoutCount;
+    }}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java
index b5482d6..eada11c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.Collection;
-import java.util.HashSet;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentCollection;
-
-@Entity
-public class HandlerCollectionInstance {
-    @Id
-    private int id;
-
-    @PersistentCollection
-    private Collection<String> collection = new HashSet<String>();
-
-    public Collection<String> getCollection() {
-        return collection;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.Collection;
+import java.util.HashSet;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+public class HandlerCollectionInstance {
+    @Id
+    private int id;
+
+    @PersistentCollection
+    private Collection<String> collection = new HashSet<String>();
+
+    public Collection<String> getCollection() {
+        return collection;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java
index 602a343..6b20211 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.jdbc.ContainerTable;
-
-@Entity
-public class HandlerToHandlerMapInstance {
-    @Id
-    private int id;
-
-    @PersistentMap
-    @ContainerTable(name="NONSTD_MAPPING_MAP")
-    private Map<String,String> map = new HashMap<String,String>();
-
-    public Map<String,String> getMap() {
-        return map;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.ContainerTable;
+
+@Entity
+public class HandlerToHandlerMapInstance {
+    @Id
+    private int id;
+
+    @PersistentMap
+    @ContainerTable(name="NONSTD_MAPPING_MAP")
+    private Map<String,String> map = new HashMap<String,String>();
+
+    public Map<String,String> getMap() {
+        return map;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java
index 6a7febc..61630e9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-
-@Entity
-public class HandlerToRelationMapInstance {
-    @Id
-    private int id;
-
-    @PersistentMap(elementCascade = CascadeType.PERSIST)
-    private Map<String,AllFieldTypes> map = new HashMap<String,AllFieldTypes>();
-
-    public Map<String,AllFieldTypes> getMap() {
-        return map;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+@Entity
+public class HandlerToRelationMapInstance {
+    @Id
+    private int id;
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    private Map<String,AllFieldTypes> map = new HashMap<String,AllFieldTypes>();
+
+    public Map<String,AllFieldTypes> getMap() {
+        return map;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneCompoundIdOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneCompoundIdOwner.java
index 2da6057..0bbf14c 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneCompoundIdOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneCompoundIdOwner.java
@@ -1,75 +1,75 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-@Entity
-@IdClass(ManyOneCompoundIdOwnerId.class)
-public class ManyOneCompoundIdOwner {
-
-    @Id
-    @GeneratedValue
-    private long longId;
-
-    @Id
-    @ManyToOne
-    private BasicEntity entityId;
-
-    private String name;
-
-    @ManyToOne
-    private ManyOneCompoundIdOwner selfRel;
-
-    @Version
-    private Integer optLock;
-
-    public long getLongId() {
-        return longId;
-    }
-
-    public BasicEntity getEntityId() { 
-        return entityId; 
-    }
-
-    public void setEntityId(BasicEntity entityId) { 
-        this.entityId = entityId; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public ManyOneCompoundIdOwner getSelfRel() { 
-        return selfRel; 
-    }
-
-    public void setSelfRel(ManyOneCompoundIdOwner selfRel) { 
-        this.selfRel = selfRel; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+@IdClass(ManyOneCompoundIdOwnerId.class)
+public class ManyOneCompoundIdOwner {
+
+    @Id
+    @GeneratedValue
+    private long longId;
+
+    @Id
+    @ManyToOne
+    private BasicEntity entityId;
+
+    private String name;
+
+    @ManyToOne
+    private ManyOneCompoundIdOwner selfRel;
+
+    @Version
+    private Integer optLock;
+
+    public long getLongId() {
+        return longId;
+    }
+
+    public BasicEntity getEntityId() { 
+        return entityId; 
+    }
+
+    public void setEntityId(BasicEntity entityId) { 
+        this.entityId = entityId; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public ManyOneCompoundIdOwner getSelfRel() { 
+        return selfRel; 
+    }
+
+    public void setSelfRel(ManyOneCompoundIdOwner selfRel) { 
+        this.selfRel = selfRel; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneIdOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneIdOwner.java
index eafc557..ef4b09e 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneIdOwner.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/ManyOneIdOwner.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-@Entity
-public class ManyOneIdOwner {
-
-    @Id
-    @ManyToOne
-    private BasicEntity id;
-
-    private String name;
-
-    @ManyToOne
-    private ManyOneIdOwner selfRel;
-
-    @Version
-    private Integer optLock;
-
-    public BasicEntity getId() { 
-        return id; 
-    }
-
-    public void setId(BasicEntity id) { 
-        this.id = id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-
-    public ManyOneIdOwner getSelfRel() { 
-        return selfRel; 
-    }
-
-    public void setSelfRel(ManyOneIdOwner selfRel) { 
-        this.selfRel = selfRel; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class ManyOneIdOwner {
+
+    @Id
+    @ManyToOne
+    private BasicEntity id;
+
+    private String name;
+
+    @ManyToOne
+    private ManyOneIdOwner selfRel;
+
+    @Version
+    private Integer optLock;
+
+    public BasicEntity getId() { 
+        return id; 
+    }
+
+    public void setId(BasicEntity id) { 
+        this.id = id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public ManyOneIdOwner getSelfRel() { 
+        return selfRel; 
+    }
+
+    public void setSelfRel(ManyOneIdOwner selfRel) { 
+        this.selfRel = selfRel; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/MultipleSameTypedEmbedded.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/MultipleSameTypedEmbedded.java
index 1ff48f7..6ab328b 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/MultipleSameTypedEmbedded.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/MultipleSameTypedEmbedded.java
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.AttributeOverride;
-import javax.persistence.AssociationOverride;
-import javax.persistence.Column;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.Version;
-
-@Entity
-public class MultipleSameTypedEmbedded { 
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @Embedded
-    @AttributeOverride(name="name", column=@Column(name="E1_NAME"))
-    @AssociationOverride(name="rel", joinColumns=@JoinColumn(name="E1_REL"))
-    private EmbeddableWithRelation embed1;
-
-    @Embedded
-    @AttributeOverride(name="name", column=@Column(name="E2_NAME"))
-    @AssociationOverride(name="rel", joinColumns=@JoinColumn(name="E2_REL"))
-    private EmbeddableWithRelation embed2;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public EmbeddableWithRelation getEmbed1() {
-        return embed1; 
-    }
-
-    public void setEmbed1(EmbeddableWithRelation embed1) {
-        this.embed1 = embed1; 
-    }
-
-    public EmbeddableWithRelation getEmbed2() {
-        return embed2; 
-    }
-
-    public void setEmbed2(EmbeddableWithRelation embed2) {
-        this.embed2 = embed2; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AssociationOverride;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Version;
+
+@Entity
+public class MultipleSameTypedEmbedded { 
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @Embedded
+    @AttributeOverride(name="name", column=@Column(name="E1_NAME"))
+    @AssociationOverride(name="rel", joinColumns=@JoinColumn(name="E1_REL"))
+    private EmbeddableWithRelation embed1;
+
+    @Embedded
+    @AttributeOverride(name="name", column=@Column(name="E2_NAME"))
+    @AssociationOverride(name="rel", joinColumns=@JoinColumn(name="E2_REL"))
+    private EmbeddableWithRelation embed2;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public EmbeddableWithRelation getEmbed1() {
+        return embed1; 
+    }
+
+    public void setEmbed1(EmbeddableWithRelation embed1) {
+        this.embed1 = embed1; 
+    }
+
+    public EmbeddableWithRelation getEmbed2() {
+        return embed2; 
+    }
+
+    public void setEmbed2(EmbeddableWithRelation embed2) {
+        this.embed2 = embed2; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Order.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Order.java
index af40e86..5757a9d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Order.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/Order.java
@@ -1,87 +1,87 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.Version;
-
-@Entity
-@Table(name="OrderTbl")
-public class Order {
-    @Id 
-    @GeneratedValue
-    int oid;
-
-    double amount;
-    boolean delivered;
-
-    @ManyToOne (fetch=FetchType.EAGER)
-    Customer customer;
-
-    @Version
-    long version;
-
-    public Order(){}
-
-    public Order(  double amt, boolean delivered, Customer c){
-        amount=amt;
-        this.delivered=delivered;
-        customer=c;
-        if (c!=null) c.getOrders().add(this);
-    }
-
-    public double getAmount() {
-        return amount;
-    }
-    
-    public void setAmount(double amount) {
-        this.amount = amount;
-    }
-    
-    public Customer getCustomer() {
-        return customer;
-    }
-    
-    public void setCustomer(Customer customer) {
-        this.customer = customer;
-    }
-    
-    public boolean isDelivered() {
-        return delivered;
-    }
-    
-    public void setDelivered(boolean delivered) {
-        this.delivered = delivered;
-    }
-    
-    public int getOid() {
-        return oid;
-    }
-
-    public String toString(){
-        return "Order:"+oid+" amount:"+amount+" delivered:"+delivered+" customer:"+
-        ( customer!=null ? customer.getCid()  :  -1 );
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name="OrderTbl")
+public class Order {
+    @Id 
+    @GeneratedValue
+    int oid;
+
+    double amount;
+    boolean delivered;
+
+    @ManyToOne (fetch=FetchType.EAGER)
+    Customer customer;
+
+    @Version
+    long version;
+
+    public Order(){}
+
+    public Order(  double amt, boolean delivered, Customer c){
+        amount=amt;
+        this.delivered=delivered;
+        customer=c;
+        if (c!=null) c.getOrders().add(this);
+    }
+
+    public double getAmount() {
+        return amount;
+    }
+    
+    public void setAmount(double amount) {
+        this.amount = amount;
+    }
+    
+    public Customer getCustomer() {
+        return customer;
+    }
+    
+    public void setCustomer(Customer customer) {
+        this.customer = customer;
+    }
+    
+    public boolean isDelivered() {
+        return delivered;
+    }
+    
+    public void setDelivered(boolean delivered) {
+        this.delivered = delivered;
+    }
+    
+    public int getOid() {
+        return oid;
+    }
+
+    public String toString(){
+        return "Order:"+oid+" amount:"+amount+" delivered:"+delivered+" customer:"+
+        ( customer!=null ? customer.getCid()  :  -1 );
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToHandlerMapInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToHandlerMapInstance.java
index 1e6be1c..4c70ba9 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToHandlerMapInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToHandlerMapInstance.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-
-@Entity
-public class RelationToHandlerMapInstance {
-    @Id
-    private int id;
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST)
-
-    private Map<AllFieldTypes,String> aftMap =
-        new HashMap<AllFieldTypes,String>();
-
-    public Map<AllFieldTypes,String> getMap() {
-        return aftMap;
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+@Entity
+public class RelationToHandlerMapInstance {
+    @Id
+    private int id;
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST)
+
+    private Map<AllFieldTypes,String> aftMap =
+        new HashMap<AllFieldTypes,String>();
+
+    public Map<AllFieldTypes,String> getMap() {
+        return aftMap;
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToRelationMapInstance.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToRelationMapInstance.java
index 58196d2..aba949d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToRelationMapInstance.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/RelationToRelationMapInstance.java
@@ -1,43 +1,43 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import org.apache.openjpa.persistence.PersistentMap;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-
-@Entity
-public class RelationToRelationMapInstance {
-    @Id
-    private int id;
-
-    @PersistentMap(keyCascade = CascadeType.PERSIST,
-        elementCascade = CascadeType.PERSIST)
-    private Map<AllFieldTypes,AllFieldTypes> map =
-        new HashMap<AllFieldTypes,AllFieldTypes>();
-
-    public Map<AllFieldTypes,AllFieldTypes> getMap() {
-        return map;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+@Entity
+public class RelationToRelationMapInstance {
+    @Id
+    private int id;
+
+    @PersistentMap(keyCascade = CascadeType.PERSIST,
+        elementCascade = CascadeType.PERSIST)
+    private Map<AllFieldTypes,AllFieldTypes> map =
+        new HashMap<AllFieldTypes,AllFieldTypes>();
+
+    public Map<AllFieldTypes,AllFieldTypes> getMap() {
+        return map;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/SimpleEmbeddable.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/SimpleEmbeddable.java
index b699d10..d8f1d50 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/SimpleEmbeddable.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/SimpleEmbeddable.java
@@ -1,34 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.Embeddable;
-
-@Embeddable
-public class SimpleEmbeddable {
-    private String embeddedString;
-
-    protected SimpleEmbeddable() {
-        // for JPA
-    }
-
-    public SimpleEmbeddable(String s) {
-        embeddedString = s;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.Embeddable;
+
+@Embeddable
+public class SimpleEmbeddable {
+    private String embeddedString;
+
+    protected SimpleEmbeddable() {
+        // for JPA
+    }
+
+    public SimpleEmbeddable(String s) {
+        embeddedString = s;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TargetedIFaceRelationParent.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TargetedIFaceRelationParent.java
index 0331f01..ae0891d 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TargetedIFaceRelationParent.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TargetedIFaceRelationParent.java
@@ -1,64 +1,64 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Version;
-
-@Entity
-public class TargetedIFaceRelationParent 
-    implements IFace {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @ManyToOne(targetEntity=TargetedIFaceRelationParent.class,
-        cascade=CascadeType.ALL)
-    private IFace iface;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public IFace getIFace() {
-        return iface; 
-    }
-
-    public void setIFace(IFace iface) {
-        this.iface = iface; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class TargetedIFaceRelationParent 
+    implements IFace {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @ManyToOne(targetEntity=TargetedIFaceRelationParent.class,
+        cascade=CascadeType.ALL)
+    private IFace iface;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public IFace getIFace() {
+        return iface; 
+    }
+
+    public void setIFace(IFace iface) {
+        this.iface = iface; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestBulkUpdatesAndEmbeddedFields.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestBulkUpdatesAndEmbeddedFields.java
index a5d96d8..cc8b2ba 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestBulkUpdatesAndEmbeddedFields.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestBulkUpdatesAndEmbeddedFields.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-/**
- * Tests OPENJPA-199
- */
-public class TestBulkUpdatesAndEmbeddedFields
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(MultipleSameTypedEmbedded.class, EmbeddableWithRelation.class,
-            CLEAR_TABLES);
-
-        em.getTransaction().begin();
-        MultipleSameTypedEmbedded pc = new MultipleSameTypedEmbedded();
-        pc.setEmbed1(new EmbeddableWithRelation());
-        pc.getEmbed1().setName("foo");
-        em.persist(pc);
-        em.getTransaction().commit();
-    }
-
-    public void testBulkUpdateOfEmbeddedField() {
-        em.getTransaction().begin();
-        assertEquals(1, em.createQuery(
-            "UPDATE MultipleSameTypedEmbedded o SET o.embed1.name = 'bar'")
-            .executeUpdate());
-        em.getTransaction().commit();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+/**
+ * Tests OPENJPA-199
+ */
+public class TestBulkUpdatesAndEmbeddedFields
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(MultipleSameTypedEmbedded.class, EmbeddableWithRelation.class,
+            CLEAR_TABLES);
+
+        em.getTransaction().begin();
+        MultipleSameTypedEmbedded pc = new MultipleSameTypedEmbedded();
+        pc.setEmbed1(new EmbeddableWithRelation());
+        pc.getEmbed1().setName("foo");
+        em.persist(pc);
+        em.getTransaction().commit();
+    }
+
+    public void testBulkUpdateOfEmbeddedField() {
+        em.getTransaction().begin();
+        assertEquals(1, em.createQuery(
+            "UPDATE MultipleSameTypedEmbedded o SET o.embed1.name = 'bar'")
+            .executeUpdate());
+        em.getTransaction().commit();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerCollections.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerCollections.java
index fbeec2c..0f255b4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerCollections.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerCollections.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.HandlerCollectionTableFieldStrategy;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestHandlerCollections
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(HandlerCollectionInstance.class,
-            CLEAR_TABLES);
-    }
-
-    public void testHandlerCollections() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
-            HandlerCollectionInstance.class);
-        assertEquals(HandlerCollectionTableFieldStrategy.class,
-            cm.getFieldMapping("collection").getStrategy().getClass());
-
-        HandlerCollectionInstance o = new HandlerCollectionInstance();
-        o.getCollection().add("foo");
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.HandlerCollectionTableFieldStrategy;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestHandlerCollections
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(HandlerCollectionInstance.class,
+            CLEAR_TABLES);
+    }
+
+    public void testHandlerCollections() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
+            HandlerCollectionInstance.class);
+        assertEquals(HandlerCollectionTableFieldStrategy.class,
+            cm.getFieldMapping("collection").getStrategy().getClass());
+
+        HandlerCollectionInstance o = new HandlerCollectionInstance();
+        o.getCollection().add("foo");
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToHandlerMaps.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToHandlerMaps.java
index f1f78b6..93c82ca 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToHandlerMaps.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToHandlerMaps.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.HandlerHandlerMapTableFieldStrategy;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestHandlerToHandlerMaps
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(HandlerToHandlerMapInstance.class,
-            CLEAR_TABLES);
-    }
-
-    public void testHandlerToHandlerMaps() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
-            HandlerToHandlerMapInstance.class);
-        FieldMapping fm = cm.getFieldMapping("map");
-        assertEquals(HandlerHandlerMapTableFieldStrategy.class,
-            fm.getStrategy().getClass());
-        assertEquals("NONSTD_MAPPING_MAP", fm.getTable().getName());
-
-        HandlerToHandlerMapInstance o = new HandlerToHandlerMapInstance();
-        o.getMap().put("foo", "bar");
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.HandlerHandlerMapTableFieldStrategy;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestHandlerToHandlerMaps
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(HandlerToHandlerMapInstance.class,
+            CLEAR_TABLES);
+    }
+
+    public void testHandlerToHandlerMaps() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
+            HandlerToHandlerMapInstance.class);
+        FieldMapping fm = cm.getFieldMapping("map");
+        assertEquals(HandlerHandlerMapTableFieldStrategy.class,
+            fm.getStrategy().getClass());
+        assertEquals("NONSTD_MAPPING_MAP", fm.getTable().getName());
+
+        HandlerToHandlerMapInstance o = new HandlerToHandlerMapInstance();
+        o.getMap().put("foo", "bar");
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java
index 9798089..936d8a2 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestHandlerToRelationMaps.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.HandlerRelationMapTableFieldStrategy;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestHandlerToRelationMaps
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(HandlerToRelationMapInstance.class, AllFieldTypes.class,
-            CLEAR_TABLES);
-    }
-
-    public void testHandlerToRelationMaps() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
-            HandlerToRelationMapInstance.class);
-        assertEquals(HandlerRelationMapTableFieldStrategy.class,
-            cm.getFieldMapping("map").getStrategy().getClass());
-
-        HandlerToRelationMapInstance o = new HandlerToRelationMapInstance();
-        o.getMap().put("foo", new AllFieldTypes());
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.HandlerRelationMapTableFieldStrategy;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestHandlerToRelationMaps
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(HandlerToRelationMapInstance.class, AllFieldTypes.class,
+            CLEAR_TABLES);
+    }
+
+    public void testHandlerToRelationMaps() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
+            HandlerToRelationMapInstance.class);
+        assertEquals(HandlerRelationMapTableFieldStrategy.class,
+            cm.getFieldMapping("map").getStrategy().getClass());
+
+        HandlerToRelationMapInstance o = new HandlerToRelationMapInstance();
+        o.getMap().put("foo", new AllFieldTypes());
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
index d4be363..a6bcd18 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
@@ -1,258 +1,258 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import junit.textui.TestRunner;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAQuery;
-import org.apache.openjpa.persistence.query.Magazine;
-import org.apache.openjpa.persistence.query.Publisher;
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-
-
-public class TestInverseEagerSQL
-    extends SQLListenerTestCase {
-
-    public void setUp() {
-        setUp(Customer.class, Customer.CustomerKey.class, Order.class, 
-        	EntityAInverseEager.class, EntityA1InverseEager.class, EntityA2InverseEager.class, 
-        	EntityBInverseEager.class, EntityCInverseEager.class, EntityDInverseEager.class,
-            Publisher.class, Magazine.class);
-        
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-
-        Customer.CustomerKey ck = new Customer.CustomerKey("USA", 1);
-        Customer c = new Customer();
-        c.setCid(ck);
-        c.setName("customer1");
-        em.persist(c);
-        
-        for (int i = 0; i < 4; i++) {
-            Order order = new Order();
-            order.setCustomer(c);
-            em.persist(order);
-        }
-
-        EntityAInverseEager a = new EntityAInverseEager("a");
-        em.persist(a);
-        
-        EntityA1InverseEager a1 = new EntityA1InverseEager("a1");
-        em.persist(a1);
-        
-        EntityA2InverseEager a2 = new EntityA2InverseEager("a2");
-        em.persist(a2);
-
-        for (int i = 0; i < 4; i++) {
-            EntityBInverseEager b = new EntityBInverseEager("b" + i);
-            a.addB(b);
-            b.setA(a);
-            em.persist(b);
-        }
-        
-        for (int i = 4; i < 8; i++) {
-            EntityBInverseEager b = new EntityBInverseEager("b" + i);
-            a1.addB(b);
-            b.setA(a1);
-            em.persist(b);
-        }
-
-        for (int i = 8; i < 12; i++) {
-            EntityBInverseEager b = new EntityBInverseEager("b" + i);
-            a2.addB(b);
-            b.setA(a2);
-            em.persist(b);
-        }
-        
-        for (int i = 0; i < 4; i++) {
-            EntityCInverseEager c1 = new EntityCInverseEager("c"+i, i, i);
-            em.persist(c1);
-
-            EntityDInverseEager d1 = new EntityDInverseEager("d"+i, "d"+i, i, i);
-            em.persist(d1);
-
-            c1.setD(d1);
-            d1.setC(c1);
-        }
-
-        Publisher p1 = new Publisher();
-        p1.setName("publisher1");
-        em.persist(p1);
-   
-        for (int i = 0; i < 4; i++) {
-            Magazine magazine = new Magazine();
-            magazine.setIdPublisher(p1);
-            magazine.setName("magagine"+i+"_"+p1.getName());
-            em.persist(magazine);
-        }
-
-        Publisher p2 = new Publisher();
-        p2.setName("publisher2");
-        em.persist(p2);
-   
-        for (int i = 0; i < 4; i++) {
-            Magazine magazine = new Magazine();
-            magazine.setIdPublisher(p2);
-            magazine.setName("magagine"+i+"_"+p2.getName());
-            em.persist(magazine);
-        }
-
-        em.flush();
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    public void testOneToManyInverseEagerQuery() {
-        sql.clear();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        OpenJPAQuery q = em.createQuery("SELECT c FROM Customer c ");
-        List<Customer> res = q.getResultList(); 
-
-        assertEquals(1, res.size());
-
-        for (int i = 0; i < res.size(); i++) {
-            Customer c = (Customer)res.get(i);
-            Collection<Order> orders = c.getOrders();
-            for (Iterator<Order> iter=orders.iterator(); iter.hasNext();) {
-                Order order = (Order)iter.next();
-                assertEquals(order.getCustomer(), c);
-            }
-        }
-        
-        assertEquals(2, sql.size());
-        em.close();
-    }
-
-    public void testOneToOneInverseEagerQuery() {
-        sql.clear();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        String query = "select c FROM EntityCInverseEager c";
-        Query q = em.createQuery(query);
-        List<EntityCInverseEager> res = q.getResultList();
-        assertEquals(4, res.size());
-
-        for (int i = 0; i < res.size(); i++) {
-            EntityCInverseEager c = (EntityCInverseEager)res.get(i);
-            EntityDInverseEager d = c.getD();
-            assertEquals(c, d.getC());
-        }
-
-        assertEquals(1, sql.size());
-        em.close();
-    }
-
-    public void testOneToManyInheritanceQuery() {
-        sql.clear();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        String query = "select a FROM EntityA1InverseEager a";
-        Query q = em.createQuery(query);
-        List list = q.getResultList();
-        assertEquals(1, list.size());
-        for (int i = 0; i < list.size(); i++) {
-            EntityA1InverseEager a1 = (EntityA1InverseEager)list.get(i);
-            Collection<EntityBInverseEager> listB = a1.getListB();
-            assertEquals(4, listB.size());
-            for (Iterator iter=listB.iterator(); iter.hasNext();) {
-                EntityBInverseEager b = (EntityBInverseEager)iter.next();
-                EntityAInverseEager a = b.getA();
-                assertEquals(a1, a);
-            }
-        }
-        assertEquals(3, sql.size());
-        sql.clear();
-
-        query = "select a FROM EntityA2InverseEager a";
-        q = em.createQuery(query);
-        list = q.getResultList();
-        assertEquals(1, list.size());
-        for (int i = 0; i < list.size(); i++) {
-            EntityA2InverseEager a2 = (EntityA2InverseEager)list.get(i);
-            Collection listB = a2.getListB();
-            assertEquals(4, listB.size());
-            for (Iterator iter=listB.iterator(); iter.hasNext();) {
-                EntityBInverseEager b = (EntityBInverseEager)iter.next();
-                EntityAInverseEager a = b.getA();
-                assertEquals(a2, a);
-            }
-        }
-        assertEquals(3, sql.size());
-        sql.clear();
-        
-        query = "select a FROM EntityAInverseEager a";
-        q = em.createQuery(query);
-        list = q.getResultList();
-        assertEquals(3, list.size());
-        for (int i = 0; i < list.size(); i++) {
-            EntityAInverseEager a0 = (EntityAInverseEager)list.get(i);
-            Collection listB = a0.getListB();
-            assertEquals(4, listB.size());
-            for (Iterator iter=listB.iterator(); iter.hasNext();) {
-                EntityBInverseEager b = (EntityBInverseEager)iter.next();
-                EntityAInverseEager a = b.getA();
-                assertEquals(a0, a);
-            }
-        }
-        
-        assertEquals(2, sql.size());
-        em.close();
-    }
-
-    public void testOneToManyEagerInverseLazyQuery() {
-        sql.clear();
-
-        OpenJPAEntityManager em = emf.createEntityManager();
-        String query = "select p FROM Publisher p";
-        Query q = em.createQuery(query);
-        List list = q.getResultList();
-        assertEquals(2, list.size());
-        assertEquals(2, sql.size());
-
-        sql.clear();
-        em.clear();
-        for (int i = 0; i < list.size(); i++) {
-            Publisher p = (Publisher) list.get(i);
-            Set<Magazine> magazines = p.getMagazineCollection();
-            assertEquals(4, magazines.size());
-            for (Iterator iter = magazines.iterator(); iter.hasNext();) {
-                Magazine m = (Magazine) iter.next();
-                Publisher mp = m.getIdPublisher();
-                assertEquals(p, mp);
-            }
-        }
-
-        assertEquals(0, sql.size());
-        em.close();
-    }
-
-    public static void main(String[] args) {
-        TestRunner.run(TestInverseEagerSQL.class);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.query.Magazine;
+import org.apache.openjpa.persistence.query.Publisher;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+
+public class TestInverseEagerSQL
+    extends SQLListenerTestCase {
+
+    public void setUp() {
+        setUp(Customer.class, Customer.CustomerKey.class, Order.class, 
+        	EntityAInverseEager.class, EntityA1InverseEager.class, EntityA2InverseEager.class, 
+        	EntityBInverseEager.class, EntityCInverseEager.class, EntityDInverseEager.class,
+            Publisher.class, Magazine.class);
+        
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        Customer.CustomerKey ck = new Customer.CustomerKey("USA", 1);
+        Customer c = new Customer();
+        c.setCid(ck);
+        c.setName("customer1");
+        em.persist(c);
+        
+        for (int i = 0; i < 4; i++) {
+            Order order = new Order();
+            order.setCustomer(c);
+            em.persist(order);
+        }
+
+        EntityAInverseEager a = new EntityAInverseEager("a");
+        em.persist(a);
+        
+        EntityA1InverseEager a1 = new EntityA1InverseEager("a1");
+        em.persist(a1);
+        
+        EntityA2InverseEager a2 = new EntityA2InverseEager("a2");
+        em.persist(a2);
+
+        for (int i = 0; i < 4; i++) {
+            EntityBInverseEager b = new EntityBInverseEager("b" + i);
+            a.addB(b);
+            b.setA(a);
+            em.persist(b);
+        }
+        
+        for (int i = 4; i < 8; i++) {
+            EntityBInverseEager b = new EntityBInverseEager("b" + i);
+            a1.addB(b);
+            b.setA(a1);
+            em.persist(b);
+        }
+
+        for (int i = 8; i < 12; i++) {
+            EntityBInverseEager b = new EntityBInverseEager("b" + i);
+            a2.addB(b);
+            b.setA(a2);
+            em.persist(b);
+        }
+        
+        for (int i = 0; i < 4; i++) {
+            EntityCInverseEager c1 = new EntityCInverseEager("c"+i, i, i);
+            em.persist(c1);
+
+            EntityDInverseEager d1 = new EntityDInverseEager("d"+i, "d"+i, i, i);
+            em.persist(d1);
+
+            c1.setD(d1);
+            d1.setC(c1);
+        }
+
+        Publisher p1 = new Publisher();
+        p1.setName("publisher1");
+        em.persist(p1);
+   
+        for (int i = 0; i < 4; i++) {
+            Magazine magazine = new Magazine();
+            magazine.setIdPublisher(p1);
+            magazine.setName("magagine"+i+"_"+p1.getName());
+            em.persist(magazine);
+        }
+
+        Publisher p2 = new Publisher();
+        p2.setName("publisher2");
+        em.persist(p2);
+   
+        for (int i = 0; i < 4; i++) {
+            Magazine magazine = new Magazine();
+            magazine.setIdPublisher(p2);
+            magazine.setName("magagine"+i+"_"+p2.getName());
+            em.persist(magazine);
+        }
+
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testOneToManyInverseEagerQuery() {
+        sql.clear();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAQuery q = em.createQuery("SELECT c FROM Customer c ");
+        List<Customer> res = q.getResultList(); 
+
+        assertEquals(1, res.size());
+
+        for (int i = 0; i < res.size(); i++) {
+            Customer c = (Customer)res.get(i);
+            Collection<Order> orders = c.getOrders();
+            for (Iterator<Order> iter=orders.iterator(); iter.hasNext();) {
+                Order order = (Order)iter.next();
+                assertEquals(order.getCustomer(), c);
+            }
+        }
+        
+        assertEquals(2, sql.size());
+        em.close();
+    }
+
+    public void testOneToOneInverseEagerQuery() {
+        sql.clear();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        String query = "select c FROM EntityCInverseEager c";
+        Query q = em.createQuery(query);
+        List<EntityCInverseEager> res = q.getResultList();
+        assertEquals(4, res.size());
+
+        for (int i = 0; i < res.size(); i++) {
+            EntityCInverseEager c = (EntityCInverseEager)res.get(i);
+            EntityDInverseEager d = c.getD();
+            assertEquals(c, d.getC());
+        }
+
+        assertEquals(1, sql.size());
+        em.close();
+    }
+
+    public void testOneToManyInheritanceQuery() {
+        sql.clear();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        String query = "select a FROM EntityA1InverseEager a";
+        Query q = em.createQuery(query);
+        List list = q.getResultList();
+        assertEquals(1, list.size());
+        for (int i = 0; i < list.size(); i++) {
+            EntityA1InverseEager a1 = (EntityA1InverseEager)list.get(i);
+            Collection<EntityBInverseEager> listB = a1.getListB();
+            assertEquals(4, listB.size());
+            for (Iterator iter=listB.iterator(); iter.hasNext();) {
+                EntityBInverseEager b = (EntityBInverseEager)iter.next();
+                EntityAInverseEager a = b.getA();
+                assertEquals(a1, a);
+            }
+        }
+        assertEquals(3, sql.size());
+        sql.clear();
+
+        query = "select a FROM EntityA2InverseEager a";
+        q = em.createQuery(query);
+        list = q.getResultList();
+        assertEquals(1, list.size());
+        for (int i = 0; i < list.size(); i++) {
+            EntityA2InverseEager a2 = (EntityA2InverseEager)list.get(i);
+            Collection listB = a2.getListB();
+            assertEquals(4, listB.size());
+            for (Iterator iter=listB.iterator(); iter.hasNext();) {
+                EntityBInverseEager b = (EntityBInverseEager)iter.next();
+                EntityAInverseEager a = b.getA();
+                assertEquals(a2, a);
+            }
+        }
+        assertEquals(3, sql.size());
+        sql.clear();
+        
+        query = "select a FROM EntityAInverseEager a";
+        q = em.createQuery(query);
+        list = q.getResultList();
+        assertEquals(3, list.size());
+        for (int i = 0; i < list.size(); i++) {
+            EntityAInverseEager a0 = (EntityAInverseEager)list.get(i);
+            Collection listB = a0.getListB();
+            assertEquals(4, listB.size());
+            for (Iterator iter=listB.iterator(); iter.hasNext();) {
+                EntityBInverseEager b = (EntityBInverseEager)iter.next();
+                EntityAInverseEager a = b.getA();
+                assertEquals(a0, a);
+            }
+        }
+        
+        assertEquals(2, sql.size());
+        em.close();
+    }
+
+    public void testOneToManyEagerInverseLazyQuery() {
+        sql.clear();
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        String query = "select p FROM Publisher p";
+        Query q = em.createQuery(query);
+        List list = q.getResultList();
+        assertEquals(2, list.size());
+        assertEquals(2, sql.size());
+
+        sql.clear();
+        em.clear();
+        for (int i = 0; i < list.size(); i++) {
+            Publisher p = (Publisher) list.get(i);
+            Set<Magazine> magazines = p.getMagazineCollection();
+            assertEquals(4, magazines.size());
+            for (Iterator iter = magazines.iterator(); iter.hasNext();) {
+                Magazine m = (Magazine) iter.next();
+                Publisher mp = m.getIdPublisher();
+                assertEquals(p, mp);
+            }
+        }
+
+        assertEquals(0, sql.size());
+        em.close();
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(TestInverseEagerSQL.class);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLazyManyToOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLazyManyToOne.java
index 5b36e0c..5b0acad 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLazyManyToOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLazyManyToOne.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.DynamicPersistenceCapable;
-
-public class TestLazyManyToOne extends SQLListenerTestCase {
-
-    private int id;
-
-    public void setUp() {
-        setUp(BasicEntity.class, UnidirectionalManyToOne.class, CLEAR_TABLES);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        UnidirectionalManyToOne pc = new UnidirectionalManyToOne();
-        pc.setRelated(new BasicEntity());
-        pc.getRelated().setName("foo");
-        em.persist(pc);
-        em.getTransaction().commit();
-        id = pc.getId();
-        em.close();
-
-        sql.clear();
-    }
-
-    public void testLazyManyToOne() {
-        EntityManager em = emf.createEntityManager();
-        UnidirectionalManyToOne pc = em.find(UnidirectionalManyToOne.class, id);
-        if (pc instanceof PersistenceCapable // unenhanced has inefficiencies
-            && !(pc instanceof DynamicPersistenceCapable))
-            assertEquals(1, sql.size());
-        assertNotNull(pc.getRelated());
-        if (pc instanceof PersistenceCapable // unenhanced has inefficiencies
-            && !(pc instanceof DynamicPersistenceCapable))
-            assertEquals(2, sql.size());
-        em.close();
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.DynamicPersistenceCapable;
+
+public class TestLazyManyToOne extends SQLListenerTestCase {
+
+    private int id;
+
+    public void setUp() {
+        setUp(BasicEntity.class, UnidirectionalManyToOne.class, CLEAR_TABLES);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        UnidirectionalManyToOne pc = new UnidirectionalManyToOne();
+        pc.setRelated(new BasicEntity());
+        pc.getRelated().setName("foo");
+        em.persist(pc);
+        em.getTransaction().commit();
+        id = pc.getId();
+        em.close();
+
+        sql.clear();
+    }
+
+    public void testLazyManyToOne() {
+        EntityManager em = emf.createEntityManager();
+        UnidirectionalManyToOne pc = em.find(UnidirectionalManyToOne.class, id);
+        if (pc instanceof PersistenceCapable // unenhanced has inefficiencies
+            && !(pc instanceof DynamicPersistenceCapable))
+            assertEquals(1, sql.size());
+        assertNotNull(pc.getRelated());
+        if (pc instanceof PersistenceCapable // unenhanced has inefficiencies
+            && !(pc instanceof DynamicPersistenceCapable))
+            assertEquals(2, sql.size());
+        em.close();
+    }
+
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestMapCollectionToBlob.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestMapCollectionToBlob.java
index f8bb7cb..8054350 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestMapCollectionToBlob.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestMapCollectionToBlob.java
@@ -1,52 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.sql.Types;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.FieldMapping;
-import org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestMapCollectionToBlob
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(HandlerToHandlerMapInstance.class, CLEAR_TABLES,
-            "openjpa.Compatibility", "StoreMapCollectionInEntityAsBlob=true");
-    }
-
-    public void testHandlerToHandlerMaps() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
-            HandlerToHandlerMapInstance.class);
-        FieldMapping fm = cm.getFieldMapping("map");        
-        assertEquals(HandlerFieldStrategy.class, fm.getStrategy().getClass());
-        assertEquals("NONSTD_MAPPING_MAP", fm.getTable().getName());
-        assertEquals(fm.getTable().getColumn("MAP").getType(), Types.BLOB);
-
-        HandlerToHandlerMapInstance o = new HandlerToHandlerMapInstance();
-        o.getMap().put("foo", "bar");
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.sql.Types;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestMapCollectionToBlob
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(HandlerToHandlerMapInstance.class, CLEAR_TABLES,
+            "openjpa.Compatibility", "StoreMapCollectionInEntityAsBlob=true");
+    }
+
+    public void testHandlerToHandlerMaps() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
+            HandlerToHandlerMapInstance.class);
+        FieldMapping fm = cm.getFieldMapping("map");        
+        assertEquals(HandlerFieldStrategy.class, fm.getStrategy().getClass());
+        assertEquals("NONSTD_MAPPING_MAP", fm.getTable().getName());
+        assertEquals(fm.getTable().getColumn("MAP").getType(), Types.BLOB);
+
+        HandlerToHandlerMapInstance o = new HandlerToHandlerMapInstance();
+        o.getMap().put("foo", "bar");
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToHandlerMaps.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToHandlerMaps.java
index bd97b8f..a3fdee3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToHandlerMaps.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToHandlerMaps.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import java.net.MalformedURLException;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.RelationHandlerMapTableFieldStrategy;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestRelationToHandlerMaps
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(RelationToHandlerMapInstance.class, AllFieldTypes.class,
-            CLEAR_TABLES);
-    }
-
-    public void testRelationToHandlerMaps() throws MalformedURLException {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
-            RelationToHandlerMapInstance.class);
-        assertEquals(RelationHandlerMapTableFieldStrategy.class,
-            cm.getFieldMapping("aftMap").getStrategy().getClass());
-
-        RelationToHandlerMapInstance o = new RelationToHandlerMapInstance();
-        AllFieldTypes key = new AllFieldTypes();
-        o.getMap().put(key, "foo");
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.net.MalformedURLException;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.RelationHandlerMapTableFieldStrategy;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestRelationToHandlerMaps
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(RelationToHandlerMapInstance.class, AllFieldTypes.class,
+            CLEAR_TABLES);
+    }
+
+    public void testRelationToHandlerMaps() throws MalformedURLException {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
+            RelationToHandlerMapInstance.class);
+        assertEquals(RelationHandlerMapTableFieldStrategy.class,
+            cm.getFieldMapping("aftMap").getStrategy().getClass());
+
+        RelationToHandlerMapInstance o = new RelationToHandlerMapInstance();
+        AllFieldTypes key = new AllFieldTypes();
+        o.getMap().put(key, "foo");
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToRelationMaps.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToRelationMaps.java
index 82b5699..eab1f9c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToRelationMaps.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestRelationToRelationMaps.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.jdbc.meta.strats.RelationRelationMapTableFieldStrategy;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.persistence.simple.AllFieldTypes;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-public class TestRelationToRelationMaps
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(RelationToRelationMapInstance.class, AllFieldTypes.class,
-            CLEAR_TABLES);
-    }
-
-    public void testRelationToRelationMaps() {
-        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
-            RelationToRelationMapInstance.class);
-        assertEquals(RelationRelationMapTableFieldStrategy.class,
-            cm.getFieldMapping("map").getStrategy().getClass());
-
-        RelationToRelationMapInstance o = new RelationToRelationMapInstance();
-        AllFieldTypes key = new AllFieldTypes();
-        AllFieldTypes val = new AllFieldTypes();
-        o.getMap().put(key, val);
-        em.getTransaction().begin();
-        em.persist(o);
-        em.getTransaction().commit();
-        em.close();
-    }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.strats.RelationRelationMapTableFieldStrategy;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+public class TestRelationToRelationMaps
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(RelationToRelationMapInstance.class, AllFieldTypes.class,
+            CLEAR_TABLES);
+    }
+
+    public void testRelationToRelationMaps() {
+        ClassMapping cm = (ClassMapping) JPAFacadeHelper.getMetaData(em,
+            RelationToRelationMapInstance.class);
+        assertEquals(RelationRelationMapTableFieldStrategy.class,
+            cm.getFieldMapping("map").getStrategy().getClass());
+
+        RelationToRelationMapInstance o = new RelationToRelationMapInstance();
+        AllFieldTypes key = new AllFieldTypes();
+        AllFieldTypes val = new AllFieldTypes();
+        o.getMap().put(key, val);
+        em.getTransaction().begin();
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+    }
 }
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/UnidirectionalManyToOne.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/UnidirectionalManyToOne.java
index c4c0bfd..4bec8e3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/UnidirectionalManyToOne.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/UnidirectionalManyToOne.java
@@ -1,53 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.relations;
-
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.FetchType;
-import javax.persistence.Entity;
-import javax.persistence.CascadeType;
-
-@Entity
-public class UnidirectionalManyToOne {
-
-    @Id
-    @GeneratedValue
-    private int id;
-
-    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
-    private BasicEntity related;
-
-    public void setRelated(BasicEntity related) {
-        this.related = related;
-    }
-
-    public BasicEntity getRelated() {
-        return related;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.FetchType;
+import javax.persistence.Entity;
+import javax.persistence.CascadeType;
+
+@Entity
+public class UnidirectionalManyToOne {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    private BasicEntity related;
+
+    public void setRelated(BasicEntity related) {
+        this.related = related;
+    }
+
+    public BasicEntity getRelated() {
+        return related;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/EntityEmployee.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/EntityEmployee.java
new file mode 100644
index 0000000..8980e66
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/EntityEmployee.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.sequence;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+/**
+ * @author Tim McConnell
+ * @since 2.0.0
+ */
+@Entity
+@Table(name="ENTITY_EMPLOYEE")
+public class EntityEmployee implements Serializable {
+
+    private static final long serialVersionUID = 2961572787273807912L;
+    
+    @Id
+    @SequenceGenerator(name="SeqEmployee", sequenceName="test_native_sequence")
+    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SeqEmployee")
+    private int id; 
+    private String firstName;
+    private String lastName;
+    private float salary;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public float getSalary() {
+        return salary;
+    }
+
+    public void setSalary(float salary) {
+        this.salary = salary;
+    }
+
+    @Override
+    public String toString() {
+        return "EntityEmployee: Employee id: " + getId() + 
+               " firstName: " + getFirstName() +
+               " lastName: " + getLastName() +
+               " salary: " + getSalary();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+            + ((getFirstName() == null) ? 0 : getFirstName().hashCode());
+        result = prime * result + getId();
+        result = prime * result
+            + ((getLastName() == null) ? 0 : getLastName().hashCode());
+        result = prime * result + Float.floatToIntBits(getSalary());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final EntityEmployee other = (EntityEmployee) obj;
+        if (getId() != other.getId()) {
+            return false;
+        }
+        if (getFirstName() == null) {
+            if (other.getFirstName() != null) {
+                return false;
+            }
+        }
+        else if (!getFirstName().equals(other.getFirstName())) {
+            return false;
+        }
+        if (getLastName() == null) {
+            if (other.getLastName() != null) {
+                return false;
+            }
+        }
+        else if (!getLastName().equals(other.getLastName())) {
+            return false;
+        }
+        if (Float.floatToIntBits(getSalary()) != Float.floatToIntBits(other
+            .getSalary())) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/EntityPerson.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/EntityPerson.java
new file mode 100644
index 0000000..e8c925c
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/EntityPerson.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.sequence;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+/**
+ * @author Tim McConnell
+ * @since 2.0.0
+ */
+@Entity
+@Table(name="ENTITY_PERSON")
+public class EntityPerson implements Serializable {
+
+    private static final long serialVersionUID = 3772049669261731520L;
+    
+    @Id
+    @SequenceGenerator(name="SeqPerson", sequenceName="test_native_sequence")
+    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SeqPerson")
+    private int id; 
+    private String firstName;
+    private String lastName;
+
+
+    public EntityPerson() {
+    }
+
+    public EntityPerson(String firstName, String lastName) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    @Override
+    public String toString() {
+        return "EntityPerson: Person id: " + getId() + 
+               " firstName: " + getFirstName() +
+               " lastName: " + getLastName();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+            + ((getFirstName() == null) ? 0 : getFirstName().hashCode());
+        result = prime * result + getId();
+        result = prime * result
+            + ((getLastName() == null) ? 0 : getLastName().hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final EntityPerson other = (EntityPerson) obj;
+        if (getId() != other.getId()) {
+            return false;
+        }
+        if (getFirstName() == null) {
+            if (other.getFirstName() != null) {
+                return false;
+            }
+        }
+        else if (!getFirstName().equals(other.getFirstName())) {
+            return false;
+        }
+        if (getLastName() == null) {
+            if (other.getLastName() != null) {
+                return false;
+            }
+        }
+        else if (!getLastName().equals(other.getLastName())) {
+            return false;
+        }
+        return true;
+    } 
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/TestSequence.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/TestSequence.java
new file mode 100644
index 0000000..ee9075a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/sequence/TestSequence.java
@@ -0,0 +1,543 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agEmployee_Last_Name to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.sequence;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * @author Tim McConnell
+ * @since 2.0.0
+ */
+public class TestSequence extends SingleEMFTestCase {
+
+    private String multiThreadExecuting = null;
+    private static final int NUMBER_ENTITIES = 5000;
+
+    public void setUp() {
+        setUp(EntityPerson.class, EntityEmployee.class, CLEAR_TABLES,
+            "openjpa.Multithreaded", "true");
+    }
+
+    // Override teardown to preserve database contents
+    @Override
+    public void tearDown() throws Exception {
+    }
+
+    public void testMultiThreadedNativeSequences() throws Exception {
+        boolean supportsNativeSequence = false;
+
+        try {
+            supportsNativeSequence = ((JDBCConfiguration) emf
+                .getConfiguration()).getDBDictionaryInstance()
+                .nextSequenceQuery != null;
+        } catch (Throwable t) {
+            supportsNativeSequence = false;
+        }
+
+        if (supportsNativeSequence) {
+            mttest(6, 8);
+            switch ((int) (Math.random() * 7)) {
+            case 0:
+                createAndRemove();
+                break;
+            case 1:
+                createManyPersonsInSeparateTransactions();
+                break;
+            case 2:
+                createManyEmployeesInSeparateTransactions();
+                break;
+            case 3:
+                createManyPersonsAndEmployeesInSeparateTransactions();
+                break;
+            case 4:
+                createManyPersonsInSingleTransaction();
+                break;
+            case 5:
+                createManyEmployeesInSingleTransaction();
+                break;
+            case 6:
+                createManyPersonsAndEmployeesInSingleTransaction();
+                break;
+            }
+        }
+    }
+
+    private void createAndRemove() {
+        int person_id;
+        int employee_id;
+
+        EntityManager em = emf.createEntityManager();
+
+        EntityPerson person = new EntityPerson();
+        person.setFirstName("Person_First_Name");
+        person.setLastName("Person_Last_Name");
+
+        EntityEmployee employee = new EntityEmployee();
+        employee.setFirstName("Employee_First_Name");
+        employee.setLastName("Employee_Last_Name");
+        employee.setSalary(NUMBER_ENTITIES);
+
+        em.getTransaction().begin();
+        em.persist(person);
+        em.persist(employee);
+        em.getTransaction().commit();
+
+        em.refresh(person);
+        em.refresh(employee);
+        person_id = person.getId();
+        employee_id = employee.getId();
+
+        person = em.find(EntityPerson.class, person_id);
+        assertTrue(person != null);
+        assertTrue(person.getId() == person_id);
+        assertTrue(person.getFirstName().equals("Person_First_Name"));
+        assertTrue(person.getLastName().equals("Person_Last_Name"));
+
+        employee = em.find(EntityEmployee.class, employee_id);
+        assertTrue(employee != null);
+        assertTrue(employee.getId() == employee_id);
+        assertTrue(employee.getFirstName().equals("Employee_First_Name"));
+        assertTrue(employee.getLastName().equals("Employee_Last_Name"));
+        assertTrue(employee.getSalary() == NUMBER_ENTITIES);
+
+        em.getTransaction().begin();
+        em.remove(person);
+        em.remove(employee);
+        em.getTransaction().commit();
+
+        em.clear();
+        em.close();
+    }
+
+    private void createManyPersonsInSeparateTransactions() {
+        EntityManager em = emf.createEntityManager();
+
+        for (int ii = 0; ii < NUMBER_ENTITIES; ii++) {
+            EntityPerson person = new EntityPerson();
+            person.setFirstName("1_First_name_" + ii);
+            person.setLastName("1_Last_name_" + ii);
+
+            em.getTransaction().begin();
+            em.persist(person);
+            em.getTransaction().commit();
+        }
+
+        em.clear();
+        em.close();
+    }
+
+    private void createManyEmployeesInSeparateTransactions() {
+        EntityManager em = emf.createEntityManager();
+
+        for (int ii = 0; ii < NUMBER_ENTITIES; ii++) {
+            EntityEmployee employee = new EntityEmployee();
+            employee.setFirstName("2_First_name_" + ii);
+            employee.setLastName("2_Last_name_" + ii);
+            employee.setSalary(ii);
+
+            em.getTransaction().begin();
+            em.persist(employee);
+            em.getTransaction().commit();
+        }
+
+        em.clear();
+        em.close();
+    }
+
+    private void createManyPersonsAndEmployeesInSeparateTransactions() {
+        EntityManager em = emf.createEntityManager();
+
+        for (int ii = 0; ii < NUMBER_ENTITIES; ii++) {
+            EntityPerson person = new EntityPerson();
+            person.setFirstName("3_First_name_" + ii);
+            person.setLastName("3_Last_name_" + ii);
+
+            EntityEmployee employee = new EntityEmployee();
+            employee.setFirstName("4_First_name_" + ii);
+            employee.setLastName("4_Last_name_" + ii);
+            employee.setSalary(ii);
+
+            em.getTransaction().begin();
+            em.persist(person);
+            em.persist(employee);
+            em.getTransaction().commit();
+        }
+
+        em.clear();
+        em.close();
+    }
+
+    private void createManyPersonsInSingleTransaction() {
+        EntityManager em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        for (int ii = 0; ii < NUMBER_ENTITIES; ii++) {
+            EntityPerson person = new EntityPerson();
+            person.setFirstName("5_First_name_" + ii);
+            person.setLastName("5_Last_name_" + ii);
+
+            em.persist(person);
+        }
+        em.getTransaction().commit();
+
+        em.clear();
+        em.close();
+    }
+
+    private void createManyEmployeesInSingleTransaction() {
+        EntityManager em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        for (int ii = 0; ii < NUMBER_ENTITIES; ii++) {
+            EntityEmployee employee = new EntityEmployee();
+            employee.setFirstName("6_First_name_" + ii);
+            employee.setLastName("6_Last_name_" + ii);
+            employee.setSalary(ii);
+
+            em.persist(employee);
+        }
+        em.getTransaction().commit();
+
+        em.clear();
+        em.close();
+    }
+
+    private void createManyPersonsAndEmployeesInSingleTransaction() {
+        EntityManager em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        for (int ii = 0; ii < NUMBER_ENTITIES; ii++) {
+            EntityPerson person = new EntityPerson();
+            person.setFirstName("7_First_name_" + ii);
+            person.setLastName("7_Last_name_" + ii);
+
+            EntityEmployee employee = new EntityEmployee();
+            employee.setFirstName("8_First_name_" + ii);
+            employee.setLastName("8_Last_name_" + ii);
+            employee.setSalary(ii);
+
+            em.persist(person);
+            em.persist(employee);
+        }
+        em.getTransaction().commit();
+
+        em.clear();
+        em.close();
+    }
+
+    /**
+     * Re-execute the invoking method a random number of times in a random
+     * number of Threads.
+     */
+    public void mttest() throws ThreadingException {
+        // 6 iterations in 8 threads is a good trade-off between
+        // tests taking way too long and having a decent chance of
+        // identifying MT problems.
+        int iterations = 6;
+        int threads = 8;
+
+        mttest(threads, iterations);
+    }
+
+    /**
+     * Execute the calling method <code>iterations</code> times in
+     * <code>threads</code> Threads.
+     */
+    public void mttest(int threads, int iterations) {
+        mttest(0, threads, iterations);
+    }
+
+    public void mttest(int serialCount, int threads, int iterations)
+        throws ThreadingException {
+        String methodName = callingMethod("mttest");
+        mttest(serialCount, threads, iterations, methodName, new Object[0]);
+    }
+
+    /**
+     * Execute a test method in multiple threads.
+     * 
+     * @param threads
+     *            the number of Threads to run in
+     * @param iterations
+     *            the number of times the method should be execute in a single
+     *            Thread
+     * @param method
+     *            the name of the method to execute
+     * @param args
+     *            the arguments to pass to the method
+     * @throws ThreadingException
+     *             if an errors occur in any of the Threads. The actual
+     *             exceptions will be embedded in the exception. Note that this
+     *             means that assert() failures will be treated as errors rather
+     *             than warnings.
+     * @author Marc Prud'hommeaux
+     */
+    public void mttest(int threads, int iterations, final String method,
+        final Object[] args) throws ThreadingException {
+        mttest(0, threads, iterations, method, args);
+    }
+
+    public void mttest(int serialCount, int threads, int iterations,
+        final String method, final Object[] args) throws ThreadingException {
+        if (multiThreadExecuting != null 
+            && multiThreadExecuting.equals(method)) {
+            // we are currently executing in multi-threaded mode:
+            // don't deadlock!
+            return;
+        }
+
+        multiThreadExecuting = method;
+
+        try {
+            Class<?>[] paramClasses = new Class[args.length];
+            for (int i = 0; i < paramClasses.length; i++)
+                paramClasses[i] = args[i].getClass();
+
+            final Method meth;
+
+            try {
+                meth = getClass().getMethod(method, paramClasses);
+            } catch (NoSuchMethodException nsme) {
+                throw new ThreadingException(nsme.toString(), nsme);
+            }
+
+            final Object thiz = this;
+
+            mttest("reflection invocation: (" + method + ")", serialCount,
+                threads, iterations, new VolatileRunnable() {
+                    public void run() throws Exception {
+                        meth.invoke(thiz, args);
+                    }
+                });
+        } finally {
+            multiThreadExecuting = null;
+        }
+    }
+
+    public void mttest(String title, final int threads, final int iterations,
+        final VolatileRunnable runner) throws ThreadingException {
+        mttest(title, 0, threads, iterations, runner);
+    }
+
+    /**
+     * Execute a test method in multiple threads.
+     * 
+     * @param title
+     *            a description of the test, for inclusion in the error message
+     * @param serialCount
+     *            the number of times to run the method serially before spawning
+     *            threads.
+     * @param threads
+     *            the number of Threads to run in
+     * @param iterations
+     *            the number of times the method should
+     * @param runner
+     *            the VolatileRunnable that will execute the actual test from
+     *            within the Thread.
+     * @throws ThreadingException
+     *             if an errors occur in any of the Threads. The actual
+     *             exceptions will be embedded in the exception. Note that this
+     *             means that assert() failures will be treated as errors rather
+     *             than warnings.
+     * @author Marc Prud'hommeaux
+     */
+    public void mttest(String title, final int serialCount, final int threads,
+        final int iterations, final VolatileRunnable runner)
+        throws ThreadingException {
+        final List exceptions = Collections.synchronizedList(new LinkedList());
+
+        Thread[] runners = new Thread[threads];
+
+        final long startMillis = System.currentTimeMillis() + 1000;
+
+        for (int i = 1; i <= threads; i++) {
+            final int thisThread = i;
+
+            runners[i - 1] = new Thread(title + " [" + i + " of " + threads
+                + "]") {
+                public void run() {
+                    // do our best to have all threads start at the exact
+                    // same time. This is imperfect, but the closer we
+                    // get to everyone starting at the same time, the
+                    // better chance we have for identifying MT problems.
+                    while (System.currentTimeMillis() < startMillis)
+                        yield();
+
+                    int thisIteration = 1;
+                    try {
+                        for (; thisIteration <= iterations; thisIteration++) {
+                            // go go go!
+                            runner.run();
+                        }
+                    } catch (Throwable error) {
+                        synchronized (exceptions) {
+                            // embed the exception into something that gives
+                            // us some more information about the threading
+                            // environment
+                            exceptions.add(new ThreadingException("thread="
+                                + this.toString() + ";threadNum=" + thisThread
+                                + ";maxThreads=" + threads + ";iteration="
+                                + thisIteration + ";maxIterations="
+                                + iterations, error));
+                        }
+                    }
+                }
+            };
+        }
+
+        // start the serial tests(does not spawn the threads)
+        for (int i = 0; i < serialCount; i++) {
+            runners[0].run();
+        }
+
+        // start the multithreaded
+        for (int i = 0; i < threads; i++) {
+            runners[i].start();
+        }
+
+        // wait for them all to complete
+        for (int i = 0; i < threads; i++) {
+            try {
+                runners[i].join();
+            } catch (InterruptedException e) {
+            }
+        }
+
+        if (exceptions.size() == 0)
+            return; // sweeeeeeeet: no errors
+
+        // embed all the exceptions that were throws into a
+        // ThreadingException
+        Throwable[] errors = (Throwable[]) exceptions.toArray(new Throwable[0]);
+        throw new ThreadingException("The " + errors.length
+            + " embedded errors " + "occured in the execution of " + iterations
+            + " iterations " + "of " + threads + " threads: [" + title + "]",
+            errors);
+    }
+
+    /**
+     * Check to see if we are in the top-level execution stack.
+     */
+    public boolean isRootThread() {
+        return multiThreadExecuting == null;
+    }
+
+    /**
+     * A Runnable that can throw an Exception: used to test cases.
+     */
+    public static interface VolatileRunnable {
+
+        public void run() throws Exception;
+    }
+
+    /**
+     * Exception for errors caught during threading tests.
+     */
+    public class ThreadingException extends RuntimeException {
+
+        private static final long serialVersionUID = -1911769845552507956L;
+        private final Throwable[] _nested;
+
+        public ThreadingException(String msg, Throwable nested) {
+            super(msg);
+            if (nested == null)
+                _nested = new Throwable[0];
+            else
+                _nested = new Throwable[] { nested };
+        }
+
+        public ThreadingException(String msg, Throwable[] nested) {
+            super(msg);
+            if (nested == null)
+                _nested = new Throwable[0];
+            else
+                _nested = nested;
+        }
+
+        public void printStackTrace() {
+            printStackTrace(System.out);
+        }
+
+        public void printStackTrace(PrintStream out) {
+            printStackTrace(new PrintWriter(out));
+        }
+
+        public void printStackTrace(PrintWriter out) {
+            super.printStackTrace(out);
+            for (int i = 0; i < _nested.length; i++) {
+                out.print("Nested Throwable #" + (i + 1) + ": ");
+                _nested[i].printStackTrace(out);
+            }
+        }
+    }
+
+    /**
+     * Return the last method name that called this one by parsing the current
+     * stack trace.
+     * 
+     * @param exclude
+     *            a method name to skip
+     * @throws IllegalStateException
+     *             If the calling method could not be identified.
+     * @author Marc Prud'hommeaux
+     */
+    public String callingMethod(String exclude) {
+        // determine the currently executing method by
+        // looking at the stack track. Hackish, but convenient.
+        StringWriter sw = new StringWriter();
+        new Exception().printStackTrace(new PrintWriter(sw));
+        for (StringTokenizer stackTrace = new StringTokenizer(sw.toString(),
+            System.getProperty("line.separator"))
+            ; stackTrace.hasMoreTokens() ; ) {
+            String line = stackTrace.nextToken().trim();
+
+            // not a stack trace element
+            if (!(line.startsWith("at ")))
+                continue;
+
+            String fullMethodName = line.substring(0, line.indexOf("("));
+
+            String shortMethodName = fullMethodName.substring(fullMethodName
+                .lastIndexOf(".") + 1);
+
+            // skip our own methods!
+            if (shortMethodName.equals("callingMethod"))
+                continue;
+            if (exclude != null && shortMethodName.equals(exclude))
+                continue;
+
+            return shortMethodName;
+        }
+
+        throw new IllegalStateException("Could not identify calling "
+            + "method in stack trace");
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/NamedEntity.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/NamedEntity.java
index 312934d..425d4fa 100755
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/NamedEntity.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/NamedEntity.java
@@ -1,49 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.simple;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Version;
-
-@Entity(name="named")
-public class NamedEntity {
-
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String name;
-
-    @Version
-    private Integer optLock;
-
-    public long getId() { 
-        return id; 
-    }
-
-    public String getName() { 
-        return name; 
-    }
-
-    public void setName(String name) { 
-        this.name = name; 
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.simple;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+@Entity(name="named")
+public class NamedEntity {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @Version
+    private Integer optLock;
+
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestBasicAnnotation.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestBasicAnnotation.java
index 390339d..3c44eb6 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestBasicAnnotation.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestBasicAnnotation.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.simple;
-
-import java.math.BigDecimal;
-import java.util.Calendar;
-import java.util.Date;
-
-import javax.persistence.EntityManager;
-
-import junit.textui.TestRunner;
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-
-/**
- * Simple test case to test the default values associated with the @Basic 
- * annotation.
- *
- * @author Kevin Sutter
- */
-public class TestBasicAnnotation
-    extends SingleEMFTestCase {
-
-    public void setUp() {
-        setUp(CLEAR_TABLES, AllFieldTypes.class);
-    }
-
-    public void testEagerFetchType() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        AllFieldTypes aft = new AllFieldTypes();
-        
-        // Initialize a sampling of the types
-        aft.setBigDecimalField(new BigDecimal(1));
-        aft.setBooleanField(false);
-        aft.setByteLob(new byte[1]);
-        aft.setCalendarField(Calendar.getInstance());
-        aft.setDateField(new Date());
-        aft.setEnumField(AllFieldTypes.EnumType.Value1);
-        aft.setSerializableField(new Date());
-        aft.setSqlTimestampField(new java.sql.Timestamp(
-                System.currentTimeMillis()));
-        aft.setStringField("aft");
-        aft.setWByteLob(new Byte[1]);
-        aft.setWDoubleField(new Double(1));
-        
-        em.persist(aft);
-        em.getTransaction().commit();
-        em.clear();
-        
-        AllFieldTypes aftQuery = (AllFieldTypes)em.createQuery
-            ("select x from AllFieldTypes x where x.stringField = 'aft'").
-            getSingleResult();
-        em.clear();  // ensure detached
-        assertFalse(em.contains(aftQuery));
-        
-        // assert that the sampling of fields are not null
-        assertNotNull(aftQuery.getBigDecimalField());
-        assertNotNull(aftQuery.getBooleanField());
-        assertNotNull(aftQuery.getByteLob());
-        assertNotNull(aftQuery.getCalendarField());
-        assertNotNull(aftQuery.getDateField());
-        assertNotNull(aftQuery.getEnumField());
-        assertNotNull(aftQuery.getSerializableField());
-        assertNotNull(aftQuery.getSqlTimestampField());
-        assertNotNull(aftQuery.getStringField());
-        assertNotNull(aftQuery.getWByteLob());
-        assertNotNull(aftQuery.getWDoubleField());
-        
-        em.close();
-    }
-
-    public static void main(String[] args) {
-        TestRunner.run(TestBasicAnnotation.class);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.simple;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Date;
+
+import javax.persistence.EntityManager;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Simple test case to test the default values associated with the @Basic 
+ * annotation.
+ *
+ * @author Kevin Sutter
+ */
+public class TestBasicAnnotation
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(CLEAR_TABLES, AllFieldTypes.class);
+    }
+
+    public void testEagerFetchType() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        AllFieldTypes aft = new AllFieldTypes();
+        
+        // Initialize a sampling of the types
+        aft.setBigDecimalField(new BigDecimal(1));
+        aft.setBooleanField(false);
+        aft.setByteLob(new byte[1]);
+        aft.setCalendarField(Calendar.getInstance());
+        aft.setDateField(new Date());
+        aft.setEnumField(AllFieldTypes.EnumType.Value1);
+        aft.setSerializableField(new Date());
+        aft.setSqlTimestampField(new java.sql.Timestamp(
+                System.currentTimeMillis()));
+        aft.setStringField("aft");
+        aft.setWByteLob(new Byte[1]);
+        aft.setWDoubleField(new Double(1));
+        
+        em.persist(aft);
+        em.getTransaction().commit();
+        em.clear();
+        
+        AllFieldTypes aftQuery = (AllFieldTypes)em.createQuery
+            ("select x from AllFieldTypes x where x.stringField = 'aft'").
+            getSingleResult();
+        em.clear();  // ensure detached
+        assertFalse(em.contains(aftQuery));
+        
+        // assert that the sampling of fields are not null
+        assertNotNull(aftQuery.getBigDecimalField());
+        assertNotNull(aftQuery.getBooleanField());
+        assertNotNull(aftQuery.getByteLob());
+        assertNotNull(aftQuery.getCalendarField());
+        assertNotNull(aftQuery.getDateField());
+        assertNotNull(aftQuery.getEnumField());
+        assertNotNull(aftQuery.getSerializableField());
+        assertNotNull(aftQuery.getSqlTimestampField());
+        assertNotNull(aftQuery.getStringField());
+        assertNotNull(aftQuery.getWByteLob());
+        assertNotNull(aftQuery.getWDoubleField());
+        
+        em.close();
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(TestBasicAnnotation.class);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestEntityManagerMerge.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestEntityManagerMerge.java
index 88fd5a7..47ae8de 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestEntityManagerMerge.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestEntityManagerMerge.java
@@ -1,115 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence.simple;
-
-import javax.persistence.EntityManager;
-
-import junit.textui.TestRunner;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
-
-/**
- * Test case to ensure that the proper JPA merge semantics are processed.
- *
- * @author Kevin Sutter
- */
-public class TestEntityManagerMerge
-    extends SingleEMTestCase {
-
-    public void setUp() {
-        setUp(AllFieldTypes.class, Person.class);
-    }
-
-    public void testMerge() {
-        // Create EntityManager and Start a transaction (1)
-        begin();
-
-        // Insert a new object into the PC
-        AllFieldTypes testObject = new AllFieldTypes();
-        testObject.setStringField("new test object");
-        persist(testObject);
-        assertTrue("testObject not found in pc", em.contains(testObject));
-        
-        // Modify this object...
-        testObject.setStringField("updated test object");
-
-        // Attempt to merge this updated object into the PC.  Should be ignored.
-        AllFieldTypes mergedObject = em.merge(testObject);
-        assertTrue("mergedObject and testObject are not equal", 
-                mergedObject.equals(testObject));
-        assertTrue("mergedObject and testObject are not ==", 
-                mergedObject == testObject);
-        assertTrue("testObject not found in pc", em.contains(testObject));
-        assertTrue("mergedObject not found in pc", em.contains(mergedObject));
-        
-        // And, once again...
-        testObject.setStringField("yet another update");
-        AllFieldTypes mergedObject2 = em.merge(testObject);
-        assertTrue("mergedObject2 and testObject are not equal", 
-                mergedObject2.equals(testObject));
-        assertTrue("mergedObject2 and testObject are not ==", 
-                mergedObject2 == testObject);
-        assertTrue("testObject not found in pc", em.contains(testObject));
-        assertTrue("mergedObject2 not found in pc", em.contains(mergedObject2));
-        
-        // Rollback
-        rollback();
-  
-    }
-    
-    /**
-     * This test verifies that persisting a new entity which matches an existing 
-     * row in the database succeeds. 
-     */
-    public void testMergeExistingEntity() {
-        Person p = new Person();
-        p.setId(102);
-
-        EntityManager em = emf.createEntityManager();
-
-        em.getTransaction().begin();
-        em.persist(p);
-        em.getTransaction().commit();
-        em.close();
-
-        em = emf.createEntityManager();
-        p = new Person();
-        p.setId(102);
-        p.setForename("Jane");
-
-        em.getTransaction().begin();
-        em.merge(p);
-        em.getTransaction().commit();
-
-        em.close();
-
-        em = emf.createEntityManager();
-        p = (Person) em.createQuery("Select p from Person p where p.id = 102")
-                .getSingleResult();
-
-        assertNotNull(p);
-        assertEquals("Jane", p.getForename());
-        
-        em.close();
-    }
-    
-    public static void main(String[] args) {
-        TestRunner.run(TestEntityManagerMerge.class);
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence.simple;
+
+import javax.persistence.EntityManager;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+/**
+ * Test case to ensure that the proper JPA merge semantics are processed.
+ *
+ * @author Kevin Sutter
+ */
+public class TestEntityManagerMerge
+    extends SingleEMTestCase {
+
+    public void setUp() {
+        setUp(AllFieldTypes.class, Person.class);
+    }
+
+    public void testMerge() {
+        // Create EntityManager and Start a transaction (1)
+        begin();
+
+        // Insert a new object into the PC
+        AllFieldTypes testObject = new AllFieldTypes();
+        testObject.setStringField("new test object");
+        persist(testObject);
+        assertTrue("testObject not found in pc", em.contains(testObject));
+        
+        // Modify this object...
+        testObject.setStringField("updated test object");
+
+        // Attempt to merge this updated object into the PC.  Should be ignored.
+        AllFieldTypes mergedObject = em.merge(testObject);
+        assertTrue("mergedObject and testObject are not equal", 
+                mergedObject.equals(testObject));
+        assertTrue("mergedObject and testObject are not ==", 
+                mergedObject == testObject);
+        assertTrue("testObject not found in pc", em.contains(testObject));
+        assertTrue("mergedObject not found in pc", em.contains(mergedObject));
+        
+        // And, once again...
+        testObject.setStringField("yet another update");
+        AllFieldTypes mergedObject2 = em.merge(testObject);
+        assertTrue("mergedObject2 and testObject are not equal", 
+                mergedObject2.equals(testObject));
+        assertTrue("mergedObject2 and testObject are not ==", 
+                mergedObject2 == testObject);
+        assertTrue("testObject not found in pc", em.contains(testObject));
+        assertTrue("mergedObject2 not found in pc", em.contains(mergedObject2));
+        
+        // Rollback
+        rollback();
+  
+    }
+    
+    /**
+     * This test verifies that persisting a new entity which matches an existing 
+     * row in the database succeeds. 
+     */
+    public void testMergeExistingEntity() {
+        Person p = new Person();
+        p.setId(102);
+
+        EntityManager em = emf.createEntityManager();
+
+        em.getTransaction().begin();
+        em.persist(p);
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        p = new Person();
+        p.setId(102);
+        p.setForename("Jane");
+
+        em.getTransaction().begin();
+        em.merge(p);
+        em.getTransaction().commit();
+
+        em.close();
+
+        em = emf.createEntityManager();
+        p = (Person) em.createQuery("Select p from Person p where p.id = 102")
+                .getSingleResult();
+
+        assertNotNull(p);
+        assertEquals("Jane", p.getForename());
+        
+        em.close();
+    }
+    
+    public static void main(String[] args) {
+        TestRunner.run(TestEntityManagerMerge.class);
+    }
+}
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xml/TestPersistenceUnitWithoutXSD.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xml/TestPersistenceUnitWithoutXSD.java
index e5e7f47..6b666c8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xml/TestPersistenceUnitWithoutXSD.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/xml/TestPersistenceUnitWithoutXSD.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.xml;
-
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.openjpa.persistence.test.PersistenceTestCase;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openjpa.enhance.PCEnhancer;
-
-public class TestPersistenceUnitWithoutXSD extends PersistenceTestCase {
-
-    public void testPersistenceUnitWithoutXSD() {
-        EntityManagerFactory emf = OpenJPAPersistence
-            .createEntityManagerFactory("incorrect-ordering-and-no-xsd",
-                "org/apache/openjpa/persistence/xml/persistence-without-xsd.xml");
-        emf.createEntityManager().close();
-        emf.close();
-    }
-
-    public void testEnhancer() {
-        PCEnhancer.main(new String[] {
-            "-p",
-            "org/apache/openjpa/persistence/xml/persistence-without-xsd.xml",
-            SimpleXmlEntity.class.getName()
-        });
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.xml;
+
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.enhance.PCEnhancer;
+
+public class TestPersistenceUnitWithoutXSD extends PersistenceTestCase {
+
+    public void testPersistenceUnitWithoutXSD() {
+        EntityManagerFactory emf = OpenJPAPersistence
+            .createEntityManagerFactory("incorrect-ordering-and-no-xsd",
+                "org/apache/openjpa/persistence/xml/persistence-without-xsd.xml");
+        emf.createEntityManager().close();
+        emf.close();
+    }
+
+    public void testEnhancer() {
+        PCEnhancer.main(new String[] {
+            "-p",
+            "org/apache/openjpa/persistence/xml/persistence-without-xsd.xml",
+            SimpleXmlEntity.class.getName()
+        });
+    }
+}
diff --git a/openjpa-persistence-jdbc/src/test/resources/META-INF/listener-orm.xml b/openjpa-persistence-jdbc/src/test/resources/META-INF/listener-orm.xml
index 1cf7f09..fbab1f5 100644
--- a/openjpa-persistence-jdbc/src/test/resources/META-INF/listener-orm.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/META-INF/listener-orm.xml
@@ -1,37 +1,40 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
-    version="1.0">
-    <persistence-unit-metadata>
-        <persistence-unit-defaults>
-            <entity-listeners>
-                <entity-listener class=
-                	"org.apache.openjpa.persistence.callbacks.ListenerImpl">
-                </entity-listener>
-            </entity-listeners>
-        </persistence-unit-defaults>
-    </persistence-unit-metadata>
-    <package>org.apache.openjpa.persistence.callbacks</package>
-    <entity class="EntityListenerEntity">
-        <exclude-default-listeners/>
-    </entity>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+    version="1.0">
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <entity-listeners>
+                <entity-listener class=
+                	"org.apache.openjpa.persistence.callbacks.ListenerImpl">
+                </entity-listener>
+            </entity-listeners>
+        </persistence-unit-defaults>
+    </persistence-unit-metadata>
+    <package>org.apache.openjpa.persistence.callbacks</package>
+    <entity class="EntityListenerEntity">
+        <exclude-default-listeners/>
+    </entity>
+    <entity class="Message">
+        <exclude-default-listeners/>
+    </entity>
 </entity-mappings>
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
index e23e21e..12f6afe 100644
--- a/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
@@ -84,16 +84,17 @@
         <mapping-file>META-INF/listener-orm.xml</mapping-file>
         <class>org.apache.openjpa.persistence.callbacks.EntityListenerEntity</class>
         <class>org.apache.openjpa.persistence.callbacks.GlobalListenerEntity</class>
+        <class>org.apache.openjpa.persistence.callbacks.Message</class>
         <properties>
             <property name="openjpa.jdbc.SynchronizeMappings"
                   value="buildSchema(ForeignKeys=true)"/>
         </properties>
-    </persistence-unit>
-    
-    <persistence-unit name="test-unique-constraint">
-        <mapping-file>org/apache/openjpa/persistence/jdbc/unique/orm.xml</mapping-file>
-        <class>org.apache.openjpa.persistence.jdbc.unique.UniqueA</class>
-        <class>org.apache.openjpa.persistence.jdbc.unique.UniqueB</class>
-    </persistence-unit>
+    </persistence-unit>
+    
+    <persistence-unit name="test-unique-constraint">
+        <mapping-file>org/apache/openjpa/persistence/jdbc/unique/orm.xml</mapping-file>
+        <class>org.apache.openjpa.persistence.jdbc.unique.UniqueA</class>
+        <class>org.apache.openjpa.persistence.jdbc.unique.UniqueB</class>
+    </persistence-unit>
     
 </persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/product-derivations-load.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/product-derivations-load.xml
index 10f14ee..037365e 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/product-derivations-load.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/product-derivations-load.xml
@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
-             version="1.0">
-
-    <persistence-unit name="foo"/>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+             version="1.0">
+
+    <persistence-unit name="foo"/>
 </persistence>
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/orm.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/orm.xml
index 47d77df..a79fc1f 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/orm.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/orm.xml
@@ -1,160 +1,160 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
-xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
-                    http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" 
-version="1.0">
-
-<persistence-unit-metadata>
-   <persistence-unit-defaults>
-       <entity-listeners>
-            <entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.DefaultCallbackListener">
-                 <pre-persist method-name="prePersist" />
-                 <post-persist method-name="postPersist" />
-                 <pre-remove method-name="preRemove" />
-                 <post-remove method-name="postRemove" />
-                 <pre-update method-name="preUpdate" />
-                 <post-update method-name="postUpdate" />
-                 <post-load method-name="postLoad" />
-            </entity-listener>
-        </entity-listeners> 
-   </persistence-unit-defaults>
-</persistence-unit-metadata>
-
-<!-- <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Schedule" metadata-complete="true">
-		<description>
-			Schedule class represents the superclass of this app...
-		</description>
-		<inheritance strategy="TABLE_PER_CLASS" />
-
-	     <entity-listeners>
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.DateValidator">
-				<pre-persist method-name="prePersist" />
-				<post-persist method-name="postPersist" />
-			</entity-listener>
-
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.StringValidator">
-				<pre-persist method-name="prePersist" />
-				<post-persist method-name="postPersist" />
-			</entity-listener>
-		</entity-listeners> 
-
-		<attributes>
-			<id name="id">
-				<generated-value strategy="AUTO" />
-			</id>
-			<basic name="dob">
-				<temporal>DATE</temporal>
-			</basic>
-			<basic name="startDate">
-				<temporal>TIME</temporal>
-			</basic>
-			<basic name="endDate">
-				<temporal>TIMESTAMP</temporal>
-			</basic>
-			<basic name="name">
-			</basic>
-		</attributes>
-	</entity>
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.FlightSchedule" metadata-complete="true">
-		<description>
-			FlightSchedule, subclass of schedule specifies the real life flight schedule 
-		</description>
-
-		<table name="Flight_Sched">
-			<unique-constraint>
-				<column-name>planeName</column-name>
-			</unique-constraint>
-		</table>
-
-		<attributes>
-			<id name="FlightNum">
-				<generated-value strategy="AUTO" />
-			</id>
-			<basic name="planeName">
-				<column name="flight_name"/>
-			</basic>
-		</attributes>
-	</entity>
-
-	 <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Employee" metadata-complete="true">
-		<inheritance strategy="JOINED" />
-
-		<entity-listeners>
-			<entity-listener class="annotations.common.apps.NameValidator">
-				<pre-persist method-name="validateName" />
-				<pre-remove method-name="validateNothing1" />
-				<post-remove method-name="validateNothing" />
-				<post-update method-name="testpost" />
-			</entity-listener>
-
-			<entity-listener class="annotations.common.apps.LongNameValidator">
-				<pre-persist method-name="validateName" />
-				<post-update method-name="testpost" />
-			</entity-listener>
-		</entity-listeners> 
-
-		<attributes>
-			<id name="id">
-			</id>
-			<basic name="name">
-			</basic>
-			<transient name="syncTime" />
-		</attributes>
-	</entity>
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.ContractEmployee" metadata-complete="true">
-	</entity>  
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TxRollbackEntity" metadata-complete="true">
-	</entity> -->
-
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity">
-    <exclude-default-listeners />
-    <entity-listeners>
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener">
-				<post-remove method-name="verifyPostRemove" />
-				<post-update method-name="verifyPostUpdate" />
-			</entity-listener>
-
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener2">
-				<pre-update method-name="verifyPreUpdate" />
-				<post-load method-name="verifyPostLoad" /> 
-			</entity-listener>
-		</entity-listeners>
-
-        <pre-persist method-name="verifyPrePersist" />
-        <post-persist method-name="verifyPostPersist" />
-        <pre-remove method-name="verifyPreRemove" />
-
-		<attributes>
-			<id name="id">
-				<generated-value strategy="AUTO" />
-			</id>
-			<basic name="name">
-			</basic>
-			<basic name="surname">
-			</basic>
-		</attributes>
-	</entity> 
-</entity-mappings>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
+                    http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" 
+version="1.0">
+
+<persistence-unit-metadata>
+   <persistence-unit-defaults>
+       <entity-listeners>
+            <entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.DefaultCallbackListener">
+                 <pre-persist method-name="prePersist" />
+                 <post-persist method-name="postPersist" />
+                 <pre-remove method-name="preRemove" />
+                 <post-remove method-name="postRemove" />
+                 <pre-update method-name="preUpdate" />
+                 <post-update method-name="postUpdate" />
+                 <post-load method-name="postLoad" />
+            </entity-listener>
+        </entity-listeners> 
+   </persistence-unit-defaults>
+</persistence-unit-metadata>
+
+<!-- <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Schedule" metadata-complete="true">
+		<description>
+			Schedule class represents the superclass of this app...
+		</description>
+		<inheritance strategy="TABLE_PER_CLASS" />
+
+	     <entity-listeners>
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.DateValidator">
+				<pre-persist method-name="prePersist" />
+				<post-persist method-name="postPersist" />
+			</entity-listener>
+
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.StringValidator">
+				<pre-persist method-name="prePersist" />
+				<post-persist method-name="postPersist" />
+			</entity-listener>
+		</entity-listeners> 
+
+		<attributes>
+			<id name="id">
+				<generated-value strategy="AUTO" />
+			</id>
+			<basic name="dob">
+				<temporal>DATE</temporal>
+			</basic>
+			<basic name="startDate">
+				<temporal>TIME</temporal>
+			</basic>
+			<basic name="endDate">
+				<temporal>TIMESTAMP</temporal>
+			</basic>
+			<basic name="name">
+			</basic>
+		</attributes>
+	</entity>
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.FlightSchedule" metadata-complete="true">
+		<description>
+			FlightSchedule, subclass of schedule specifies the real life flight schedule 
+		</description>
+
+		<table name="Flight_Sched">
+			<unique-constraint>
+				<column-name>planeName</column-name>
+			</unique-constraint>
+		</table>
+
+		<attributes>
+			<id name="FlightNum">
+				<generated-value strategy="AUTO" />
+			</id>
+			<basic name="planeName">
+				<column name="flight_name"/>
+			</basic>
+		</attributes>
+	</entity>
+
+	 <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Employee" metadata-complete="true">
+		<inheritance strategy="JOINED" />
+
+		<entity-listeners>
+			<entity-listener class="annotations.common.apps.NameValidator">
+				<pre-persist method-name="validateName" />
+				<pre-remove method-name="validateNothing1" />
+				<post-remove method-name="validateNothing" />
+				<post-update method-name="testpost" />
+			</entity-listener>
+
+			<entity-listener class="annotations.common.apps.LongNameValidator">
+				<pre-persist method-name="validateName" />
+				<post-update method-name="testpost" />
+			</entity-listener>
+		</entity-listeners> 
+
+		<attributes>
+			<id name="id">
+			</id>
+			<basic name="name">
+			</basic>
+			<transient name="syncTime" />
+		</attributes>
+	</entity>
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.ContractEmployee" metadata-complete="true">
+	</entity>  
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TxRollbackEntity" metadata-complete="true">
+	</entity> -->
+
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity">
+    <exclude-default-listeners />
+    <entity-listeners>
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener">
+				<post-remove method-name="verifyPostRemove" />
+				<post-update method-name="verifyPostUpdate" />
+			</entity-listener>
+
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener2">
+				<pre-update method-name="verifyPreUpdate" />
+				<post-load method-name="verifyPostLoad" /> 
+			</entity-listener>
+		</entity-listeners>
+
+        <pre-persist method-name="verifyPrePersist" />
+        <post-persist method-name="verifyPostPersist" />
+        <pre-remove method-name="verifyPreRemove" />
+
+		<attributes>
+			<id name="id">
+				<generated-value strategy="AUTO" />
+			</id>
+			<basic name="name">
+			</basic>
+			<basic name="surname">
+			</basic>
+		</attributes>
+	</entity> 
+</entity-mappings>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/persistence.xml
index 91a307b..19dffcf 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/annotype/META-INF/persistence.xml
@@ -1,48 +1,48 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbedOwner</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.AnnoTest1</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.AnnoTest2</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.AnnoTest3</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.ContractEmployee</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Employee</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Entity1</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Entity2</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Flat1</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Flat2</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Generator</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TablePerClass1</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TablePerClass2</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.OrderByEntity</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddableSuperSub</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddedIdEntity</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbedValue</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbedValue2</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Schedule</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.FlightSchedule</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddedIdClass</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddableSuper</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TxRollbackEntity</class>
-	</persistence-unit>
-</persistence>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbedOwner</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.AnnoTest1</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.AnnoTest2</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.AnnoTest3</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.ContractEmployee</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Employee</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Entity1</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Entity2</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Flat1</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Flat2</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Generator</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TablePerClass1</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TablePerClass2</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.OrderByEntity</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddableSuperSub</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.PropertyAccess1</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddedIdEntity</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbedValue</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbedValue2</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Schedule</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.FlightSchedule</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddedIdClass</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.EmbeddableSuper</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TxRollbackEntity</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/orm.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/orm.xml
index dfd2b46..14a43af 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/orm.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/orm.xml
@@ -1,160 +1,160 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
-xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
-                    http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" 
-version="1.0">
-
-<persistence-unit-metadata>
-   <persistence-unit-defaults>
-       <entity-listeners>
-            <entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.DefaultCallbackListener">
-                 <pre-persist method-name="prePersist" />
-                 <post-persist method-name="postPersist" />
-                 <pre-remove method-name="preRemove" />
-                 <post-remove method-name="postRemove" />
-                 <pre-update method-name="preUpdate" />
-                 <post-update method-name="postUpdate" />
-                 <post-load method-name="postLoad" />
-            </entity-listener>
-        </entity-listeners> 
-   </persistence-unit-defaults>
-</persistence-unit-metadata>
-
-<!-- <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Schedule" metadata-complete="true">
-		<description>
-			Schedule class represents the superclass of this app...
-		</description>
-		<inheritance strategy="TABLE_PER_CLASS" />
-
-	     <entity-listeners>
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.DateValidator">
-				<pre-persist method-name="prePersist" />
-				<post-persist method-name="postPersist" />
-			</entity-listener>
-
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.StringValidator">
-				<pre-persist method-name="prePersist" />
-				<post-persist method-name="postPersist" />
-			</entity-listener>
-		</entity-listeners> 
-
-		<attributes>
-			<id name="id">
-				<generated-value strategy="AUTO" />
-			</id>
-			<basic name="dob">
-				<temporal>DATE</temporal>
-			</basic>
-			<basic name="startDate">
-				<temporal>TIME</temporal>
-			</basic>
-			<basic name="endDate">
-				<temporal>TIMESTAMP</temporal>
-			</basic>
-			<basic name="name">
-			</basic>
-		</attributes>
-	</entity>
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.FlightSchedule" metadata-complete="true">
-		<description>
-			FlightSchedule, subclass of schedule specifies the real life flight schedule 
-		</description>
-
-		<table name="Flight_Sched">
-			<unique-constraint>
-				<column-name>planeName</column-name>
-			</unique-constraint>
-		</table>
-
-		<attributes>
-			<id name="FlightNum">
-				<generated-value strategy="AUTO" />
-			</id>
-			<basic name="planeName">
-				<column name="flight_name"/>
-			</basic>
-		</attributes>
-	</entity>
-
-	 <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Employee" metadata-complete="true">
-		<inheritance strategy="JOINED" />
-
-		<entity-listeners>
-			<entity-listener class="annotations.common.apps.NameValidator">
-				<pre-persist method-name="validateName" />
-				<pre-remove method-name="validateNothing1" />
-				<post-remove method-name="validateNothing" />
-				<post-update method-name="testpost" />
-			</entity-listener>
-
-			<entity-listener class="annotations.common.apps.LongNameValidator">
-				<pre-persist method-name="validateName" />
-				<post-update method-name="testpost" />
-			</entity-listener>
-		</entity-listeners> 
-
-		<attributes>
-			<id name="id">
-			</id>
-			<basic name="name">
-			</basic>
-			<transient name="syncTime" />
-		</attributes>
-	</entity>
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.ContractEmployee" metadata-complete="true">
-	</entity>  
-
-	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TxRollbackEntity" metadata-complete="true">
-	</entity> -->
-
-
-  <!-- <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity">
-    <exclude-default-listeners />
-    <entity-listeners>
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener">
-				<post-remove method-name="verifyPostRemove" />
-				<post-update method-name="verifyPostUpdate" />
-			</entity-listener>
-
-			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener2">
-				<pre-update method-name="verifyPreUpdate" />
-				<post-load method-name="verifyPostLoad" /> 
-			</entity-listener>
-		</entity-listeners>
-
-        <pre-persist method-name="verifyPrePersist" />
-        <post-persist method-name="verifyPostPersist" />
-        <pre-remove method-name="verifyPreRemove" />
-
-		<attributes>
-			<id name="id">
-				<generated-value strategy="AUTO" />
-			</id>
-			<basic name="name">
-			</basic>
-			<basic name="surname">
-			</basic>
-		</attributes>
-	</entity> -->
-</entity-mappings>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
+                    http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" 
+version="1.0">
+
+<persistence-unit-metadata>
+   <persistence-unit-defaults>
+       <entity-listeners>
+            <entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.DefaultCallbackListener">
+                 <pre-persist method-name="prePersist" />
+                 <post-persist method-name="postPersist" />
+                 <pre-remove method-name="preRemove" />
+                 <post-remove method-name="postRemove" />
+                 <pre-update method-name="preUpdate" />
+                 <post-update method-name="postUpdate" />
+                 <post-load method-name="postLoad" />
+            </entity-listener>
+        </entity-listeners> 
+   </persistence-unit-defaults>
+</persistence-unit-metadata>
+
+<!-- <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Schedule" metadata-complete="true">
+		<description>
+			Schedule class represents the superclass of this app...
+		</description>
+		<inheritance strategy="TABLE_PER_CLASS" />
+
+	     <entity-listeners>
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.DateValidator">
+				<pre-persist method-name="prePersist" />
+				<post-persist method-name="postPersist" />
+			</entity-listener>
+
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.StringValidator">
+				<pre-persist method-name="prePersist" />
+				<post-persist method-name="postPersist" />
+			</entity-listener>
+		</entity-listeners> 
+
+		<attributes>
+			<id name="id">
+				<generated-value strategy="AUTO" />
+			</id>
+			<basic name="dob">
+				<temporal>DATE</temporal>
+			</basic>
+			<basic name="startDate">
+				<temporal>TIME</temporal>
+			</basic>
+			<basic name="endDate">
+				<temporal>TIMESTAMP</temporal>
+			</basic>
+			<basic name="name">
+			</basic>
+		</attributes>
+	</entity>
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.FlightSchedule" metadata-complete="true">
+		<description>
+			FlightSchedule, subclass of schedule specifies the real life flight schedule 
+		</description>
+
+		<table name="Flight_Sched">
+			<unique-constraint>
+				<column-name>planeName</column-name>
+			</unique-constraint>
+		</table>
+
+		<attributes>
+			<id name="FlightNum">
+				<generated-value strategy="AUTO" />
+			</id>
+			<basic name="planeName">
+				<column name="flight_name"/>
+			</basic>
+		</attributes>
+	</entity>
+
+	 <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.Employee" metadata-complete="true">
+		<inheritance strategy="JOINED" />
+
+		<entity-listeners>
+			<entity-listener class="annotations.common.apps.NameValidator">
+				<pre-persist method-name="validateName" />
+				<pre-remove method-name="validateNothing1" />
+				<post-remove method-name="validateNothing" />
+				<post-update method-name="testpost" />
+			</entity-listener>
+
+			<entity-listener class="annotations.common.apps.LongNameValidator">
+				<pre-persist method-name="validateName" />
+				<post-update method-name="testpost" />
+			</entity-listener>
+		</entity-listeners> 
+
+		<attributes>
+			<id name="id">
+			</id>
+			<basic name="name">
+			</basic>
+			<transient name="syncTime" />
+		</attributes>
+	</entity>
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.ContractEmployee" metadata-complete="true">
+	</entity>  
+
+	<entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.annotype.TxRollbackEntity" metadata-complete="true">
+	</entity> -->
+
+
+  <!-- <entity class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity">
+    <exclude-default-listeners />
+    <entity-listeners>
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener">
+				<post-remove method-name="verifyPostRemove" />
+				<post-update method-name="verifyPostUpdate" />
+			</entity-listener>
+
+			<entity-listener class="org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.EntityDDListener2">
+				<pre-update method-name="verifyPreUpdate" />
+				<post-load method-name="verifyPostLoad" /> 
+			</entity-listener>
+		</entity-listeners>
+
+        <pre-persist method-name="verifyPrePersist" />
+        <post-persist method-name="verifyPostPersist" />
+        <pre-remove method-name="verifyPreRemove" />
+
+		<attributes>
+			<id name="id">
+				<generated-value strategy="AUTO" />
+			</id>
+			<basic name="name">
+			</basic>
+			<basic name="surname">
+			</basic>
+		</attributes>
+	</entity> -->
+</entity-mappings>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/persistence.xml
index 0e0a1b9..4806fca 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/annotations/common/apps/annotApp/ddtype/META-INF/persistence.xml
@@ -1,33 +1,33 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.Employee</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.ContractEmployee</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.TxRollbackEntity</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity2</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntitySub</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.Entity1</class>
-		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.Entity2</class>
-	</persistence-unit>
-
-</persistence>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.Employee</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.ContractEmployee</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.TxRollbackEntity</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntity2</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.LifeCycleDDEntitySub</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.Entity1</class>
+		<class>org.apache.openjpa.persistence.annotations.common.apps.annotApp.ddtype.Entity2</class>
+	</persistence-unit>
+
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/cache/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/cache/common/apps/META-INF/persistence.xml
index fe205a2..43b7bad 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/cache/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/cache/common/apps/META-INF/persistence.xml
@@ -1,29 +1,29 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
-  version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-	    <class>org.apache.openjpa.persistence.cache.common.apps.Entity1</class>
-	    <class>org.apache.openjpa.persistence.cache.common.apps.Entity2</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+  version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+	    <class>org.apache.openjpa.persistence.cache.common.apps.Entity1</class>
+	    <class>org.apache.openjpa.persistence.cache.common.apps.Entity2</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/common/apps/META-INF/persistence.xml
index f60e418..0dd7cff 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/common/apps/META-INF/persistence.xml
@@ -1,45 +1,45 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.common.apps.Entity1</class>
-		<class>org.apache.openjpa.persistence.common.apps.Entity2</class>
-		<class>org.apache.openjpa.persistence.common.apps.RuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.common.apps.RuntimeTest2</class>
-		<class>org.apache.openjpa.persistence.common.apps.Course</class>
-		<class>org.apache.openjpa.persistence.common.apps.Department</class>
-		<class>org.apache.openjpa.persistence.common.apps.Student</class>
-		<class>org.apache.openjpa.persistence.common.apps.ArtCourse</class>
-		<class>org.apache.openjpa.persistence.common.apps.ScienceCourse</class>
-		<class>org.apache.openjpa.persistence.common.apps.EmbeddedOwnerPC</class>
-		<class>org.apache.openjpa.persistence.common.apps.EmbeddedPC</class>
-		<class>org.apache.openjpa.persistence.common.apps.ComplexEmbeddedPC</class>
-		<class>org.apache.openjpa.persistence.common.apps.CompUser</class>
-		<class>org.apache.openjpa.persistence.common.apps.MaleUser</class>
-		<class>org.apache.openjpa.persistence.common.apps.Address</class>
-		<class>org.apache.openjpa.persistence.common.apps.FemaleUser</class>
-		<properties>
-			<property name="openjpa.ConnectionFactoryProperties" value="MaxActive=110, MaxIdle=10, ValidationTimeout=50000, 
-                                                                     MaxCachedStatements=10, ValidationSQL='', MaxWait=10000, TestOnBorrow=true" />
-			<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
-		</properties>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.common.apps.Entity1</class>
+		<class>org.apache.openjpa.persistence.common.apps.Entity2</class>
+		<class>org.apache.openjpa.persistence.common.apps.RuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.common.apps.RuntimeTest2</class>
+		<class>org.apache.openjpa.persistence.common.apps.Course</class>
+		<class>org.apache.openjpa.persistence.common.apps.Department</class>
+		<class>org.apache.openjpa.persistence.common.apps.Student</class>
+		<class>org.apache.openjpa.persistence.common.apps.ArtCourse</class>
+		<class>org.apache.openjpa.persistence.common.apps.ScienceCourse</class>
+		<class>org.apache.openjpa.persistence.common.apps.EmbeddedOwnerPC</class>
+		<class>org.apache.openjpa.persistence.common.apps.EmbeddedPC</class>
+		<class>org.apache.openjpa.persistence.common.apps.ComplexEmbeddedPC</class>
+		<class>org.apache.openjpa.persistence.common.apps.CompUser</class>
+		<class>org.apache.openjpa.persistence.common.apps.MaleUser</class>
+		<class>org.apache.openjpa.persistence.common.apps.Address</class>
+		<class>org.apache.openjpa.persistence.common.apps.FemaleUser</class>
+		<properties>
+			<property name="openjpa.ConnectionFactoryProperties" value="MaxActive=110, MaxIdle=10, ValidationTimeout=50000, 
+                                                                     MaxCachedStatements=10, ValidationSQL='', MaxWait=10000, TestOnBorrow=true" />
+			<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
+		</properties>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/conf/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/conf/common/apps/META-INF/persistence.xml
index d428dad..236adfc 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/conf/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/conf/common/apps/META-INF/persistence.xml
@@ -1,25 +1,25 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/datacache/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/datacache/common/apps/META-INF/persistence.xml
index a2c7a8f..13aabf0 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/datacache/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/datacache/common/apps/META-INF/persistence.xml
@@ -1,53 +1,53 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AppIdCacheObject</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachA</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachB</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachC</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachD</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachE</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachF</class>
-<!--		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectInterface</class>-->
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectWithExternalizedFields</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectC</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectD</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectF</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectG</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectH</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.FlushDataCacheObject</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild2</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectBChild1</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest2</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.SelfReferencingCacheTestObject</class>
-		<class>org.apache.openjpa.persistence.datacache.common.apps.TransactionalClassPC</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AppIdCacheObject</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachA</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachB</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachC</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachD</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachE</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.AttachF</class>
+<!--		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectInterface</class>-->
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectWithExternalizedFields</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectA</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectB</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectC</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectD</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectE</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectF</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectG</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectH</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectJ</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.FlushDataCacheObject</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild1</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectAChild2</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.CacheObjectBChild1</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.RuntimeTest2</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.SelfReferencingCacheTestObject</class>
+		<class>org.apache.openjpa.persistence.datacache.common.apps.TransactionalClassPC</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/enhance/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/enhance/common/apps/META-INF/persistence.xml
index bf0e14c..0b3dca3 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/enhance/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/enhance/common/apps/META-INF/persistence.xml
@@ -1,41 +1,41 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.PCClone</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.NonPCClone</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.SubclassClone</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.NoClone</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.NoNoArgs</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.No2NoArgs</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.No3NoArgs</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.BackingFieldNameMismatchInstance</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.BaseEntity</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.BasicSubclassInstance</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.DetachablePC</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.DetachableVersionedPC</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance2</class>
-		<class>org.apache.openjpa.persistence.enhance.common.apps.DerivedEntity</class>
-
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.PCClone</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.NonPCClone</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.SubclassClone</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.NoClone</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.NoNoArgs</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.No2NoArgs</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.No3NoArgs</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.BackingFieldNameMismatchInstance</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.BaseEntity</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.BasicSubclassInstance</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.DetachablePC</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.DetachableVersionedPC</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.ManagedInverseTestInstance2</class>
+		<class>org.apache.openjpa.persistence.enhance.common.apps.DerivedEntity</class>
+
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/entityoperation/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/entityoperation/common/apps/META-INF/persistence.xml
index d88b56e..6c03f8d 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/entityoperation/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/entityoperation/common/apps/META-INF/persistence.xml
@@ -1,26 +1,26 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.entityoperation.common.apps.CascadesEntity</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.entityoperation.common.apps.CascadesEntity</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/event/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/event/common/apps/META-INF/persistence.xml
index 3d7d2cb..36cb45d 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/event/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/event/common/apps/META-INF/persistence.xml
@@ -1,29 +1,29 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.event.common.apps.RuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.event.common.apps.RuntimeTest2</class>
-		<class>org.apache.openjpa.persistence.event.common.apps.RuntimeTest4</class>
-		<class>org.apache.openjpa.persistence.event.common.apps.TransactionalClassPC</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.event.common.apps.RuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.event.common.apps.RuntimeTest2</class>
+		<class>org.apache.openjpa.persistence.event.common.apps.RuntimeTest4</class>
+		<class>org.apache.openjpa.persistence.event.common.apps.TransactionalClassPC</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/META-INF/persistence.xml
index 5193f54..1e8e940 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/META-INF/persistence.xml
@@ -1,43 +1,43 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
-  version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC1</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC2</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC4</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC5</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.CustomMappingPC</class>
-        <class>org.apache.openjpa.persistence.jdbc.common.apps.DFGTest</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.EagerPC</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.EagerPCSub</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC2</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC3</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC4</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.InvertA</class>
-        <class>org.apache.openjpa.persistence.jdbc.common.apps.InvertB</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+  version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC1</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC2</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC4</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.ConstantJoinPC5</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.CustomMappingPC</class>
+        <class>org.apache.openjpa.persistence.jdbc.common.apps.DFGTest</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.EagerPC</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.EagerPCSub</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC2</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC3</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC4</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.InvertA</class>
+        <class>org.apache.openjpa.persistence.jdbc.common.apps.InvertB</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/META-INF/persistence.xml
index 541304d..9d482d0 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/common/apps/mappingApp/META-INF/persistence.xml
@@ -1,34 +1,34 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.EntityWithCompositeId</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.OwnerOfEntityWithCompositeId</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.RecursiveEntityWithCompositeId</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapAddress</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapItem</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapOrder</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapPerson</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.Entity1</class>
-		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.Entity2</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.EntityWithCompositeId</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.OwnerOfEntityWithCompositeId</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.RecursiveEntityWithCompositeId</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapAddress</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapItem</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapOrder</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.SQLMapPerson</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.Entity1</class>
+		<class>org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.Entity2</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml
index 1093cc0..297393c 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/jdbc/unique/orm.xml
@@ -1,119 +1,119 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements.  See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership.  The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License.  You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied.  See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
-	version="1.0">
-	
-	<persistence-unit-metadata>
-		<xml-mapping-metadata-complete/>
-	</persistence-unit-metadata>
-	
-	
-	<package>org.apache.openjpa.persistence.jdbc.unique</package>
-	<entity name="UniqueA" class="UniqueA">
-		<table name="UNIQUE_A_XML">
-			<unique-constraint>
-				<column-name>a1x</column-name>
-				<column-name>a2x</column-name>
-			</unique-constraint>
-			<unique-constraint>
-				<column-name>a3x</column-name>
-				<column-name>a4x</column-name>
-			</unique-constraint>
-		</table>
-		<secondary-table name="UNIQUE_SECONDARY_XML">
-			<unique-constraint>
-				<column-name>sa1x</column-name>
-			</unique-constraint>
-		</secondary-table>
-		<attributes>
-			<id name="aid">
-			</id>
-			<basic name="a1">
-				<column name="a1x"/>
-			</basic>
-			<basic name="a2">
-				<column name="a2x"/>
-			</basic>
-			<basic name="a3">
-				<column name="a3x"/>
-			</basic>
-			<basic name="a4">
-				<column name="a4x"/>
-			</basic>
-			<basic name="a5">
-				<column name="a5x"/>
-			</basic>
-			<basic name="a6">
-				<column name="a6x"/>
-			</basic>
-			
-			<basic name="sa1">
-				<column name="sa1x" table="UNIQUE_SECONDARY_XML" />
-			</basic>
-			<basic name="sa2">
-				<column name="sa2x" table="UNIQUE_SECONDARY_XML" />
-			</basic>
-
-			<many-to-many name="bs">
-				<join-table name="UNIQUE_JOINTABLE_XML">
-					<join-column name="FK_A_XML" referenced-column-name="aid" nullable="false"/>
-					<inverse-join-column name="FK_B_XML" referenced-column-name="bid" nullable="false"/>
-					<unique-constraint>
-						<column-name>FK_A_XML</column-name>
-						<column-name>FK_B_XML</column-name>
-					</unique-constraint>
-				</join-table>
-			</many-to-many>
-		</attributes>
-	</entity>
-
-	<entity name="UniqueB" class="UniqueB">
-		<table name="UNIQUE_B_XML">
-			<unique-constraint>
-				<column-name>b1x</column-name>
-				<column-name>b2x</column-name>
-			</unique-constraint>
-		</table>
-		<attributes>
-			<id name="bid">
-				<generated-value strategy="TABLE"
-					generator="testGeneratorXML" />
-				<table-generator name="testGeneratorXML"
-					table="UNIQUE_GENERATOR_XML" pk-column-name="GEN1_XML"
-					value-column-name="GEN2_XML">
-					<unique-constraint>
-						<column-name>GEN1_XML</column-name>
-						<column-name>GEN2_XML</column-name>
-					</unique-constraint>
-				</table-generator>
-			</id>
-			<basic name="b1">
-				<column name="b1x"/>
-			</basic>
-			<basic name="b2">
-				<column name="b2x"/>
-			</basic>
-		</attributes>
-	</entity>
-</entity-mappings>
-
-
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+-->
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+	version="1.0">
+	
+	<persistence-unit-metadata>
+		<xml-mapping-metadata-complete/>
+	</persistence-unit-metadata>
+	
+	
+	<package>org.apache.openjpa.persistence.jdbc.unique</package>
+	<entity name="UniqueA" class="UniqueA">
+		<table name="UNIQUE_A_XML">
+			<unique-constraint>
+				<column-name>a1x</column-name>
+				<column-name>a2x</column-name>
+			</unique-constraint>
+			<unique-constraint>
+				<column-name>a3x</column-name>
+				<column-name>a4x</column-name>
+			</unique-constraint>
+		</table>
+		<secondary-table name="UNIQUE_SECONDARY_XML">
+			<unique-constraint>
+				<column-name>sa1x</column-name>
+			</unique-constraint>
+		</secondary-table>
+		<attributes>
+			<id name="aid">
+			</id>
+			<basic name="a1">
+				<column name="a1x"/>
+			</basic>
+			<basic name="a2">
+				<column name="a2x"/>
+			</basic>
+			<basic name="a3">
+				<column name="a3x"/>
+			</basic>
+			<basic name="a4">
+				<column name="a4x"/>
+			</basic>
+			<basic name="a5">
+				<column name="a5x"/>
+			</basic>
+			<basic name="a6">
+				<column name="a6x"/>
+			</basic>
+			
+			<basic name="sa1">
+				<column name="sa1x" table="UNIQUE_SECONDARY_XML" />
+			</basic>
+			<basic name="sa2">
+				<column name="sa2x" table="UNIQUE_SECONDARY_XML" />
+			</basic>
+
+			<many-to-many name="bs">
+				<join-table name="UNIQUE_JOINTABLE_XML">
+					<join-column name="FK_A_XML" referenced-column-name="aid" nullable="false"/>
+					<inverse-join-column name="FK_B_XML" referenced-column-name="bid" nullable="false"/>
+					<unique-constraint>
+						<column-name>FK_A_XML</column-name>
+						<column-name>FK_B_XML</column-name>
+					</unique-constraint>
+				</join-table>
+			</many-to-many>
+		</attributes>
+	</entity>
+
+	<entity name="UniqueB" class="UniqueB">
+		<table name="UNIQUE_B_XML">
+			<unique-constraint>
+				<column-name>b1x</column-name>
+				<column-name>b2x</column-name>
+			</unique-constraint>
+		</table>
+		<attributes>
+			<id name="bid">
+				<generated-value strategy="TABLE"
+					generator="testGeneratorXML" />
+				<table-generator name="testGeneratorXML"
+					table="UNIQUE_GENERATOR_XML" pk-column-name="GEN1_XML"
+					value-column-name="GEN2_XML">
+					<unique-constraint>
+						<column-name>GEN1_XML</column-name>
+						<column-name>GEN2_XML</column-name>
+					</unique-constraint>
+				</table-generator>
+			</id>
+			<basic name="b1">
+				<column name="b1x"/>
+			</basic>
+			<basic name="b2">
+				<column name="b2x"/>
+			</basic>
+		</attributes>
+	</entity>
+</entity-mappings>
+
+
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/kernel/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/kernel/common/apps/META-INF/persistence.xml
index fa6143d..644dc52 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/kernel/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/kernel/common/apps/META-INF/persistence.xml
@@ -1,124 +1,124 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<!-- <class>org.apache.openjpa.persistence.kernel.common.apps.AbstractMappedAppIdSuper</class> -->
-
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AImplB</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AllFieldsTypeTest</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdClassString</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdHolder</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubB</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AbstractMappedAppIdSuper</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubD</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubE</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubF</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ArraysTest</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachA</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachB</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachD</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachE</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachF</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachVersionA</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachVersionB</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachVersionC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.BlobTest</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ByteArray</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.CalendarFields</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ColumnIOPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ComplexEmbeddedPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ConcreteMappedAppIdSub</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.DateVersion</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.DependentFieldsPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.DetachSMPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.EmbeddedOwnerPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.EmbeddedPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.Entity1</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.Entity2</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ExternalValues</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.Inner</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InstanceCallbacksTest</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ModInstanceCallbackTests</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceHolder</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl1</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl2</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl3</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl4</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InverseA</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.InverseB</class>
-        	<class>org.apache.openjpa.persistence.kernel.common.apps.Lobs</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC2</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.LockGroupPCKnownSubclass</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ManagedInterfaceOwner</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ManagedInterfaceOwnerAppId</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.MapElementPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.MapElementPCChild</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.MixedInterfaceImpl</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.NonMappedInterfaceImpl</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ObjectCollectionHolder</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.OuterJoinValuePC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCAddress</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCClassPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCCompany</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCCountry</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCDepartment</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCDirectory</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCEmployee</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCFile</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PCPerson</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PersistenceAware</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.PersistentMapHolder</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ProxiesPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.RecursivelyEmbeddedPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest3</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest5</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SCOTest</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SecondaryTab</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SequenceAssigned</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SequenceAssigned2</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SequenceAssigned3</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdByte</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdChar</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdInt</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdLong</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdShort</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdString</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdWrapper</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ValueStrategyPC</class>
-		<class>org.apache.openjpa.persistence.kernel.TestEJBLobs$Inner</class>
-		<class>org.apache.openjpa.persistence.kernel.TestEJBLobs$Inner2</class>
-		<class>org.apache.openjpa.persistence.kernel.TestStaticInnerClasses$Inner</class>
-		<class>org.apache.openjpa.persistence.kernel.TestEJBNoPersistentFields$Nholder</class>
-		<class>org.apache.openjpa.persistence.kernel.TestEJBNoPersistentFields$NoPersistentFieldsPC</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest2</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<!-- <class>org.apache.openjpa.persistence.kernel.common.apps.AbstractMappedAppIdSuper</class> -->
+
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AImplB</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AllFieldsTypeTest</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdClassString</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdHolder</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubB</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AbstractMappedAppIdSuper</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubD</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubE</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AppIdSubF</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ArraysTest</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachA</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachB</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachD</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachE</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachF</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachVersionA</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachVersionB</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.AttachVersionC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.BlobTest</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ByteArray</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.CalendarFields</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ColumnIOPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ComplexEmbeddedPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ConcreteMappedAppIdSub</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.DateVersion</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.DependentFieldsPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.DetachSMPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.EmbeddedOwnerPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.EmbeddedPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.Entity1</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.Entity2</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ExternalValues</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.Inner</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InstanceCallbacksTest</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ModInstanceCallbackTests</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceHolder</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl1</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl2</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl3</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InterfaceTestImpl4</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InverseA</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.InverseB</class>
+        	<class>org.apache.openjpa.persistence.kernel.common.apps.Lobs</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.LockGroupPC2</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.LockGroupPCKnownSubclass</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ManagedInterfaceOwner</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ManagedInterfaceOwnerAppId</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.MapElementPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.MapElementPCChild</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.MixedInterfaceImpl</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.NonMappedInterfaceImpl</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ObjectCollectionHolder</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.OuterJoinValuePC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCAddress</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCClassPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCCompany</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCCountry</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCDepartment</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCDirectory</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCEmployee</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCFile</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PCPerson</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PersistenceAware</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.PersistentMapHolder</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ProxiesPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.RecursivelyEmbeddedPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest3</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest5</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SCOTest</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SecondaryTab</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SequenceAssigned</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SequenceAssigned2</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SequenceAssigned3</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdByte</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdChar</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdInt</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdLong</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdShort</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdString</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.SingleIdWrapper</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ValueStrategyPC</class>
+		<class>org.apache.openjpa.persistence.kernel.TestEJBLobs$Inner</class>
+		<class>org.apache.openjpa.persistence.kernel.TestEJBLobs$Inner2</class>
+		<class>org.apache.openjpa.persistence.kernel.TestStaticInnerClasses$Inner</class>
+		<class>org.apache.openjpa.persistence.kernel.TestEJBNoPersistentFields$Nholder</class>
+		<class>org.apache.openjpa.persistence.kernel.TestEJBNoPersistentFields$NoPersistentFieldsPC</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.kernel.common.apps.ModRuntimeTest2</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/meta/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/meta/common/apps/META-INF/persistence.xml
index ed80b03..4ad1096 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/meta/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/meta/common/apps/META-INF/persistence.xml
@@ -1,47 +1,47 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-		<class>org.apache.openjpa.persistence.meta.common.apps.ExternalValues</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.FieldOrderPC</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.FieldOrderPCSubclass</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest1</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest1$Inner</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest2</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest3</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest4</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest5</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest6</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.NonPersistentFieldsPC</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.OrderByPC</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.OrderByPCRel</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.OrderByPCRelSub</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.RuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.RuntimeTest2</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.RuntimeTest3</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned2</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned3</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.ValueStrategyPC</class>
-		<class>org.apache.openjpa.persistence.meta.common.apps.TransactionalClassPC</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<class>org.apache.openjpa.persistence.meta.common.apps.ExternalValues</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.FieldOrderPC</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.FieldOrderPCSubclass</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest1</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest1$Inner</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest2</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest3</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest4</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest5</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.MetaTest6</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.NonPersistentFieldsPC</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.OrderByPC</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.OrderByPCRel</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.OrderByPCRelSub</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.RuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.RuntimeTest2</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.RuntimeTest3</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned2</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.SequenceAssigned3</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.ValueStrategyPC</class>
+		<class>org.apache.openjpa.persistence.meta.common.apps.TransactionalClassPC</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/query/common/apps/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/query/common/apps/META-INF/persistence.xml
index 06b01c4..7d71ad1 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/query/common/apps/META-INF/persistence.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/query/common/apps/META-INF/persistence.xml
@@ -1,49 +1,49 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
-    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
-		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-        <class>org.apache.openjpa.persistence.query.common.apps.Entity1</class>
-        <class>org.apache.openjpa.persistence.query.common.apps.Entity2</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest2</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest3</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest4</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest5</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.SimpleAppIdPC</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.CompoundAppIdPC</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest1</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest2</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest3</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest4</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.CompoundAppIdPC</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexA</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexB</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexC</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexD</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexE</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexF</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ComplexG</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.CircularFKPC</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.CircularFKPC2</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ModRuntimeTest1</class>
-		<class>org.apache.openjpa.persistence.query.common.apps.ModRuntimeTest2</class>
-	</persistence-unit>
-</persistence>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+	<persistence-unit name="TestConv" transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+        <class>org.apache.openjpa.persistence.query.common.apps.Entity1</class>
+        <class>org.apache.openjpa.persistence.query.common.apps.Entity2</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest2</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest3</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest4</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.RuntimeTest5</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.SimpleAppIdPC</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.CompoundAppIdPC</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest1</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest2</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest3</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.QueryTest4</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.CompoundAppIdPC</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexA</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexB</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexC</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexD</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexE</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexF</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ComplexG</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.CircularFKPC</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.CircularFKPC2</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ModRuntimeTest1</class>
+		<class>org.apache.openjpa.persistence.query.common.apps.ModRuntimeTest2</class>
+	</persistence-unit>
+</persistence>
diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xml/persistence-without-xsd.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xml/persistence-without-xsd.xml
index 808573b..c687dc0 100644
--- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xml/persistence-without-xsd.xml
+++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xml/persistence-without-xsd.xml
@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<persistence>
-    <persistence-unit name="incorrect-ordering-and-no-xsd">
-        <properties>
-            <property name="openjpa.Id" value="incorrect-ordering-pu"/>
-        </properties>
-        <class>org.apache.openjpa.persistence.xml.SimpleXmlEntity</class>
-        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-    </persistence-unit>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<persistence>
+    <persistence-unit name="incorrect-ordering-and-no-xsd">
+        <properties>
+            <property name="openjpa.Id" value="incorrect-ordering-pu"/>
+        </properties>
+        <class>org.apache.openjpa.persistence.xml.SimpleXmlEntity</class>
+        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+    </persistence-unit>
 </persistence>
\ No newline at end of file
diff --git a/openjpa-persistence/pom.xml b/openjpa-persistence/pom.xml
index 52804ac..8b36a57 100644
--- a/openjpa-persistence/pom.xml
+++ b/openjpa-persistence/pom.xml
@@ -31,7 +31,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
index b310a3c..f4691b5 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
@@ -482,7 +482,10 @@
             return null;
 
         Entity entity = (Entity) _cls.getAnnotation(Entity.class);
+        MappedSuperclass mapped = (MappedSuperclass)
+        _cls.getAnnotation(MappedSuperclass.class);
         if (isMetaDataMode()) {
+            meta.setAbstract(mapped != null);
             // while the spec only provides for embedded exclusive, it doesn't
             // seem hard to support otherwise
             if (entity == null)
@@ -754,6 +757,8 @@
                 org.apache.openjpa.datacache.DataCache.NAME_DEFAULT);
         else
             meta.setDataCacheName(null);
+        
+        meta.setIsCacheable(cache.enabled(), true);
     }
 
     private void parseManagedInterface(ClassMetaData meta,
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoClearType.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoClearType.java
index 92e6989..e402a73 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoClearType.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoClearType.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import org.apache.openjpa.kernel.AutoClear;
-
-/**
- * The possible settings for the auto-clear behavior of an
- * {@link OpenJPAEntityManager}.
- *
- * @since 1.0.0
- * @published
- */
-public enum AutoClearType {
-    DATASTORE(AutoClear.CLEAR_DATASTORE),
-    ALL(AutoClear.CLEAR_ALL);
-
-    private final int autoClearConstant;
-
-    private AutoClearType(int value) {
-        autoClearConstant = value;
-    }
-
-    int toKernelConstant() {
-        return autoClearConstant;
-    }
-
-    static AutoClearType fromKernelConstant(int kernelConstant) {
-        switch (kernelConstant) {
-            case AutoClear.CLEAR_DATASTORE:
-                return DATASTORE;
-
-            case AutoClear.CLEAR_ALL:
-                return ALL;
-
-            default:
-                throw new IllegalArgumentException(kernelConstant + "");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.AutoClear;
+
+/**
+ * The possible settings for the auto-clear behavior of an
+ * {@link OpenJPAEntityManager}.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum AutoClearType {
+    DATASTORE(AutoClear.CLEAR_DATASTORE),
+    ALL(AutoClear.CLEAR_ALL);
+
+    private final int autoClearConstant;
+
+    private AutoClearType(int value) {
+        autoClearConstant = value;
+    }
+
+    int toKernelConstant() {
+        return autoClearConstant;
+    }
+
+    static AutoClearType fromKernelConstant(int kernelConstant) {
+        switch (kernelConstant) {
+            case AutoClear.CLEAR_DATASTORE:
+                return DATASTORE;
+
+            case AutoClear.CLEAR_ALL:
+                return ALL;
+
+            default:
+                throw new IllegalArgumentException(kernelConstant + "");
+        }
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoDetachType.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoDetachType.java
index a4c9d84..88aa1ad 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoDetachType.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AutoDetachType.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import java.util.EnumSet;
-
-import org.apache.openjpa.kernel.AutoDetach;
-
-/**
- * The possible settings for the auto-detach behavior of an
- * {@link OpenJPAEntityManager}.
- *
- * @since 1.0.0
- * @published
- */
-public enum AutoDetachType {
-    CLOSE(AutoDetach.DETACH_CLOSE),
-    COMMIT(AutoDetach.DETACH_COMMIT),
-    NON_TRANSACTIONAL_READ(AutoDetach.DETACH_NONTXREAD),
-    ROLLBACK(AutoDetach.DETACH_ROLLBACK);
-
-    private final int autoDetachConstant;
-
-    private AutoDetachType(int value) {
-        autoDetachConstant = value;
-    }
-
-    public static EnumSet<AutoDetachType> toEnumSet(int autoDetach) {
-        EnumSet<AutoDetachType> types = EnumSet.noneOf(AutoDetachType.class);
-        if ((autoDetach & AutoDetach.DETACH_CLOSE) != 0)
-            types.add(CLOSE);
-        if ((autoDetach & AutoDetach.DETACH_COMMIT) != 0)
-            types.add(COMMIT);
-        if ((autoDetach & AutoDetach.DETACH_NONTXREAD) != 0)
-            types.add(NON_TRANSACTIONAL_READ);
-        if ((autoDetach & AutoDetach.DETACH_ROLLBACK) != 0)
-            types.add(ROLLBACK);
-        return types;
-    }
-
-    public static int fromEnumSet(EnumSet<AutoDetachType> types) {
-        int autoDetach = 0;
-        for (AutoDetachType type : types)
-            autoDetach |= type.autoDetachConstant;
-        return autoDetach;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import java.util.EnumSet;
+
+import org.apache.openjpa.kernel.AutoDetach;
+
+/**
+ * The possible settings for the auto-detach behavior of an
+ * {@link OpenJPAEntityManager}.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum AutoDetachType {
+    CLOSE(AutoDetach.DETACH_CLOSE),
+    COMMIT(AutoDetach.DETACH_COMMIT),
+    NON_TRANSACTIONAL_READ(AutoDetach.DETACH_NONTXREAD),
+    ROLLBACK(AutoDetach.DETACH_ROLLBACK);
+
+    private final int autoDetachConstant;
+
+    private AutoDetachType(int value) {
+        autoDetachConstant = value;
+    }
+
+    public static EnumSet<AutoDetachType> toEnumSet(int autoDetach) {
+        EnumSet<AutoDetachType> types = EnumSet.noneOf(AutoDetachType.class);
+        if ((autoDetach & AutoDetach.DETACH_CLOSE) != 0)
+            types.add(CLOSE);
+        if ((autoDetach & AutoDetach.DETACH_COMMIT) != 0)
+            types.add(COMMIT);
+        if ((autoDetach & AutoDetach.DETACH_NONTXREAD) != 0)
+            types.add(NON_TRANSACTIONAL_READ);
+        if ((autoDetach & AutoDetach.DETACH_ROLLBACK) != 0)
+            types.add(ROLLBACK);
+        return types;
+    }
+
+    public static int fromEnumSet(EnumSet<AutoDetachType> types) {
+        int autoDetach = 0;
+        for (AutoDetachType type : types)
+            autoDetach |= type.autoDetachConstant;
+        return autoDetach;
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/CallbackMode.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/CallbackMode.java
index 58bfddb..02fe56f 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/CallbackMode.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/CallbackMode.java
@@ -1,66 +1,66 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import java.util.EnumSet;
-
-import org.apache.openjpa.event.CallbackModes;
-
-/**
- * The possible settings for the callback behavior of an
- * {@link OpenJPAEntityManager}.
- *
- * @since 1.0.0
- * @published
- */
-public enum CallbackMode {
-    FAIL_FAST(CallbackModes.CALLBACK_FAIL_FAST),
-    IGNORE(CallbackModes.CALLBACK_IGNORE),
-    LOG(CallbackModes.CALLBACK_LOG),
-    RETHROW(CallbackModes.CALLBACK_RETHROW),
-    ROLLBACK(CallbackModes.CALLBACK_ROLLBACK);
-
-    private final int callbackMode;
-
-    private CallbackMode(int value) {
-        callbackMode = value;
-    }
-
-    static EnumSet<CallbackMode> toEnumSet(int callback) {
-        EnumSet<CallbackMode> modes = EnumSet.noneOf(CallbackMode.class);
-        if ((callback & CallbackModes.CALLBACK_FAIL_FAST) != 0)
-            modes.add(FAIL_FAST);
-        if ((callback & CallbackModes.CALLBACK_IGNORE) != 0)
-            modes.add(IGNORE);
-        if ((callback & CallbackModes.CALLBACK_LOG) != 0)
-            modes.add(LOG);
-        if ((callback & CallbackModes.CALLBACK_RETHROW) != 0)
-            modes.add(RETHROW);
-        if ((callback & CallbackModes.CALLBACK_ROLLBACK) != 0)
-            modes.add(ROLLBACK);
-        return modes;
-    }
-
-    static int fromEnumSet(EnumSet<CallbackMode> modes) {
-        int callback = 0;
-        for (CallbackMode mode : modes)
-            callback |= mode.callbackMode;
-        return callback;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import java.util.EnumSet;
+
+import org.apache.openjpa.event.CallbackModes;
+
+/**
+ * The possible settings for the callback behavior of an
+ * {@link OpenJPAEntityManager}.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum CallbackMode {
+    FAIL_FAST(CallbackModes.CALLBACK_FAIL_FAST),
+    IGNORE(CallbackModes.CALLBACK_IGNORE),
+    LOG(CallbackModes.CALLBACK_LOG),
+    RETHROW(CallbackModes.CALLBACK_RETHROW),
+    ROLLBACK(CallbackModes.CALLBACK_ROLLBACK);
+
+    private final int callbackMode;
+
+    private CallbackMode(int value) {
+        callbackMode = value;
+    }
+
+    static EnumSet<CallbackMode> toEnumSet(int callback) {
+        EnumSet<CallbackMode> modes = EnumSet.noneOf(CallbackMode.class);
+        if ((callback & CallbackModes.CALLBACK_FAIL_FAST) != 0)
+            modes.add(FAIL_FAST);
+        if ((callback & CallbackModes.CALLBACK_IGNORE) != 0)
+            modes.add(IGNORE);
+        if ((callback & CallbackModes.CALLBACK_LOG) != 0)
+            modes.add(LOG);
+        if ((callback & CallbackModes.CALLBACK_RETHROW) != 0)
+            modes.add(RETHROW);
+        if ((callback & CallbackModes.CALLBACK_ROLLBACK) != 0)
+            modes.add(ROLLBACK);
+        return modes;
+    }
+
+    static int fromEnumSet(EnumSet<CallbackMode> modes) {
+        int callback = 0;
+        for (CallbackMode mode : modes)
+            callback |= mode.callbackMode;
+        return callback;
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/ConnectionRetainMode.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/ConnectionRetainMode.java
index 5a62fa3..5a77e82 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/ConnectionRetainMode.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/ConnectionRetainMode.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import org.apache.openjpa.kernel.ConnectionRetainModes;
-
-/**
- * The possible values for use when configuring the connection retain
- * behavior for an {@link OpenJPAEntityManager}.
- *
- * @since 1.0.0
- * @published
- */
-public enum ConnectionRetainMode {
-    ON_DEMAND(ConnectionRetainModes.CONN_RETAIN_DEMAND),
-    TRANSACTION(ConnectionRetainModes.CONN_RETAIN_TRANS),
-    ALWAYS(ConnectionRetainModes.CONN_RETAIN_ALWAYS);
-
-    private final int connectionRetainConstant;
-
-    private ConnectionRetainMode(int value) {
-        connectionRetainConstant = value;
-    }
-
-    int toKernelConstant() {
-        return connectionRetainConstant;
-    }
-
-    static ConnectionRetainMode fromKernelConstant(int kernelConstant) {
-        switch (kernelConstant) {
-            case ConnectionRetainModes.CONN_RETAIN_DEMAND:
-                return ON_DEMAND;
-
-            case ConnectionRetainModes.CONN_RETAIN_ALWAYS:
-                return ALWAYS;
-
-            case ConnectionRetainModes.CONN_RETAIN_TRANS:
-                return TRANSACTION;
-
-            default:
-                throw new IllegalArgumentException(kernelConstant + "");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.ConnectionRetainModes;
+
+/**
+ * The possible values for use when configuring the connection retain
+ * behavior for an {@link OpenJPAEntityManager}.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum ConnectionRetainMode {
+    ON_DEMAND(ConnectionRetainModes.CONN_RETAIN_DEMAND),
+    TRANSACTION(ConnectionRetainModes.CONN_RETAIN_TRANS),
+    ALWAYS(ConnectionRetainModes.CONN_RETAIN_ALWAYS);
+
+    private final int connectionRetainConstant;
+
+    private ConnectionRetainMode(int value) {
+        connectionRetainConstant = value;
+    }
+
+    int toKernelConstant() {
+        return connectionRetainConstant;
+    }
+
+    static ConnectionRetainMode fromKernelConstant(int kernelConstant) {
+        switch (kernelConstant) {
+            case ConnectionRetainModes.CONN_RETAIN_DEMAND:
+                return ON_DEMAND;
+
+            case ConnectionRetainModes.CONN_RETAIN_ALWAYS:
+                return ALWAYS;
+
+            case ConnectionRetainModes.CONN_RETAIN_TRANS:
+                return TRANSACTION;
+
+            default:
+                throw new IllegalArgumentException(kernelConstant + "");
+        }
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/DetachStateType.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/DetachStateType.java
index 01e8003..db6a0fd 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/DetachStateType.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/DetachStateType.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import org.apache.openjpa.kernel.DetachState;
-
-/**
- * The possible settings for the detachment behavior of an
- * {@link OpenJPAEntityManager}.
- *
- * @since 1.0.0
- * @published
- */
-public enum DetachStateType {
-    FETCH_GROUPS(DetachState.DETACH_FETCH_GROUPS),
-    LOADED(DetachState.DETACH_LOADED),
-    ALL(DetachState.DETACH_ALL);
-
-    private final int detachStateConstant;
-
-    private DetachStateType(int value) {
-        detachStateConstant = value;
-    }
-
-    int toKernelConstant() {
-        return detachStateConstant;
-    }
-
-    static DetachStateType fromKernelConstant(int kernelConstant) {
-        switch (kernelConstant) {
-            case DetachState.DETACH_FETCH_GROUPS:
-                return FETCH_GROUPS;
-
-            case DetachState.DETACH_LOADED:
-                return LOADED;
-
-            case DetachState.DETACH_ALL:
-                return ALL;
-
-            default:
-                throw new IllegalArgumentException(kernelConstant + "");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.DetachState;
+
+/**
+ * The possible settings for the detachment behavior of an
+ * {@link OpenJPAEntityManager}.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum DetachStateType {
+    FETCH_GROUPS(DetachState.DETACH_FETCH_GROUPS),
+    LOADED(DetachState.DETACH_LOADED),
+    ALL(DetachState.DETACH_ALL);
+
+    private final int detachStateConstant;
+
+    private DetachStateType(int value) {
+        detachStateConstant = value;
+    }
+
+    int toKernelConstant() {
+        return detachStateConstant;
+    }
+
+    static DetachStateType fromKernelConstant(int kernelConstant) {
+        switch (kernelConstant) {
+            case DetachState.DETACH_FETCH_GROUPS:
+                return FETCH_GROUPS;
+
+            case DetachState.DETACH_LOADED:
+                return LOADED;
+
+            case DetachState.DETACH_ALL:
+                return ALL;
+
+            default:
+                throw new IllegalArgumentException(kernelConstant + "");
+        }
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
index b29248c..8866590 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
@@ -1,1374 +1,1374 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.persistence;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
-import java.lang.reflect.Array;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import javax.persistence.EntityManager;
-import javax.persistence.FlushModeType;
-import javax.persistence.LockModeType;
-import javax.persistence.Query;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.ee.ManagedRuntime;
-import org.apache.openjpa.enhance.PCEnhancer;
-import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.kernel.AbstractBrokerFactory;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.DelegatingBroker;
-import org.apache.openjpa.kernel.FindCallbacks;
-import org.apache.openjpa.kernel.LockLevels;
-import org.apache.openjpa.kernel.OpCallbacks;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.QueryFlushModes;
-import org.apache.openjpa.kernel.QueryLanguages;
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.QueryMetaData;
-import org.apache.openjpa.meta.SequenceMetaData;
-import org.apache.openjpa.util.Exceptions;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.RuntimeExceptionTranslator;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Implementation of {@link EntityManager} interface.
- *
- * @author Patrick Linskey
- * @author Abe White
- * @nojavadoc
- */
-public class EntityManagerImpl
-    implements OpenJPAEntityManagerSPI, Externalizable,
-    FindCallbacks, OpCallbacks, Closeable, OpenJPAEntityTransaction {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (EntityManagerImpl.class);
-    private static final Object[] EMPTY_OBJECTS = new Object[0];
-
-    private DelegatingBroker _broker;
-    private EntityManagerFactoryImpl _emf;
-    private Map<FetchConfiguration,FetchPlan> _plans =
-        new IdentityHashMap<FetchConfiguration,FetchPlan>(1);
-
-    private RuntimeExceptionTranslator ret =
-        PersistenceExceptions.getRollbackTranslator(this);
-
-    public EntityManagerImpl() {
-        // for Externalizable
-    }
-
-    /**
-     * Constructor; supply factory and delegate.
-     */
-    public EntityManagerImpl(EntityManagerFactoryImpl factory,
-        Broker broker) {
-        initialize(factory, broker);
-    }
-
-    private void initialize(EntityManagerFactoryImpl factory, Broker broker) {
-        _emf = factory;
-        _broker = new DelegatingBroker(broker, ret);
-        _broker.setImplicitBehavior(this, ret);
-    }
-
-    /**
-     * Broker delegate.
-     */
-    public Broker getBroker() {
-        return _broker.getDelegate();
-    }
-
-    public OpenJPAEntityManagerFactory getEntityManagerFactory() {
-        return _emf;
-    }
-
-    public OpenJPAConfiguration getConfiguration() {
-        return _broker.getConfiguration();
-    }
-
-    public FetchPlan getFetchPlan() {
-        assertNotCloseInvoked();
-        _broker.lock();
-        try {
-            FetchConfiguration fc = _broker.getFetchConfiguration();
-            FetchPlan fp = _plans.get(fc);
-            if (fp == null) {
-                fp = _emf.toFetchPlan(_broker, fc);
-                _plans.put(fc, fp);
-            }
-            return fp;
-        } finally {
-            _broker.unlock();
-        }
-    }
-
-    public FetchPlan pushFetchPlan() {
-        assertNotCloseInvoked();
-        _broker.lock();
-        try {
-            _broker.pushFetchConfiguration();
-            return getFetchPlan();
-        } finally {
-            _broker.unlock();
-        }
-    }
-
-    public void popFetchPlan() {
-        assertNotCloseInvoked();
-        _broker.lock();
-        try {
-            _broker.popFetchConfiguration();
-        } finally {
-            _broker.unlock();
-        }
-    }
-
-    public ConnectionRetainMode getConnectionRetainMode() {
-        return ConnectionRetainMode.fromKernelConstant(
-            _broker.getConnectionRetainMode());
-    }
-
-    public boolean isTransactionManaged() {
-        return _broker.isManaged();
-    }
-
-    public boolean isManaged() {
-        return _broker.isManaged();
-    }
-
-    public ManagedRuntime getManagedRuntime() {
-        return _broker.getManagedRuntime();
-    }
-
-    public boolean getSyncWithManagedTransactions() {
-        return _broker.getSyncWithManagedTransactions();
-    }
-
-    public void setSyncWithManagedTransactions(boolean sync) {
-        assertNotCloseInvoked();
-        _broker.setSyncWithManagedTransactions(sync);
-    }
-
-    public ClassLoader getClassLoader() {
-        return _broker.getClassLoader();
-    }
-
-    public String getConnectionUserName() {
-        return _broker.getConnectionUserName();
-    }
-
-    public String getConnectionPassword() {
-        return _broker.getConnectionPassword();
-    }
-
-    public boolean getMultithreaded() {
-        return _broker.getMultithreaded();
-    }
-
-    public void setMultithreaded(boolean multithreaded) {
-        assertNotCloseInvoked();
-        _broker.setMultithreaded(multithreaded);
-    }
-
-    public boolean getIgnoreChanges() {
-        return _broker.getIgnoreChanges();
-    }
-
-    public void setIgnoreChanges(boolean val) {
-        assertNotCloseInvoked();
-        _broker.setIgnoreChanges(val);
-    }
-
-    public boolean getNontransactionalRead() {
-        return _broker.getNontransactionalRead();
-    }
-
-    public void setNontransactionalRead(boolean val) {
-        assertNotCloseInvoked();
-        _broker.setNontransactionalRead(val);
-    }
-
-    public boolean getNontransactionalWrite() {
-        return _broker.getNontransactionalWrite();
-    }
-
-    public void setNontransactionalWrite(boolean val) {
-        assertNotCloseInvoked();
-        _broker.setNontransactionalWrite(val);
-    }
-
-    public boolean getOptimistic() {
-        return _broker.getOptimistic();
-    }
-
-    public void setOptimistic(boolean val) {
-        assertNotCloseInvoked();
-        _broker.setOptimistic(val);
-    }
-
-    public RestoreStateType getRestoreState() {
-        return RestoreStateType.fromKernelConstant(_broker.getRestoreState());
-    }
-
-    public void setRestoreState(RestoreStateType val) {
-        assertNotCloseInvoked();
-        _broker.setRestoreState(val.toKernelConstant());
-    }
-
-    public void setRestoreState(int restore) {
-        assertNotCloseInvoked();
-        _broker.setRestoreState(restore);
-    }
-
-    public boolean getRetainState() {
-        return _broker.getRetainState();
-    }
-
-    public void setRetainState(boolean val) {
-        assertNotCloseInvoked();
-        _broker.setRetainState(val);
-    }
-
-    public AutoClearType getAutoClear() {
-        return AutoClearType.fromKernelConstant(_broker.getAutoClear());
-    }
-
-    public void setAutoClear(AutoClearType val) {
-        assertNotCloseInvoked();
-        _broker.setAutoClear(val.toKernelConstant());
-    }
-
-    public void setAutoClear(int autoClear) {
-        assertNotCloseInvoked();
-        _broker.setAutoClear(autoClear);
-    }
-
-    public DetachStateType getDetachState() {
-        return DetachStateType.fromKernelConstant(_broker.getDetachState());
-    }
-
-    public void setDetachState(DetachStateType type) {
-        assertNotCloseInvoked();
-        _broker.setDetachState(type.toKernelConstant());
-    }
-
-    public void setDetachState(int detach) {
-        assertNotCloseInvoked();
-        _broker.setDetachState(detach);
-    }
-
-    public EnumSet<AutoDetachType> getAutoDetach() {
-        return AutoDetachType.toEnumSet(_broker.getAutoDetach());
-    }
-
-    public void setAutoDetach(AutoDetachType flag) {
-        assertNotCloseInvoked();
-        _broker.setAutoDetach(AutoDetachType.fromEnumSet(EnumSet.of(flag)));
-    }
-
-    public void setAutoDetach(EnumSet<AutoDetachType> flags) {
-        assertNotCloseInvoked();
-        _broker.setAutoDetach(AutoDetachType.fromEnumSet(flags));
-    }
-
-    public void setAutoDetach(int autoDetachFlags) {
-        assertNotCloseInvoked();
-        _broker.setAutoDetach(autoDetachFlags);
-    }
-
-    public void setAutoDetach(AutoDetachType value, boolean on) {
-        assertNotCloseInvoked();
-        _broker.setAutoDetach(AutoDetachType.fromEnumSet(EnumSet.of(value)),on);
-    }
-
-    public void setAutoDetach(int flag, boolean on) {
-        assertNotCloseInvoked();
-        _broker.setAutoDetach(flag, on);
-    }
-
-    public boolean getEvictFromStoreCache() {
-        return _broker.getEvictFromDataCache();
-    }
-
-    public void setEvictFromStoreCache(boolean evict) {
-        assertNotCloseInvoked();
-        _broker.setEvictFromDataCache(evict);
-    }
-
-    public boolean getPopulateStoreCache() {
-        return _broker.getPopulateDataCache();
-    }
-
-    public void setPopulateStoreCache(boolean cache) {
-        assertNotCloseInvoked();
-        _broker.setPopulateDataCache(cache);
-    }
-
-    public boolean isTrackChangesByType() {
-        return _broker.isTrackChangesByType();
-    }
-
-    public void setTrackChangesByType(boolean trackByType) {
-        assertNotCloseInvoked();
-        _broker.setTrackChangesByType(trackByType);
-    }
-
-    public boolean isLargeTransaction() {
-        return isTrackChangesByType();
-    }
-
-    public void setLargeTransaction(boolean value) {
-        setTrackChangesByType(value);
-    }
-
-    public Object getUserObject(Object key) {
-        return _broker.getUserObject(key);
-    }
-
-    public Object putUserObject(Object key, Object val) {
-        assertNotCloseInvoked();
-        return _broker.putUserObject(key, val);
-    }
-
-    public void addTransactionListener(Object listener) {
-        assertNotCloseInvoked();
-        _broker.addTransactionListener(listener);
-    }
-
-    public void removeTransactionListener(Object listener) {
-        assertNotCloseInvoked();
-        _broker.removeTransactionListener(listener);
-    }
-
-    public EnumSet<CallbackMode> getTransactionListenerCallbackModes() {
-        return CallbackMode.toEnumSet(
-            _broker.getTransactionListenerCallbackMode());
-    }
-
-    public void setTransactionListenerCallbackMode(CallbackMode mode) {
-        assertNotCloseInvoked();
-        _broker.setTransactionListenerCallbackMode(
-            CallbackMode.fromEnumSet(EnumSet.of(mode)));
-    }
-
-    public void setTransactionListenerCallbackMode(EnumSet<CallbackMode> modes){
-        assertNotCloseInvoked();
-        _broker.setTransactionListenerCallbackMode(
-            CallbackMode.fromEnumSet(modes));
-    }
-
-    public int getTransactionListenerCallbackMode() {
-        return _broker.getTransactionListenerCallbackMode();
-    }
-
-    public void setTransactionListenerCallbackMode(int callbackMode) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void addLifecycleListener(Object listener, Class... classes) {
-        assertNotCloseInvoked();
-        _broker.addLifecycleListener(listener, classes);
-    }
-
-    public void removeLifecycleListener(Object listener) {
-        assertNotCloseInvoked();
-        _broker.removeLifecycleListener(listener);
-    }
-
-    public EnumSet<CallbackMode> getLifecycleListenerCallbackModes() {
-        return CallbackMode.toEnumSet(
-            _broker.getLifecycleListenerCallbackMode());
-    }
-
-    public void setLifecycleListenerCallbackMode(CallbackMode mode) {
-        assertNotCloseInvoked();
-        _broker.setLifecycleListenerCallbackMode(
-            CallbackMode.fromEnumSet(EnumSet.of(mode)));
-    }
-
-    public void setLifecycleListenerCallbackMode(EnumSet<CallbackMode> modes) {
-        assertNotCloseInvoked();
-        _broker.setLifecycleListenerCallbackMode(
-            CallbackMode.fromEnumSet(modes));
-    }
-
-    public int getLifecycleListenerCallbackMode() {
-        return _broker.getLifecycleListenerCallbackMode();
-    }
-
-    public void setLifecycleListenerCallbackMode(int callbackMode) {
-        assertNotCloseInvoked();
-        _broker.setLifecycleListenerCallbackMode(callbackMode);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T getReference(Class<T> cls, Object oid) {
-        assertNotCloseInvoked();
-        oid = _broker.newObjectId(cls, oid);
-        return (T) _broker.find(oid, false, this);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T find(Class<T> cls, Object oid) {
-        assertNotCloseInvoked();
-        oid = _broker.newObjectId(cls, oid);
-        return (T) _broker.find(oid, true, this);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T[] findAll(Class<T> cls, Object... oids) {
-        if (oids.length == 0)
-            return (T[]) Array.newInstance(cls, 0);
-        Collection<T> ret = findAll(cls, Arrays.asList(oids));
-        return ret.toArray((T[]) Array.newInstance(cls, ret.size()));
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> Collection<T> findAll(final Class<T> cls, Collection oids) {
-        assertNotCloseInvoked();
-        Object[] objs = _broker.findAll(oids, true, new FindCallbacks() {
-            public Object processArgument(Object oid) {
-                return _broker.newObjectId(cls, oid);
-            }
-
-            public Object processReturn(Object oid, OpenJPAStateManager sm) {
-                return EntityManagerImpl.this.processReturn(oid, sm);
-            }
-        });
-        return (Collection<T>) Arrays.asList(objs);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T findCached(Class<T> cls, Object oid) {
-        assertNotCloseInvoked();
-        return (T) _broker.findCached(_broker.newObjectId(cls, oid), this);
-    }
-
-    public Class getObjectIdClass(Class cls) {
-        assertNotCloseInvoked();
-        if (cls == null)
-            return null;
-        return JPAFacadeHelper.fromOpenJPAObjectIdClass
-                (_broker.getObjectIdType(cls));
-    }
-
-    public OpenJPAEntityTransaction getTransaction() {
-        if (_broker.isManaged())
-            throw new InvalidStateException(_loc.get("get-managed-trans"),
-                null, null, false);
-        return this;
-    }
-
-    public void joinTransaction() {
-        assertNotCloseInvoked();
-        if (!_broker.syncWithManagedTransaction())
-            throw new TransactionRequiredException(_loc.get
-                ("no-managed-trans"), null, null, false);
-    }
-
-    public void begin() {
-        _broker.begin();
-    }
-
-    public void commit() {
-        try {
-            _broker.commit();
-        } catch (RollbackException e) {
-            throw e;
-        } catch (IllegalStateException e) {
-            throw e;
-        } catch (Exception e) {
-            // RollbackExceptions are special and aren't handled by the
-            // normal exception translator, since the spec says they
-            // should be thrown whenever the commit fails for any reason at
-            // all, wheras the exception translator handles exceptions that
-            // are caused for specific reasons
-            throw new RollbackException(e);
-        }
-    }
-
-    public void rollback() {
-        _broker.rollback();
-    }
-
-    public void commitAndResume() {
-        _broker.commitAndResume();
-    }
-
-    public void rollbackAndResume() {
-        _broker.rollbackAndResume();
-    }
-
-    public Throwable getRollbackCause() {
-        if (!isActive())
-            throw new IllegalStateException(_loc.get("no-transaction")
-                .getMessage());
-
-        return _broker.getRollbackCause();
-    }
-
-    public boolean getRollbackOnly() {
-        if (!isActive())
-            throw new IllegalStateException(_loc.get("no-transaction")
-                .getMessage());
-
-        return _broker.getRollbackOnly();
-    }
-
-    public void setRollbackOnly() {
-        _broker.setRollbackOnly();
-    }
-
-    public void setRollbackOnly(Throwable cause) {
-        _broker.setRollbackOnly(cause);
-    }
-
-    public void setSavepoint(String name) {
-        assertNotCloseInvoked();
-        _broker.setSavepoint(name);
-    }
-
-    public void rollbackToSavepoint() {
-        assertNotCloseInvoked();
-        _broker.rollbackToSavepoint();
-    }
-
-    public void rollbackToSavepoint(String name) {
-        assertNotCloseInvoked();
-        _broker.rollbackToSavepoint(name);
-    }
-
-    public void releaseSavepoint() {
-        assertNotCloseInvoked();
-        _broker.releaseSavepoint();
-    }
-
-    public void releaseSavepoint(String name) {
-        assertNotCloseInvoked();
-        _broker.releaseSavepoint(name);
-    }
-
-    public void flush() {
-        assertNotCloseInvoked();
-        _broker.assertOpen();
-        _broker.assertActiveTransaction();
-        _broker.flush();
-    }
-
-    public void preFlush() {
-        assertNotCloseInvoked();
-        _broker.preFlush();
-    }
-
-    public void validateChanges() {
-        assertNotCloseInvoked();
-        _broker.validateChanges();
-    }
-
-    public boolean isActive() {
-        return isOpen() && _broker.isActive();
-    }
-
-    public boolean isStoreActive() {
-        return _broker.isStoreActive();
-    }
-
-    public void beginStore() {
-        _broker.beginStore();
-    }
-
-    public boolean contains(Object entity) {
-        assertNotCloseInvoked();
-        if (entity == null)
-            return false;
-        OpenJPAStateManager sm = _broker.getStateManager(entity);
-        if (sm == null
-            && !ImplHelper.isManagedType(getConfiguration(), entity.getClass()))
-            throw new ArgumentException(_loc.get("not-entity",
-                entity.getClass()), null, null, true);
-        return sm != null && !sm.isDeleted();
-    }
-
-    public boolean containsAll(Object... entities) {
-        for (Object entity : entities)
-            if (!contains(entity))
-                return false;
-        return true;
-    }
-
-    public boolean containsAll(Collection entities) {
-        for (Object entity : entities)
-            if (!contains(entity))
-                return false;
-        return true;
-    }
-
-    public void persist(Object entity) {
-        assertNotCloseInvoked();
-        _broker.persist(entity, this);
-    }
-
-    public void persistAll(Object... entities) {
-        persistAll(Arrays.asList(entities));
-    }
-
-    public void persistAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.persistAll(entities, this);
-    }
-
-    public void remove(Object entity) {
-        assertNotCloseInvoked();
-        _broker.delete(entity, this);
-    }
-
-    public void removeAll(Object... entities) {
-        removeAll(Arrays.asList(entities));
-    }
-
-    public void removeAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.deleteAll(entities, this);
-    }
-
-    public void release(Object entity) {
-        assertNotCloseInvoked();
-        _broker.release(entity, this);
-    }
-
-    public void releaseAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.releaseAll(entities, this);
-    }
-
-    public void releaseAll(Object... entities) {
-        releaseAll(Arrays.asList(entities));
-    }
-
-    public void refresh(Object entity) {
-        assertNotCloseInvoked();
-        _broker.assertWriteOperation();
-        _broker.refresh(entity, this);
-    }
-
-    public void refreshAll() {
-        assertNotCloseInvoked();
-        _broker.assertWriteOperation();
-        _broker.refreshAll(_broker.getTransactionalObjects(), this);
-    }
-
-    public void refreshAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.assertWriteOperation();
-        _broker.refreshAll(entities, this);
-    }
-
-    public void refreshAll(Object... entities) {
-        refreshAll(Arrays.asList(entities));
-    }
-
-    public void retrieve(Object entity) {
-        assertNotCloseInvoked();
-        _broker.retrieve(entity, true, this);
-    }
-
-    public void retrieveAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.retrieveAll(entities, true, this);
-    }
-
-    public void retrieveAll(Object... entities) {
-        retrieveAll(Arrays.asList(entities));
-    }
-
-    public void evict(Object entity) {
-        assertNotCloseInvoked();
-        _broker.evict(entity, this);
-    }
-
-    public void evictAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.evictAll(entities, this);
-    }
-
-    public void evictAll(Object... entities) {
-        evictAll(Arrays.asList(entities));
-    }
-
-    public void evictAll() {
-        assertNotCloseInvoked();
-        _broker.evictAll(this);
-    }
-
-    public void evictAll(Class cls) {
-        assertNotCloseInvoked();
-        _broker.evictAll(_broker.newExtent(cls, true), this);
-    }
-
-    public void evictAll(Extent extent) {
-        assertNotCloseInvoked();
-        _broker.evictAll(((ExtentImpl) extent).getDelegate(), this);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T detach(T entity) {
-        assertNotCloseInvoked();
-        return (T) _broker.detach(entity, this);
-    }
-
-    public Object[] detachAll(Object... entities) {
-        assertNotCloseInvoked();
-        return _broker.detachAll(Arrays.asList(entities), this);
-    }
-
-    public Collection detachAll(Collection entities) {
-        assertNotCloseInvoked();
-        return Arrays.asList(_broker.detachAll(entities, this));
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T merge(T entity) {
-        assertNotCloseInvoked();
-        return (T) _broker.attach(entity, true, this);
-    }
-
-    public Object[] mergeAll(Object... entities) {
-        if (entities.length == 0)
-            return EMPTY_OBJECTS;
-        return mergeAll(Arrays.asList(entities)).toArray();
-    }
-
-    public Collection mergeAll(Collection entities) {
-        assertNotCloseInvoked();
-        return Arrays.asList(_broker.attachAll(entities, true, this));
-    }
-
-    public void transactional(Object entity, boolean updateVersion) {
-        assertNotCloseInvoked();
-        _broker.transactional(entity, updateVersion, this);
-    }
-
-    public void transactionalAll(Collection objs, boolean updateVersion) {
-        assertNotCloseInvoked();
-        _broker.transactionalAll(objs, updateVersion, this);
-    }
-
-    public void transactionalAll(Object[] objs, boolean updateVersion) {
-        assertNotCloseInvoked();
-        _broker.transactionalAll(Arrays.asList(objs), updateVersion, this);
-    }
-
-    public void nontransactional(Object entity) {
-        assertNotCloseInvoked();
-        _broker.nontransactional(entity, this);
-    }
-
-    public void nontransactionalAll(Collection objs) {
-        assertNotCloseInvoked();
-        _broker.nontransactionalAll(objs, this);
-    }
-
-    public void nontransactionalAll(Object[] objs) {
-        assertNotCloseInvoked();
-        _broker.nontransactionalAll(Arrays.asList(objs), this);
-    }
-
-    public Generator getNamedGenerator(String name) {
-        assertNotCloseInvoked();
-        try {
-            SequenceMetaData meta = _broker.getConfiguration().
-                getMetaDataRepositoryInstance().getSequenceMetaData(name,
-                _broker.getClassLoader(), true);
-            Seq seq = meta.getInstance(_broker.getClassLoader());
-            return new GeneratorImpl(seq, name, _broker, null);
-        } catch (RuntimeException re) {
-            throw PersistenceExceptions.toPersistenceException(re);
-        }
-    }
-
-    public Generator getIdGenerator(Class forClass) {
-        assertNotCloseInvoked();
-        try {
-            ClassMetaData meta = _broker.getConfiguration().
-                getMetaDataRepositoryInstance().getMetaData(forClass,
-                _broker.getClassLoader(), true);
-            Seq seq = _broker.getIdentitySequence(meta);
-            return (seq == null) ? null : new GeneratorImpl(seq, null, _broker,
-                meta);
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        }
-    }
-
-    public Generator getFieldGenerator(Class forClass, String fieldName) {
-        assertNotCloseInvoked();
-        try {
-            ClassMetaData meta = _broker.getConfiguration().
-                getMetaDataRepositoryInstance().getMetaData(forClass,
-                _broker.getClassLoader(), true);
-            FieldMetaData fmd = meta.getField(fieldName);
-            if (fmd == null)
-                throw new ArgumentException(_loc.get("no-named-field",
-                    forClass, fieldName), null, null, false);
-
-            Seq seq = _broker.getValueSequence(fmd);
-            return (seq == null) ? null : new GeneratorImpl(seq, null, _broker,
-                meta);
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        }
-    }
-
-    public <T> Extent<T> createExtent(Class<T> cls, boolean subclasses) {
-        assertNotCloseInvoked();
-        return new ExtentImpl<T>(this, _broker.newExtent(cls, subclasses));
-    }
-
-    public OpenJPAQuery createQuery(String query) {
-        return createQuery(JPQLParser.LANG_JPQL, query);
-    }
-
-    public OpenJPAQuery createQuery(String language, String query) {
-        assertNotCloseInvoked();
-        return new QueryImpl(this, ret, _broker.newQuery(language, query));
-    }
-
-    public OpenJPAQuery createQuery(Query query) {
-        if (query == null)
-            return createQuery((String) null);
-        assertNotCloseInvoked();
-        org.apache.openjpa.kernel.Query q = ((QueryImpl) query).getDelegate();
-        return new QueryImpl(this, ret, _broker.newQuery(q.getLanguage(),
-            q));
-    }
-
-    public OpenJPAQuery createNamedQuery(String name) {
-        assertNotCloseInvoked();
-        _broker.assertOpen();
-        try {
-            QueryMetaData meta = _broker.getConfiguration().
-                getMetaDataRepositoryInstance().getQueryMetaData(null, name,
-                _broker.getClassLoader(), true);
-            org.apache.openjpa.kernel.Query del =
-                _broker.newQuery(meta.getLanguage(), null);
-            meta.setInto(del);
-            del.compile();
-
-            OpenJPAQuery q = new QueryImpl(this, ret, del);
-            String[] hints = meta.getHintKeys();
-            Object[] values = meta.getHintValues();
-            for (int i = 0; i < hints.length; i++)
-                q.setHint(hints[i], values[i]);
-            return q;
-        } catch (RuntimeException re) {
-            throw PersistenceExceptions.toPersistenceException(re);
-        }
-    }
-
-    public OpenJPAQuery createNativeQuery(String query) {
-        validateSQL(query);
-        return createQuery(QueryLanguages.LANG_SQL, query);
-    }
-
-    public OpenJPAQuery createNativeQuery(String query, Class cls) {
-        return createNativeQuery(query).setResultClass(cls);
-    }
-
-    public OpenJPAQuery createNativeQuery(String query, String mappingName) {
-        assertNotCloseInvoked();
-        validateSQL(query);
-        org.apache.openjpa.kernel.Query kernelQuery = _broker.newQuery(
-            QueryLanguages.LANG_SQL, query);
-        kernelQuery.setResultMapping(null, mappingName);
-        return new QueryImpl(this, ret, kernelQuery);
-    }
-
-    /**
-     * Validate that the user provided SQL.
-     */
-    private static void validateSQL(String query) {
-        if (StringUtils.trimToNull(query) == null)
-            throw new ArgumentException(_loc.get("no-sql"), null, null, false);
-    }
-
-    public void setFlushMode(FlushModeType flushMode) {
-        assertNotCloseInvoked();
-        _broker.assertOpen();
-        _broker.getFetchConfiguration().setFlushBeforeQueries
-            (toFlushBeforeQueries(flushMode));
-    }
-
-    public FlushModeType getFlushMode() {
-        assertNotCloseInvoked();
-        _broker.assertOpen();
-        return fromFlushBeforeQueries(_broker.getFetchConfiguration().
-            getFlushBeforeQueries());
-    }
-
-    /**
-     * Translate our internal flush constant to a flush mode enum value.
-     */
-    static FlushModeType fromFlushBeforeQueries(int flush) {
-        switch (flush) {
-            case QueryFlushModes.FLUSH_TRUE:
-                return FlushModeType.AUTO;
-            case QueryFlushModes.FLUSH_FALSE:
-                return FlushModeType.COMMIT;
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Translate a flush mode enum value to our internal flush constant.
-     */
-    static int toFlushBeforeQueries(FlushModeType flushMode) {
-        // choose default for null
-        if (flushMode == null)
-            return QueryFlushModes.FLUSH_WITH_CONNECTION;
-        if (flushMode == FlushModeType.AUTO)
-            return QueryFlushModes.FLUSH_TRUE;
-        if (flushMode == FlushModeType.COMMIT)
-            return QueryFlushModes.FLUSH_FALSE;
-        throw new ArgumentException(flushMode.toString(), null, null, false);
-    }
-
-    public void clear() {
-        assertNotCloseInvoked();
-        _broker.detachAll(this, false);
-    }
-
-    public Object getDelegate() {
-        _broker.assertOpen();
-        assertNotCloseInvoked();
-        return this;
-    }
-
-    public LockModeType getLockMode(Object entity) {
-        assertNotCloseInvoked();
-        return fromLockLevel(_broker.getLockLevel(entity));
-    }
-
-    public void lock(Object entity, LockModeType mode) {
-        assertNotCloseInvoked();
-        _broker.lock(entity, toLockLevel(mode), -1, this);
-    }
-
-    public void lock(Object entity) {
-        assertNotCloseInvoked();
-        _broker.lock(entity, this);
-    }
-
-    public void lock(Object entity, LockModeType mode, int timeout) {
-        assertNotCloseInvoked();
-        _broker.lock(entity, toLockLevel(mode), timeout, this);
-    }
-
-    public void lockAll(Collection entities) {
-        assertNotCloseInvoked();
-        _broker.lockAll(entities, this);
-    }
-
-    public void lockAll(Collection entities, LockModeType mode, int timeout) {
-        assertNotCloseInvoked();
-        _broker.lockAll(entities, toLockLevel(mode), timeout, this);
-    }
-
-    public void lockAll(Object... entities) {
-        lockAll(Arrays.asList(entities));
-    }
-
-    public void lockAll(Object[] entities, LockModeType mode, int timeout) {
-        lockAll(Arrays.asList(entities), mode, timeout);
-    }
-
-    /**
-     * Translate our internal lock level to a javax.persistence enum value.
-     */
-    static LockModeType fromLockLevel(int level) {
-        if (level < LockLevels.LOCK_READ)
-            return null;
-        if (level < LockLevels.LOCK_WRITE)
-            return LockModeType.READ;
-        return LockModeType.WRITE;
-    }
-
-    /**
-     * Translate the javax.persistence enum value to our internal lock level.
-     */
-    static int toLockLevel(LockModeType mode) {
-        if (mode == null)
-            return LockLevels.LOCK_NONE;
-        if (mode == LockModeType.READ)
-            return LockLevels.LOCK_READ;
-        if (mode == LockModeType.WRITE)
-            return LockLevels.LOCK_WRITE;
-        throw new ArgumentException(mode.toString(), null, null, true);
-    }
-
-    public boolean cancelAll() {
-        return _broker.cancelAll();
-    }
-
-    public Object getConnection() {
-        return _broker.getConnection();
-    }
-
-    public Collection getManagedObjects() {
-        return _broker.getManagedObjects();
-    }
-
-    public Collection getTransactionalObjects() {
-        return _broker.getTransactionalObjects();
-    }
-
-    public Collection getPendingTransactionalObjects() {
-        return _broker.getPendingTransactionalObjects();
-    }
-
-    public Collection getDirtyObjects() {
-        return _broker.getDirtyObjects();
-    }
-
-    public boolean getOrderDirtyObjects() {
-        return _broker.getOrderDirtyObjects();
-    }
-
-    public void setOrderDirtyObjects(boolean order) {
-        assertNotCloseInvoked();
-        _broker.setOrderDirtyObjects(order);
-    }
-
-    public void dirtyClass(Class cls) {
-        assertNotCloseInvoked();
-        _broker.dirtyType(cls);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Collection<Class> getPersistedClasses() {
-        return (Collection<Class>) _broker.getPersistedTypes();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Collection<Class> getUpdatedClasses() {
-        return (Collection<Class>) _broker.getUpdatedTypes();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Collection<Class> getRemovedClasses() {
-        return (Collection<Class>) _broker.getDeletedTypes();
-    }
-
-    public <T> T createInstance(Class<T> cls) {
-        assertNotCloseInvoked();
-        return (T) _broker.newInstance(cls);
-    }
-
-    public void close() {
-        assertNotCloseInvoked();
-        _broker.close();
-    }
-
-    public boolean isOpen() {
-        return !_broker.isCloseInvoked();
-    }
-
-    public void dirty(Object o, String field) {
-        assertNotCloseInvoked();
-        OpenJPAStateManager sm = _broker.getStateManager(o);
-        try {
-            if (sm != null)
-                sm.dirty(field);
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        }
-    }
-
-    public Object getObjectId(Object o) {
-        assertNotCloseInvoked();
-        return JPAFacadeHelper.fromOpenJPAObjectId(_broker.getObjectId(o));
-    }
-
-    public boolean isDirty(Object o) {
-        assertNotCloseInvoked();
-        return _broker.isDirty(o);
-    }
-
-    public boolean isTransactional(Object o) {
-        assertNotCloseInvoked();
-        return _broker.isTransactional(o);
-    }
-
-    public boolean isPersistent(Object o) {
-        assertNotCloseInvoked();
-        return _broker.isPersistent(o);
-    }
-
-    public boolean isNewlyPersistent(Object o) {
-        assertNotCloseInvoked();
-        return _broker.isNew(o);
-    }
-
-    public boolean isRemoved(Object o) {
-        assertNotCloseInvoked();
-        return _broker.isDeleted(o);
-    }
-
-    public boolean isDetached(Object entity) {
-        assertNotCloseInvoked();
-        return _broker.isDetached(entity);
-    }
-
-    public Object getVersion(Object o) {
-        assertNotCloseInvoked();
-        return _broker.getVersion(o);
-    }
-
-    /**
-     * Throw appropriate exception if close has been invoked but the broker
-     * is still open.  We test only for this because if the broker is already
-     * closed, it will throw its own more informative exception when we 
-     * delegate the pending operation to it.
-     */
-    void assertNotCloseInvoked() {
-        if (!_broker.isClosed() && _broker.isCloseInvoked())
-            throw new InvalidStateException(_loc.get("close-invoked"), null,
-                null, true);
-    }
-
-    ////////////////////////////////
-    // FindCallbacks implementation
-    ////////////////////////////////
-
-    public Object processArgument(Object arg) {
-        return arg;
-    }
-
-    public Object processReturn(Object oid, OpenJPAStateManager sm) {
-        return (sm == null || sm.isDeleted()) ? null : sm.getManagedInstance();
-    }
-
-    //////////////////////////////
-    // OpCallbacks implementation
-    //////////////////////////////
-
-    public int processArgument(int op, Object obj, OpenJPAStateManager sm) {
-        switch (op) {
-            case OP_DELETE:
-                // cascade through non-persistent non-detached instances
-                if (sm == null && !_broker.isDetached(obj))
-                    return ACT_CASCADE;
-                if (sm != null && !sm.isDetached() && !sm.isPersistent())
-                    return ACT_CASCADE;
-                // ignore deleted instances
-                if (sm != null && sm.isDeleted())
-                    return ACT_NONE;
-                break;
-            case OP_ATTACH:
-                // die on removed
-                if (sm != null && sm.isDeleted())
-                    throw new UserException(_loc.get("removed",
-                        Exceptions.toString(obj))).setFailedObject(obj);
-                // cascade through managed instances
-                if (sm != null && !sm.isDetached())
-                    return ACT_CASCADE;
-                break;
-            case OP_REFRESH:
-                // die on unmanaged instances
-                if (sm == null)
-                    throw new UserException(_loc.get("not-managed",
-                        Exceptions.toString(obj))).setFailedObject(obj);
-                break;
-        }
-        return ACT_RUN | ACT_CASCADE;
-    }
-
-    public int hashCode() {
-        return _broker.hashCode();
-    }
-
-    public boolean equals(Object other) {
-        if (other == this)
-            return true;
-        if (!(other instanceof EntityManagerImpl))
-            return false;
-        return _broker.equals(((EntityManagerImpl) other)._broker);
-    }
-
-    public void readExternal(ObjectInput in)
-        throws IOException, ClassNotFoundException {
-        try {
-            ret = PersistenceExceptions.getRollbackTranslator(this);
-
-            // this assumes that serialized Brokers are from something
-            // that extends AbstractBrokerFactory.
-            Object factoryKey = in.readObject();
-            AbstractBrokerFactory factory =
-                AbstractBrokerFactory.getPooledFactoryForKey(factoryKey);
-            byte[] brokerBytes = (byte[]) in.readObject();
-            ObjectInputStream innerIn = new BrokerBytesInputStream(brokerBytes,
-                factory.getConfiguration());
-
-            Broker broker = (Broker) innerIn.readObject();
-            EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl)
-                JPAFacadeHelper.toEntityManagerFactory(
-                    broker.getBrokerFactory());
-            broker.putUserObject(JPAFacadeHelper.EM_KEY, this);
-            initialize(emf, broker);
-        } catch (RuntimeException re) {
-            try {
-                re = ret.translate(re);
-            } catch (Exception e) {
-                // ignore
-            }
-            throw re;
-        }
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        try {
-            // this requires that only AbstractBrokerFactory-sourced
-            // brokers can be serialized
-            Object factoryKey = ((AbstractBrokerFactory) _broker
-                .getBrokerFactory()).getPoolKey();
-            out.writeObject(factoryKey);
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream innerOut = new ObjectOutputStream(baos);
-            innerOut.writeObject(_broker.getDelegate());
-            innerOut.flush();
-            out.writeObject(baos.toByteArray());
-        } catch (RuntimeException re) {
-            try {
-                re = ret.translate(re);
-            } catch (Exception e) {
-                // ignore
-            }
-            throw re;
-        }
-    }
-
-    private static class BrokerBytesInputStream extends ObjectInputStream {
-
-        private OpenJPAConfiguration conf;
-
-        BrokerBytesInputStream(byte[] bytes, OpenJPAConfiguration conf)
-            throws IOException {
-            super(new ByteArrayInputStream(bytes));
-            if (conf == null)
-                throw new IllegalArgumentException(
-                    "Illegal null argument to ObjectInputStreamWithLoader");
-            this.conf = conf;
-        }
-
-        /**
-         * Make a primitive array class
-         */
-        private Class primitiveType(char type) {
-            switch (type) {
-                case 'B': return byte.class;
-                case 'C': return char.class;
-                case 'D': return double.class;
-                case 'F': return float.class;
-                case 'I': return int.class;
-                case 'J': return long.class;
-                case 'S': return short.class;
-                case 'Z': return boolean.class;
-                default: return null;
-            }
-        }
-
-        protected Class resolveClass(ObjectStreamClass classDesc)
-            throws IOException, ClassNotFoundException {
-
-            String cname = classDesc.getName();
-            if (cname.startsWith("[")) {
-                // An array
-                Class component;		// component class
-                int dcount;			    // dimension
-                for (dcount=1; cname.charAt(dcount)=='['; dcount++) ;
-                if (cname.charAt(dcount) == 'L') {
-                    component = lookupClass(cname.substring(dcount+1,
-                        cname.length()-1));
-                } else {
-                    if (cname.length() != dcount+1) {
-                        throw new ClassNotFoundException(cname);// malformed
-                    }
-                    component = primitiveType(cname.charAt(dcount));
-                }
-                int dim[] = new int[dcount];
-                for (int i=0; i<dcount; i++) {
-                    dim[i]=0;
-                }
-                return Array.newInstance(component, dim).getClass();
-            } else {
-                return lookupClass(cname);
-            }
-        }
-
-        /**
-         * If this is a generated subclass, look up the corresponding Class
-         * object via metadata.
-         */
-        private Class lookupClass(String className)
-            throws ClassNotFoundException {
-            try {
-                return Class.forName(className);
-            } catch (ClassNotFoundException e) {
-                if (PCEnhancer.isPCSubclassName(className)) {
-                    String superName = PCEnhancer.toManagedTypeName(className);
-                    ClassMetaData[] metas = conf.getMetaDataRepositoryInstance()
-                        .getMetaDatas();
-                    for (int i = 0; i < metas.length; i++) {
-                        if (superName.equals(
-                            metas[i].getDescribedType().getName())) {
-                            return PCRegistry.getPCType(
-                                metas[i].getDescribedType());
-                        }
-                    }
-
-                    // if it's not found, try to look for it anyways
-                    return Class.forName(className);
-                } else {
-                    throw e;
-                }
-            }
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Query;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.enhance.PCEnhancer;
+import org.apache.openjpa.enhance.PCRegistry;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.DelegatingBroker;
+import org.apache.openjpa.kernel.FindCallbacks;
+import org.apache.openjpa.kernel.LockLevels;
+import org.apache.openjpa.kernel.OpCallbacks;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.QueryFlushModes;
+import org.apache.openjpa.kernel.QueryLanguages;
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.QueryMetaData;
+import org.apache.openjpa.meta.SequenceMetaData;
+import org.apache.openjpa.util.Exceptions;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.RuntimeExceptionTranslator;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Implementation of {@link EntityManager} interface.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ * @nojavadoc
+ */
+public class EntityManagerImpl
+    implements OpenJPAEntityManagerSPI, Externalizable,
+    FindCallbacks, OpCallbacks, Closeable, OpenJPAEntityTransaction {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (EntityManagerImpl.class);
+    private static final Object[] EMPTY_OBJECTS = new Object[0];
+
+    private DelegatingBroker _broker;
+    private EntityManagerFactoryImpl _emf;
+    private Map<FetchConfiguration,FetchPlan> _plans =
+        new IdentityHashMap<FetchConfiguration,FetchPlan>(1);
+
+    private RuntimeExceptionTranslator ret =
+        PersistenceExceptions.getRollbackTranslator(this);
+
+    public EntityManagerImpl() {
+        // for Externalizable
+    }
+
+    /**
+     * Constructor; supply factory and delegate.
+     */
+    public EntityManagerImpl(EntityManagerFactoryImpl factory,
+        Broker broker) {
+        initialize(factory, broker);
+    }
+
+    private void initialize(EntityManagerFactoryImpl factory, Broker broker) {
+        _emf = factory;
+        _broker = new DelegatingBroker(broker, ret);
+        _broker.setImplicitBehavior(this, ret);
+    }
+
+    /**
+     * Broker delegate.
+     */
+    public Broker getBroker() {
+        return _broker.getDelegate();
+    }
+
+    public OpenJPAEntityManagerFactory getEntityManagerFactory() {
+        return _emf;
+    }
+
+    public OpenJPAConfiguration getConfiguration() {
+        return _broker.getConfiguration();
+    }
+
+    public FetchPlan getFetchPlan() {
+        assertNotCloseInvoked();
+        _broker.lock();
+        try {
+            FetchConfiguration fc = _broker.getFetchConfiguration();
+            FetchPlan fp = _plans.get(fc);
+            if (fp == null) {
+                fp = _emf.toFetchPlan(_broker, fc);
+                _plans.put(fc, fp);
+            }
+            return fp;
+        } finally {
+            _broker.unlock();
+        }
+    }
+
+    public FetchPlan pushFetchPlan() {
+        assertNotCloseInvoked();
+        _broker.lock();
+        try {
+            _broker.pushFetchConfiguration();
+            return getFetchPlan();
+        } finally {
+            _broker.unlock();
+        }
+    }
+
+    public void popFetchPlan() {
+        assertNotCloseInvoked();
+        _broker.lock();
+        try {
+            _broker.popFetchConfiguration();
+        } finally {
+            _broker.unlock();
+        }
+    }
+
+    public ConnectionRetainMode getConnectionRetainMode() {
+        return ConnectionRetainMode.fromKernelConstant(
+            _broker.getConnectionRetainMode());
+    }
+
+    public boolean isTransactionManaged() {
+        return _broker.isManaged();
+    }
+
+    public boolean isManaged() {
+        return _broker.isManaged();
+    }
+
+    public ManagedRuntime getManagedRuntime() {
+        return _broker.getManagedRuntime();
+    }
+
+    public boolean getSyncWithManagedTransactions() {
+        return _broker.getSyncWithManagedTransactions();
+    }
+
+    public void setSyncWithManagedTransactions(boolean sync) {
+        assertNotCloseInvoked();
+        _broker.setSyncWithManagedTransactions(sync);
+    }
+
+    public ClassLoader getClassLoader() {
+        return _broker.getClassLoader();
+    }
+
+    public String getConnectionUserName() {
+        return _broker.getConnectionUserName();
+    }
+
+    public String getConnectionPassword() {
+        return _broker.getConnectionPassword();
+    }
+
+    public boolean getMultithreaded() {
+        return _broker.getMultithreaded();
+    }
+
+    public void setMultithreaded(boolean multithreaded) {
+        assertNotCloseInvoked();
+        _broker.setMultithreaded(multithreaded);
+    }
+
+    public boolean getIgnoreChanges() {
+        return _broker.getIgnoreChanges();
+    }
+
+    public void setIgnoreChanges(boolean val) {
+        assertNotCloseInvoked();
+        _broker.setIgnoreChanges(val);
+    }
+
+    public boolean getNontransactionalRead() {
+        return _broker.getNontransactionalRead();
+    }
+
+    public void setNontransactionalRead(boolean val) {
+        assertNotCloseInvoked();
+        _broker.setNontransactionalRead(val);
+    }
+
+    public boolean getNontransactionalWrite() {
+        return _broker.getNontransactionalWrite();
+    }
+
+    public void setNontransactionalWrite(boolean val) {
+        assertNotCloseInvoked();
+        _broker.setNontransactionalWrite(val);
+    }
+
+    public boolean getOptimistic() {
+        return _broker.getOptimistic();
+    }
+
+    public void setOptimistic(boolean val) {
+        assertNotCloseInvoked();
+        _broker.setOptimistic(val);
+    }
+
+    public RestoreStateType getRestoreState() {
+        return RestoreStateType.fromKernelConstant(_broker.getRestoreState());
+    }
+
+    public void setRestoreState(RestoreStateType val) {
+        assertNotCloseInvoked();
+        _broker.setRestoreState(val.toKernelConstant());
+    }
+
+    public void setRestoreState(int restore) {
+        assertNotCloseInvoked();
+        _broker.setRestoreState(restore);
+    }
+
+    public boolean getRetainState() {
+        return _broker.getRetainState();
+    }
+
+    public void setRetainState(boolean val) {
+        assertNotCloseInvoked();
+        _broker.setRetainState(val);
+    }
+
+    public AutoClearType getAutoClear() {
+        return AutoClearType.fromKernelConstant(_broker.getAutoClear());
+    }
+
+    public void setAutoClear(AutoClearType val) {
+        assertNotCloseInvoked();
+        _broker.setAutoClear(val.toKernelConstant());
+    }
+
+    public void setAutoClear(int autoClear) {
+        assertNotCloseInvoked();
+        _broker.setAutoClear(autoClear);
+    }
+
+    public DetachStateType getDetachState() {
+        return DetachStateType.fromKernelConstant(_broker.getDetachState());
+    }
+
+    public void setDetachState(DetachStateType type) {
+        assertNotCloseInvoked();
+        _broker.setDetachState(type.toKernelConstant());
+    }
+
+    public void setDetachState(int detach) {
+        assertNotCloseInvoked();
+        _broker.setDetachState(detach);
+    }
+
+    public EnumSet<AutoDetachType> getAutoDetach() {
+        return AutoDetachType.toEnumSet(_broker.getAutoDetach());
+    }
+
+    public void setAutoDetach(AutoDetachType flag) {
+        assertNotCloseInvoked();
+        _broker.setAutoDetach(AutoDetachType.fromEnumSet(EnumSet.of(flag)));
+    }
+
+    public void setAutoDetach(EnumSet<AutoDetachType> flags) {
+        assertNotCloseInvoked();
+        _broker.setAutoDetach(AutoDetachType.fromEnumSet(flags));
+    }
+
+    public void setAutoDetach(int autoDetachFlags) {
+        assertNotCloseInvoked();
+        _broker.setAutoDetach(autoDetachFlags);
+    }
+
+    public void setAutoDetach(AutoDetachType value, boolean on) {
+        assertNotCloseInvoked();
+        _broker.setAutoDetach(AutoDetachType.fromEnumSet(EnumSet.of(value)),on);
+    }
+
+    public void setAutoDetach(int flag, boolean on) {
+        assertNotCloseInvoked();
+        _broker.setAutoDetach(flag, on);
+    }
+
+    public boolean getEvictFromStoreCache() {
+        return _broker.getEvictFromDataCache();
+    }
+
+    public void setEvictFromStoreCache(boolean evict) {
+        assertNotCloseInvoked();
+        _broker.setEvictFromDataCache(evict);
+    }
+
+    public boolean getPopulateStoreCache() {
+        return _broker.getPopulateDataCache();
+    }
+
+    public void setPopulateStoreCache(boolean cache) {
+        assertNotCloseInvoked();
+        _broker.setPopulateDataCache(cache);
+    }
+
+    public boolean isTrackChangesByType() {
+        return _broker.isTrackChangesByType();
+    }
+
+    public void setTrackChangesByType(boolean trackByType) {
+        assertNotCloseInvoked();
+        _broker.setTrackChangesByType(trackByType);
+    }
+
+    public boolean isLargeTransaction() {
+        return isTrackChangesByType();
+    }
+
+    public void setLargeTransaction(boolean value) {
+        setTrackChangesByType(value);
+    }
+
+    public Object getUserObject(Object key) {
+        return _broker.getUserObject(key);
+    }
+
+    public Object putUserObject(Object key, Object val) {
+        assertNotCloseInvoked();
+        return _broker.putUserObject(key, val);
+    }
+
+    public void addTransactionListener(Object listener) {
+        assertNotCloseInvoked();
+        _broker.addTransactionListener(listener);
+    }
+
+    public void removeTransactionListener(Object listener) {
+        assertNotCloseInvoked();
+        _broker.removeTransactionListener(listener);
+    }
+
+    public EnumSet<CallbackMode> getTransactionListenerCallbackModes() {
+        return CallbackMode.toEnumSet(
+            _broker.getTransactionListenerCallbackMode());
+    }
+
+    public void setTransactionListenerCallbackMode(CallbackMode mode) {
+        assertNotCloseInvoked();
+        _broker.setTransactionListenerCallbackMode(
+            CallbackMode.fromEnumSet(EnumSet.of(mode)));
+    }
+
+    public void setTransactionListenerCallbackMode(EnumSet<CallbackMode> modes){
+        assertNotCloseInvoked();
+        _broker.setTransactionListenerCallbackMode(
+            CallbackMode.fromEnumSet(modes));
+    }
+
+    public int getTransactionListenerCallbackMode() {
+        return _broker.getTransactionListenerCallbackMode();
+    }
+
+    public void setTransactionListenerCallbackMode(int callbackMode) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addLifecycleListener(Object listener, Class... classes) {
+        assertNotCloseInvoked();
+        _broker.addLifecycleListener(listener, classes);
+    }
+
+    public void removeLifecycleListener(Object listener) {
+        assertNotCloseInvoked();
+        _broker.removeLifecycleListener(listener);
+    }
+
+    public EnumSet<CallbackMode> getLifecycleListenerCallbackModes() {
+        return CallbackMode.toEnumSet(
+            _broker.getLifecycleListenerCallbackMode());
+    }
+
+    public void setLifecycleListenerCallbackMode(CallbackMode mode) {
+        assertNotCloseInvoked();
+        _broker.setLifecycleListenerCallbackMode(
+            CallbackMode.fromEnumSet(EnumSet.of(mode)));
+    }
+
+    public void setLifecycleListenerCallbackMode(EnumSet<CallbackMode> modes) {
+        assertNotCloseInvoked();
+        _broker.setLifecycleListenerCallbackMode(
+            CallbackMode.fromEnumSet(modes));
+    }
+
+    public int getLifecycleListenerCallbackMode() {
+        return _broker.getLifecycleListenerCallbackMode();
+    }
+
+    public void setLifecycleListenerCallbackMode(int callbackMode) {
+        assertNotCloseInvoked();
+        _broker.setLifecycleListenerCallbackMode(callbackMode);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getReference(Class<T> cls, Object oid) {
+        assertNotCloseInvoked();
+        oid = _broker.newObjectId(cls, oid);
+        return (T) _broker.find(oid, false, this);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T find(Class<T> cls, Object oid) {
+        assertNotCloseInvoked();
+        oid = _broker.newObjectId(cls, oid);
+        return (T) _broker.find(oid, true, this);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T[] findAll(Class<T> cls, Object... oids) {
+        if (oids.length == 0)
+            return (T[]) Array.newInstance(cls, 0);
+        Collection<T> ret = findAll(cls, Arrays.asList(oids));
+        return ret.toArray((T[]) Array.newInstance(cls, ret.size()));
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> Collection<T> findAll(final Class<T> cls, Collection oids) {
+        assertNotCloseInvoked();
+        Object[] objs = _broker.findAll(oids, true, new FindCallbacks() {
+            public Object processArgument(Object oid) {
+                return _broker.newObjectId(cls, oid);
+            }
+
+            public Object processReturn(Object oid, OpenJPAStateManager sm) {
+                return EntityManagerImpl.this.processReturn(oid, sm);
+            }
+        });
+        return (Collection<T>) Arrays.asList(objs);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T findCached(Class<T> cls, Object oid) {
+        assertNotCloseInvoked();
+        return (T) _broker.findCached(_broker.newObjectId(cls, oid), this);
+    }
+
+    public Class getObjectIdClass(Class cls) {
+        assertNotCloseInvoked();
+        if (cls == null)
+            return null;
+        return JPAFacadeHelper.fromOpenJPAObjectIdClass
+                (_broker.getObjectIdType(cls));
+    }
+
+    public OpenJPAEntityTransaction getTransaction() {
+        if (_broker.isManaged())
+            throw new InvalidStateException(_loc.get("get-managed-trans"),
+                null, null, false);
+        return this;
+    }
+
+    public void joinTransaction() {
+        assertNotCloseInvoked();
+        if (!_broker.syncWithManagedTransaction())
+            throw new TransactionRequiredException(_loc.get
+                ("no-managed-trans"), null, null, false);
+    }
+
+    public void begin() {
+        _broker.begin();
+    }
+
+    public void commit() {
+        try {
+            _broker.commit();
+        } catch (RollbackException e) {
+            throw e;
+        } catch (IllegalStateException e) {
+            throw e;
+        } catch (Exception e) {
+            // RollbackExceptions are special and aren't handled by the
+            // normal exception translator, since the spec says they
+            // should be thrown whenever the commit fails for any reason at
+            // all, wheras the exception translator handles exceptions that
+            // are caused for specific reasons
+            throw new RollbackException(e);
+        }
+    }
+
+    public void rollback() {
+        _broker.rollback();
+    }
+
+    public void commitAndResume() {
+        _broker.commitAndResume();
+    }
+
+    public void rollbackAndResume() {
+        _broker.rollbackAndResume();
+    }
+
+    public Throwable getRollbackCause() {
+        if (!isActive())
+            throw new IllegalStateException(_loc.get("no-transaction")
+                .getMessage());
+
+        return _broker.getRollbackCause();
+    }
+
+    public boolean getRollbackOnly() {
+        if (!isActive())
+            throw new IllegalStateException(_loc.get("no-transaction")
+                .getMessage());
+
+        return _broker.getRollbackOnly();
+    }
+
+    public void setRollbackOnly() {
+        _broker.setRollbackOnly();
+    }
+
+    public void setRollbackOnly(Throwable cause) {
+        _broker.setRollbackOnly(cause);
+    }
+
+    public void setSavepoint(String name) {
+        assertNotCloseInvoked();
+        _broker.setSavepoint(name);
+    }
+
+    public void rollbackToSavepoint() {
+        assertNotCloseInvoked();
+        _broker.rollbackToSavepoint();
+    }
+
+    public void rollbackToSavepoint(String name) {
+        assertNotCloseInvoked();
+        _broker.rollbackToSavepoint(name);
+    }
+
+    public void releaseSavepoint() {
+        assertNotCloseInvoked();
+        _broker.releaseSavepoint();
+    }
+
+    public void releaseSavepoint(String name) {
+        assertNotCloseInvoked();
+        _broker.releaseSavepoint(name);
+    }
+
+    public void flush() {
+        assertNotCloseInvoked();
+        _broker.assertOpen();
+        _broker.assertActiveTransaction();
+        _broker.flush();
+    }
+
+    public void preFlush() {
+        assertNotCloseInvoked();
+        _broker.preFlush();
+    }
+
+    public void validateChanges() {
+        assertNotCloseInvoked();
+        _broker.validateChanges();
+    }
+
+    public boolean isActive() {
+        return isOpen() && _broker.isActive();
+    }
+
+    public boolean isStoreActive() {
+        return _broker.isStoreActive();
+    }
+
+    public void beginStore() {
+        _broker.beginStore();
+    }
+
+    public boolean contains(Object entity) {
+        assertNotCloseInvoked();
+        if (entity == null)
+            return false;
+        OpenJPAStateManager sm = _broker.getStateManager(entity);
+        if (sm == null
+            && !ImplHelper.isManagedType(getConfiguration(), entity.getClass()))
+            throw new ArgumentException(_loc.get("not-entity",
+                entity.getClass()), null, null, true);
+        return sm != null && !sm.isDeleted();
+    }
+
+    public boolean containsAll(Object... entities) {
+        for (Object entity : entities)
+            if (!contains(entity))
+                return false;
+        return true;
+    }
+
+    public boolean containsAll(Collection entities) {
+        for (Object entity : entities)
+            if (!contains(entity))
+                return false;
+        return true;
+    }
+
+    public void persist(Object entity) {
+        assertNotCloseInvoked();
+        _broker.persist(entity, this);
+    }
+
+    public void persistAll(Object... entities) {
+        persistAll(Arrays.asList(entities));
+    }
+
+    public void persistAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.persistAll(entities, this);
+    }
+
+    public void remove(Object entity) {
+        assertNotCloseInvoked();
+        _broker.delete(entity, this);
+    }
+
+    public void removeAll(Object... entities) {
+        removeAll(Arrays.asList(entities));
+    }
+
+    public void removeAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.deleteAll(entities, this);
+    }
+
+    public void release(Object entity) {
+        assertNotCloseInvoked();
+        _broker.release(entity, this);
+    }
+
+    public void releaseAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.releaseAll(entities, this);
+    }
+
+    public void releaseAll(Object... entities) {
+        releaseAll(Arrays.asList(entities));
+    }
+
+    public void refresh(Object entity) {
+        assertNotCloseInvoked();
+        _broker.assertWriteOperation();
+        _broker.refresh(entity, this);
+    }
+
+    public void refreshAll() {
+        assertNotCloseInvoked();
+        _broker.assertWriteOperation();
+        _broker.refreshAll(_broker.getTransactionalObjects(), this);
+    }
+
+    public void refreshAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.assertWriteOperation();
+        _broker.refreshAll(entities, this);
+    }
+
+    public void refreshAll(Object... entities) {
+        refreshAll(Arrays.asList(entities));
+    }
+
+    public void retrieve(Object entity) {
+        assertNotCloseInvoked();
+        _broker.retrieve(entity, true, this);
+    }
+
+    public void retrieveAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.retrieveAll(entities, true, this);
+    }
+
+    public void retrieveAll(Object... entities) {
+        retrieveAll(Arrays.asList(entities));
+    }
+
+    public void evict(Object entity) {
+        assertNotCloseInvoked();
+        _broker.evict(entity, this);
+    }
+
+    public void evictAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.evictAll(entities, this);
+    }
+
+    public void evictAll(Object... entities) {
+        evictAll(Arrays.asList(entities));
+    }
+
+    public void evictAll() {
+        assertNotCloseInvoked();
+        _broker.evictAll(this);
+    }
+
+    public void evictAll(Class cls) {
+        assertNotCloseInvoked();
+        _broker.evictAll(_broker.newExtent(cls, true), this);
+    }
+
+    public void evictAll(Extent extent) {
+        assertNotCloseInvoked();
+        _broker.evictAll(((ExtentImpl) extent).getDelegate(), this);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T detach(T entity) {
+        assertNotCloseInvoked();
+        return (T) _broker.detach(entity, this);
+    }
+
+    public Object[] detachAll(Object... entities) {
+        assertNotCloseInvoked();
+        return _broker.detachAll(Arrays.asList(entities), this);
+    }
+
+    public Collection detachAll(Collection entities) {
+        assertNotCloseInvoked();
+        return Arrays.asList(_broker.detachAll(entities, this));
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T merge(T entity) {
+        assertNotCloseInvoked();
+        return (T) _broker.attach(entity, true, this);
+    }
+
+    public Object[] mergeAll(Object... entities) {
+        if (entities.length == 0)
+            return EMPTY_OBJECTS;
+        return mergeAll(Arrays.asList(entities)).toArray();
+    }
+
+    public Collection mergeAll(Collection entities) {
+        assertNotCloseInvoked();
+        return Arrays.asList(_broker.attachAll(entities, true, this));
+    }
+
+    public void transactional(Object entity, boolean updateVersion) {
+        assertNotCloseInvoked();
+        _broker.transactional(entity, updateVersion, this);
+    }
+
+    public void transactionalAll(Collection objs, boolean updateVersion) {
+        assertNotCloseInvoked();
+        _broker.transactionalAll(objs, updateVersion, this);
+    }
+
+    public void transactionalAll(Object[] objs, boolean updateVersion) {
+        assertNotCloseInvoked();
+        _broker.transactionalAll(Arrays.asList(objs), updateVersion, this);
+    }
+
+    public void nontransactional(Object entity) {
+        assertNotCloseInvoked();
+        _broker.nontransactional(entity, this);
+    }
+
+    public void nontransactionalAll(Collection objs) {
+        assertNotCloseInvoked();
+        _broker.nontransactionalAll(objs, this);
+    }
+
+    public void nontransactionalAll(Object[] objs) {
+        assertNotCloseInvoked();
+        _broker.nontransactionalAll(Arrays.asList(objs), this);
+    }
+
+    public Generator getNamedGenerator(String name) {
+        assertNotCloseInvoked();
+        try {
+            SequenceMetaData meta = _broker.getConfiguration().
+                getMetaDataRepositoryInstance().getSequenceMetaData(name,
+                _broker.getClassLoader(), true);
+            Seq seq = meta.getInstance(_broker.getClassLoader());
+            return new GeneratorImpl(seq, name, _broker, null);
+        } catch (RuntimeException re) {
+            throw PersistenceExceptions.toPersistenceException(re);
+        }
+    }
+
+    public Generator getIdGenerator(Class forClass) {
+        assertNotCloseInvoked();
+        try {
+            ClassMetaData meta = _broker.getConfiguration().
+                getMetaDataRepositoryInstance().getMetaData(forClass,
+                _broker.getClassLoader(), true);
+            Seq seq = _broker.getIdentitySequence(meta);
+            return (seq == null) ? null : new GeneratorImpl(seq, null, _broker,
+                meta);
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        }
+    }
+
+    public Generator getFieldGenerator(Class forClass, String fieldName) {
+        assertNotCloseInvoked();
+        try {
+            ClassMetaData meta = _broker.getConfiguration().
+                getMetaDataRepositoryInstance().getMetaData(forClass,
+                _broker.getClassLoader(), true);
+            FieldMetaData fmd = meta.getField(fieldName);
+            if (fmd == null)
+                throw new ArgumentException(_loc.get("no-named-field",
+                    forClass, fieldName), null, null, false);
+
+            Seq seq = _broker.getValueSequence(fmd);
+            return (seq == null) ? null : new GeneratorImpl(seq, null, _broker,
+                meta);
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        }
+    }
+
+    public <T> Extent<T> createExtent(Class<T> cls, boolean subclasses) {
+        assertNotCloseInvoked();
+        return new ExtentImpl<T>(this, _broker.newExtent(cls, subclasses));
+    }
+
+    public OpenJPAQuery createQuery(String query) {
+        return createQuery(JPQLParser.LANG_JPQL, query);
+    }
+
+    public OpenJPAQuery createQuery(String language, String query) {
+        assertNotCloseInvoked();
+        return new QueryImpl(this, ret, _broker.newQuery(language, query));
+    }
+
+    public OpenJPAQuery createQuery(Query query) {
+        if (query == null)
+            return createQuery((String) null);
+        assertNotCloseInvoked();
+        org.apache.openjpa.kernel.Query q = ((QueryImpl) query).getDelegate();
+        return new QueryImpl(this, ret, _broker.newQuery(q.getLanguage(),
+            q));
+    }
+
+    public OpenJPAQuery createNamedQuery(String name) {
+        assertNotCloseInvoked();
+        _broker.assertOpen();
+        try {
+            QueryMetaData meta = _broker.getConfiguration().
+                getMetaDataRepositoryInstance().getQueryMetaData(null, name,
+                _broker.getClassLoader(), true);
+            org.apache.openjpa.kernel.Query del =
+                _broker.newQuery(meta.getLanguage(), null);
+            meta.setInto(del);
+            del.compile();
+
+            OpenJPAQuery q = new QueryImpl(this, ret, del);
+            String[] hints = meta.getHintKeys();
+            Object[] values = meta.getHintValues();
+            for (int i = 0; i < hints.length; i++)
+                q.setHint(hints[i], values[i]);
+            return q;
+        } catch (RuntimeException re) {
+            throw PersistenceExceptions.toPersistenceException(re);
+        }
+    }
+
+    public OpenJPAQuery createNativeQuery(String query) {
+        validateSQL(query);
+        return createQuery(QueryLanguages.LANG_SQL, query);
+    }
+
+    public OpenJPAQuery createNativeQuery(String query, Class cls) {
+        return createNativeQuery(query).setResultClass(cls);
+    }
+
+    public OpenJPAQuery createNativeQuery(String query, String mappingName) {
+        assertNotCloseInvoked();
+        validateSQL(query);
+        org.apache.openjpa.kernel.Query kernelQuery = _broker.newQuery(
+            QueryLanguages.LANG_SQL, query);
+        kernelQuery.setResultMapping(null, mappingName);
+        return new QueryImpl(this, ret, kernelQuery);
+    }
+
+    /**
+     * Validate that the user provided SQL.
+     */
+    private static void validateSQL(String query) {
+        if (StringUtils.trimToNull(query) == null)
+            throw new ArgumentException(_loc.get("no-sql"), null, null, false);
+    }
+
+    public void setFlushMode(FlushModeType flushMode) {
+        assertNotCloseInvoked();
+        _broker.assertOpen();
+        _broker.getFetchConfiguration().setFlushBeforeQueries
+            (toFlushBeforeQueries(flushMode));
+    }
+
+    public FlushModeType getFlushMode() {
+        assertNotCloseInvoked();
+        _broker.assertOpen();
+        return fromFlushBeforeQueries(_broker.getFetchConfiguration().
+            getFlushBeforeQueries());
+    }
+
+    /**
+     * Translate our internal flush constant to a flush mode enum value.
+     */
+    static FlushModeType fromFlushBeforeQueries(int flush) {
+        switch (flush) {
+            case QueryFlushModes.FLUSH_TRUE:
+                return FlushModeType.AUTO;
+            case QueryFlushModes.FLUSH_FALSE:
+                return FlushModeType.COMMIT;
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Translate a flush mode enum value to our internal flush constant.
+     */
+    static int toFlushBeforeQueries(FlushModeType flushMode) {
+        // choose default for null
+        if (flushMode == null)
+            return QueryFlushModes.FLUSH_WITH_CONNECTION;
+        if (flushMode == FlushModeType.AUTO)
+            return QueryFlushModes.FLUSH_TRUE;
+        if (flushMode == FlushModeType.COMMIT)
+            return QueryFlushModes.FLUSH_FALSE;
+        throw new ArgumentException(flushMode.toString(), null, null, false);
+    }
+
+    public void clear() {
+        assertNotCloseInvoked();
+        _broker.detachAll(this, false);
+    }
+
+    public Object getDelegate() {
+        _broker.assertOpen();
+        assertNotCloseInvoked();
+        return this;
+    }
+
+    public LockModeType getLockMode(Object entity) {
+        assertNotCloseInvoked();
+        return fromLockLevel(_broker.getLockLevel(entity));
+    }
+
+    public void lock(Object entity, LockModeType mode) {
+        assertNotCloseInvoked();
+        _broker.lock(entity, toLockLevel(mode), -1, this);
+    }
+
+    public void lock(Object entity) {
+        assertNotCloseInvoked();
+        _broker.lock(entity, this);
+    }
+
+    public void lock(Object entity, LockModeType mode, int timeout) {
+        assertNotCloseInvoked();
+        _broker.lock(entity, toLockLevel(mode), timeout, this);
+    }
+
+    public void lockAll(Collection entities) {
+        assertNotCloseInvoked();
+        _broker.lockAll(entities, this);
+    }
+
+    public void lockAll(Collection entities, LockModeType mode, int timeout) {
+        assertNotCloseInvoked();
+        _broker.lockAll(entities, toLockLevel(mode), timeout, this);
+    }
+
+    public void lockAll(Object... entities) {
+        lockAll(Arrays.asList(entities));
+    }
+
+    public void lockAll(Object[] entities, LockModeType mode, int timeout) {
+        lockAll(Arrays.asList(entities), mode, timeout);
+    }
+
+    /**
+     * Translate our internal lock level to a javax.persistence enum value.
+     */
+    static LockModeType fromLockLevel(int level) {
+        if (level < LockLevels.LOCK_READ)
+            return null;
+        if (level < LockLevels.LOCK_WRITE)
+            return LockModeType.READ;
+        return LockModeType.WRITE;
+    }
+
+    /**
+     * Translate the javax.persistence enum value to our internal lock level.
+     */
+    static int toLockLevel(LockModeType mode) {
+        if (mode == null)
+            return LockLevels.LOCK_NONE;
+        if (mode == LockModeType.READ)
+            return LockLevels.LOCK_READ;
+        if (mode == LockModeType.WRITE)
+            return LockLevels.LOCK_WRITE;
+        throw new ArgumentException(mode.toString(), null, null, true);
+    }
+
+    public boolean cancelAll() {
+        return _broker.cancelAll();
+    }
+
+    public Object getConnection() {
+        return _broker.getConnection();
+    }
+
+    public Collection getManagedObjects() {
+        return _broker.getManagedObjects();
+    }
+
+    public Collection getTransactionalObjects() {
+        return _broker.getTransactionalObjects();
+    }
+
+    public Collection getPendingTransactionalObjects() {
+        return _broker.getPendingTransactionalObjects();
+    }
+
+    public Collection getDirtyObjects() {
+        return _broker.getDirtyObjects();
+    }
+
+    public boolean getOrderDirtyObjects() {
+        return _broker.getOrderDirtyObjects();
+    }
+
+    public void setOrderDirtyObjects(boolean order) {
+        assertNotCloseInvoked();
+        _broker.setOrderDirtyObjects(order);
+    }
+
+    public void dirtyClass(Class cls) {
+        assertNotCloseInvoked();
+        _broker.dirtyType(cls);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection<Class> getPersistedClasses() {
+        return (Collection<Class>) _broker.getPersistedTypes();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection<Class> getUpdatedClasses() {
+        return (Collection<Class>) _broker.getUpdatedTypes();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection<Class> getRemovedClasses() {
+        return (Collection<Class>) _broker.getDeletedTypes();
+    }
+
+    public <T> T createInstance(Class<T> cls) {
+        assertNotCloseInvoked();
+        return (T) _broker.newInstance(cls);
+    }
+
+    public void close() {
+        assertNotCloseInvoked();
+        _broker.close();
+    }
+
+    public boolean isOpen() {
+        return !_broker.isCloseInvoked();
+    }
+
+    public void dirty(Object o, String field) {
+        assertNotCloseInvoked();
+        OpenJPAStateManager sm = _broker.getStateManager(o);
+        try {
+            if (sm != null)
+                sm.dirty(field);
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        }
+    }
+
+    public Object getObjectId(Object o) {
+        assertNotCloseInvoked();
+        return JPAFacadeHelper.fromOpenJPAObjectId(_broker.getObjectId(o));
+    }
+
+    public boolean isDirty(Object o) {
+        assertNotCloseInvoked();
+        return _broker.isDirty(o);
+    }
+
+    public boolean isTransactional(Object o) {
+        assertNotCloseInvoked();
+        return _broker.isTransactional(o);
+    }
+
+    public boolean isPersistent(Object o) {
+        assertNotCloseInvoked();
+        return _broker.isPersistent(o);
+    }
+
+    public boolean isNewlyPersistent(Object o) {
+        assertNotCloseInvoked();
+        return _broker.isNew(o);
+    }
+
+    public boolean isRemoved(Object o) {
+        assertNotCloseInvoked();
+        return _broker.isDeleted(o);
+    }
+
+    public boolean isDetached(Object entity) {
+        assertNotCloseInvoked();
+        return _broker.isDetached(entity);
+    }
+
+    public Object getVersion(Object o) {
+        assertNotCloseInvoked();
+        return _broker.getVersion(o);
+    }
+
+    /**
+     * Throw appropriate exception if close has been invoked but the broker
+     * is still open.  We test only for this because if the broker is already
+     * closed, it will throw its own more informative exception when we 
+     * delegate the pending operation to it.
+     */
+    void assertNotCloseInvoked() {
+        if (!_broker.isClosed() && _broker.isCloseInvoked())
+            throw new InvalidStateException(_loc.get("close-invoked"), null,
+                null, true);
+    }
+
+    ////////////////////////////////
+    // FindCallbacks implementation
+    ////////////////////////////////
+
+    public Object processArgument(Object arg) {
+        return arg;
+    }
+
+    public Object processReturn(Object oid, OpenJPAStateManager sm) {
+        return (sm == null || sm.isDeleted()) ? null : sm.getManagedInstance();
+    }
+
+    //////////////////////////////
+    // OpCallbacks implementation
+    //////////////////////////////
+
+    public int processArgument(int op, Object obj, OpenJPAStateManager sm) {
+        switch (op) {
+            case OP_DELETE:
+                // cascade through non-persistent non-detached instances
+                if (sm == null && !_broker.isDetached(obj))
+                    return ACT_CASCADE;
+                if (sm != null && !sm.isDetached() && !sm.isPersistent())
+                    return ACT_CASCADE;
+                // ignore deleted instances
+                if (sm != null && sm.isDeleted())
+                    return ACT_NONE;
+                break;
+            case OP_ATTACH:
+                // die on removed
+                if (sm != null && sm.isDeleted())
+                    throw new UserException(_loc.get("removed",
+                        Exceptions.toString(obj))).setFailedObject(obj);
+                // cascade through managed instances
+                if (sm != null && !sm.isDetached())
+                    return ACT_CASCADE;
+                break;
+            case OP_REFRESH:
+                // die on unmanaged instances
+                if (sm == null)
+                    throw new UserException(_loc.get("not-managed",
+                        Exceptions.toString(obj))).setFailedObject(obj);
+                break;
+        }
+        return ACT_RUN | ACT_CASCADE;
+    }
+
+    public int hashCode() {
+        return _broker.hashCode();
+    }
+
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+        if (!(other instanceof EntityManagerImpl))
+            return false;
+        return _broker.equals(((EntityManagerImpl) other)._broker);
+    }
+
+    public void readExternal(ObjectInput in)
+        throws IOException, ClassNotFoundException {
+        try {
+            ret = PersistenceExceptions.getRollbackTranslator(this);
+
+            // this assumes that serialized Brokers are from something
+            // that extends AbstractBrokerFactory.
+            Object factoryKey = in.readObject();
+            AbstractBrokerFactory factory =
+                AbstractBrokerFactory.getPooledFactoryForKey(factoryKey);
+            byte[] brokerBytes = (byte[]) in.readObject();
+            ObjectInputStream innerIn = new BrokerBytesInputStream(brokerBytes,
+                factory.getConfiguration());
+
+            Broker broker = (Broker) innerIn.readObject();
+            EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl)
+                JPAFacadeHelper.toEntityManagerFactory(
+                    broker.getBrokerFactory());
+            broker.putUserObject(JPAFacadeHelper.EM_KEY, this);
+            initialize(emf, broker);
+        } catch (RuntimeException re) {
+            try {
+                re = ret.translate(re);
+            } catch (Exception e) {
+                // ignore
+            }
+            throw re;
+        }
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        try {
+            // this requires that only AbstractBrokerFactory-sourced
+            // brokers can be serialized
+            Object factoryKey = ((AbstractBrokerFactory) _broker
+                .getBrokerFactory()).getPoolKey();
+            out.writeObject(factoryKey);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream innerOut = new ObjectOutputStream(baos);
+            innerOut.writeObject(_broker.getDelegate());
+            innerOut.flush();
+            out.writeObject(baos.toByteArray());
+        } catch (RuntimeException re) {
+            try {
+                re = ret.translate(re);
+            } catch (Exception e) {
+                // ignore
+            }
+            throw re;
+        }
+    }
+
+    private static class BrokerBytesInputStream extends ObjectInputStream {
+
+        private OpenJPAConfiguration conf;
+
+        BrokerBytesInputStream(byte[] bytes, OpenJPAConfiguration conf)
+            throws IOException {
+            super(new ByteArrayInputStream(bytes));
+            if (conf == null)
+                throw new IllegalArgumentException(
+                    "Illegal null argument to ObjectInputStreamWithLoader");
+            this.conf = conf;
+        }
+
+        /**
+         * Make a primitive array class
+         */
+        private Class primitiveType(char type) {
+            switch (type) {
+                case 'B': return byte.class;
+                case 'C': return char.class;
+                case 'D': return double.class;
+                case 'F': return float.class;
+                case 'I': return int.class;
+                case 'J': return long.class;
+                case 'S': return short.class;
+                case 'Z': return boolean.class;
+                default: return null;
+            }
+        }
+
+        protected Class resolveClass(ObjectStreamClass classDesc)
+            throws IOException, ClassNotFoundException {
+
+            String cname = classDesc.getName();
+            if (cname.startsWith("[")) {
+                // An array
+                Class component;		// component class
+                int dcount;			    // dimension
+                for (dcount=1; cname.charAt(dcount)=='['; dcount++) ;
+                if (cname.charAt(dcount) == 'L') {
+                    component = lookupClass(cname.substring(dcount+1,
+                        cname.length()-1));
+                } else {
+                    if (cname.length() != dcount+1) {
+                        throw new ClassNotFoundException(cname);// malformed
+                    }
+                    component = primitiveType(cname.charAt(dcount));
+                }
+                int dim[] = new int[dcount];
+                for (int i=0; i<dcount; i++) {
+                    dim[i]=0;
+                }
+                return Array.newInstance(component, dim).getClass();
+            } else {
+                return lookupClass(cname);
+            }
+        }
+
+        /**
+         * If this is a generated subclass, look up the corresponding Class
+         * object via metadata.
+         */
+        private Class lookupClass(String className)
+            throws ClassNotFoundException {
+            try {
+                return Class.forName(className);
+            } catch (ClassNotFoundException e) {
+                if (PCEnhancer.isPCSubclassName(className)) {
+                    String superName = PCEnhancer.toManagedTypeName(className);
+                    ClassMetaData[] metas = conf.getMetaDataRepositoryInstance()
+                        .getMetaDatas();
+                    for (int i = 0; i < metas.length; i++) {
+                        if (superName.equals(
+                            metas[i].getDescribedType().getName())) {
+                            return PCRegistry.getPCType(
+                                metas[i].getDescribedType());
+                        }
+                    }
+
+                    // if it's not found, try to look for it anyways
+                    return Class.forName(className);
+                } else {
+                    throw e;
+                }
+            }
+        }
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java
index 7f12f0c..7351e34 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAFacadeHelper.java
@@ -1,319 +1,319 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.util.BigDecimalId;
-import org.apache.openjpa.util.BigIntegerId;
-import org.apache.openjpa.util.ByteId;
-import org.apache.openjpa.util.CharId;
-import org.apache.openjpa.util.DoubleId;
-import org.apache.openjpa.util.FloatId;
-import org.apache.openjpa.util.Id;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.IntId;
-import org.apache.openjpa.util.LongId;
-import org.apache.openjpa.util.ObjectId;
-import org.apache.openjpa.util.OpenJPAId;
-import org.apache.openjpa.util.ShortId;
-import org.apache.openjpa.util.StringId;
-import org.apache.openjpa.lib.util.Localizer;
-
-/**
- * Helper class for switching between OpenJPA's JPA facade and the underlying
- * Broker kernel.
- *
- * @since 1.0.0
- * @nojavadoc
- */
-public class JPAFacadeHelper {
-
-    public static final String EM_KEY =
-        "org.apache.openjpa.persistence.EntityManager";
-    public static final String EMF_KEY =
-        "org.apache.openjpa.persistence.EntityManagerFactory";
-
-    private static final Localizer _loc =
-        Localizer.forPackage(JPAFacadeHelper.class);
-
-    public static OpenJPAEntityManagerFactory toEntityManagerFactory(
-        BrokerFactory factory) {
-        if (factory == null)
-            return null;
-
-        factory.lock();
-        try {
-            OpenJPAEntityManagerFactory emf = (OpenJPAEntityManagerFactory)
-                factory.getUserObject(EMF_KEY);
-            if (emf == null) {
-                emf = EntityManagerFactoryValue.newFactory(factory);
-                factory.putUserObject(EMF_KEY, emf);
-            }
-            return emf;
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        } finally {
-            factory.unlock();
-        }
-    }
-
-    /**
-     * Return the underlying broker factory for the given persistence manager
-     * factory facade.
-     */
-    public static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
-        if (emf == null)
-            return null;
-        if (!(emf instanceof EntityManagerFactoryImpl)) {
-            Class c = emf.getClass();
-            try {
-                // either cast here may fail
-                emf = (EntityManagerFactoryImpl) ((OpenJPAEntityManagerFactory)
-                    emf).getUserObject(EMF_KEY);
-            } catch (ClassCastException cce) {
-                throw new ArgumentException(_loc.get(
-                    "cant-convert-brokerfactory", c), null, null, false);
-            }
-        }
-        return ((EntityManagerFactoryImpl) emf).getBrokerFactory();
-    }
-
-    /**
-     * Return a persistence manager facade to the given broker retaining
-     * previously associated persistence context type.
-     */
-    public static OpenJPAEntityManager toEntityManager(Broker broker) {
-        if (broker == null)
-            return null;
-
-        broker.lock();
-        try {
-            OpenJPAEntityManager em = (OpenJPAEntityManager)
-                broker.getUserObject(EM_KEY);
-            if (em == null) {
-                EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl)
-                    toEntityManagerFactory(broker.getBrokerFactory());
-                em = emf.newEntityManagerImpl(broker);
-                broker.putUserObject(EM_KEY, em);
-            }
-            return em;
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        } finally {
-            broker.unlock();
-        }
-    }
-
-    /**
-     * Return the underlying broker for the given entity manager facade.
-     */
-    public static Broker toBroker(EntityManager em) {
-        if (em == null)
-            return null;
-        if (!(em instanceof EntityManagerImpl)) {
-            Class c = em.getClass();
-            try {
-                // either cast here may fail
-                em = (EntityManagerImpl) ((OpenJPAEntityManager) em).
-                    getUserObject(EM_KEY);
-            } catch (ClassCastException cce) {
-                throw new ArgumentException(_loc.get("cant-convert-broker", c),
-                    new Throwable[] { cce }, null, false);
-            }
-        }
-        return ((EntityManagerImpl) em).getBroker();
-    }
-
-    /**
-     * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated with the
-     * persistent object <code>o</code>.
-     */
-    public static ClassMetaData getMetaData(Object o) {
-        if (o == null)
-            return null;
-        EntityManager em = OpenJPAPersistence.getEntityManager(o);
-        return (em == null) ? null : getMetaData(em,
-            ImplHelper.getManagedInstance(o).getClass());
-    }
-
-    /**
-     * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
-     * with the persistent type <code>cls</code>.
-     */
-    public static ClassMetaData getMetaData(EntityManager em, Class cls) {
-        if (em == null)
-            throw new NullPointerException("em == null");
-
-        OpenJPAEntityManagerSPI kem = (OpenJPAEntityManagerSPI)
-            OpenJPAPersistence.cast(em);
-        try {
-            return kem.getConfiguration().getMetaDataRepositoryInstance().
-                getMetaData(cls, kem.getClassLoader(), false);
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        }
-    }
-
-    /**
-     * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
-     * with the persistent type <code>cls</code>.
-     */
-    public static ClassMetaData getMetaData(EntityManagerFactory emf,
-        Class cls) {
-        if (emf == null)
-            throw new NullPointerException("emf == null");
-
-        OpenJPAEntityManagerFactorySPI emfSPI =
-            (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf);
-        try {
-            return emfSPI.getConfiguration().getMetaDataRepositoryInstance().
-                getMetaData(cls, null, false);
-        } catch (Exception e) {
-            throw PersistenceExceptions.toPersistenceException(e);
-        }
-    }
-
-    /**
-     * Translate from a OpenJPA identity object to a Persistence one.
-     */
-    public static Object fromOpenJPAObjectId(Object oid) {
-        if (oid instanceof OpenJPAId)
-            return ((OpenJPAId) oid).getIdObject();
-        return oid;
-    }
-
-    /**
-     * Translate from a Persistence identity object to a OpenJPA one.
-     */
-    public static Object toOpenJPAObjectId(ClassMetaData meta, Object oid) {
-        if (oid == null || meta == null)
-            return null;
-
-        Class cls = meta.getDescribedType();
-        if (meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
-            return new Id(cls, ((Number) oid).longValue());
-
-        if (oid instanceof Byte)
-            return new ByteId(cls, (Byte) oid);
-        if (oid instanceof Character)
-            return new CharId(cls, (Character) oid);
-        if (oid instanceof Double)
-            return new DoubleId(cls, (Double) oid);
-        if (oid instanceof Float)
-            return new FloatId(cls, (Float) oid);
-        if (oid instanceof Integer)
-            return new IntId(cls, (Integer) oid);
-        if (oid instanceof Long)
-            return new LongId(cls, (Long) oid);
-        if (oid instanceof Short)
-            return new ShortId(cls, (Short) oid);
-        if (oid instanceof String)
-            return new StringId(cls, (String) oid);
-        if (oid instanceof BigDecimal)
-            return new BigDecimalId(cls, (BigDecimal) oid);
-        if (oid instanceof BigInteger)
-            return new BigIntegerId(cls, (BigInteger) oid);
-        return new ObjectId(cls, oid);
-    }
-
-    /**
-     * Return an array of OpenJPA oids for the given native oid array.
-     */
-    public static Object[] toOpenJPAObjectIds(ClassMetaData meta,
-        Object... oids) {
-        if (oids == null || oids.length == 0)
-            return oids;
-
-        // since the class if fixed for all oids, we can tell if we have to
-        // translate the array based on whether the first oid needs translating
-        Object oid = toOpenJPAObjectId(meta, oids[0]);
-        if (oid == oids[0])
-            return oids;
-
-        Object[] copy = new Object[oids.length];
-        copy[0] = oid;
-        for (int i = 1; i < oids.length; i++)
-            copy[i] = toOpenJPAObjectId(meta, oids[i]);
-        return copy;
-    }
-
-    /**
-     * Return a collection of OpenJPA oids for the given native oid collection.
-     */
-    public static Collection toOpenJPAObjectIds(ClassMetaData meta,
-        Collection oids) {
-        if (oids == null || oids.isEmpty())
-            return oids;
-
-        // since the class if fixed for all oids, we can tell if we have to
-        // translate the array based on whether the first oid needs translating
-        Iterator itr = oids.iterator();
-        Object orig = itr.next();
-        Object oid = toOpenJPAObjectId(meta, orig);
-        if (oid == orig)
-            return oids;
-
-        Collection copy = new ArrayList(oids.size());
-        copy.add(oid);
-        while (itr.hasNext())
-            copy.add(toOpenJPAObjectId(meta, itr.next()));
-        return copy;
-    }
-
-    /**
-     * Translate from a OpenJPA identity class to a native one.
-     */
-    public static Class fromOpenJPAObjectIdClass(Class oidClass) {
-        if (oidClass == null)
-            return null;
-        if (oidClass == Id.class)
-            return Long.class;
-        if (oidClass == ByteId.class)
-            return Byte.class;
-        if (oidClass == CharId.class)
-            return Character.class;
-        if (oidClass == DoubleId.class)
-            return Double.class;
-        if (oidClass == FloatId.class)
-            return Float.class;
-        if (oidClass == IntId.class)
-            return Integer.class;
-        if (oidClass == LongId.class)
-            return Long.class;
-        if (oidClass == ShortId.class)
-            return Short.class;
-        if (oidClass == StringId.class)
-            return String.class;
-        if (oidClass == BigDecimalId.class)
-            return BigDecimal.class;
-        if (oidClass == BigIntegerId.class)
-            return BigInteger.class;
-        return oidClass;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.BigDecimalId;
+import org.apache.openjpa.util.BigIntegerId;
+import org.apache.openjpa.util.ByteId;
+import org.apache.openjpa.util.CharId;
+import org.apache.openjpa.util.DoubleId;
+import org.apache.openjpa.util.FloatId;
+import org.apache.openjpa.util.Id;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.IntId;
+import org.apache.openjpa.util.LongId;
+import org.apache.openjpa.util.ObjectId;
+import org.apache.openjpa.util.OpenJPAId;
+import org.apache.openjpa.util.ShortId;
+import org.apache.openjpa.util.StringId;
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * Helper class for switching between OpenJPA's JPA facade and the underlying
+ * Broker kernel.
+ *
+ * @since 1.0.0
+ * @nojavadoc
+ */
+public class JPAFacadeHelper {
+
+    public static final String EM_KEY =
+        "org.apache.openjpa.persistence.EntityManager";
+    public static final String EMF_KEY =
+        "org.apache.openjpa.persistence.EntityManagerFactory";
+
+    private static final Localizer _loc =
+        Localizer.forPackage(JPAFacadeHelper.class);
+
+    public static OpenJPAEntityManagerFactory toEntityManagerFactory(
+        BrokerFactory factory) {
+        if (factory == null)
+            return null;
+
+        factory.lock();
+        try {
+            OpenJPAEntityManagerFactory emf = (OpenJPAEntityManagerFactory)
+                factory.getUserObject(EMF_KEY);
+            if (emf == null) {
+                emf = EntityManagerFactoryValue.newFactory(factory);
+                factory.putUserObject(EMF_KEY, emf);
+            }
+            return emf;
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        } finally {
+            factory.unlock();
+        }
+    }
+
+    /**
+     * Return the underlying broker factory for the given persistence manager
+     * factory facade.
+     */
+    public static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
+        if (emf == null)
+            return null;
+        if (!(emf instanceof EntityManagerFactoryImpl)) {
+            Class c = emf.getClass();
+            try {
+                // either cast here may fail
+                emf = (EntityManagerFactoryImpl) ((OpenJPAEntityManagerFactory)
+                    emf).getUserObject(EMF_KEY);
+            } catch (ClassCastException cce) {
+                throw new ArgumentException(_loc.get(
+                    "cant-convert-brokerfactory", c), null, null, false);
+            }
+        }
+        return ((EntityManagerFactoryImpl) emf).getBrokerFactory();
+    }
+
+    /**
+     * Return a persistence manager facade to the given broker retaining
+     * previously associated persistence context type.
+     */
+    public static OpenJPAEntityManager toEntityManager(Broker broker) {
+        if (broker == null)
+            return null;
+
+        broker.lock();
+        try {
+            OpenJPAEntityManager em = (OpenJPAEntityManager)
+                broker.getUserObject(EM_KEY);
+            if (em == null) {
+                EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl)
+                    toEntityManagerFactory(broker.getBrokerFactory());
+                em = emf.newEntityManagerImpl(broker);
+                broker.putUserObject(EM_KEY, em);
+            }
+            return em;
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        } finally {
+            broker.unlock();
+        }
+    }
+
+    /**
+     * Return the underlying broker for the given entity manager facade.
+     */
+    public static Broker toBroker(EntityManager em) {
+        if (em == null)
+            return null;
+        if (!(em instanceof EntityManagerImpl)) {
+            Class c = em.getClass();
+            try {
+                // either cast here may fail
+                em = (EntityManagerImpl) ((OpenJPAEntityManager) em).
+                    getUserObject(EM_KEY);
+            } catch (ClassCastException cce) {
+                throw new ArgumentException(_loc.get("cant-convert-broker", c),
+                    new Throwable[] { cce }, null, false);
+            }
+        }
+        return ((EntityManagerImpl) em).getBroker();
+    }
+
+    /**
+     * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated with the
+     * persistent object <code>o</code>.
+     */
+    public static ClassMetaData getMetaData(Object o) {
+        if (o == null)
+            return null;
+        EntityManager em = OpenJPAPersistence.getEntityManager(o);
+        return (em == null) ? null : getMetaData(em,
+            ImplHelper.getManagedInstance(o).getClass());
+    }
+
+    /**
+     * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
+     * with the persistent type <code>cls</code>.
+     */
+    public static ClassMetaData getMetaData(EntityManager em, Class cls) {
+        if (em == null)
+            throw new NullPointerException("em == null");
+
+        OpenJPAEntityManagerSPI kem = (OpenJPAEntityManagerSPI)
+            OpenJPAPersistence.cast(em);
+        try {
+            return kem.getConfiguration().getMetaDataRepositoryInstance().
+                getMetaData(cls, kem.getClassLoader(), false);
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        }
+    }
+
+    /**
+     * Returns the {@link org.apache.openjpa.meta.ClassMetaData} associated
+     * with the persistent type <code>cls</code>.
+     */
+    public static ClassMetaData getMetaData(EntityManagerFactory emf,
+        Class cls) {
+        if (emf == null)
+            throw new NullPointerException("emf == null");
+
+        OpenJPAEntityManagerFactorySPI emfSPI =
+            (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(emf);
+        try {
+            return emfSPI.getConfiguration().getMetaDataRepositoryInstance().
+                getMetaData(cls, null, false);
+        } catch (Exception e) {
+            throw PersistenceExceptions.toPersistenceException(e);
+        }
+    }
+
+    /**
+     * Translate from a OpenJPA identity object to a Persistence one.
+     */
+    public static Object fromOpenJPAObjectId(Object oid) {
+        if (oid instanceof OpenJPAId)
+            return ((OpenJPAId) oid).getIdObject();
+        return oid;
+    }
+
+    /**
+     * Translate from a Persistence identity object to a OpenJPA one.
+     */
+    public static Object toOpenJPAObjectId(ClassMetaData meta, Object oid) {
+        if (oid == null || meta == null)
+            return null;
+
+        Class cls = meta.getDescribedType();
+        if (meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
+            return new Id(cls, ((Number) oid).longValue());
+
+        if (oid instanceof Byte)
+            return new ByteId(cls, (Byte) oid);
+        if (oid instanceof Character)
+            return new CharId(cls, (Character) oid);
+        if (oid instanceof Double)
+            return new DoubleId(cls, (Double) oid);
+        if (oid instanceof Float)
+            return new FloatId(cls, (Float) oid);
+        if (oid instanceof Integer)
+            return new IntId(cls, (Integer) oid);
+        if (oid instanceof Long)
+            return new LongId(cls, (Long) oid);
+        if (oid instanceof Short)
+            return new ShortId(cls, (Short) oid);
+        if (oid instanceof String)
+            return new StringId(cls, (String) oid);
+        if (oid instanceof BigDecimal)
+            return new BigDecimalId(cls, (BigDecimal) oid);
+        if (oid instanceof BigInteger)
+            return new BigIntegerId(cls, (BigInteger) oid);
+        return new ObjectId(cls, oid);
+    }
+
+    /**
+     * Return an array of OpenJPA oids for the given native oid array.
+     */
+    public static Object[] toOpenJPAObjectIds(ClassMetaData meta,
+        Object... oids) {
+        if (oids == null || oids.length == 0)
+            return oids;
+
+        // since the class if fixed for all oids, we can tell if we have to
+        // translate the array based on whether the first oid needs translating
+        Object oid = toOpenJPAObjectId(meta, oids[0]);
+        if (oid == oids[0])
+            return oids;
+
+        Object[] copy = new Object[oids.length];
+        copy[0] = oid;
+        for (int i = 1; i < oids.length; i++)
+            copy[i] = toOpenJPAObjectId(meta, oids[i]);
+        return copy;
+    }
+
+    /**
+     * Return a collection of OpenJPA oids for the given native oid collection.
+     */
+    public static Collection toOpenJPAObjectIds(ClassMetaData meta,
+        Collection oids) {
+        if (oids == null || oids.isEmpty())
+            return oids;
+
+        // since the class if fixed for all oids, we can tell if we have to
+        // translate the array based on whether the first oid needs translating
+        Iterator itr = oids.iterator();
+        Object orig = itr.next();
+        Object oid = toOpenJPAObjectId(meta, orig);
+        if (oid == orig)
+            return oids;
+
+        Collection copy = new ArrayList(oids.size());
+        copy.add(oid);
+        while (itr.hasNext())
+            copy.add(toOpenJPAObjectId(meta, itr.next()));
+        return copy;
+    }
+
+    /**
+     * Translate from a OpenJPA identity class to a native one.
+     */
+    public static Class fromOpenJPAObjectIdClass(Class oidClass) {
+        if (oidClass == null)
+            return null;
+        if (oidClass == Id.class)
+            return Long.class;
+        if (oidClass == ByteId.class)
+            return Byte.class;
+        if (oidClass == CharId.class)
+            return Character.class;
+        if (oidClass == DoubleId.class)
+            return Double.class;
+        if (oidClass == FloatId.class)
+            return Float.class;
+        if (oidClass == IntId.class)
+            return Integer.class;
+        if (oidClass == LongId.class)
+            return Long.class;
+        if (oidClass == ShortId.class)
+            return Short.class;
+        if (oidClass == StringId.class)
+            return String.class;
+        if (oidClass == BigDecimalId.class)
+            return BigDecimal.class;
+        if (oidClass == BigIntegerId.class)
+            return BigInteger.class;
+        return oidClass;
+	}
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactorySPI.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactorySPI.java
index 38b7f28..a5b7058 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactorySPI.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactorySPI.java
@@ -1,71 +1,71 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import java.util.Map;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-
-public interface OpenJPAEntityManagerFactorySPI
-    extends OpenJPAEntityManagerFactory {
-
-    /**
-     * Register a listener for lifecycle-related events on the specified
-     * classes. If the classes are null, all events will be propagated to
-     * the listener. The listener will be passed on to all new entity
-     * managers. See the <code>org.apache.openjpa.event</code> package for
-     * listener types.
-     *
-     * @since 0.3.3
-     */
-    public void addLifecycleListener(Object listener, Class... classes);
-
-    /**
-     * Remove a listener for lifecycle-related events.
-     *
-     * @since 0.3.3
-     */
-    public void removeLifecycleListener (Object listener);
-
-    /**
-     * Register a listener for transaction-related events on the specified
-     * classes. The listener will be passed on to all new entity
-     * managers. See the <code>org.apache.openjpa.event</code> package for
-     * listener types.
-     *
-     * @since 1.0.0
-     */
-    public void addTransactionListener(Object listener);
-
-    /**
-     * Remove a listener for transaction-related events.
-     *
-     * @since 1.0.0
-     */
-    public void removeTransactionListener (Object listener);
-
-    /**
-     * Return the configuration for this factory.
-     */
-    public OpenJPAConfiguration getConfiguration();
-
-    public OpenJPAEntityManagerSPI createEntityManager();
-
-    public OpenJPAEntityManagerSPI createEntityManager(Map props);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import java.util.Map;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+public interface OpenJPAEntityManagerFactorySPI
+    extends OpenJPAEntityManagerFactory {
+
+    /**
+     * Register a listener for lifecycle-related events on the specified
+     * classes. If the classes are null, all events will be propagated to
+     * the listener. The listener will be passed on to all new entity
+     * managers. See the <code>org.apache.openjpa.event</code> package for
+     * listener types.
+     *
+     * @since 0.3.3
+     */
+    public void addLifecycleListener(Object listener, Class... classes);
+
+    /**
+     * Remove a listener for lifecycle-related events.
+     *
+     * @since 0.3.3
+     */
+    public void removeLifecycleListener (Object listener);
+
+    /**
+     * Register a listener for transaction-related events on the specified
+     * classes. The listener will be passed on to all new entity
+     * managers. See the <code>org.apache.openjpa.event</code> package for
+     * listener types.
+     *
+     * @since 1.0.0
+     */
+    public void addTransactionListener(Object listener);
+
+    /**
+     * Remove a listener for transaction-related events.
+     *
+     * @since 1.0.0
+     */
+    public void removeTransactionListener (Object listener);
+
+    /**
+     * Return the configuration for this factory.
+     */
+    public OpenJPAConfiguration getConfiguration();
+
+    public OpenJPAEntityManagerSPI createEntityManager();
+
+    public OpenJPAEntityManagerSPI createEntityManager(Map props);
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerSPI.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerSPI.java
index db052ac..1a80ffc 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerSPI.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerSPI.java
@@ -1,108 +1,108 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import java.util.EnumSet;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.ee.ManagedRuntime;
-
-public interface OpenJPAEntityManagerSPI
-    extends OpenJPAEntityManager {
-
-    /**
-     * Return the configuration associated with this entity manager.
-     */
-    public OpenJPAConfiguration getConfiguration();
-
-    /**
-     * Return the managed runtime in use.
-     */
-    public ManagedRuntime getManagedRuntime();
-
-    //////////
-    // Events
-    //////////
-
-    /**
-     * Register a listener for transaction-related events.
-     */
-    public void addTransactionListener(Object listener);
-
-    /**
-     * Remove a listener for transaction-related events.
-     */
-    public void removeTransactionListener(Object listener);
-
-    /**
-     * The {@link CallbackMode} flags for handling transaction listener
-     * exceptions.
-     *
-     * @since 1.1.0
-     */
-    public EnumSet<CallbackMode> getTransactionListenerCallbackModes();
-
-    /**
-     * The {@link CallbackMode} flag for handling transaction listener
-     * exceptions. The flags provided here will entirely replace the
-     * previous settings.
-     */
-    public void setTransactionListenerCallbackMode(CallbackMode mode);
-
-    /**
-     * The {@link CallbackMode} flags for handling transaction listener
-     * exceptions. The flags provided here will entirely replace the
-     * previous settings.
-     */
-    public void setTransactionListenerCallbackMode(EnumSet<CallbackMode> modes);
-
-    /**
-     * Register a listener for lifecycle-related events on the specified
-     * classes. If the classes are null, all events will be propagated to
-     * the listener.
-     */
-    public void addLifecycleListener(Object listener, Class... classes);
-
-    /**
-     * Remove a listener for lifecycle-related events.
-     */
-    public void removeLifecycleListener(Object listener);
-
-    /**
-     * The {@link CallbackMode} flags for handling lifecycle listener
-     * exceptions.
-     *
-     * @since 1.1.0
-     */
-    public EnumSet<CallbackMode> getLifecycleListenerCallbackModes();
-
-    /**
-     * The {@link CallbackMode} flag for handling lifecycle listener
-     * exceptions. The flags provided here will entirely replace the
-     * previous settings.
-     */
-    public void setLifecycleListenerCallbackMode(CallbackMode mode);
-
-    /**
-     * The {@link CallbackMode} flags for handling lifecycle listener
-     * exceptions. The flags provided here will entirely replace the
-     * previous settings.
-     */
-    public void setLifecycleListenerCallbackMode(EnumSet<CallbackMode> modes);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import java.util.EnumSet;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.ee.ManagedRuntime;
+
+public interface OpenJPAEntityManagerSPI
+    extends OpenJPAEntityManager {
+
+    /**
+     * Return the configuration associated with this entity manager.
+     */
+    public OpenJPAConfiguration getConfiguration();
+
+    /**
+     * Return the managed runtime in use.
+     */
+    public ManagedRuntime getManagedRuntime();
+
+    //////////
+    // Events
+    //////////
+
+    /**
+     * Register a listener for transaction-related events.
+     */
+    public void addTransactionListener(Object listener);
+
+    /**
+     * Remove a listener for transaction-related events.
+     */
+    public void removeTransactionListener(Object listener);
+
+    /**
+     * The {@link CallbackMode} flags for handling transaction listener
+     * exceptions.
+     *
+     * @since 1.1.0
+     */
+    public EnumSet<CallbackMode> getTransactionListenerCallbackModes();
+
+    /**
+     * The {@link CallbackMode} flag for handling transaction listener
+     * exceptions. The flags provided here will entirely replace the
+     * previous settings.
+     */
+    public void setTransactionListenerCallbackMode(CallbackMode mode);
+
+    /**
+     * The {@link CallbackMode} flags for handling transaction listener
+     * exceptions. The flags provided here will entirely replace the
+     * previous settings.
+     */
+    public void setTransactionListenerCallbackMode(EnumSet<CallbackMode> modes);
+
+    /**
+     * Register a listener for lifecycle-related events on the specified
+     * classes. If the classes are null, all events will be propagated to
+     * the listener.
+     */
+    public void addLifecycleListener(Object listener, Class... classes);
+
+    /**
+     * Remove a listener for lifecycle-related events.
+     */
+    public void removeLifecycleListener(Object listener);
+
+    /**
+     * The {@link CallbackMode} flags for handling lifecycle listener
+     * exceptions.
+     *
+     * @since 1.1.0
+     */
+    public EnumSet<CallbackMode> getLifecycleListenerCallbackModes();
+
+    /**
+     * The {@link CallbackMode} flag for handling lifecycle listener
+     * exceptions. The flags provided here will entirely replace the
+     * previous settings.
+     */
+    public void setLifecycleListenerCallbackMode(CallbackMode mode);
+
+    /**
+     * The {@link CallbackMode} flags for handling lifecycle listener
+     * exceptions. The flags provided here will entirely replace the
+     * previous settings.
+     */
+    public void setLifecycleListenerCallbackMode(EnumSet<CallbackMode> modes);
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityTransaction.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityTransaction.java
index 87f905b..7b7cf85 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityTransaction.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityTransaction.java
@@ -1,71 +1,71 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import javax.persistence.EntityTransaction;
-
-/**
- * Extension of the JPA {@link EntityTransaction} interface.
- *
- * @since 1.0.0
- * @published
- */
-public interface OpenJPAEntityTransaction
-    extends EntityTransaction {
-
-    /**
-     * Issue a commit and then start a new transaction. This is identical to:
-     * <pre> manager.commit (); manager.begin ();
-     * </pre> except that the entity manager's internal atomic lock is utilized,
-     * so this method can be safely executed from multiple threads.
-     *
-     * @see javax.persistence.EntityTransaction#commit()
-     * @see javax.persistence.EntityTransaction#begin()
-     */
-    public void commitAndResume();
-
-    /**
-     * Issue a rollback and then start a new transaction. This is identical to:
-     * <pre> manager.rollback (); manager.begin ();
-     * </pre> except that the entity manager's internal atomic lock is utilized,
-     * so this method can be safely executed from multiple threads.
-     *
-     * @see javax.persistence.EntityTransaction#rollback()
-     * @see javax.persistence.EntityTransaction#begin()
-     */
-    public void rollbackAndResume();
-
-    /**
-     * Mark the current transaction for rollback with the specified cause
-     * of the rollback.
-     *
-     * @since 0.9.7
-     */
-    public void setRollbackOnly(Throwable cause);
-
-    /**
-     * Returns the Throwable that caused the transaction to be
-     * marked for rollback.
-     *
-     * @return the Throwable, or null if none was given
-     *
-     * @since 0.9.7
-     */
-    public Throwable getRollbackCause();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import javax.persistence.EntityTransaction;
+
+/**
+ * Extension of the JPA {@link EntityTransaction} interface.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public interface OpenJPAEntityTransaction
+    extends EntityTransaction {
+
+    /**
+     * Issue a commit and then start a new transaction. This is identical to:
+     * <pre> manager.commit (); manager.begin ();
+     * </pre> except that the entity manager's internal atomic lock is utilized,
+     * so this method can be safely executed from multiple threads.
+     *
+     * @see javax.persistence.EntityTransaction#commit()
+     * @see javax.persistence.EntityTransaction#begin()
+     */
+    public void commitAndResume();
+
+    /**
+     * Issue a rollback and then start a new transaction. This is identical to:
+     * <pre> manager.rollback (); manager.begin ();
+     * </pre> except that the entity manager's internal atomic lock is utilized,
+     * so this method can be safely executed from multiple threads.
+     *
+     * @see javax.persistence.EntityTransaction#rollback()
+     * @see javax.persistence.EntityTransaction#begin()
+     */
+    public void rollbackAndResume();
+
+    /**
+     * Mark the current transaction for rollback with the specified cause
+     * of the rollback.
+     *
+     * @since 0.9.7
+     */
+    public void setRollbackOnly(Throwable cause);
+
+    /**
+     * Returns the Throwable that caused the transaction to be
+     * marked for rollback.
+     *
+     * @return the Throwable, or null if none was given
+     *
+     * @since 0.9.7
+     */
+    public Throwable getRollbackCause();
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAQuerySPI.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAQuerySPI.java
index 997259d..bde8162 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAQuerySPI.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAQuerySPI.java
@@ -1,46 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import org.apache.openjpa.kernel.exps.FilterListener;
-import org.apache.openjpa.kernel.exps.AggregateListener;
-
-public interface OpenJPAQuerySPI
-    extends OpenJPAQuery {
-
-    /**
-     * Register a filter listener for the query.
-     */
-    public OpenJPAQuery addFilterListener(FilterListener listener);
-
-    /**
-     * Remove a filter listener from the query.
-     */
-    public OpenJPAQuery removeFilterListener(FilterListener listener);
-
-    /**
-     * Register an aggregate listener for the query.
-     */
-    public OpenJPAQuery addAggregateListener(AggregateListener listener);
-
-    /**
-     * Remove an aggregate listener from the query.
-     */
-    public OpenJPAQuery removeAggregateListener(AggregateListener listener);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.exps.FilterListener;
+import org.apache.openjpa.kernel.exps.AggregateListener;
+
+public interface OpenJPAQuerySPI
+    extends OpenJPAQuery {
+
+    /**
+     * Register a filter listener for the query.
+     */
+    public OpenJPAQuery addFilterListener(FilterListener listener);
+
+    /**
+     * Remove a filter listener from the query.
+     */
+    public OpenJPAQuery removeFilterListener(FilterListener listener);
+
+    /**
+     * Register an aggregate listener for the query.
+     */
+    public OpenJPAQuery addAggregateListener(AggregateListener listener);
+
+    /**
+     * Remove an aggregate listener from the query.
+     */
+    public OpenJPAQuery removeAggregateListener(AggregateListener listener);
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
index 47e59619..953fe7c 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
@@ -20,24 +20,30 @@
 
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.IllegalClassFormatException;
+import java.security.AccessController;
 import java.security.ProtectionDomain;
 import java.util.Map;
+
 import javax.persistence.EntityManager;
 import javax.persistence.spi.ClassTransformer;
 import javax.persistence.spi.PersistenceProvider;
 import javax.persistence.spi.PersistenceUnitInfo;
 
 import org.apache.openjpa.conf.BrokerValue;
+import org.apache.openjpa.conf.MetaDataRepositoryValue;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
 import org.apache.openjpa.enhance.PCClassFileTransformer;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
 import org.apache.openjpa.kernel.Bootstrap;
 import org.apache.openjpa.kernel.BrokerFactory;
 import org.apache.openjpa.lib.conf.Configuration;
 import org.apache.openjpa.lib.conf.ConfigurationProvider;
 import org.apache.openjpa.lib.conf.Configurations;
 import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.meta.MetaDataModes;
 import org.apache.openjpa.meta.MetaDataRepository;
 import org.apache.openjpa.util.ClassResolver;
@@ -79,6 +85,8 @@
                 return null;
 
             BrokerFactory factory = getBrokerFactory(cp, poolValue, null);
+            preloadMetaDataRepository(factory);
+            
             return JPAFacadeHelper.toEntityManagerFactory(factory);
         } catch (Exception e) {
             throw PersistenceExceptions.toPersistenceException(e);
@@ -153,6 +161,7 @@
                         _loc.get("transformer-registration-error", pui));
                 }
             }
+            preloadMetaDataRepository(factory);           
             return JPAFacadeHelper.toEntityManagerFactory(factory);
         } catch (Exception e) {
             throw PersistenceExceptions.toPersistenceException(e);
@@ -177,6 +186,30 @@
     protected OpenJPAConfiguration newConfigurationImpl() {
         return new OpenJPAConfigurationImpl();
     }
+
+    /**
+     * Private worker method that will call to the MetaDataRepository to preload if the provided
+     * BrokerFactory is configured to do so.
+     */
+    private void preloadMetaDataRepository(BrokerFactory factory){
+        // We need to wait to preload until after we get back a fully configured/instantiated
+        // BrokerFactory. This is because it is possible that someone has extended OpenJPA
+        // functions and they need to be allowed time to configure themselves before we go off and
+        // start instanting configurable objects (ie:openjpa.MetaDataRepository). Don't catch
+        // any exceptions here because we want to fail-fast.
+        OpenJPAConfiguration conf = factory.getConfiguration();
+        Options o = Configurations.parseProperties(Configurations.getProperties(conf.getMetaDataRepository()));
+        if (MetaDataRepository.needsPreload(o) == true) {
+            MetaDataRepository mdr = conf.getMetaDataRepositoryInstance(); 
+            mdr.setValidate(MetaDataRepository.VALIDATE_RUNTIME, true);
+            mdr.setResolve(MetaDataRepository.MODE_MAPPING_INIT, true);
+            
+            // Load persistent classes and hook in subclasser
+            ((AbstractBrokerFactory) factory).loadPersistentTypes((ClassLoader) AccessController
+                .doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
+            mdr.preload();
+        }
+    }
     
     /**
      * Java EE 5 class transformer.
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryOperationType.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryOperationType.java
index 5ff4163..a683f8d 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryOperationType.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryOperationType.java
@@ -1,59 +1,59 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import org.apache.openjpa.kernel.QueryOperations;
-
-/**
- * The possible operations that a query can perform.
- *
- * @since 1.0.0
- * @published
- */
-public enum QueryOperationType {
-    SELECT(QueryOperations.OP_SELECT),
-    DELETE(QueryOperations.OP_DELETE),
-    UPDATE(QueryOperations.OP_UPDATE);
-
-    private final int queryOperationConstant;
-
-    private QueryOperationType(int value) {
-        queryOperationConstant = value;
-    }
-
-    int toKernelConstant() {
-        return queryOperationConstant;
-    }
-
-    static QueryOperationType fromKernelConstant(int kernelConstant) {
-        switch (kernelConstant) {
-            case QueryOperations.OP_SELECT:
-                return SELECT;
-
-            case QueryOperations.OP_UPDATE:
-                return UPDATE;
-
-            case QueryOperations.OP_DELETE:
-                return DELETE;
-
-            default:
-                throw new IllegalArgumentException(kernelConstant + "");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.QueryOperations;
+
+/**
+ * The possible operations that a query can perform.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum QueryOperationType {
+    SELECT(QueryOperations.OP_SELECT),
+    DELETE(QueryOperations.OP_DELETE),
+    UPDATE(QueryOperations.OP_UPDATE);
+
+    private final int queryOperationConstant;
+
+    private QueryOperationType(int value) {
+        queryOperationConstant = value;
+    }
+
+    int toKernelConstant() {
+        return queryOperationConstant;
+    }
+
+    static QueryOperationType fromKernelConstant(int kernelConstant) {
+        switch (kernelConstant) {
+            case QueryOperations.OP_SELECT:
+                return SELECT;
+
+            case QueryOperations.OP_UPDATE:
+                return UPDATE;
+
+            case QueryOperations.OP_DELETE:
+                return DELETE;
+
+            default:
+                throw new IllegalArgumentException(kernelConstant + "");
+        }
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/RestoreStateType.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/RestoreStateType.java
index 12c0dd5..f65439b 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/RestoreStateType.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/RestoreStateType.java
@@ -1,60 +1,60 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import org.apache.openjpa.kernel.RestoreState;
-
-/**
- * The possible settings for the restore behavior after transaction rollback
- * of an {@link OpenJPAEntityManager}.
- *
- * @since 1.0.0
- * @published
- */
-public enum RestoreStateType {
-    NONE(RestoreState.RESTORE_NONE),
-    IMMUTABLE(RestoreState.RESTORE_IMMUTABLE),
-    ALL(RestoreState.RESTORE_ALL);
-
-    private final int restoreStateConstant;
-
-    private RestoreStateType(int value) {
-        restoreStateConstant = value;
-    }
-
-    int toKernelConstant() {
-        return restoreStateConstant;
-    }
-
-    static RestoreStateType fromKernelConstant(int kernelConstant) {
-        switch (kernelConstant) {
-            case RestoreState.RESTORE_NONE:
-                return NONE;
-
-            case RestoreState.RESTORE_IMMUTABLE:
-                return IMMUTABLE;
-
-            case RestoreState.RESTORE_ALL:
-                return ALL;
-
-            default:
-                throw new IllegalArgumentException(kernelConstant + "");
-        }
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.RestoreState;
+
+/**
+ * The possible settings for the restore behavior after transaction rollback
+ * of an {@link OpenJPAEntityManager}.
+ *
+ * @since 1.0.0
+ * @published
+ */
+public enum RestoreStateType {
+    NONE(RestoreState.RESTORE_NONE),
+    IMMUTABLE(RestoreState.RESTORE_IMMUTABLE),
+    ALL(RestoreState.RESTORE_ALL);
+
+    private final int restoreStateConstant;
+
+    private RestoreStateType(int value) {
+        restoreStateConstant = value;
+    }
+
+    int toKernelConstant() {
+        return restoreStateConstant;
+    }
+
+    static RestoreStateType fromKernelConstant(int kernelConstant) {
+        switch (kernelConstant) {
+            case RestoreState.RESTORE_NONE:
+                return NONE;
+
+            case RestoreState.RESTORE_IMMUTABLE:
+                return IMMUTABLE;
+
+            case RestoreState.RESTORE_ALL:
+                return ALL;
+
+            default:
+                throw new IllegalArgumentException(kernelConstant + "");
+        }
+    }
+}
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
index 3c5a083..e467f0e 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
@@ -786,6 +786,7 @@
             String name = attrs.getValue("name");
             if (!StringUtils.isEmpty(name))
                 meta.setTypeAlias(name);
+            meta.setAbstract(mappedSuper);
             meta.setEmbeddedOnly(mappedSuper || "embeddable".equals(elem));
             if (mappedSuper)
                 meta.setIdentityType(meta.ID_UNKNOWN);
diff --git a/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestEnumToKernelConstantMappings.java b/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestEnumToKernelConstantMappings.java
index 752b56a..a98a966 100644
--- a/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestEnumToKernelConstantMappings.java
+++ b/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestEnumToKernelConstantMappings.java
@@ -1,270 +1,270 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence;
-
-import java.util.EnumSet;
-
-import junit.framework.TestCase;
-import org.apache.openjpa.kernel.ConnectionRetainModes;
-import org.apache.openjpa.kernel.DetachState;
-import org.apache.openjpa.kernel.RestoreState;
-import org.apache.openjpa.kernel.AutoClear;
-import org.apache.openjpa.kernel.AutoDetach;
-import org.apache.openjpa.kernel.QueryOperations;
-import org.apache.openjpa.event.CallbackModes;
-
-public class TestEnumToKernelConstantMappings
-    extends TestCase {
-
-    public void testConnectionRetainModes() {
-        assertEquals(ConnectionRetainModes.CONN_RETAIN_ALWAYS,
-            ConnectionRetainMode.ALWAYS.toKernelConstant());
-        assertEquals(ConnectionRetainMode.ALWAYS,
-            ConnectionRetainMode.fromKernelConstant(
-                ConnectionRetainModes.CONN_RETAIN_ALWAYS));
-        assertEquals(ConnectionRetainMode.ALWAYS.toKernelConstant(),
-            ConnectionRetainMode.ALWAYS.ordinal());
-
-        assertEquals(ConnectionRetainModes.CONN_RETAIN_DEMAND,
-            ConnectionRetainMode.ON_DEMAND.toKernelConstant());
-        assertEquals(ConnectionRetainMode.ON_DEMAND,
-            ConnectionRetainMode.fromKernelConstant(
-                ConnectionRetainModes.CONN_RETAIN_DEMAND));
-        assertEquals(ConnectionRetainMode.ON_DEMAND.toKernelConstant(),
-            ConnectionRetainMode.ON_DEMAND.ordinal());
-
-        assertEquals(ConnectionRetainModes.CONN_RETAIN_TRANS,
-            ConnectionRetainMode.TRANSACTION.toKernelConstant());
-        assertEquals(ConnectionRetainMode.TRANSACTION,
-            ConnectionRetainMode.fromKernelConstant(
-                ConnectionRetainModes.CONN_RETAIN_TRANS));
-        assertEquals(ConnectionRetainMode.TRANSACTION.toKernelConstant(),
-            ConnectionRetainMode.TRANSACTION.ordinal());
-
-        assertEquals(getConstantCount(ConnectionRetainModes.class),
-            ConnectionRetainMode.values().length);
-    }
-
-    public void testDetachState() {
-        assertEquals(DetachState.DETACH_ALL,
-            DetachStateType.ALL.toKernelConstant());
-        assertEquals(DetachStateType.ALL,
-            DetachStateType.fromKernelConstant(DetachState.DETACH_ALL));
-        assertEquals(DetachStateType.ALL.toKernelConstant(),
-            DetachStateType.ALL.ordinal());
-
-        assertEquals(DetachState.DETACH_FETCH_GROUPS,
-            DetachStateType.FETCH_GROUPS.toKernelConstant());
-        assertEquals(DetachStateType.FETCH_GROUPS,
-            DetachStateType.fromKernelConstant(
-                DetachState.DETACH_FETCH_GROUPS));
-        assertEquals(DetachStateType.FETCH_GROUPS.toKernelConstant(),
-            DetachStateType.FETCH_GROUPS.ordinal());
-
-        assertEquals(DetachState.DETACH_LOADED,
-            DetachStateType.LOADED.toKernelConstant());
-        assertEquals(DetachStateType.LOADED,
-            DetachStateType.fromKernelConstant(DetachState.DETACH_LOADED));
-        assertEquals(DetachStateType.LOADED.toKernelConstant(),
-            DetachStateType.LOADED.ordinal());
-
-        // subtract 1 for DetachState.DETACH_FGS, which is deprecated
-        assertEquals(getConstantCount(DetachState.class) - 1,
-            DetachStateType.values().length);
-    }
-
-    public void testRestoreState() {
-        assertEquals(RestoreState.RESTORE_ALL,
-            RestoreStateType.ALL.toKernelConstant());
-        assertEquals(RestoreStateType.ALL,
-            RestoreStateType.fromKernelConstant(RestoreState.RESTORE_ALL));
-        assertEquals(RestoreStateType.ALL.toKernelConstant(),
-            RestoreStateType.ALL.ordinal());
-
-        assertEquals(RestoreState.RESTORE_IMMUTABLE,
-            RestoreStateType.IMMUTABLE.toKernelConstant());
-        assertEquals(RestoreStateType.IMMUTABLE,
-            RestoreStateType.fromKernelConstant(
-                RestoreState.RESTORE_IMMUTABLE));
-        assertEquals(RestoreStateType.IMMUTABLE.toKernelConstant(),
-            RestoreStateType.IMMUTABLE.ordinal());
-
-        assertEquals(RestoreState.RESTORE_NONE,
-            RestoreStateType.NONE.toKernelConstant());
-        assertEquals(RestoreStateType.NONE,
-            RestoreStateType.fromKernelConstant(RestoreState.RESTORE_NONE));
-        assertEquals(RestoreStateType.NONE.toKernelConstant(),
-            RestoreStateType.NONE.ordinal());
-
-        assertEquals(getConstantCount(RestoreState.class),
-            RestoreStateType.values().length);
-    }
-
-    public void testAutoClear() {
-        assertEquals(AutoClear.CLEAR_ALL, AutoClearType.ALL.toKernelConstant());
-        assertEquals(AutoClearType.ALL,
-            AutoClearType.fromKernelConstant(AutoClear.CLEAR_ALL));
-        assertEquals(AutoClearType.ALL.toKernelConstant(),
-            AutoClearType.ALL.ordinal());
-
-        assertEquals(AutoClear.CLEAR_DATASTORE,
-            AutoClearType.DATASTORE.toKernelConstant());
-        assertEquals(AutoClearType.DATASTORE,
-            AutoClearType.fromKernelConstant(AutoClear.CLEAR_DATASTORE));
-        assertEquals(AutoClearType.DATASTORE.toKernelConstant(),
-            AutoClearType.DATASTORE.ordinal());
-
-        assertEquals(getConstantCount(AutoClear.class),
-            AutoClearType.values().length);
-    }
-
-    public void testAutoDetach() {
-        assertEquals(getConstantCount(AutoDetach.class),
-            AutoDetachType.values().length);
-
-        assertEquals(EnumSet.of(AutoDetachType.CLOSE),
-            AutoDetachType.toEnumSet(AutoDetach.DETACH_CLOSE));
-        assertEquals(AutoDetach.DETACH_CLOSE,
-            AutoDetachType.fromEnumSet(EnumSet.of(AutoDetachType.CLOSE)));
-
-        assertEquals(EnumSet.of(AutoDetachType.COMMIT),
-            AutoDetachType.toEnumSet(AutoDetach.DETACH_COMMIT));
-        assertEquals(AutoDetach.DETACH_COMMIT,
-            AutoDetachType.fromEnumSet(EnumSet.of(AutoDetachType.COMMIT)));
-
-        assertEquals(EnumSet.of(AutoDetachType.NON_TRANSACTIONAL_READ),
-            AutoDetachType.toEnumSet(AutoDetach.DETACH_NONTXREAD));
-        assertEquals(AutoDetach.DETACH_NONTXREAD,
-            AutoDetachType.fromEnumSet(
-                EnumSet.of(AutoDetachType.NON_TRANSACTIONAL_READ)));
-
-        assertEquals(EnumSet.of(AutoDetachType.ROLLBACK),
-            AutoDetachType.toEnumSet(AutoDetach.DETACH_ROLLBACK));
-        assertEquals(AutoDetach.DETACH_ROLLBACK,
-            AutoDetachType.fromEnumSet(EnumSet.of(AutoDetachType.ROLLBACK)));
-
-
-        assertEquals(EnumSet.of(AutoDetachType.CLOSE, AutoDetachType.COMMIT),
-            AutoDetachType.toEnumSet(
-                AutoDetach.DETACH_CLOSE | AutoDetach.DETACH_COMMIT));
-        assertEquals(AutoDetach.DETACH_ROLLBACK | AutoDetach.DETACH_CLOSE,
-            AutoDetachType.fromEnumSet(
-                EnumSet.of(AutoDetachType.ROLLBACK, AutoDetachType.CLOSE)));
-
-
-        assertEquals(EnumSet.allOf(AutoDetachType.class),
-            AutoDetachType.toEnumSet(
-                AutoDetach.DETACH_CLOSE
-                    | AutoDetach.DETACH_COMMIT
-                    | AutoDetach.DETACH_NONTXREAD
-                    | AutoDetach.DETACH_ROLLBACK));
-        assertEquals(AutoDetach.DETACH_CLOSE
-                    | AutoDetach.DETACH_COMMIT
-                    | AutoDetach.DETACH_NONTXREAD
-                    | AutoDetach.DETACH_ROLLBACK,
-            AutoDetachType.fromEnumSet(EnumSet.allOf(AutoDetachType.class)));
-    }
-
-    public void testCallbackMode() {
-        assertEquals(getConstantCount(CallbackModes.class),
-            CallbackMode.values().length);
-
-        assertEquals(EnumSet.of(CallbackMode.FAIL_FAST),
-            CallbackMode.toEnumSet(CallbackModes.CALLBACK_FAIL_FAST));
-        assertEquals(CallbackModes.CALLBACK_FAIL_FAST,
-            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.FAIL_FAST)));
-
-        assertEquals(EnumSet.of(CallbackMode.IGNORE),
-            CallbackMode.toEnumSet(CallbackModes.CALLBACK_IGNORE));
-        assertEquals(CallbackModes.CALLBACK_IGNORE,
-            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.IGNORE)));
-
-        assertEquals(EnumSet.of(CallbackMode.LOG),
-            CallbackMode.toEnumSet(CallbackModes.CALLBACK_LOG));
-        assertEquals(CallbackModes.CALLBACK_LOG,
-            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.LOG)));
-
-        assertEquals(EnumSet.of(CallbackMode.RETHROW),
-            CallbackMode.toEnumSet(CallbackModes.CALLBACK_RETHROW));
-        assertEquals(CallbackModes.CALLBACK_RETHROW,
-            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.RETHROW)));
-
-        assertEquals(EnumSet.of(CallbackMode.ROLLBACK),
-            CallbackMode.toEnumSet(CallbackModes.CALLBACK_ROLLBACK));
-        assertEquals(CallbackModes.CALLBACK_ROLLBACK,
-            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.ROLLBACK)));
-
-
-        assertEquals(EnumSet.of(CallbackMode.ROLLBACK, CallbackMode.IGNORE),
-            CallbackMode.toEnumSet(CallbackModes.CALLBACK_ROLLBACK
-                | CallbackModes.CALLBACK_IGNORE));
-        assertEquals(
-            CallbackModes.CALLBACK_ROLLBACK | CallbackModes.CALLBACK_IGNORE,
-            CallbackMode.fromEnumSet(
-                EnumSet.of(CallbackMode.ROLLBACK, CallbackMode.IGNORE)));
-
-
-        assertEquals(EnumSet.allOf(CallbackMode.class),
-            CallbackMode.toEnumSet(
-                CallbackModes.CALLBACK_FAIL_FAST
-                    | CallbackModes.CALLBACK_IGNORE
-                    | CallbackModes.CALLBACK_LOG
-                    | CallbackModes.CALLBACK_RETHROW
-                    | CallbackModes.CALLBACK_ROLLBACK));
-        assertEquals(CallbackModes.CALLBACK_FAIL_FAST
-                    | CallbackModes.CALLBACK_IGNORE
-                    | CallbackModes.CALLBACK_LOG
-                    | CallbackModes.CALLBACK_RETHROW
-                    | CallbackModes.CALLBACK_ROLLBACK,
-            CallbackMode.fromEnumSet(EnumSet.allOf(CallbackMode.class)));
-    }
-
-    public void testQueryOperationTypes() {
-        assertEquals(QueryOperations.OP_SELECT,
-            QueryOperationType.SELECT.toKernelConstant());
-        assertEquals(QueryOperationType.SELECT,
-            QueryOperationType.fromKernelConstant(
-                QueryOperations.OP_SELECT));
-        assertEquals(QueryOperationType.SELECT.toKernelConstant(),
-            QueryOperationType.SELECT.ordinal() + 1);
-
-        assertEquals(QueryOperations.OP_UPDATE,
-            QueryOperationType.UPDATE.toKernelConstant());
-        assertEquals(QueryOperationType.UPDATE,
-            QueryOperationType.fromKernelConstant(
-                QueryOperations.OP_UPDATE));
-        assertEquals(QueryOperationType.UPDATE.toKernelConstant(),
-            QueryOperationType.UPDATE.ordinal() + 1);
-
-        assertEquals(QueryOperations.OP_DELETE,
-            QueryOperationType.DELETE.toKernelConstant());
-        assertEquals(QueryOperationType.DELETE,
-            QueryOperationType.fromKernelConstant(
-                QueryOperations.OP_DELETE));
-        assertEquals(QueryOperationType.DELETE.toKernelConstant(),
-            QueryOperationType.DELETE.ordinal() + 1);
-
-        assertEquals(getConstantCount(QueryOperations.class),
-            QueryOperationType.values().length);
-    }
-
-    private int getConstantCount(Class cls) {
-        return cls.getDeclaredFields().length;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence;
+
+import java.util.EnumSet;
+
+import junit.framework.TestCase;
+import org.apache.openjpa.kernel.ConnectionRetainModes;
+import org.apache.openjpa.kernel.DetachState;
+import org.apache.openjpa.kernel.RestoreState;
+import org.apache.openjpa.kernel.AutoClear;
+import org.apache.openjpa.kernel.AutoDetach;
+import org.apache.openjpa.kernel.QueryOperations;
+import org.apache.openjpa.event.CallbackModes;
+
+public class TestEnumToKernelConstantMappings
+    extends TestCase {
+
+    public void testConnectionRetainModes() {
+        assertEquals(ConnectionRetainModes.CONN_RETAIN_ALWAYS,
+            ConnectionRetainMode.ALWAYS.toKernelConstant());
+        assertEquals(ConnectionRetainMode.ALWAYS,
+            ConnectionRetainMode.fromKernelConstant(
+                ConnectionRetainModes.CONN_RETAIN_ALWAYS));
+        assertEquals(ConnectionRetainMode.ALWAYS.toKernelConstant(),
+            ConnectionRetainMode.ALWAYS.ordinal());
+
+        assertEquals(ConnectionRetainModes.CONN_RETAIN_DEMAND,
+            ConnectionRetainMode.ON_DEMAND.toKernelConstant());
+        assertEquals(ConnectionRetainMode.ON_DEMAND,
+            ConnectionRetainMode.fromKernelConstant(
+                ConnectionRetainModes.CONN_RETAIN_DEMAND));
+        assertEquals(ConnectionRetainMode.ON_DEMAND.toKernelConstant(),
+            ConnectionRetainMode.ON_DEMAND.ordinal());
+
+        assertEquals(ConnectionRetainModes.CONN_RETAIN_TRANS,
+            ConnectionRetainMode.TRANSACTION.toKernelConstant());
+        assertEquals(ConnectionRetainMode.TRANSACTION,
+            ConnectionRetainMode.fromKernelConstant(
+                ConnectionRetainModes.CONN_RETAIN_TRANS));
+        assertEquals(ConnectionRetainMode.TRANSACTION.toKernelConstant(),
+            ConnectionRetainMode.TRANSACTION.ordinal());
+
+        assertEquals(getConstantCount(ConnectionRetainModes.class),
+            ConnectionRetainMode.values().length);
+    }
+
+    public void testDetachState() {
+        assertEquals(DetachState.DETACH_ALL,
+            DetachStateType.ALL.toKernelConstant());
+        assertEquals(DetachStateType.ALL,
+            DetachStateType.fromKernelConstant(DetachState.DETACH_ALL));
+        assertEquals(DetachStateType.ALL.toKernelConstant(),
+            DetachStateType.ALL.ordinal());
+
+        assertEquals(DetachState.DETACH_FETCH_GROUPS,
+            DetachStateType.FETCH_GROUPS.toKernelConstant());
+        assertEquals(DetachStateType.FETCH_GROUPS,
+            DetachStateType.fromKernelConstant(
+                DetachState.DETACH_FETCH_GROUPS));
+        assertEquals(DetachStateType.FETCH_GROUPS.toKernelConstant(),
+            DetachStateType.FETCH_GROUPS.ordinal());
+
+        assertEquals(DetachState.DETACH_LOADED,
+            DetachStateType.LOADED.toKernelConstant());
+        assertEquals(DetachStateType.LOADED,
+            DetachStateType.fromKernelConstant(DetachState.DETACH_LOADED));
+        assertEquals(DetachStateType.LOADED.toKernelConstant(),
+            DetachStateType.LOADED.ordinal());
+
+        // subtract 1 for DetachState.DETACH_FGS, which is deprecated
+        assertEquals(getConstantCount(DetachState.class) - 1,
+            DetachStateType.values().length);
+    }
+
+    public void testRestoreState() {
+        assertEquals(RestoreState.RESTORE_ALL,
+            RestoreStateType.ALL.toKernelConstant());
+        assertEquals(RestoreStateType.ALL,
+            RestoreStateType.fromKernelConstant(RestoreState.RESTORE_ALL));
+        assertEquals(RestoreStateType.ALL.toKernelConstant(),
+            RestoreStateType.ALL.ordinal());
+
+        assertEquals(RestoreState.RESTORE_IMMUTABLE,
+            RestoreStateType.IMMUTABLE.toKernelConstant());
+        assertEquals(RestoreStateType.IMMUTABLE,
+            RestoreStateType.fromKernelConstant(
+                RestoreState.RESTORE_IMMUTABLE));
+        assertEquals(RestoreStateType.IMMUTABLE.toKernelConstant(),
+            RestoreStateType.IMMUTABLE.ordinal());
+
+        assertEquals(RestoreState.RESTORE_NONE,
+            RestoreStateType.NONE.toKernelConstant());
+        assertEquals(RestoreStateType.NONE,
+            RestoreStateType.fromKernelConstant(RestoreState.RESTORE_NONE));
+        assertEquals(RestoreStateType.NONE.toKernelConstant(),
+            RestoreStateType.NONE.ordinal());
+
+        assertEquals(getConstantCount(RestoreState.class),
+            RestoreStateType.values().length);
+    }
+
+    public void testAutoClear() {
+        assertEquals(AutoClear.CLEAR_ALL, AutoClearType.ALL.toKernelConstant());
+        assertEquals(AutoClearType.ALL,
+            AutoClearType.fromKernelConstant(AutoClear.CLEAR_ALL));
+        assertEquals(AutoClearType.ALL.toKernelConstant(),
+            AutoClearType.ALL.ordinal());
+
+        assertEquals(AutoClear.CLEAR_DATASTORE,
+            AutoClearType.DATASTORE.toKernelConstant());
+        assertEquals(AutoClearType.DATASTORE,
+            AutoClearType.fromKernelConstant(AutoClear.CLEAR_DATASTORE));
+        assertEquals(AutoClearType.DATASTORE.toKernelConstant(),
+            AutoClearType.DATASTORE.ordinal());
+
+        assertEquals(getConstantCount(AutoClear.class),
+            AutoClearType.values().length);
+    }
+
+    public void testAutoDetach() {
+        assertEquals(getConstantCount(AutoDetach.class),
+            AutoDetachType.values().length);
+
+        assertEquals(EnumSet.of(AutoDetachType.CLOSE),
+            AutoDetachType.toEnumSet(AutoDetach.DETACH_CLOSE));
+        assertEquals(AutoDetach.DETACH_CLOSE,
+            AutoDetachType.fromEnumSet(EnumSet.of(AutoDetachType.CLOSE)));
+
+        assertEquals(EnumSet.of(AutoDetachType.COMMIT),
+            AutoDetachType.toEnumSet(AutoDetach.DETACH_COMMIT));
+        assertEquals(AutoDetach.DETACH_COMMIT,
+            AutoDetachType.fromEnumSet(EnumSet.of(AutoDetachType.COMMIT)));
+
+        assertEquals(EnumSet.of(AutoDetachType.NON_TRANSACTIONAL_READ),
+            AutoDetachType.toEnumSet(AutoDetach.DETACH_NONTXREAD));
+        assertEquals(AutoDetach.DETACH_NONTXREAD,
+            AutoDetachType.fromEnumSet(
+                EnumSet.of(AutoDetachType.NON_TRANSACTIONAL_READ)));
+
+        assertEquals(EnumSet.of(AutoDetachType.ROLLBACK),
+            AutoDetachType.toEnumSet(AutoDetach.DETACH_ROLLBACK));
+        assertEquals(AutoDetach.DETACH_ROLLBACK,
+            AutoDetachType.fromEnumSet(EnumSet.of(AutoDetachType.ROLLBACK)));
+
+
+        assertEquals(EnumSet.of(AutoDetachType.CLOSE, AutoDetachType.COMMIT),
+            AutoDetachType.toEnumSet(
+                AutoDetach.DETACH_CLOSE | AutoDetach.DETACH_COMMIT));
+        assertEquals(AutoDetach.DETACH_ROLLBACK | AutoDetach.DETACH_CLOSE,
+            AutoDetachType.fromEnumSet(
+                EnumSet.of(AutoDetachType.ROLLBACK, AutoDetachType.CLOSE)));
+
+
+        assertEquals(EnumSet.allOf(AutoDetachType.class),
+            AutoDetachType.toEnumSet(
+                AutoDetach.DETACH_CLOSE
+                    | AutoDetach.DETACH_COMMIT
+                    | AutoDetach.DETACH_NONTXREAD
+                    | AutoDetach.DETACH_ROLLBACK));
+        assertEquals(AutoDetach.DETACH_CLOSE
+                    | AutoDetach.DETACH_COMMIT
+                    | AutoDetach.DETACH_NONTXREAD
+                    | AutoDetach.DETACH_ROLLBACK,
+            AutoDetachType.fromEnumSet(EnumSet.allOf(AutoDetachType.class)));
+    }
+
+    public void testCallbackMode() {
+        assertEquals(getConstantCount(CallbackModes.class),
+            CallbackMode.values().length);
+
+        assertEquals(EnumSet.of(CallbackMode.FAIL_FAST),
+            CallbackMode.toEnumSet(CallbackModes.CALLBACK_FAIL_FAST));
+        assertEquals(CallbackModes.CALLBACK_FAIL_FAST,
+            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.FAIL_FAST)));
+
+        assertEquals(EnumSet.of(CallbackMode.IGNORE),
+            CallbackMode.toEnumSet(CallbackModes.CALLBACK_IGNORE));
+        assertEquals(CallbackModes.CALLBACK_IGNORE,
+            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.IGNORE)));
+
+        assertEquals(EnumSet.of(CallbackMode.LOG),
+            CallbackMode.toEnumSet(CallbackModes.CALLBACK_LOG));
+        assertEquals(CallbackModes.CALLBACK_LOG,
+            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.LOG)));
+
+        assertEquals(EnumSet.of(CallbackMode.RETHROW),
+            CallbackMode.toEnumSet(CallbackModes.CALLBACK_RETHROW));
+        assertEquals(CallbackModes.CALLBACK_RETHROW,
+            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.RETHROW)));
+
+        assertEquals(EnumSet.of(CallbackMode.ROLLBACK),
+            CallbackMode.toEnumSet(CallbackModes.CALLBACK_ROLLBACK));
+        assertEquals(CallbackModes.CALLBACK_ROLLBACK,
+            CallbackMode.fromEnumSet(EnumSet.of(CallbackMode.ROLLBACK)));
+
+
+        assertEquals(EnumSet.of(CallbackMode.ROLLBACK, CallbackMode.IGNORE),
+            CallbackMode.toEnumSet(CallbackModes.CALLBACK_ROLLBACK
+                | CallbackModes.CALLBACK_IGNORE));
+        assertEquals(
+            CallbackModes.CALLBACK_ROLLBACK | CallbackModes.CALLBACK_IGNORE,
+            CallbackMode.fromEnumSet(
+                EnumSet.of(CallbackMode.ROLLBACK, CallbackMode.IGNORE)));
+
+
+        assertEquals(EnumSet.allOf(CallbackMode.class),
+            CallbackMode.toEnumSet(
+                CallbackModes.CALLBACK_FAIL_FAST
+                    | CallbackModes.CALLBACK_IGNORE
+                    | CallbackModes.CALLBACK_LOG
+                    | CallbackModes.CALLBACK_RETHROW
+                    | CallbackModes.CALLBACK_ROLLBACK));
+        assertEquals(CallbackModes.CALLBACK_FAIL_FAST
+                    | CallbackModes.CALLBACK_IGNORE
+                    | CallbackModes.CALLBACK_LOG
+                    | CallbackModes.CALLBACK_RETHROW
+                    | CallbackModes.CALLBACK_ROLLBACK,
+            CallbackMode.fromEnumSet(EnumSet.allOf(CallbackMode.class)));
+    }
+
+    public void testQueryOperationTypes() {
+        assertEquals(QueryOperations.OP_SELECT,
+            QueryOperationType.SELECT.toKernelConstant());
+        assertEquals(QueryOperationType.SELECT,
+            QueryOperationType.fromKernelConstant(
+                QueryOperations.OP_SELECT));
+        assertEquals(QueryOperationType.SELECT.toKernelConstant(),
+            QueryOperationType.SELECT.ordinal() + 1);
+
+        assertEquals(QueryOperations.OP_UPDATE,
+            QueryOperationType.UPDATE.toKernelConstant());
+        assertEquals(QueryOperationType.UPDATE,
+            QueryOperationType.fromKernelConstant(
+                QueryOperations.OP_UPDATE));
+        assertEquals(QueryOperationType.UPDATE.toKernelConstant(),
+            QueryOperationType.UPDATE.ordinal() + 1);
+
+        assertEquals(QueryOperations.OP_DELETE,
+            QueryOperationType.DELETE.toKernelConstant());
+        assertEquals(QueryOperationType.DELETE,
+            QueryOperationType.fromKernelConstant(
+                QueryOperations.OP_DELETE));
+        assertEquals(QueryOperationType.DELETE.toKernelConstant(),
+            QueryOperationType.DELETE.ordinal() + 1);
+
+        assertEquals(getConstantCount(QueryOperations.class),
+            QueryOperationType.values().length);
+    }
+
+    private int getConstantCount(Class cls) {
+        return cls.getDeclaredFields().length;
+    }
+}
diff --git a/openjpa-project/CHANGES.txt b/openjpa-project/CHANGES.txt
index 837b1bc..6757821 100644
--- a/openjpa-project/CHANGES.txt
+++ b/openjpa-project/CHANGES.txt
@@ -1,20 +1,16 @@
-                           Release Notes for OpenJPA 1.2.1
+                           Release Notes for OpenJPA 1.2.2
 
         * Overview
         * License
         * Prerequisites
         * Documentation
         * Getting Involved
-        * Bugs
-        * Improvements
-        * New Features
-        * Task
-        * Test
+        * JIRA Issues resolved
 
 Overview
 
-   These notes describe the difference between OpenJPA release 1.2.1 and the
-   preceding release: 1.2.0. 
+   These notes describe the difference between OpenJPA release 1.2.2 and the
+   preceding release: 1.2.1. 
 
    OpenJPA is a feature-rich implementation of the persistence part of Java
    Community Process JSR-220 (Enterprise JavaBeans 3.0), which is known as
@@ -81,83 +77,55 @@
           freenode.net.
         * Bugs and other issues can be posted on the project JIRA.
 
-                          OpenJPA 1.2.1 Release Notes
+    JIRA Issues Resolved in this release
 Sub-task
 
-    * [OPENJPA-681] - Subquery generates SQL with syntax error
-    * [OPENJPA-708] - sub-sub-query generates SQL with syntax error
-    * [OPENJPA-744] - Extra SQL on LAZY/EAGER ManyToOne relation
-    * [OPENJPA-765] - Check for insertable or updateable before checking value 
-                      for null
-
+    * [OPENJPA-1023] - Message files contain windows EOL characters
+    * [OPENJPA-1210] - Specify derby timeouts via properties.
 Bug
 
-    * [OPENJPA-646] - JDK problems with defineClass and enum class types
-    * [OPENJPA-650] - Document openjpa.RuntimeUnenhancedClasses=unsupported/
-                      warn configuration property
-    * [OPENJPA-676] - Connection used for NativeSequences is not closed
-    * [OPENJPA-679] - java.lang.ArrayIndexOutOfBoundsException may occur when
-                      a relation field is annotated as a primary key and a foreign key
-    * [OPENJPA-685] - Problem enhancing test cases with Maven 2.0.9
-    * [OPENJPA-702] - MappingTool fails requires appropriate DESCSTAT parm 
-                      value on DB2 for z/OS
-    * [OPENJPA-710] - Unordered collection field adds ORDER BY clause
-    * [OPENJPA-711] - PDF manual lacks images
-    * [OPENJPA-713] - openjpa-1.2.0.jar file is 11 MB
-    * [OPENJPA-715] - OpenJpa does not generate IDs properly. "duplicate key 
-                      value in a unique or primary key constraint" while merging object tree.
-    * [OPENJPA-719] - GeneralException in PCEnhancer during class transform in 
-                      Turkish locale AppServer setting
-    * [OPENJPA-724] - Corrections for the manual
-    * [OPENJPA-727] - Image mapping-table.png missing in HTML manual
-    * [OPENJPA-731] - Bug on FetchType.EAGER when QuerySQLCache is turned on
-    * [OPENJPA-733] - Entity contains pseudo-attached embeddable after detach
-    * [OPENJPA-745] - Sybase by default silently truncates a string which is 
-                      longer than the column length without raising an exception
-    * [OPENJPA-755] - OpenJPA thows EntityExistsException trying persist a
-                      preexisting, detached entity
-    * [OPENJPA-762] - Batch execution fails for Oracle when batch limit set to
-                      -1 (unlimited batch size)
-    * [OPENJPA-777] - Exception is thrown during retrieval of an entity which 
-                      contains a persistent collection of embeddable
-    * [OPENJPA-811] - With Oracle, OpenJPA allows setting non-nullable field to null 
-    * [OPENJPA-835] - Loading nested toMany EAGER relation resuled in 
-                      PersistenceException
-    * [OPENJPA-838] - fix parameter setting problem when QuerySQLCache is on
-    * [OPENJPA-843] - Unnecessary version update on inverse-side of a 1-m 
-                      relationship
-    * [OPENJPA-853] - Informix cursor not open problem if synchronizeMapping 
-                      set true
-    * [OPENJPA-864] - Subquery problems with SYNTAX_DATABASE (Oracle)
-    * [OPENJPA-872] - Compound custom id in bidirectional many-to-one
-    * [OPENJPA-912] - Potential NPE in setInverseRelation
-    * [OPENJPA-917] - stored procedures throw InvalidStateException when using 
-                      getSingleResult() or getResultList()
-    * [OPENJPA-919] - JUnit for Bi-directional OneToOne with null relationships
-    * [OPENJPA-925] - Bidirectional OneToOne relation incorrectly set in 
-                      loadEagerJoin
+    * [OPENJPA-466] - Primary key constraint violated using (Oracle) sequence to generate ID in multithreaded app
+    * [OPENJPA-714] - "Encountered unmanaged object in persistent field" error while merging object tree
+    * [OPENJPA-732] - Updates to entities via Lifecycle callback methods
+    * [OPENJPA-873] - @MappedSuperClass Cause Null Pointer Exception in Class With IdClass
+    * [OPENJPA-896] - Several source files include Windows EoL chars
+    * [OPENJPA-1025] - AbstractResultList.subList throws UnsupportedOperationException
+    * [OPENJPA-1029] - SQLServerDictionary causes NumberFormatException if MS SQL Server JDBC driver is used
+    * [OPENJPA-1061] - Entities extending from a Mapped Superclass that defines the ID fields share the same ObjectID type parameter
+    * [OPENJPA-1067] - SetQueryTimeout(x) where x != 0 causes SQLException with DB2 on Z/OS
+    * [OPENJPA-1141] - NPE at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1400)
+    * [OPENJPA-1156] - Path length issues on Windows
+    * [OPENJPA-1197] - NativeQueries fail with MySQL
+    * [OPENJPA-1308] - shouldn't always use CAST with UPPER and LOWER for DB2
+    * [OPENJPA-1326] - ReverseMappingTool and SchemaTool failing for Sybase
+    * [OPENJPA-1328] - Move cacheable class configuration to ClassMetaData
+    * [OPENJPA-1359] - SQLServer driver 2.0 works, but causes exception in SQLServerDictionary on the first connection
+    * [OPENJPA-1384] - ClassNotFoundException for custom DBDictionary used by EJB
+    * [OPENJPA-1397] - NULL in columns part of an @IdClass composite key leads to "disappearing" (null) returned objects
+    * [OPENJPA-1400] - Unable to persist a relationship to a detached Entity
+    * [OPENJPA-1421] - Reduce lock contention in JDBCStoreManager
+    * [OPENJPA-1441] - NPE when enhancing a Serializable, versioned class
+    * [OPENJPA-1457] - Remove Java.net maven repostiory from tck pom.xml
 
 Improvement
 
-    * [OPENJPA-686] - Openjpa manual needs to be updated for database 
-                      restriction on BigDecimal field on Sybase
-    * [OPENJPA-726] - Provide MD5Sums for latest downloads
-    * [OPENJPA-742] - Add line number and column number to QueryMetaData
-    * [OPENJPA-752] - ProxySetupStateManager.setProxyData routing through 
-                      PersistanceCapable caused "PersistenceException: null"
-    * [OPENJPA-772] - Proper maven pluginManagement and use ianal-maven-plugin
-                      for enforcing legal files
-    * [OPENJPA-779] - patch for eclipse .project and .classpath files...
-    * [OPENJPA-817] - Order of inserts lost when using ConstraintUpdateManager
-    * [OPENJPA-876] - Better test profiles for proprietary databases (DB2, 
-                      Oracle) and continuous build
-    * [OPENJPA-881] - Enable connection pooling for testcases.
-    * [OPENJPA-901] - Use hosted JAI artifacts as the default for the docbook build
+    * [OPENJPA-250] - Reduce synchronization bottlenecks in data cache, metadata repository, and lifecycle event manager
+    * [OPENJPA-975] - Oracle needs ability to not have an escape character for search strings.
+    * [OPENJPA-991] - Implement LockTimeout using db specific server-side lock timeout feature
+    * [OPENJPA-1045] - Add opt-in and opt-out configuration for L2 DataCache
+    * [OPENJPA-1136] - Add .gitignore for git users
+    * [OPENJPA-1171] - Use StringBuilder instead of StringBuffer in SQLBuffer
+    * [OPENJPA-1172] - Use java.util.concurrent.ConcurrentHashMap rather than a synchronized HashMap in ClassMapping.
+    * [OPENJPA-1414] - Performance improvements for detach
+    * [OPENJPA-1415] - Performance improvement by reduced logging of batched OLE
+
+Test
+    * [OPENJPA-1071] - Derby test suit speed-up
+    * [OPENJPA-1092] - enable test case for jpql
 
 Changes for previous releases
 
-OpenJPA 1.2.0 Changes: http://svn.apache.org/viewvc/openjpa/tags/1.1.0/openjpa-project/CHANGES.txt?view=markup
+OpenJPA 1.2.1 Changes: http://svn.apache.org/viewvc/openjpa/tags/1.2.1/openjpa-project/CHANGES.txt?view=co
 
-OpenJPA 1.1.0 Changes: http://svn.apache.org/viewvc/openjpa/tags/1.1.0/openjpa-project/CHANGES.txt?view=markup
+OpenJPA 1.2.0 Changes: http://svn.apache.org/viewvc/openjpa/tags/1.2.0/openjpa-project/CHANGES.txt?view=co
 
-OpenJPA 1.0.0 Changes: http://svn.apache.org/viewvc/openjpa/tags/1.0.0/openjpa-project/CHANGES.txt?view=markup
diff --git a/openjpa-project/RELEASE-NOTES.html b/openjpa-project/RELEASE-NOTES.html
index 3cd421f..267b385 100644
--- a/openjpa-project/RELEASE-NOTES.html
+++ b/openjpa-project/RELEASE-NOTES.html
@@ -1,7 +1,7 @@
 <html>
-<title>Release Notes for OpenJPA 1.2.1</title>
+<title>Release Notes for OpenJPA 1.2.2</title>
 <body>
-<h1>Release Notes for OpenJPA</h1>
+<h1>Release Notes for OpenJPA 1.2.2</h1>
 
 <ul>
 <li><a href="#Overview">Overview</a></li>
@@ -9,17 +9,14 @@
 <li><a href="#Prerequisites">Prerequisites</a></li>
 <li><a href="#Documentation">Documentation</a></li>
 <li><a href="#GetInvolved">Getting Involved</a></li>
-<li><a href="#Sub-task">Sub-task</a></li>
-<li><a href="#Bug">Bug</a></li>
-<li><a href="#Improvement">Improvement</a></li>
-<li><a href="#New Feature">New Feature</a></li>
+<li><a href="#JIRA">JIRA Issues Resolved</a></li>
 <li><a href="#Previous">RELEASE-NOTES for previous releases</a></li>
 </ul>
 
 <h2><a name="Overview"></a>Overview</h2>
 
-<p> These notes describe the difference between OpenJPA release 1.2.1
-and the preceding release: 1.2.0.
+<p> These notes describe the difference between OpenJPA release 1.2.2
+and the preceding release: 1.2.1.
 <P>
 OpenJPA is a feature-rich implementation of the persistence part of 
 Java Community Process JSR-220 (Enterprise JavaBeans 3.0), which is
@@ -96,117 +93,102 @@
     <li> Bugs and other issues can be posted on the project JIRA. </li>
 </ul>
 
+<h2><a name="JIRA"</a>JIRA Issues Fixed in this release</h2>
 
-        Release Notes - OpenJPA - Version 1.2.1.
+<h3>        Sub-task
+</h3>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1023'>OPENJPA-1023</a>] -         Message files contain windows EOL characters
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1210'>OPENJPA-1210</a>] -         Specify derby timeouts via properties.
+</li>
+</ul>
     
-<h2><a name='Sub-task'>        Sub-task
-</h2>
+<h3>        Bug
+</h3>
 <ul>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-681'>OPENJPA-681</a>] -         Subquery generates SQL with syntax error
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-466'>OPENJPA-466</a>] -         Primary key constraint violated using (Oracle) sequence to generate ID in multithreaded app
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-708'>OPENJPA-708</a>] -         sub-sub-query generates SQL with syntax error
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-714'>OPENJPA-714</a>] -         &quot;Encountered unmanaged object in persistent field&quot; error while merging object tree
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-744'>OPENJPA-744</a>] -         Extra SQL on LAZY/EAGER  ManyToOne relation
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-732'>OPENJPA-732</a>] -         Updates to entities via Lifecycle callback methods 
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-765'>OPENJPA-765</a>] -         Check for insertable or updateable before checking value for null
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-873'>OPENJPA-873</a>] -         @MappedSuperClass Cause Null Pointer Exception in Class With IdClass
 </li>
-</ul>    
-
-<h2><a name='Bug'>        Bug
-</h2>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-896'>OPENJPA-896</a>] -         Several source files include Windows EoL chars
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1025'>OPENJPA-1025</a>] -         AbstractResultList.subList throws UnsupportedOperationException
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1029'>OPENJPA-1029</a>] -         SQLServerDictionary causes NumberFormatException if MS SQL Server JDBC driver is used
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1061'>OPENJPA-1061</a>] -         Entities extending from a Mapped Superclass that defines the ID fields share the same ObjectID type parameter
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1067'>OPENJPA-1067</a>] -         SetQueryTimeout(x) where x != 0 causes SQLException with DB2 on Z/OS
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1141'>OPENJPA-1141</a>] -         NPE  at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1400)
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1156'>OPENJPA-1156</a>] -         Path length issues on Windows 
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1197'>OPENJPA-1197</a>] -         NativeQueries fail with MySQL 
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1308'>OPENJPA-1308</a>] -         shouldn't always use CAST with UPPER and LOWER for DB2
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1326'>OPENJPA-1326</a>] -         ReverseMappingTool and SchemaTool failing for Sybase
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1328'>OPENJPA-1328</a>] -         Move cacheable class configuration to ClassMetaData
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1359'>OPENJPA-1359</a>] -         SQLServer driver 2.0 works, but causes exception in SQLServerDictionary on the first connection
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1384'>OPENJPA-1384</a>] -         ClassNotFoundException for custom DBDictionary used by EJB
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1397'>OPENJPA-1397</a>] -         NULL in columns part of an @IdClass composite key leads to &quot;disappearing&quot; (null) returned objects
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1400'>OPENJPA-1400</a>] -         Unable to persist a relationship to a detached Entity 
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1421'>OPENJPA-1421</a>] -         Reduce lock contention in JDBCStoreManager
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1441'>OPENJPA-1441</a>] -         NPE when enhancing a Serializable, versioned class
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1457'>OPENJPA-1457</a>] -         Remove Java.net maven repostiory from tck pom.xml
+</li>
+</ul>
+    
+<h3>        Improvement
+</h3>
 <ul>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-646'>OPENJPA-646</a>] -         JDK problems with defineClass and enum class types
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-250'>OPENJPA-250</a>] -         Reduce synchronization bottlenecks in data cache, metadata repository, and lifecycle event manager
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-650'>OPENJPA-650</a>] -         Document openjpa.RuntimeUnenhancedClasses=unsupported/warn configuration property
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-975'>OPENJPA-975</a>] -         Oracle needs ability to not have an escape character for search strings.
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-676'>OPENJPA-676</a>] -         Connection used for NativeSequences is not closed
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-991'>OPENJPA-991</a>] -         Implement LockTimeout using db specific server-side lock timeout feature
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-679'>OPENJPA-679</a>] -         java.lang.ArrayIndexOutOfBoundsException may occur when a relation field is annotated as a primary key and a foreign key
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1045'>OPENJPA-1045</a>] -         Add opt-in and opt-out configuration for L2 DataCache
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-685'>OPENJPA-685</a>] -         Problem enhancing test cases with Maven 2.0.9 
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1136'>OPENJPA-1136</a>] -         Add .gitignore for git users
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-702'>OPENJPA-702</a>] -         MappingTool fails requires appropriate DESCSTAT parm value on DB2 for z/OS
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1171'>OPENJPA-1171</a>] -         Use StringBuilder instead of StringBuffer in SQLBuffer
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-710'>OPENJPA-710</a>] -         Unordered collection field adds ORDER BY clause
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1172'>OPENJPA-1172</a>] -         Use java.util.concurrent.ConcurrentHashMap rather than a synchronized HashMap in ClassMapping.
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-711'>OPENJPA-711</a>] -         PDF manual lacks images
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1414'>OPENJPA-1414</a>] -         Performance improvements for detach
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-713'>OPENJPA-713</a>] -         openjpa-1.2.0.jar file is 11 MB
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1415'>OPENJPA-1415</a>] -         Performance improvement by reduced logging of batched OLE
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-715'>OPENJPA-715</a>] -         OpenJpa does not generate IDs properly. &quot;duplicate key value in a unique or primary key constraint&quot; while merging object tree.
+</ul>
+                                
+<h3>        Test
+</h3>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1071'>OPENJPA-1071</a>] -         Derby test suit speed-up
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-719'>OPENJPA-719</a>] -         GeneralException in PCEnhancer during class transform in Turkish locale AppServer setting
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1092'>OPENJPA-1092</a>] -         enable test case for jpql
 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-724'>OPENJPA-724</a>] -         Corrections for the manual
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-727'>OPENJPA-727</a>] -         Image mapping-table.png missing in HTML manual
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-731'>OPENJPA-731</a>] -         Bug on FetchType.EAGER when QuerySQLCache is turned on
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-733'>OPENJPA-733</a>] -         Entity contains pseudo-attached embeddable after detach
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-745'>OPENJPA-745</a>] -         Sybase by default silently truncates a string which is longer than the column length without raising an exception 
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-755'>OPENJPA-755</a>] -         OpenJPA thows EntityExistsException trying persist a preexisting, detached entity
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-762'>OPENJPA-762</a>] -         Batch execution fails for Oracle when batch limit set to -1 (unlimited batch size)
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-777'>OPENJPA-777</a>] -         Exception is thrown during retrieval of an entity which contains a persistent collection of embeddable
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-835'>OPENJPA-835</a>] -         Loading nested toMany EAGER relation resuled in PersistenceException
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-811'>OPENJPA-811</a>] -         With Oracle, OpenJPA allows setting non-nullable field to null
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-838'>OPENJPA-838</a>] -         fix parameter setting problem when QuerySQLCache is on
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-843'>OPENJPA-843</a>] -         Unnecessary version update on inverse-side of a 1-m relationship
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-853'>OPENJPA-853</a>] -         Informix cursor not open problem if synchronizeMapping set true
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-864'>OPENJPA-864</a>] -         Subquery problems with SYNTAX_DATABASE (Oracle)
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-872'>OPENJPA-872</a>] -         Compound custom id in bidirectional many-to-one
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-912'>OPENJPA-912</a>] -         Potential NPE in setInverseRelation
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-917'>OPENJPA-917</a>] -         stored procedures throw InvalidStateException when using getSingleResult() or getResultList()
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-919'>OPENJPA-919</a>] -         JUnit for Bi-directional OneToOne with null relationships
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-925'>OPENJPA-925</a>] -         Bidirectional OneToOne relation incorrectly set in loadEagerJoin
-</li>
-</ul>    
-
-<h2><a name='Improvement'>        Improvement
-</h2>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-686'>OPENJPA-686</a>] -         Openjpa manual needs to be updated for database restriction on BigDecimal field on Sybase
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-726'>OPENJPA-726</a>] -         Provide MD5Sums for latest downloads
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-742'>OPENJPA-742</a>] -         Add line number and column number to QueryMetaData
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-752'>OPENJPA-752</a>] -         ProxySetupStateManager.setProxyData routing through PersistanceCapable caused &quot;PersistenceException: null&quot;
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-772'>OPENJPA-772</a>] -         Proper maven pluginManagement and use ianal-maven-plugin for enforcing legal files
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-779'>OPENJPA-779</a>] -         patch for eclipse .project and .classpath files...
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-817'>OPENJPA-817</a>] -         Order of inserts lost when using ConstraintUpdateManager
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-876'>OPENJPA-876</a>] -         Better test profiles for proprietary databases (DB2, Oracle) and continuous build
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-881'>OPENJPA-881</a>] -         Enable connection pooling for testcases. 
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-901'>OPENJPA-901</a>] -         Use hosted JAI artifacts as the default for the docbook build
-</li>
-</ul> 
-
+</ul>
 
 <h2><a name="Previous"></a>         Previous Releases
 </h2>
 Release notes for earlier releases of OpenJPA may be found in SVN at the following locations. 
-<li><a href='http://svn.apache.org/viewvc/openjpa/tags/1.2.0/openjpa-project/RELEASE-NOTES.html?view=markup'>OpenJPA 1.2.0 RELEASE-NOTES.html</a></li>
- <li><a href='http://svn.apache.org/viewvc/openjpa/tags/1.1.0/openjpa-project/RELEASE-NOTES.html?view=markup'>OpenJPA 1.1.0 RELEASE-NOTES.html</a></li>
-<li><a href='http://svn.apache.org/viewvc/openjpa/tags/1.0.0/openjpa-project/RELEASE-NOTES.html?view=markup'>OpenJPA 1.0.0 RELEASE-NOTES.html</a></li>
+<li><a href='http://svn.apache.org/viewvc/openjpa/tags/1.2.1/openjpa-project/RELEASE-NOTES.html?view=co'>OpenJPA 1.2.1 RELEASE-NOTES.html</a></li>
+<li><a href='http://svn.apache.org/viewvc/openjpa/tags/1.2.0/openjpa-project/RELEASE-NOTES.html?view=co'>OpenJPA 1.2.0 RELEASE-NOTES.html</a></li>
 </body>
 </html>
diff --git a/openjpa-project/assembly.xml b/openjpa-project/assembly.xml
index 2462fc6..2748816 100644
--- a/openjpa-project/assembly.xml
+++ b/openjpa-project/assembly.xml
@@ -1,102 +1,102 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<assembly>
-    <id>binary</id>
-    <formats>
-        <format>zip</format>
-    </formats>
-    <includeBaseDirectory>true</includeBaseDirectory>
-    <fileSets>
-        <fileSet>
-            <directory>target/aggregate</directory>
-            <outputDirectory>/</outputDirectory>
-        </fileSet>
-        <fileSet>
-            <includes>
-                <include>README</include>
-                <include>DISCLAIMER</include>
-                <include>LICENSE</include>
-                <include>STATUS</include>
-                <include>NOTICE</include>
-                <include>README.txt</include>
-                <include>DISCLAIMER.txt</include>
-                <include>LICENSE.txt</include>
-                <include>STATUS.txt</include>
-                <include>NOTICE.txt</include>
-                <include>RELEASE-NOTES</include>
-                <include>RELEASE-NOTES.html</include>
-                <include>RELEASE-NOTES.txt</include>
-                <include>CHANGES</include>
-                <include>CHANGES.txt</include>
-            </includes>
-        </fileSet>
-        <!--
-        <fileSet>
-            <directory>licenses</directory>
-            <outputDirectory>/lib</outputDirectory>
-            <includes>
-                <include>*</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>target/examples</directory>
-            <outputDirectory>/examples</outputDirectory>
-        </fileSet>
-        -->
-        <fileSet>
-            <directory>target/manual</directory>
-            <outputDirectory>docs/manual</outputDirectory>
-        </fileSet>
-        <fileSet>
-            <directory>../target/site/apidocs</directory>
-            <outputDirectory>docs/javadoc</outputDirectory>
-        </fileSet>
-        <fileSet>
-            <directory>../openjpa-examples/src/main/java</directory>
-            <outputDirectory>examples</outputDirectory>
-        </fileSet>
-    </fileSets>
-    <dependencySets>
-        <dependencySet>
-            <outputDirectory>/</outputDirectory>
-            <unpack>false</unpack>
-            <scope>runtime</scope>
-            <includes>
-                <include>org.apache.openjpa:openjpa</include>
-            </includes>
-        </dependencySet>
-        <dependencySet>
-            <outputDirectory>/lib</outputDirectory>
-            <unpack>false</unpack>
-            <scope>runtime</scope>
-            <includes>
-                <include>net.sourceforge.serp:serp</include>
-                <include>org.apache.derby:derby</include>
-
-                <include>commons-lang:commons-lang</include>
-                <include>commons-collections:commons-collections</include>
-                <include>commons-pool:commons-pool</include>
-
-                <include>org.apache.geronimo.specs:geronimo-jta_1.1_spec</include>
-                <include>org.apache.geronimo.specs:geronimo-jpa_3.0_spec</include>
-            </includes>
-        </dependencySet>
-    </dependencySets>
-</assembly>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<assembly>
+    <id>binary</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target/aggregate</directory>
+            <outputDirectory>/</outputDirectory>
+        </fileSet>
+        <fileSet>
+            <includes>
+                <include>README</include>
+                <include>DISCLAIMER</include>
+                <include>LICENSE</include>
+                <include>STATUS</include>
+                <include>NOTICE</include>
+                <include>README.txt</include>
+                <include>DISCLAIMER.txt</include>
+                <include>LICENSE.txt</include>
+                <include>STATUS.txt</include>
+                <include>NOTICE.txt</include>
+                <include>RELEASE-NOTES</include>
+                <include>RELEASE-NOTES.html</include>
+                <include>RELEASE-NOTES.txt</include>
+                <include>CHANGES</include>
+                <include>CHANGES.txt</include>
+            </includes>
+        </fileSet>
+        <!--
+        <fileSet>
+            <directory>licenses</directory>
+            <outputDirectory>/lib</outputDirectory>
+            <includes>
+                <include>*</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>target/examples</directory>
+            <outputDirectory>/examples</outputDirectory>
+        </fileSet>
+        -->
+        <fileSet>
+            <directory>target/manual</directory>
+            <outputDirectory>docs/manual</outputDirectory>
+        </fileSet>
+        <fileSet>
+            <directory>../target/site/apidocs</directory>
+            <outputDirectory>docs/javadoc</outputDirectory>
+        </fileSet>
+        <fileSet>
+            <directory>../openjpa-examples/src/main/java</directory>
+            <outputDirectory>examples</outputDirectory>
+        </fileSet>
+    </fileSets>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <unpack>false</unpack>
+            <scope>runtime</scope>
+            <includes>
+                <include>org.apache.openjpa:openjpa</include>
+            </includes>
+        </dependencySet>
+        <dependencySet>
+            <outputDirectory>/lib</outputDirectory>
+            <unpack>false</unpack>
+            <scope>runtime</scope>
+            <includes>
+                <include>net.sourceforge.serp:serp</include>
+                <include>org.apache.derby:derby</include>
+
+                <include>commons-lang:commons-lang</include>
+                <include>commons-collections:commons-collections</include>
+                <include>commons-pool:commons-pool</include>
+
+                <include>org.apache.geronimo.specs:geronimo-jta_1.1_spec</include>
+                <include>org.apache.geronimo.specs:geronimo-jpa_3.0_spec</include>
+            </includes>
+        </dependencySet>
+    </dependencySets>
+</assembly>
diff --git a/openjpa-project/pom.xml b/openjpa-project/pom.xml
index 13e9b59..3f60ab9 100644
--- a/openjpa-project/pom.xml
+++ b/openjpa-project/pom.xml
@@ -41,7 +41,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
 
     <properties>
diff --git a/openjpa-project/src/doc/manual/jpa_overview_pc.xml b/openjpa-project/src/doc/manual/jpa_overview_pc.xml
index ada76bc..65ecc96 100644
--- a/openjpa-project/src/doc/manual/jpa_overview_pc.xml
+++ b/openjpa-project/src/doc/manual/jpa_overview_pc.xml
@@ -65,11 +65,11 @@
 An instance of an embeddable class, on the other hand, is only stored as part of
 a separate entity. Embeddable instances have no persistent identity, and are
 never returned directly from the <classname>EntityManager</classname> or from a
-<classname>Query</classname> unless the query uses a projection on owning class 
-to the embedded instance. For example, if <classname>Address</classname> is 
-embedded in <classname>Company</classname>, then 
-a query <classname>"SELECT a FROM Address a"</classname> will never return the 
-embedded <classname>Address</classname> of <classname>Company</classname>; 
+<classname>Query</classname> unless the query uses a projection on owning class 
+to the embedded instance. For example, if <classname>Address</classname> is 
+embedded in <classname>Company</classname>, then 
+a query <classname>"SELECT a FROM Address a"</classname> will never return the 
+embedded <classname>Address</classname> of <classname>Company</classname>; 
 but a projection query such as
 <classname>"SELECT c.address FROM Company c"</classname> will.
     </para>
diff --git a/openjpa-project/src/doc/manual/manual.xml b/openjpa-project/src/doc/manual/manual.xml
index 56f345e..4932454 100644
--- a/openjpa-project/src/doc/manual/manual.xml
+++ b/openjpa-project/src/doc/manual/manual.xml
@@ -46,7 +46,7 @@
     <!ENTITY ref_guide_deploy.xml SYSTEM "ref_guide_deploy.xml">
     <!ENTITY ref_guide_runtime.xml SYSTEM "ref_guide_runtime.xml">
     <!ENTITY ref_guide_caching.xml SYSTEM "ref_guide_caching.xml">
-    <!ENTITY ref_guide_remote.xml SYSTEM "ref_guide_remote.xml">
+    <!ENTITY ref_guide_remote.xml SYSTEM "ref_guide_remote.xml">
     <!ENTITY ref_guide_slice.xml SYSTEM "ref_guide_slice.xml">
     <!ENTITY ref_guide_integration.xml SYSTEM "ref_guide_integration.xml">
     <!ENTITY ref_guide_optimization.xml SYSTEM "ref_guide_optimization.xml">
@@ -101,7 +101,7 @@
         &ref_guide_deploy.xml;
         &ref_guide_runtime.xml;
         &ref_guide_caching.xml;
-        &ref_guide_remote.xml;
+        &ref_guide_remote.xml;
         &ref_guide_slice.xml;
         &ref_guide_integration.xml;
         &ref_guide_optimization.xml;
diff --git a/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml b/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
index c301231..24b64f4 100644
--- a/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
+++ b/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
@@ -1926,6 +1926,22 @@
 languages, such as JDOQL.  Defaults to <literal>"\\"</literal> 
 (a single backslash in Java speak).
                     </para>
+                </listitem>                
+                <listitem id="DBDictionary.RequiresSearchStringEscapeForLike">
+                    <para>
+                    <indexterm>
+                        <primary>
+                            SQL
+                        </primary>
+                        <secondary>
+                            RequiresSearchStringEscapeForLike
+                        </secondary>
+                    </indexterm>
+<literal>RequiresSearchStringEscapeForLike</literal>:
+When true, the database requires an escape string for queries that use
+<literal>LIKE</literal>.  The escape string can be specified using
+<literal>searchStringEscape</literal>.  Defaults to <literal>true</literal>.
+                    </para>
                 </listitem>
                 <listitem id="DBDictionary.SelectWords">
                     <para>
@@ -3583,7 +3599,13 @@
                 <para>
 <literal>always</literal>: Each <classname>EntityManager</classname> obtains a
 single connection and uses it until the <classname>EntityManager</classname>
-closes.
+closes. Great care should be taken when using this property if the application 
+cannot close the EntityManager (ie container-managed EntityManagers in a JEE 
+Application Server). In this case the connection will remain open for an 
+undefined time and the application may not be able to recover from a terminated
+connection(ie if a TCP/IP timeout severs the connection to the database). 
+For this reason the <literal>always</literal> option should not be used with 
+container managed EntityManagers.
                 </para>
             </listitem>
             <listitem>
diff --git a/openjpa-project/src/doc/manual/ref_guide_mapping.xml b/openjpa-project/src/doc/manual/ref_guide_mapping.xml
index 8000ed7..5c0ca29 100644
--- a/openjpa-project/src/doc/manual/ref_guide_mapping.xml
+++ b/openjpa-project/src/doc/manual/ref_guide_mapping.xml
@@ -1,3501 +1,3501 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<chapter id="ref_guide_mapping">
-    <title>
-        Mapping
-    </title>
-    <indexterm zone="ref_guide_mapping">
-        <primary>
-            mapping metadata
-        </primary>
-    </indexterm>
-    <para>
-The JPA Overview's <xref linkend="jpa_overview_mapping"/> explains
-object-relational mapping under JPA. This chapter reviews the mapping utilities
-OpenJPA provides and examines OpenJPA features that go beyond the JPA
-specification.
-    </para>
-    <section id="ref_guide_mapping_mappingtool">
-        <title>
-            Forward Mapping
-        </title>
-        <indexterm zone="ref_guide_mapping_mappingtool">
-            <primary>
-                forward mapping
-            </primary>
-        </indexterm>
-        <indexterm zone="ref_guide_mapping_mappingtool">
-            <primary>
-                mapping tool
-            </primary>
-            <seealso>
-                forward mapping
-            </seealso>
-        </indexterm>
-        <indexterm>
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                forward mapping
-            </secondary>
-            <see>
-                forward mapping
-            </see>
-        </indexterm>
-        <para>
-<emphasis>Forward mapping</emphasis> is the process of creating mappings and
-their corresponding database schema from your object model. OpenJPA supports
-forward mapping through the <emphasis>mapping tool</emphasis>. The next section
-presents several common mapping tool use cases. You can invoke the tool through
-its Java class,
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingTool"><classname>
-org.apache.openjpa.jdbc.meta.MappingTool</classname></ulink>.
-        </para>
-        <note>
-            <para>
-<xref linkend="ref_guide_integration_mappingtool"/> describes the mapping
-tool Ant task.
-            </para>
-        </note>
-        <example id="ref_guide_mapping_mappingtool_typical">
-            <title>
-                Using the Mapping Tool
-            </title>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java
-</programlisting>
-        </example>
-        <para>
-In addition to the universal flags of the
-<link linkend="ref_guide_conf_devtools">configuration framework</link>, the
-mapping tool accepts the following command line arguments:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-<literal>-schemaAction/-sa &lt;add | refresh | drop | build | retain | reflect | createDB | dropDB | import | export | none&gt;
-</literal>: The action to take on the schema. These options correspond to the
-same-named actions on the schema tool described in
-<xref linkend="ref_guide_schema_schematool"/>. Actions can be composed in a
-comma-separated list. Unless you are running the mapping tool on all of
-your persistent types at once or dropping a mapping, we strongly
-recommend you use the default <literal>add</literal> action or the
-<literal>build</literal> action. Otherwise you may end up inadvertently
-dropping schema components that are used by classes you are not
-currently running the tool over.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-schemaFile/-sf &lt;stdout | output file&gt;</literal>: Use this
-option to write the planned schema to an XML document rather than modify the
-database. The document can then be manipulated and committed to the database
-with the <link linkend="ref_guide_schema_schematool"> schema tool</link>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-sqlFile/-sql &lt;stdout | output file&gt;</literal>: Use this option
-to write the planned schema modifications to a SQL script rather than modify the
-database. Combine this with a <literal>schemaAction</literal> of <literal>build
-</literal> to generate a script that recreates the schema for the current
-mappings, even if the schema already exists.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-dropTables/-dt &lt;true/t | false/f&gt;</literal>: Corresponds to the
-same-named option on the schema tool.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-dropSequences/-dsq &lt;true/t | false/f&gt;</literal>: Corresponds to
-the same-named option on the schema tool.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-openjpaTables/-ot &lt;true/t | false/f&gt;</literal>: Corresponds to
-the same-named option on the schema tool.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-ignoreErrors/-i &lt;true/t | false/f&gt;</literal>: Corresponds to
-the same-named option on the schema tool.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-schemas/-s &lt;schema and table names&gt;</literal>: Corresponds to
-the same-named option on the schema tool. This option is ignored if <literal>
-readSchema</literal> is not set to <literal>true</literal>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-readSchema/-rs &lt;true/t | false/f&gt;</literal>: Set this option to
-<literal>true</literal> to read the entire existing schema when the tool runs.
-Reading the existing schema ensures that OpenJPA does not generate any mappings
-that use table, index, primary key, or foreign key names that conflict with
-existing names. Depending on the JDBC driver, though, it can be a slow process
-for large schemas.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-primaryKeys/-pk &lt;true/t | false/f&gt;</literal>: Whether to read
-and manipulate primary key information of existing tables. Defaults to false.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-foreignKeys/-fk &lt;true/t | false/f&gt;</literal>: Whether to read
-and manipulate foreign key information of existing tables. Defaults to false.
-This means that to add any new foreign keys to a class that has already been
-mapped, you must explicitly set this flag to true.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-indexes/-ix &lt;true/t | false/f&gt;</literal>: Whether to read and
-manipulate index information of existing tables. Defaults to false. This means
-that to add any new indexes to a class that has already been mapped once, you
-must explicitly set this flag to true.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-sequences/-sq &lt;true/t | false/f&gt;</literal>: Whether to
-manipulate sequences. Defaults to true.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>-meta/-m &lt;true/t | false/f&gt;</literal>: Whether the given action
-applies to metadata rather than or in addition to mappings.
-                </para>
-            </listitem>
-        </itemizedlist>
-        <para>
-The mapping tool also uses an <literal>-action/-a</literal> argument to specify
-the action to take on each class. The available actions are:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-<literal>buildSchema</literal>: This is the default action. It
-makes the database schema match your existing mappings. If your provided
-mappings conflict with your class definitions, OpenJPA will fail with an
-informative exception.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>validate</literal>: Ensure that the mappings for the given classes are
-valid and that they match the schema. No mappings or tables will be changed. An
-exception is thrown if any mappings are invalid.
-                </para>
-            </listitem>
-        </itemizedlist>
-        <para>
-Each additional argument to the tool should be one of:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-The full name of a persistent class.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-The .java file for a persistent class.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-The <filename>.class</filename> file of a persistent class.
-                </para>
-            </listitem>
-        </itemizedlist>
-        <para>
-If you do not supply any arguments to the mapping tool, it will run on the
-classes in your persistent classes list (see
-<xref linkend="ref_guide_pc_pcclasses"/>).
-        </para>
-        <para>
-The mappings generated by the mapping tool are stored by the system <emphasis>
-mapping factory</emphasis>. <xref linkend="ref_guide_mapping_factory"/>
-discusses your mapping factory options.
-        </para>
-        <section id="ref_guide_mapping_mappingtool_examples">
-            <title>
-                Using the Mapping Tool
-            </title>
-            <indexterm zone="ref_guide_mapping_mappingtool_examples">
-                <primary>
-                    mapping tool
-                </primary>
-                <secondary>
-                    use cases
-                </secondary>
-            </indexterm>
-            <para>
-The JPA specification defines a comprehensive set of defaults for missing
-mapping information. Thus, forward mapping in JPA is virtually automatic. After
-using the mapping annotations covered in <xref linkend="jpa_overview_mapping"/>
-of the JPA Overview to override any unsatisfactory defaults, run the
-mapping tool on your persistent classes.  The default <literal>buildSchema
-</literal> mapping tool action manipulates the database schema to
-match your mappings. It fails if any of your mappings don't match your object
-model.
-            </para>
-            <example id="ref_guide_mapping_mappingtool_buildschema">
-                <title>
-                    Creating the Relational Schema from Mappings
-                </title>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java
-</programlisting>
-            </example>
-            <para>
-To drop the schema for a persistent class, set the mapping tool's <literal>
-schemaAction</literal> to <literal>drop</literal>.
-            </para>
-            <example id="ref_guide_mapping_mappingtool_cleanup_tables">
-                <title>
-                    Refreshing entire schema and cleaning out tables
-                </title>
-	            <indexterm zone="ref_guide_mapping_mappingtool_cleanup_tables">
-    	            <primary>
-        	            testing
-            	    </primary>
-                	<secondary>
-                    	Rebuild mappings and clean tables
-	                </secondary>
-    	        </indexterm>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction add,deleteTableContents
-</programlisting>
-            </example>
-            <example id="ref_guide_mapping_mappingtool_dropschema">
-                <title>
-                    Dropping Mappings and Association Schema
-                </title>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction drop Magazine.java
-</programlisting>
-            </example>
-        </section>
-        <section id="ref_guide_ddl_examples">
-            <title>
-                Generating DDL SQL
-            </title>
-            <indexterm zone="ref_guide_ddl_examples">
-                <primary>
-                    mapping tool
-                </primary>
-                <secondary>
-                    DDL generation
-                </secondary>
-            </indexterm>
-            <indexterm zone="ref_guide_ddl_examples">
-                <primary>
-                    DDL
-                </primary>
-                <secondary>
-                    with mapping tool
-                </secondary>
-            </indexterm>
-            <para>
-The examples below show how to use the mapping tool to generate DDL SQL scripts,
-rather than modifying the database directly.
-            </para>
-            <example id="ref_guid_mapping_ddl_full_ddl">
-                <title>
-                    Create DDL for Current Mappings
-                </title>
-                <para>
-This example uses your existing mappings to determine the needed schema, then
-writes the SQL to create that schema to <filename>create.sql</filename>.
-                </para>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction build -sql create.sql Magazine.java
-</programlisting>
-            </example>
-            <example id="ref_guid_mapping_ddl_part_ddl">
-                <title>
-                    Create DDL to Update Database for Current Mappings
-                </title>
-                <para>
-This example uses your existing mappings to determine the needed schema. It then
-writes the SQL to add any missing tables and columns to the current schema to
-<filename>update.sql</filename>.
-                </para>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool -sql update.sql Magazine.java
-</programlisting>
-            </example>
-        </section>
-        <section id="ref_guide_mapping_synch">
-            <title>
-                Runtime Forward Mapping
-            </title>
-            <indexterm zone="ref_guide_mapping_synch">
-                <primary>
-                    forward mapping
-                </primary>
-                <secondary>
-                    automatic runtime mapping
-                </secondary>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_synch">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    automatic runtime mapping
-                </secondary>
-            </indexterm>
-            <para>
-You can configure OpenJPA to automatically run the mapping tool at runtime
-through the <link linkend="openjpa.jdbc.SynchronizeMappings"><literal>
-openjpa.jdbc.SynchronizeMappings</literal></link> configuration property. Using
-this property saves you the trouble of running the mapping tool manually, and is
-meant for use during rapid test/debug cycles.
-            </para>
-            <para>
-In order to enable automatic runtime mapping, you must first list all your
-persistent classes as described in <xref linkend="ref_guide_pc_pcclasses"/>.
-            </para>
-            <para>
-OpenJPA will run the mapping tool on these classes when your application obtains
-its first <classname>EntityManager</classname>.
-            </para>
-            <para>
-The <literal>openjpa.jdbc.SynchronizeMappings</literal> property is a plugin
-string (see <xref linkend="ref_guide_conf_plugins"/>) where the class
-name is the mapping tool action to invoke, and the properties are the
-<classname>MappingTool</classname> class' JavaBean properties. These properties
-correspond go the long versions of the tool's command line flags.
-            </para>
-            <example id="ref_guide_mapping_synchex">
-                <title>
-                    Configuring Runtime Forward Mapping
-                </title>
-<programlisting>
-&lt;property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/&gt;
-</programlisting>
-                <para>
-The setting above corresponds to running the following command:
-                </para>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool -action buildSchema -foreignKeys true
-</programlisting>
-            </example>
-        </section>
-    </section>
-    <section id="ref_guide_pc_reverse">
-        <title>
-            Reverse Mapping
-        </title>
-        <indexterm zone="ref_guide_pc_reverse">
-            <primary>
-                reverse mapping
-            </primary>
-        </indexterm>
-        <indexterm zone="ref_guide_pc_reverse">
-            <primary>
-                reverse mapping tool
-            </primary>
-            <seealso>
-                reverse mapping
-            </seealso>
-        </indexterm>
-        <indexterm>
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                reverse mapping
-            </secondary>
-            <see>
-                reverse mapping
-            </see>
-        </indexterm>
-        <para>
-OpenJPA includes a <emphasis>reverse mapping</emphasis> tool for generating
-persistent class definitions, complete with metadata, from an existing database
-schema. You do not have to use the reverse mapping tool to access an existing
-schema; you are free to write your classes and mappings yourself, as described
-in <xref linkend="ref_guide_mapping_middle"/>. The reverse mapping tool,
-however, can give you an excellent starting point from which to grow your
-persistent classes.
-        </para>
-        <para>
-To use the reverse mapping tool, follow the steps below:
-        </para>
-        <orderedlist>
-            <listitem>
-                <para>
-Use the <link linkend="ref_guide_schema_schematool"> schema tool</link> to
-export your current schema to an XML schema file. You can skip this step and the
-next step if you want to run the reverse mapping tool directly against the
-database.
-                </para>
-                <example id="ref_guide_pc_reverse_schemagen">
-                    <title>
-                        Reflection with the Schema Tool
-                    </title>
-<programlisting>
-java org.apache.openjpa.jdbc.schema.SchemaTool -a reflect -f schema.xml
-</programlisting>
-                </example>
-            </listitem>
-            <listitem>
-                <para>
-Examine the generated schema file. JDBC drivers often provide incomplete or
-faulty metadata, in which case the file will not exactly match the actual
-schema. Alter the XML file to match the true schema. The XML format for the
-schema file is described in <xref linkend="ref_guide_schema_xml"/>.
-                </para>
-                <para>
-After fixing any errors in the schema file, modify the XML to include foreign
-keys between all relations. The schema tool will have automatically detected
-existing foreign key constraints; many schemas, however, do not employ database
-foreign keys for every relation. By manually adding any missing foreign keys,
-you will give the reverse mapping tool the information it needs to generate the
-proper relations between the persistent classes it creates.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-Run the reverse mapping tool on the finished schema file. If you do not supply
-the schema file to reverse map, the tool will run directly against the schema in
-the database. The tool can be run via its Java class,
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseMappingTool">
-<classname>org.apache.openjpa.jdbc.meta.ReverseMappingTool</classname></ulink>.
-                </para>
-                <example id="ref_guide_pc_reverse_reversemappingtool">
-                    <title>
-                        Using the Reverse Mapping Tool
-                    </title>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -d ~/src -cp customizer.properties schema.xml
-</programlisting>
-                </example>
-                <para>
-In addition to OpenJPA's <link linkend="ref_guide_conf_devtools">standard
-configuration flags</link>, including
-<link linkend="ref_guide_conf_devtools_format">code formatting options</link>,
-the reverse mapping tool recognizes the following command line arguments:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>-schemas/-s &lt;schema and table names&gt;</literal>: A
-comma-separated list of schema and table names to reverse map, if no XML schema
-file is supplied. Each element of the list must follow the naming conventions
-for the <literal>openjpa.jdbc.Schemas</literal> property described in
-<xref linkend="ref_guide_schema_info_list"/>. In fact, if this flag is
-omitted, it defaults to the value of the <literal>Schemas</literal> property. If
-the <literal>Schemas</literal> property is not defined, all schemas will be
-reverse-mapped.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-package/-pkg &lt;package name&gt;</literal>: The package name of the
-generated classes. If no package name is given, the generated code will not
-contain package declarations.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-directory/-d &lt;output directory&gt;</literal>: All generated code
-and metadata will be written to the directory at this path. If the path does not
-match the package of a class, the package structure will be created beneath this
-directory. Defaults to the current directory.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-metadata/-md &lt;class | package | none&gt;</literal>: Specify the
-level the metadata should be generated at. Defaults to generating a single
-package-level metadata file. Set to <literal>none</literal> to disable orm.xml
-generation.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-annotations/-ann &lt;true/t | false/f&gt;</literal>: Set to true to
-generate JPA annotations in generated java classes.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-accessType/-access &lt;field | property&gt;</literal>: Change access
-type for generated annotations. Defaults to field access.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-useSchemaName/-sn &lt;true/t | false/f&gt;</literal>: Set this flag
-to <literal>true</literal> to include the schema as well as table name in the
-name of each generated class. This can be useful when dealing with multiple
-schemas with same-named tables.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-useForeignKeyName/-fkn &lt;true/t | false/f&gt;</literal>: Set this
-flag to <literal>true</literal> if you would like field names for relations to
-be based on the database foreign key name. By default, relation field names are
-derived from the name of the related class.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-nullableAsObject/-no &lt;true/t | false/f&gt;</literal>: By default,
-all non-foreign key columns are mapped to primitives. Set this flag to <literal>
-true</literal> to generate primitive wrapper fields instead for columns that
-allow null values.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-blobAsObject/-bo &lt;true/t | false/f&gt;</literal>: By default, all
-binary columns are mapped to <classname>byte[]</classname> fields. Set this flag
-to <literal>true</literal> to map them to <classname>Object</classname> fields
-instead. Note that when mapped this way, the column is presumed to contain a
-serialized Java object.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-primaryKeyOnJoin/-pkj &lt;true/t | false/f&gt;</literal>: The
-standard reverse mapping tool behavior is to map all tables with primary keys to
-persistent classes. If your schema has primary keys on many-many join tables as
-well, set this flag to <literal>true</literal> to avoid creating classes for
-those tables.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-inverseRelations/-ir &lt;true/t | false/f&gt;</literal>: Set to
-<literal>false</literal> to prevent the creation of inverse 1-many/1-1 relations
-for every many-1/1-1 relation detected.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-useGenericCollections/-gc &lt;true/t | false/f&gt;</literal>: Set to
-true to use generic collections on OneToMany and ManyToMany relations (requires
-JDK 1.5 or higher).
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-useDatastoreIdentity/-ds &lt;true/t | false/f&gt;</literal>: Set to
-<literal>true</literal> to use datastore identity for tables that have single
-numeric primary key columns. The tool typically uses application identity for
-all generated classes.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-useBuiltinIdentityClass/-bic &lt;true/t | false/f&gt;</literal>: Set
-to <literal>false</literal> to prevent the tool from using built-in application
-identity classes when possible. This will force the tool to to create custom
-application identity classes even when there is only one primary key column.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-innerIdentityClasses/-inn &lt;true/t | false/f&gt;</literal>: Set to
-<literal>true</literal> to have any generated application identity classes be
-created as static inner classes within the persistent classes. Defaults to
-<literal>false</literal>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-identityClassSuffix/-is &lt;suffix&gt;</literal>: Suffix to append to
-class names to form application identity class names, or for inner identity
-classes, the inner class name. Defaults to <literal>Id</literal>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-typeMap/-typ &lt;type mapping&gt;</literal>: A string that specifies
-the default Java classes to generate for each SQL type that is seen in the
-schema. The format is <literal> SQLTYPE1=JavaClass1,SQLTYPE2=JavaClass2
-</literal>. The SQL type name first looks for a customization based on <literal>
-SQLTYPE(SIZE,PRECISION)</literal>, then <literal>SQLTYPE(SIZE)</literal>, then
-<literal>SQLTYPE(SIZE,PRECISION)</literal>. So if a column whose type name is
-<literal>CHAR</literal> is found, it will first look for the <literal>
-CHAR(50,0)</literal> type name specification, then it will look for <literal>
-CHAR(50)</literal>, and finally it will just look for <literal>CHAR</literal>.
-For example, to generate a char array for every <literal>CHAR</literal> column
-whose size is exactly 50, and to generate a <literal>short</literal> for every
-type name of <literal>INTEGER</literal>, you might specify: <literal>
-CHAR(50)=char[],INTEGER=short</literal>. Note that since various databases
-report different type names differently, one database's type name specification
-might not work for another database. Enable <literal>TRACE</literal> level
-logging on the <literal>MetaData</literal> channel to track which type names
-OpenJPA is examining.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-customizerClass/-cc &lt;class name&gt;</literal>: The full class name
-of a
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html">
-<classname>org.apache.openjpa.jdbc.meta.ReverseCustomizer</classname></ulink>
-customization plugin. If you do not specify a reverse customizer of your own,
-the system defaults to a
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html">
-<classname>PropertiesReverseCustomizer</classname></ulink>. This customizer
-allows you to specify simple customization options in the properties file given
-with the <literal>-customizerProperties</literal> flag below. We present the
-available property keys <link linkend="ref_guide_pc_reverse_custom">
-below</link>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-customizerProperties/-cp &lt;properties file or resource&gt;</literal>
-: The path or resource name of a properties file to pass to the reverse
-customizer on initialization.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>-customizer./-c.&lt;property name&gt; &lt;property value&gt;</literal>
-: The given property name will be matched with the corresponding Java bean
-property in the specified reverse customizer, and set to the given value.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-                <para>
-Running the tool will generate <filename>.java</filename> files for each
-generated class (and its application identity class, if applicable), along with
-JPA annotations (if enabled by setting <literal>-annotations true</literal>),
-or an <filename>orm.xml</filename> file (if not disabled with <literal>
--metadata none</literal>) containing the corresponding persistence metadata.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-Examine the generated class, metadata, and mapping information, and modify it as
-necessary. Remember that the reverse mapping tool only provides a starting
-point, and you are free to make whatever modifications you like to the code it
-generates.
-                </para>
-                <para>
-After you are satisfied with the generated classes and their mappings, you
-should first compile the classes with <literal>javac</literal>, <literal>
-jikes</literal>, or your favorite Java compiler. Make sure the classes are
-located in the directory corresponding to the <literal>-package</literal> flag
-you gave the reverse mapping tool.  Next, if you have generated an <filename>
-orm.xml</filename>, move that file to a <filename>META-INF</filename> directory
-within a directory in your classpath.  Finally, enhance the classes
-if necessary (see <xref linkend="ref_guide_pc_enhance"/>).
-                </para>
-            </listitem>
-        </orderedlist>
-        <para>
-Your persistent classes are now ready to access your existing schema.
-        </para>
-        <section id="ref_guide_pc_reverse_custom">
-            <title>
-                Customizing Reverse Mapping
-            </title>
-            <para>
-The <classname>org.apache.openjpa.jdbc.meta.ReverseCustomizer</classname> plugin
-interface allows you to customze the reverse mapping process. See the class
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html">
-Javadoc</ulink> for details on the hooks that this interface provides. Specify
-the concrete plugin implementation to use with the <literal>
--customizerClass/-cc</literal> command-line flag, described in the preceding
-section.
-            </para>
-            <para>
-By default, the reverse mapping tool uses a
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html">
-<classname>org.apache.openjpa.jdbc.meta.PropertiesReverseCustomizer</classname>
-</ulink>. This customizer allows you to perform relatively simple
-customizations through the properties file named with the <literal>
--customizerProperties</literal> tool flag. The customizer recognizes the
-following properties:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-<literal>&lt;table name&gt;.table-type &lt;type&gt;</literal>: Override the
-default type of the table with name <literal>&lt;table name&gt;</literal>.
-Legal values are:
-                    </para>
-                    <itemizedlist>
-                        <listitem>
-                            <para>
-<literal>base</literal>: Primary table for a base class.
-                            </para>
-                        </listitem>
-                        <listitem>
-                            <para>
-<literal>secondary</literal>: Secondary table for a class. The table must have
-a foreign key joining to a class table.
-                            </para>
-                        </listitem>
-                        <listitem>
-                            <para>
-<literal>secondary-outer</literal>: Outer-joined secondary table for a class.
-The table must have a foreign key joining to a class table.
-                            </para>
-                        </listitem>
-                        <listitem>
-                            <para>
-<literal>association</literal>: Association table. The table must have two
-foreign keys to class tables.
-                            </para>
-                        </listitem>
-                        <listitem>
-                            <para>
-<literal>collection</literal>: Collection table. The table must have one
-foreign key to a class table and one data column.
-                            </para>
-                        </listitem>
-                        <listitem>
-                            <para>
-<literal>subclass</literal>: A joined subclass table. The table must have a
-foreign key to the superclass' table.
-                            </para>
-                        </listitem>
-                        <listitem>
-                            <para>
-<literal>none</literal>: The table should not be reverse-mapped.
-                            </para>
-                        </listitem>
-                    </itemizedlist>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;class name&gt;.rename &lt;new class name&gt;</literal>: Override
-the given tool-generated name <literal>&lt;class name&gt;</literal> with a new
-value. Use full class names, including package. You are free to rename a class
-to a new package. Specify a value of <literal>none</literal> to reject the class
-and leave the corresponding table unmapped.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;table name&gt;.class-name &lt;new class name&gt;</literal>: Assign
-the given fully-qualified class name to the type created from the table with
-name <literal>&lt;table name&gt;</literal>. Use a value of <literal>none
-</literal> to prevent reverse mapping this table. This property can be used in
-place of the <literal>rename</literal> property.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;class name&gt;.identity &lt;datastore | builtin | identity class
-name&gt;</literal>: Set this property to <literal>datastore</literal> to use
-datastore identity for the class <literal>&lt;class name&gt;</literal>,
-<literal>builtin</literal> to use a built-in identity class, or the desired
-application identity class name. Give full class names, including package. You
-are free to change the package of the identity class this way. If the persistent
-class has been renamed, use the new class name for this property key. Remember
-that datastore identity requires a table with a single numeric primary key
-column, and built-in identity requires a single primary key column of any type.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;class name&gt;.&lt;field name&gt;.rename &lt;new field name&gt;
-</literal>: Override the tool-generated <literal>&lt;field name&gt;</literal> in
-class <literal>&lt;class name&gt;</literal> with the given name. Use the field
-owner's full class name in the property key. If the field owner's class was
-renamed, use the new class name. The property value should be the new field
-name, without the preceding class name. Use a value of <literal>none</literal>
-to reject the generated mapping and remove the field from the class.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;table name&gt;.&lt;column name&gt;.field-name &lt;new field
-name&gt;</literal>: Set the generated field name for the <literal>&lt;table
-name&gt;</literal> table's <literal>&lt;column name&gt;</literal> column. If
-this is a multi-column mapping, any of the columns can be used. Use a value of
-<literal>none</literal> to prevent the column and its associated columns from
-being reverse-mapped.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;class name&gt;.&lt;field name&gt;.type &lt;field type&gt;</literal>
-: The type to give the named field. Use full class names. If the field or the
-field's owner class has been renamed, use the new name.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>&lt;class name&gt;.&lt;field name&gt;.value</literal>: The initial
-value for the named field. The given string will be placed as-is in the
-generated Java code, so be sure it is valid Java. If the field or the field's
-owner class has been renamed, use the new name.
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <para>
-All property keys are optional; if not specified, the customizer keeps the
-default value generated by the reverse mapping tool.
-            </para>
-            <example id="ref_guide_pc_reverse_custom_ex">
-                <title>
-                    Customizing Reverse Mapping with Properties
-                </title>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -cp custom.properties schema.xml
-</programlisting>
-                <para>
-Example <filename>custom.properties</filename>:
-                </para>
-<programlisting>
-com.xyz.TblMagazine.rename:             com.xyz.Magazine
-com.xyz.TblArticle.rename:              com.xyz.Article
-com.xyz.TblPubCompany.rename:           com.xyz.pub.Company
-com.xyz.TblSysInfo.rename:              none
-
-com.xyz.Magazine.allArticles.rename:    articles
-com.xyz.Magazine.articles.type:         java.util.Collection
-com.xyz.Magazine.articles.value:        new TreeSet()
-com.xyz.Magazine.identity:              datastore
-
-com.xyz.pub.Company.identity:           com.xyz.pub.CompanyId
-</programlisting>
-            </example>
-        </section>
-    </section>
-    <section id="ref_guide_mapping_middle">
-        <title>
-            Meet-in-the-Middle Mapping
-        </title>
-        <indexterm zone="ref_guide_pc_reverse">
-            <primary>
-                meet-in-the-middle mapping
-            </primary>
-        </indexterm>
-        <indexterm zone="ref_guide_pc_reverse">
-            <primary>
-                reverse mapping tool
-            </primary>
-            <seealso>
-                reverse mapping
-            </seealso>
-        </indexterm>
-        <indexterm>
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                meet-in-the-middle mapping
-            </secondary>
-            <see>
-                meet-in-the-middle mapping
-            </see>
-        </indexterm>
-        <para>
-In the <emphasis>meet-in-the-middle</emphasis>
-mapping approach, you control both the relational model and the object model. It
-is up to you to define the mappings between these models.  The mapping
-tool's <literal>validate</literal> action is useful to meet-in-the-middle
-mappers. This action verifies that the mapping information for a class matches
-the class definition and the existing schema. It throws an informative exception
-when your mappings are incorrect.
-        </para>
-        <example id="ref_guide_mapping_mappingtool_validate">
-            <title>
-                Validating Mappings
-            </title>
-<programlisting>
-java org.apache.openjpa.jdbc.meta.MappingTool -action validate Magazine.java
-</programlisting>
-        </example>
-        <para>
-The <literal>buildSchema</literal> action we discussed in
-<xref linkend="ref_guide_mapping_mappingtool"/> is also somewhat useful
-during meet-in-the-middle mapping. Unlike the <literal>validate</literal>
-action, which throws an exception if your mapping data does not match the
-existing schema, the <literal>buildSchema</literal> action assumes your mapping
-data is correct, and modifies the schema to match your mappings. This lets you
-modify your mapping data manually, but saves you the hassle of using your
-database's tools to bring the schema up-to-date.
-        </para>
-    </section>
-    <section id="ref_guide_mapping_defaults">
-        <title>
-            Mapping Defaults
-        </title>
-        <indexterm zone="ref_guide_mapping_defaults">
-            <primary>
-                MappingDefaults
-            </primary>
-        </indexterm>
-        <indexterm zone="ref_guide_mapping_defaults">
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                defaults
-            </secondary>
-            <see>
-                MappingDefaults
-            </see>
-        </indexterm>
-        <para>
-The previous sections showed how to use the mapping tool to generate default
-mappings. But how does the mapping tool know what mappings to generate? The
-answer lies in the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingDefaults.html">
-<classname>org.apache.openjpa.jdbc.meta.MappingDefaults</classname></ulink>
-interface. OpenJPA uses an instance of this interface to decide how to name
-tables and columns, where to put foreign keys, and generally how to create a
-schema that matches your object model.
-        </para>
-        <important>
-            <para>
-OpenJPA relies on foreign key constraint information at runtime to order SQL
-appropriately. Be sure to set your mapping defaults to reflect your existing
-database constraints, set the schema factory to reflect on the database for
-constraint information (see <xref linkend="ref_guide_schema_info_factory"/>),
-or use explicit foreign key mappings as described in
-<xref linkend="ref_guide_mapping_jpa_fk"/>.
-            </para>
-        </important>
-        <para>
-The <link linkend="openjpa.jdbc.MappingDefaults"><literal>
-openjpa.jdbc.MappingDefaults</literal></link> configuration property controls
-the <classname>MappingDefaults</classname> interface implementation in use. This
-is a plugin property (see <xref linkend="ref_guide_conf_plugins"/>), so
-you can substitute your own implementation or configure the existing ones.
-OpenJPA includes the following standard implementations:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-<literal>jpa</literal>: Provides defaults in compliance with the JPA standard.
-This is an alias for the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.html">
-<classname>org.apache.openjpa.persistence.jdbc.PersistenceMappingDefaults
-</classname></ulink> class. This class extends the <classname>
-MappingDefaultsImpl</classname> class described below, so it has all the same
-properties (though with different default values), as well as:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>PrependFieldNameToJoinTableInverseJoinColumns</literal>: Whether to
-prepend the owning field name to the names of inverse join columns in join
-tables.  Defaults to true per the JPA specification.  Set to false for
-compatibility with older OpenJPA versions which did not prepend the field name.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </listitem>
-            <listitem>
-                <para>
-<literal>default</literal>: This is an alias for the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.html">
-<classname>org.apache.openjpa.jdbc.meta.MappingDefaultsImpl</classname></ulink>
-class. This default implementation is highly configurable. It has the following
-properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>DefaultMissingInfo</literal>: Whether to default missing column and
-table names rather than throw an exception. If set to false, full explicit
-mappings are required at runtime and when using mapping tool actions like
-<literal>buildSchema</literal> and <literal>validate</literal>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<indexterm><primary>Hungarian notation</primary></indexterm>
-<literal>RemoveHungarianNotation</literal>: Switches on/off removal of
-Hungarian notation when generating column names.
-Fields such as <literal>mFoobar</literal> and <literal>strBarFoo</literal>
-would become columns named <literal>foobar</literal> and
-<literal>barfoo</literal> respectively. OpenJPA will search for the first
-instance of a uppercase character in the field name and then truncate the
-column name to remove anything before it.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>BaseClassStrategy</literal>: The default mapping strategy for base
-classes. You can specify a built-in strategy alias or the full class name of a
-<link linkend="ref_guide_mapping_custom_class">custom class strategy</link>.
-You can also use OpenJPA's plugin format (see
-<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
-strategy instance. See the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
-<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for
-available strategies.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>SubclassStrategy</literal>: The default mapping strategy for
-subclasses. You can specify a builtin strategy alias or the full class name of a
-<link linkend="ref_guide_mapping_custom_class"> custom class strategy</link>.
-You can also use OpenJPA's plugin format (see
-<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
-strategy instance. Common strategies are <literal>vertical</literal> and
-<literal>flat</literal>, the default. See the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
-<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all
-available strategies.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>VersionStrategy</literal>: The default version strategy for classes
-without a version field. You can specify a builtin strategy alias or the full
-class name of a <link linkend="ref_guide_mapping_custom_versdiscrim"> custom
-version strategy</link>. You can also use OpenJPA's plugin format (see
-<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
-strategy instance. Common strategies are <literal>none</literal>, <literal>
-state-comparison</literal>, <literal> timestamp</literal>, and <literal>
-version-number</literal>, the default. See the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
-<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all
-available strategies.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>DiscriminatorStrategy</literal>: The default discriminator strategy
-when no discriminator value is given. You can specify a builtin strategy alias
-or the full class name of a
-<link linkend="ref_guide_mapping_custom_versdiscrim"> custom discriminator
-strategy</link>. You can also use OpenJPA's plugin format (see
-<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
-strategy instance. Common strategies are <literal>final</literal> for a base
-class without subclasses, <literal>none</literal> to use joins to subclass
-tables rather than a discriminator column, and <literal> class-name</literal>,
-the default. See the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
-<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all
-available strategies.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>FieldStrategies</literal>: This property associates field types with
-custom strategies. The format of this property is similar to that of plugin
-strings (see <xref linkend="ref_guide_conf_plugins"/> ), without the class
-name. It is a comma-separated list of key/value pairs, where each key is a
-possible field type, and each value is itself a plugin string describing the
-strategy for that type. We present an example below. See
-<xref linkend="ref_guide_mapping_custom_field"/> for information on custum
-field strategies.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>ForeignKeyDeleteAction</literal>: The default delete action of foreign
-keys representing relations to other objects. Recognized values include
-<literal>restrict</literal>, <literal>cascade</literal>, <literal>null</literal>
-, <literal>default</literal>. These values correspond exactly to the standard
-database foreign key actions of the same names.
-                        </para>
-                        <para>
-The value <literal>none</literal> tells OpenJPA not to create database foreign
-keys on relation columns. This is the default.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>JoinForeignKeyDeleteAction</literal>: The defualt delete action of
-foreign keys that join join secondary, collection, map, or subclass tables to
-the primary table. Accepts the same values as the <literal>
-ForeignKeyDeleteAction</literal> property above.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>DeferConstraints</literal>: Whether to use deferred database
-constraints if possible. Defaults to false.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>IndexLogicalForeignKeys</literal>: Boolean property controlling
-whether to create indexes on logical foreign keys. Logical foreign keys are
-columns that represent a link between tables, but have been configured through
-the <literal>ForeignKey</literal> properties above not to use a physical
-database foreign key. Defaults to true.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>DataStoreIdColumnName</literal>: The default name of datastore
-identity columns.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>DiscriminatorColumnName</literal>: The default name of discriminator
-columns.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>IndexDiscriminator</literal>: Whether to index the discriminator
-column. Defaults to true.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>VersionColumnName</literal>: The default name of version columns.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>IndexVersion</literal>: Whether to index the version column. Defaults
-to false.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>AddNullIndicator</literal>: Whether to create a synthetic null
-indicator column for embedded mappings. The null indicator column allows OpenJPA
-to distinguish between a null embedded object and one with default values for
-all persistent fields.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>NullIndicatorColumnName</literal>: The default name of synthetic null
-indicator columns for embedded objects.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>OrderLists</literal>: Whether to create a database ordering column for
-maintaining the order of persistent lists and arrays.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>OrderColumnName</literal>: The default name of collection and array
-ordering columns.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>StoreEnumOrdinal</literal>: Set to true to store enum fields as
-numeric ordinal values in the database. The default is to store the enum value
-name as a string, which is more robust if the Java enum declaration might be
-rearranged.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>StoreUnmappedObjectIdString</literal>: Set to true to store the
-stringified identity of related objects when the declared related type is
-unmapped. By default, OpenJPA stores the related object's primary key value(s).
-However, this breaks down if different subclasses of the related type use
-incompatible primary key structures. In that case, stringifying the identity
-value is the better choice.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </listitem>
-        </itemizedlist>
-        <para>
-The example below turns on foreign key generation during schema creation and
-associates the <classname>org.mag.data.InfoStruct</classname> field type with
-the custom <classname>org.mag.mapping.InfoStructHandler</classname> value
-handler.
-        </para>
-        <example id="ref_guide_mapping_defaults_conf">
-            <title>
-                Configuring Mapping Defaults
-            </title>
-<programlisting>
-&lt;property name="openjpa.jdbc.MappingDefaults"
-    value="ForeignKeyDeleteAction=restrict,
-    FieldStrategies='org.mag.data.InfoStruct=org.mag.mapping.InfoStructHandler'"/&gt;
-</programlisting>
-        </example>
-    </section>
-    <section id="ref_guide_mapping_factory">
-        <title>
-            Mapping Factory
-        </title>
-        <indexterm zone="ref_guide_mapping_factory">
-            <primary>
-                MappingFactory
-            </primary>
-        </indexterm>
-        <indexterm>
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                loading and storing
-            </secondary>
-            <see>
-                MappingFactory
-            </see>
-        </indexterm>
-        <para>
-An important decision in the object-relational mapping process is how and where
-to store the data necessary to map your persistent classes to the database
-schema.
-        </para>
-        <para>
-<xref linkend="ref_guide_meta_factory"/> introduced OpenJPA's <classname>
-MetaDataFactory</classname> interface. OpenJPA uses this same interface to
-abstract the storage and retrieval of mapping information. OpenJPA includes the
-built-in mapping factories below, and you can create your own factory if you
-have custom needs. You control which mapping factory OpenJPA uses with the
-<link linkend="openjpa.jdbc.MappingFactory"><literal>
-openjpa.jdbc.MappingFactory</literal></link> configuration property.
-        </para>
-        <para>
-The bundled mapping factories are:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-<literal>-</literal>: Leaving the <literal> openjpa.jdbc.MappingFactory
-</literal> property unset allows your metadata factory to take over mappings as
-well.  If you are using the default <literal>jpa</literal> metadata factory,
-OpenJPA will read mapping information from your annotations and
-<filename>orm.xml</filename> when you leave the mapping factory unspecified.
-                </para>
-            </listitem>
-        </itemizedlist>
-        <example id="ref_guide_mapping_factory_jpa">
-            <title>
-                Standard JPA Configuration
-            </title>
-            <para>
-In the standard JPA configuration, the mapping factory is left unset.
-            </para>
-<programlisting>
-&lt;property name="openjpa.MetaDataFactory" value="jpa"/&gt;
-</programlisting>
-        </example>
-    </section>
-    <section id="ref_guide_mapping_notes_nonstdjoins">
-        <title>
-            Non-Standard Joins
-        </title>
-        <indexterm zone="ref_guide_mapping_notes_nonstdjoins">
-            <primary>
-                joins
-            </primary>
-            <secondary>
-                non-standard
-            </secondary>
-        </indexterm>
-        <para>
-The JPA Overview's <xref linkend="jpa_overview_mapping"/> explains join
-mapping. All of the examples in that document, however, use "standard" joins, in
-that there is one foreign key column for each primary key column in the target
-table. OpenJPA supports additional join patterns, including partial primary key
-joins, non-primary key joins, and joins using constant values.
-        </para>
-        <para>
-        <indexterm>
-            <primary>
-                joins
-            </primary>
-            <secondary>
-                partial primary key
-            </secondary>
-        </indexterm>
-In a partial primary key join, the source table only has foreign key columns for
-a subset of the primary key columns in the target table. So long as this subset
-of columns correctly identifies the proper row(s) in the referenced table,
-OpenJPA will function properly. There is no special syntax for expressing a
-partial primary key join - just do not include column definitions for missing
-foreign key columns.
-        </para>
-        <para>
-        <indexterm>
-            <primary>
-                joins
-            </primary>
-            <secondary>
-                non-primary key
-            </secondary>
-        </indexterm>
-In a non-primary key join, at least one of the target columns is not a primary
-key. Once again, OpenJPA supports this join type with the same syntax as a
-primary key join. There is one restriction, however: each non-primary key column
-you are joining to must be controlled by a field mapping that implements the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/Joinable.html"><classname>
-org.apache.openjpa.jdbc.meta.Joinable</classname></ulink> interface. All built
-in basic mappings implement this interface, including basic fields of embedded
-objects. OpenJPA will also respect any custom mappings that implement this
-interface. See <xref linkend="ref_guide_mapping_custom"/> for an
-examination of custom mappings.
-        </para>
-        <para>
-        <indexterm>
-            <primary>
-                joins
-            </primary>
-            <secondary>
-                constant
-            </secondary>
-        </indexterm>
-Not all joins consist of only links between columns. In some cases you might
-have a schema in which one of the join criteria is that a column in the source
-or target table must have some constant value. OpenJPA calls joins involving
-constant values <emphasis>constant joins</emphasis>.
-        </para>
-        <para>
-To form a constant join in JPA mapping, first set the <literal>JoinColumn
-</literal>'s <literal>name</literal> attribute to the name of the column. If the
-column with the constant value is the target of the join, give its fully
-qualified name in the form <literal>&lt;table name&gt;.&lt;column name&gt;
-</literal>. Next, set the <literal>referencedColumnName</literal> attribute to
-the constant value. If the constant value is a string, place it in single quotes
-to differentiate it from a column name.
-        </para>
-        <mediaobject>
-            <imageobject>
-                <!-- PNG image data, 427 x 211 (see README) -->
-                <imagedata fileref="img/joins-constant.png" width="285px"/>
-
-            </imageobject>
-        </mediaobject>
-        <para>
-Consider the tables above. First, we want to join row <literal>T1.R1</literal>
-to row <literal>T2.R1</literal>. If we just join column <literal>T1.FK</literal>
-to <literal>T2.PK1</literal>, we will wind up matching both <literal>T2.R1
-</literal> and <literal> T2.R2</literal>. So in addition to joining <literal>
-T1.FK</literal> to <literal>T2.PK1</literal>, we also have to specify that
-<literal>T2.PK2</literal> has the value <literal>a</literal>. Here is how we'd
-accomplish this in mapping metadata.
-        </para>
-<programlisting>
-@Entity
-@Table(name="T1")
-public class ...  {
-
-    @ManyToOne
-    @JoinColumns({
-        @JoinColumn(name="FK" referencedColumnName="PK1"),
-        @JoinColumn(name="T2.PK2" referencedColumnName="'a'")
-    });
-    private ...;
-}
-</programlisting>
-        <para>
-Notice that we had to fully qualify the name of column <literal>PK2</literal>
-because it is in the target table. Also notice that we put single quotes around
-the constant value so that it won't be confused with a column name. You do not
-need single quotes for numeric constants. For example, the syntax to join
-<literal>T1.R2</literal> to <literal>T2.R4</literal> is:
-        </para>
-<programlisting>
-@Entity
-@Table(name="T1")
-public class ...  {
-
-    @ManyToOne
-    @JoinColumns({
-        @JoinColumn(name="FK" referencedColumnName="PK2"),
-        @JoinColumn(name="T2.PK1" referencedColumnName="2")
-    });
-    private ...;
-}
-</programlisting>
-        <para>
-Finally, from the inverse direction, these joins would look like this:
-        </para>
-<programlisting>
-@Entity
-@Table(name="T2")
-public class ...  {
-
-    @ManyToOne
-    @JoinColumns({
-        @JoinColumn(name="T1.FK" referencedColumnName="PK1"),
-        @JoinColumn(name="PK2" referencedColumnName="'a'")
-    });
-    private ...;
-
-    @ManyToOne
-    @JoinColumns({
-        @JoinColumn(name="T1.FK" referencedColumnName="PK2"),
-        @JoinColumn(name="PK1" referencedColumnName="2")
-    });
-    private ...;
-}
-</programlisting>
-    </section>
-    <section id="ref_guide_mapping_jpa">
-        <title>
-            Additional JPA Mappings
-        </title>
-        <indexterm zone="ref_guide_mapping_jpa">
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                JPA additions
-            </secondary>
-        </indexterm>
-        <para>
-OpenJPA supports many persistence strategies beyond those of the JPA
-specification. <xref linkend="ref_guide_meta_jpa"/> covered the logical
-metadata for OpenJPA's additional persistence strategies. We now demonstrate how
-to map entities using these strategies to the database.
-        </para>
-        <section id="ref_guide_mapping_jpa_datastoreid">
-            <title>
-                Datastore Identity Mapping
-            </title>
-            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
-                <primary>
-                    datastore identity
-                </primary>
-                <secondary>
-                    mapping
-                </secondary>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    datastore identity
-                </secondary>
-                <seealso>
-                    identity
-                </seealso>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
-                <primary>
-                    DataStoreIdColumn
-                </primary>
-                <seealso>
-                    mapping metadata
-                </seealso>
-            </indexterm>
-            <indexterm>
-                <primary>
-                    primary key
-                </primary>
-            </indexterm>
-            <para>
-<xref linkend="ref_guide_pc_oid"/> describes how to use datastore identity
-in JPA. OpenJPA requires a single numeric primary key column to hold datastore
-identity values. The
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DataStoreIdColumn.html">
-<classname>org.apache.openjpa.persistence.jdbc.DataStoreIdColumn</classname>
-</ulink> annotation customizes the datastore identity column. This annotation
-has the following properties:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-<literal>String name</literal>: Defaults to <literal>ID</literal>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>int precision</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>String columnDefinition</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>boolean insertable</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>boolean updatable</literal>
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <para>
-All properties correspond exactly to the same-named properties on the standard
-<classname>Column</classname> annotation, described in
-<xref linkend="jpa_overview_mapping_column"/>.
-            </para>
-            <example id="ref_guide_mapping_jpa_datastoreidex">
-                <title>
-                    Datastore Identity Mapping
-                </title>
-<programlisting>
-import org.apache.openjpa.persistence.*;
-import org.apache.openjpa.persistence.jdbc.*;
-
-@Entity
-@Table(name="LOGS")
-@DataStoreIdColumn(name="ENTRY")
-public class LogEntry {
-
-    @Lob
-    private String content;
-
-    ...
-}
-</programlisting>
-            </example>
-        </section>
-        <section id="ref_guide_mapping_jpa_version">
-            <title>
-                Surrogate Version Mapping
-            </title>
-            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
-                <primary>
-                    version
-                </primary>
-                <secondary>
-                    mapping
-                </secondary>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_jpa_version">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    version
-                </secondary>
-                <seealso>
-                    version
-                </seealso>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_jpa_version">
-                <primary>
-                    VersionColumn
-                </primary>
-                <seealso>
-                    mapping metadata
-                </seealso>
-            </indexterm>
-            <para>
-OpenJPA supports version fields as defined by the JPA specification, but allows
-you to use a surrogate version column in place of a version field if you like.
-You map the surrogate version column with the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumn.html">
-<classname>org.apache.openjpa.persistence.jdbc.VersionColumn</classname></ulink>
-annotation. You can also use the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumns.html">
-<classname>org.apache.openjpa.persistence.jdbc.VersionColumns</classname>
-</ulink> annotation to declare an array of <classname>VersionColumn</classname>
-values. Each <classname>VersionColumn</classname> has the following properties:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-<literal>String name</literal>: Defaults to <literal>VERSN</literal>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>int length</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>int precision</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>int scale</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>String columnDefinition</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>boolean nullable</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>boolean insertable</literal>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>boolean updatable</literal>
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <para>
-All properties correspond exactly to the same-named properties on the standard
-<classname>Column</classname> annotation, described in
-<xref linkend="jpa_overview_mapping_column"/>.
-            </para>
-            <para>
-By default, OpenJPA assumes that surrogate versioning uses a version number
-strategy. You can choose a different strategy with the <classname>
-VersionStrategy</classname> annotation described in
-<xref linkend="version-strategy"/>.
-            </para>
-        </section>
-        <section id="ref_guide_mapping_jpa_columns">
-            <title>
-                Multi-Column Mappings
-            </title>
-            <indexterm zone="ref_guide_mapping_jpa_columns">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    column
-                </secondary>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_jpa_columns">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    multi-column mappings
-                </secondary>
-            </indexterm>
-            <indexterm zone="ref_guide_mapping_jpa_columns">
-                <primary>
-                    Columns
-                </primary>
-                <seealso>
-                    mapping metadata
-                </seealso>
-            </indexterm>
-            <para>
-OpenJPA makes it easy to create multi-column
-<link linkend="ref_guide_mapping_custom_field">custom mappings</link>. The JPA
-specification includes a <classname>Column</classname> annotation, but is
-missing a way to declare multiple columns for a single field. OpenJPA remedies
-this with the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Columns.html">
-<classname>org.apache.openjpa.persistence.jdbc.Columns</classname></ulink>
-annotation, which contains an array of <classname>Column</classname> values.
-            </para>
-            <para>
-Remember to annotate custom field types with <classname>Persistent</classname>,
-as described in <xref linkend="ref_guide_meta_jpa_persistent"/>.
-            </para>
-        </section>
-        <section id="ref_guide_mapping_jpa_fieldjoin">
-            <title>
-                Join Column Attribute Targets
-            </title>
-            <para>
-<xref linkend="jpa_overview_mapping_rel"/> in the JPA Overview introduced
-you to the <classname>JoinColumn</classname> annotation. A <classname>
-JoinColumn</classname>'s <literal> referencedColumnName</literal> property
-declares which column in the table of the related type this join column links
-to. Suppose, however, that the related type is unmapped, or that it is part of a
-table-per-class inheritance hierarchy. Each subclass that might be assigned to
-the field could reside in a different table, and could use entirely different
-names for its primary key columns. It becomes impossible to supply a single
-<literal>referencedColumnName</literal> that works for all subclasses.
-            </para>
-            <para>
-OpenJPA rectifies this by allowing you to declare which <emphasis>attribute
-</emphasis> in the related type each join column links to, rather than which
-column. If the attribute is mapped differently in various subclass tables,
-OpenJPA automatically forms the proper join for the subclass record at hand. The
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumn.html">
-<classname>org.apache.openjpa.persistence.jdbc.XJoinColumn</classname></ulink>
-annotation has all the same properties as the standard <classname>JoinColumn
-</classname> annotation, but adds an additional <literal>
-referencedAttributeName</literal> property for this purpose. Simply use a
-<classname>XJoinColumn</classname> in place of a <classname>JoinColumn
-</classname> whenever you need to access this added functionality.
-            </para>
-            <para>
-For compound keys, use the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumns.html">
-<classname>org.apache.openjpa.persistence.jdbc.XJoinColumns</classname></ulink>
-annotation. The value of this annotation is an array of individual <classname>
-XJoinColumn</classname>s.
-            </para>
-        </section>
-        <section id="ref_guide_mapping_jpa_embed">
-            <title>
-                Embedded Mapping
-            </title>
-            <para>
-JPA uses the <classname>AttributeOverride</classname> annotation to override the
-default mappings of an embeddable class. The JPA Overview details this process
-in <xref linkend="jpa_overview_mapping_embed"/>. <classname>
-AttributeOverride</classname>s suffice for simple mappings, but do not allow
-you to override complex mappings. Also, JPA has no way to differentitate between
-a null embedded object and one with default values for all of its fields.
-            </para>
-            <para>
-OpenJPA overcomes these shortcomings with the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EmbeddedMapping.html">
-<classname>org.apache.openjpa.persistence.jdbc.EmbeddedMapping</classname>
-</ulink> annotation. This annotation has the following properties:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-<literal>String nullIndicatorColumnName</literal>: If the named column's value
-is <literal>NULL</literal>, then the embedded object is assumed to be null. If
-the named column has a non- <literal>NULL</literal> value, then the embedded
-object will get loaded and populated with data from the other embedded fields.
-This property is entirely optional. By default, OpenJPA always assumes the
-embedded object is non-null, just as in standard JPA mapping.
-                    </para>
-                    <para>
-If the column you name does not belong to any fields of the embedded object,
-OpenJPA will create a synthetic null-indicator column with this name. In fact,
-you can specify a value of <literal>true</literal> to simply indicate that you
-want a synthetic null-indicator column, without having to come up with a name
-for it. A value of <literal>false</literal> signals that you explicitly do not
-want a null-indicator column created for this mapping (in case you have
-configured your <link linkend="ref_guide_mapping_defaults">mapping defaults
-</link> to create one by default).
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>String nullIndicatorFieldName</literal>: Rather than name a null
-indicator column, you can name a field of the embedded type. OpenJPA will use
-the column of this field as the null-indicator column.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>MappingOverride[] overrides</literal>: This array allows you to
-override any mapping of the embedded object.
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <para>
-The <classname>EmbeddedMapping</classname>'s <literal>overrides</literal> array
-serves the same purpose as standard JPA's <classname>AttributeOverride
-</classname>s and <classname>AssociationOverride</classname> s. In fact, you can
-also use the <classname>MappingOverride</classname> annotation on an entity
-class to override a complex mapping of its mapped superclass, just as you can
-with <classname> AttributeOverride</classname> and <classname>
-AssociationOverride</classname> s. The <classname>MappingOverrides</classname>
-annotation, whose value is an array of <classname>MappingOverride</classname> s,
-allows you to overide multiple mapped superclass mappings.
-            </para>
-            <para>
-Each
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/MappingOverride.html">
-<classname>org.apache.openjpa.persistence.jdbc.MappingOverride</classname>
-</ulink> annotation has the following properties:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-<literal>String name</literal>: The name of the field that is being overridden.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>Column[] columns</literal>: Columns for the new field mapping.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>XJoinColumn[] joinColumns</literal>: Join columns for the new field
-mapping, if it is a relation field.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>ContainerTable containerTable</literal>: Table for the new collection
-or map field mapping. We cover collection mappings in
-<xref linkend="ref_guide_mapping_jpa_coll"/>, and map mappings in
-<xref linkend="ref_guide_mapping_jpa_map"/>.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-<literal>ElementJoinColumn[] elementJoinColumns</literal>: Element join columns
-for the new collection or map field mapping. You will see how to use element
-join columns in <xref linkend="ref_guide_mapping_jpa_coll_joincols"/>.
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <para>
-The following example defines an embeddable <classname> PathCoordinate
-</classname> class with a custom mapping of a <classname>java.awt.Point
-</classname> field to two columns. It then defines an entity which embeds a
-<classname> PointCoordinate</classname> and overrides the default mapping for
-the point field. The entity also declares that if the <classname>PathCoordinate
-</classname>'s <literal>siteName</literal> field column is null, it means that
-no <classname>PathCoordinate</classname> is stored in the embedded record; the
-owning field will load as null.
-            </para>
-            <example id="ref_guide_mapping_jpa_embedex">
-                <title>
-                    Overriding Complex Mappings
-                </title>
-<programlisting>
-import org.apache.openjpa.persistence.jdbc.*;
-
-@Embeddable
-public class PathCoordinate {
-
-    private String siteName;
-
-    @Persistent
-    @Strategy("com.xyz.openjpa.PointValueHandler")
-    private Point point;
-
-    ...
-}
-
-@Entity
-public class Path {
-
-    @Embedded
-    @EmbeddedMapping(nullIndicatorFieldName="siteName", overrides={
-        @MappingOverride(name="siteName", columns=@Column(name="START_SITE")),
-        @MappingOverride(name="point", columns={
-            @Column(name="START_X"),
-            @Column(name="START_Y")
-        })
-    })
-    private PathCoordinate start;
-
-    ...
-}
-</programlisting>
-            </example>
-        </section>
-        <section id="ref_guide_mapping_jpa_coll">
-            <title>
-                Collections
-            </title>
-            <indexterm zone="ref_guide_mapping_jpa_coll">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    collections
-                </secondary>
-            </indexterm>
-            <para>
-In <xref linkend="ref_guide_meta_jpa_persistent_coll"/>, we explored the
-<classname>PersistentCollection</classname> annotation for persistent collection
-fields that aren't a standard <literal>OneToMany</literal> or <literal>
-ManyToMany</literal> relation. To map these non-standard collections, combine
-OpenJPA's <classname>ContainerTable</classname> annotation with
-<classname>ElementJoinColumn</classname>s.
-We explore the annotations below.
-            </para>
-            <section id="ref_guide_mapping_jpa_coll_table">
-                <title>
-                    Container Table
-                </title>
-                <indexterm zone="ref_guide_mapping_jpa_coll_table">
-                    <primary>
-                        ContainerTable
-                    </primary>
-                    <seealso>
-                        mapping metadata
-                    </seealso>
-                </indexterm>
-                <para>
-The
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ContainerTable.html">
-<classname>org.apache.openjpa.persistence.jdbc.ContainerTable</classname>
-</ulink> annotation describes a database table that holds collection (or map)
-elements. This annotation has the following properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>String name</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>String catalog</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>String schema</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>XJoinColumn[] joinColumns</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>ForeignKey joinForeignKey</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>Index joinIndex</literal>
-                        </para>
-                    </listitem>
-                </itemizedlist>
-                <para>
-The <literal>name</literal>, <literal>catalog</literal>, <literal>schema
-</literal>, and <literal>joinColumns</literal> properties describe the container
-table and how it joins to the owning entity's table. These properties correspond
-to the same-named properties on the standard <classname> JoinTable</classname>
-annotation, described in <xref linkend="jpa_overview_mapping_assoccoll"/>
-. If left unspecified, the name of the table defaults to the first five
-characters of the entity table name, plus an underscore, plus the field name.
-The <literal>joinForeignKey</literal> and <literal> joinIndex</literal>
-properties override default foreign key and index generation for the join
-columns. We explore foreign keys and indexes later in this chapter.
-                </para>
-                <para>
-You may notice that the container table does not define how to store the
-collection elements. That is left to separate annotations, which are the subject
-of the next sections.
-                </para>
-            </section>
-            <section id="ref_guide_mapping_jpa_coll_joincols">
-                <title>
-                    Element Join Columns
-                </title>
-                <indexterm zone="ref_guide_mapping_jpa_coll_joincols">
-                    <primary>
-                        ElementJoinColumn
-                    </primary>
-                    <seealso>
-                        mapping metadata
-                    </seealso>
-                </indexterm>
-                <para>
-Element join columns are equivalent to standard JPA join columns, except that
-they represent a join to a collection or map element entity rather than a direct
-relation. You represent an element join column with OpenJPA's
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumn.html">
-<classname>org.apache.openjpa.persistence.jdbc.ElementJoinColumn</classname>
-</ulink> annotation. To declare a compound join, enclose an array of <classname>
-ElementJoinColumn</classname>s in the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumns.html">
-<classname>org.apache.openjpa.persistence.jdbc.ElementJoinColumns</classname>
-</ulink> annotation.
-                </para>
-                <para>
-An <classname>ElementJoinColumn</classname> always resides in a container table,
-so it does not have the <literal> table</literal> property of a standard
-<classname> JoinColumn</classname>. Like <classname> XJoinColumn</classname>s
-above, <classname> ElementJoinColumn</classname>s can reference a linked
-attribute rather than a static linked column. Otherwise, the <classname>
-ElementJoinColumn</classname> and standard <classname>JoinColumn</classname>
-annotations are equivalent. See <xref linkend="jpa_overview_mapping_rel"/>
-in the JPA Overview for a review of the <classname>JoinColumn</classname>
-annotation.
-                </para>
-            </section>
-            <section id="ref_guide_mapping_jpa_coll_order">
-                <title>
-                    Order Column
-                </title>
-                <indexterm zone="ref_guide_mapping_jpa_coll_order">
-                    <primary>
-                        OrderColumn
-                    </primary>
-                    <seealso>
-                        mapping metadata
-                    </seealso>
-                </indexterm>
-                <para>
-Relational databases do not guarantee that records are returned in insertion
-order. If you want to make sure that your collection elements are loaded in the
-same order they were in when last stored, you must declare an order column.
-OpenJPA's
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/OrderColumn">
-<classname>org.apache.openjpa.persistence.jdbc.OrderColumn</classname></ulink>
-annotation has the following properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>String name</literal>: Defaults to <literal>ORDR</literal>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>boolean enabled</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>int precision</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>String columnDefinition</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>boolean insertable</literal>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>boolean updatable</literal>
-                        </para>
-                    </listitem>
-                </itemizedlist>
-                <para>
-Order columns are always in the container table. You can explicitly turn off
-ordering (if you have enabled it by default via your
-<link linkend="ref_guide_mapping_defaults"> mapping defaults</link>) by setting
-the <literal>enabled</literal> property to <literal>false</literal>. All other
-properties correspond exactly to the same-named properties on the standard
-<classname>Column</classname> annotation, described in
-<xref linkend="jpa_overview_mapping_column"/>.
-                </para>
-            </section>
-        </section>
-        <section id="ref_guide_mapping_jpa_onemany">
-            <title>
-                One-Sided One-Many Mapping
-            </title>
-            <indexterm zone="ref_guide_mapping_jpa_onemany">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    collections
-                </secondary>
-                <tertiary>
-                    JPA one-sided one-many
-                </tertiary>
-            </indexterm>
-            <para>
-The previous section covered the use of <classname>ElementJoinColumn</classname>
-annotations in conjunction with a <classname>ContainerTable</classname> for
-mapping collections to dedicate tables. <classname>ElementJoinColumn</classname>
-s, however, have one additional use: to create a one-sided one-many mapping.
-Standard JPA supports <classname>OneToMany</classname> fields without a
-<literal>mappedBy</literal> inverse, but only by mapping these fields to a
-<classname>JoinTable</classname> (see
-<xref linkend="jpa_overview_mapping_assoccoll"/> in the JPA Overview for
-details). Often, you'd like to create a one-many association based on an inverse
-foreign key (logical or actual) in the table of the related type.
-            </para>
-            <mediaobject>
-                <imageobject>
-                    <!-- PNG image data, 392 x 192 (see README) -->
-                    <imagedata fileref="img/inv-key-coll.png" width="261"/>
-
-                </imageobject>
-            </mediaobject>
-            <para>
-Consider the model above. <classname>Subscription</classname> has a collection
-of <classname>LineItem</classname> s, but <classname>LineItem</classname> has
-no inverse relation to <classname>Subscription</classname>. To retrieve all of
-the <classname>LineItem</classname> records for a <classname>Subscription
-</classname>, we join the <literal>SUB_ID</literal> inverse foreign key column
-in the <literal>LINE_ITEM</literal> table to the primary key column of the
-<literal>SUB</literal> table. The example below shows how to represent this
-model in mapping annotations. Note that OpenJPA automatically assumes an inverse
-foreign key mapping when element join columns are given, but no container or
-join table is given.
-            </para>
-            <example id="ref_guide_mapping_jpa_onemanyex">
-                <title>
-                    One-Sided One-Many Mapping
-                </title>
-<programlisting>
-package org.mag.subscribe;
-
-import org.apache.openjpa.persistence.jdbc.*;
-
-@Entity
-@Table(name="LINE_ITEM", schema="CNTRCT")
-public class LineItem {
-    ...
-}
-
-@Entity
-@Table(name="SUB", schema="CNTRCT")
-public class Subscription {
-
-    @Id private long id;
-
-    @OneToMany
-    @ElementJoinColumn(name="SUB_ID", referencedColumnName="ID")
-    private Collection&lt;LineItem&gt; items;
-
-    ...
-}
-</programlisting>
-            </example>
-        </section>
-        <section id="ref_guide_mapping_jpa_map">
-            <title>
-                Maps
-            </title>
-            <indexterm zone="ref_guide_mapping_jpa_map">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    maps
-                </secondary>
-            </indexterm>
-            <para>
-We detailed the <literal>ContainerTable</literal> annotation in
-<xref linkend="ref_guide_mapping_jpa_coll_table"/>. Custom map mappings may
-also use this annotation to represent a map table.
-            </para>
-        </section>
-        <section id="ref_guide_mapping_jpa_constraints">
-            <title>
-                Indexes and Constraints
-            </title>
-            <para>
-OpenJPA uses index information during schema generation to index the proper
-columns. OpenJPA uses foreign key and unique constraint information during
-schema creation to generate the proper database constraints, and also at runtime
-to order SQL statements to avoid constraint violations while maximizing SQL
-batch size.
-            </para>
-            <para>
-OpenJPA assumes certain columns have indexes or constraints based on your
-mapping defaults, as detailed in <xref linkend="ref_guide_mapping_defaults"/>.
-You can override the configured defaults on individual joins, field
-values, collection elements, map keys, or map values using the annotations
-presented in the following sections.
-            </para>
-            <section id="ref_guide_mapping_jpa_index">
-                <title>
-                    Indexes
-                </title>
-                <indexterm zone="ref_guide_mapping_jpa_index">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        indexes
-                    </secondary>
-                </indexterm>
-                <indexterm zone="ref_guide_mapping_jpa_index">
-                    <primary>
-                        indexes
-                    </primary>
-                </indexterm>
-                <para>
-The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Index.html">
-<classname>org.apache.openjpa.persistence.jdbc.Index</classname></ulink>
-annotation represents an index on the columns of a field. It is also used within
-the <link linkend="ref_guide_mapping_jpa_coll_table"><classname>ContainerTable
-</classname></link> annotation to index join columns.
-To index the columns of a collection element, use the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementIndex.html">
-<classname> org.apache.openjpa.persistence.jdbc.ElementIndex</classname></ulink>
-annotation. These annotations have the following properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>boolean enabled</literal>: Set this property to <literal>false
-</literal> to explicitly tell OpenJPA not to index these columns, when OpenJPA
-would otherwise do so.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>String name</literal>: The name of the index. OpenJPA will choose a
-name if you do not provide one.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>boolean unique</literal>: Whether to create a unique index. Defaults
-to false.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </section>
-            <section id="ref_guide_mapping_jpa_fk">
-                <title>
-                    Foreign Keys
-                </title>
-                <indexterm zone="ref_guide_mapping_jpa_fk">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        foreign keys
-                    </secondary>
-                </indexterm>
-                <indexterm zone="ref_guide_mapping_jpa_fk">
-                    <primary>
-                        foreign keys
-                    </primary>
-                </indexterm>
-                <para>
-The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKey.html">
-<classname>org.apache.openjpa.persistence.jdbc.ForeignKey</classname></ulink>
-annotation represents a foreign key on the columns of a field. It is also used
-within the <link linkend="ref_guide_mapping_jpa_coll_table"><classname>
-ContainerTable</classname></link> annotation to set a database foreign key on
-join columns.  To set a constraint to the columns of a collection element, use
-the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementForeignKey.html">
-<classname> org.apache.openjpa.persistence.jdbc.ElementForeignKey</classname>
-</ulink> annotation. These annotations have the following properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>boolean enabled</literal>: Set this property to <literal>false
-</literal> to explicitly tell OpenJPA not to set a foreign key on these columns,
-when OpenJPA would otherwise do so.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>String name</literal>: The name of the foreign key. OpenJPA will
-choose a name if you do not provide one, or will create an anonymous key.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>boolean deferred</literal>: Whether to create a deferred key if
-supported by the database.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>ForeignKeyAction deleteAction</literal>: Value from the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html">
-<classname>org.apache.openjpa.persistence.jdbc.ForeignKeyAction</classname>
-</ulink> enum identifying the desired delete action. Defaults to <literal>
-RESTRICT</literal>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>ForeignKeyAction updateAction</literal>: Value from the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html">
-<classname>org.apache.openjpa.persistence.jdbc.ForeignKeyAction</classname>
-</ulink> enum identifying the desired update action. Defaults to <literal>
-RESTRICT</literal>.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-                <para>
-Keep in mind that OpenJPA uses foreign key information at runtime to avoid
-constraint violations; it is important, therefore, that your
-<link linkend="ref_guide_mapping_defaults">mapping defaults</link> and foreign
-key annotations combine to accurately reflect your existing database
-constraints, or that  you configure OpenJPA to reflect on your database schema
-to discover existing foreign keys (see
-<xref linkend="ref_guide_schema_info_factory"/>).
-                </para>
-            </section>
-            <section id="ref_guide_mapping_jpa_unique">
-                <title>
-                    Unique Constraints
-                </title>
-                <indexterm zone="ref_guide_mapping_jpa_unique">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        unique constraints
-                    </secondary>
-                </indexterm>
-                <indexterm zone="ref_guide_mapping_jpa_unique">
-                    <primary>
-                        unique constraints
-                    </primary>
-                </indexterm>
-                <para>
-The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Unique.html">
-<classname>org.apache.openjpa.persistence.jdbc.Unique</classname></ulink>
-annotation represents a unqiue constraint on the columns of a field. It is more
-convenient than using the <literal>uniqueConstraints</literal> property of
-standard JPA <classname>Table</classname> and <classname>SecondaryTable
-</classname> annotations, because you can apply it directly to the constrained
-field. The <classname>Unique</classname> annotation has the following
-properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>boolean enabled</literal>: Set this property to <literal>false
-</literal> to explicitly tell OpenJPA not to constrain these columns, when
-OpenJPA would otherwise do so.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>String name</literal>: The name of the constraint. OpenJPA will choose
-a name if you do not provide one, or will create an anonymous constraint.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>boolean deferred</literal>: Whether to create a deferred constraint if
-supported by the database.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </section>
-        </section>
-        <section id="ref_guide_xmlmapping">
-		    <title>
-              XML Column Mapping
-            </title>
-              <indexterm zone="ref_guide_xmlmapping">
-                  <primary>
-                      mapping metadata
-                  </primary>
-                  <secondary>
-                      xml column mapping
-                  </secondary>
-              </indexterm>
-              <indexterm zone="ref_guide_xmlmapping">
-                  <primary>
-                      xml mapping column
-                  </primary>
-              </indexterm>
-              <para>
-DB2, Oracle and SQLServer support XML column types and
-XPath queries and indexes over these columns.OpenJPA supports mapping of an
-entity property mapped to an XML column.
-              </para>
-              <para>
-Annotate the entity property using the XMLValueHandler strategy:
-		      </para>
-<programlisting>
-@Persistent
-@Strategy(&quot;org.apache.openjpa.jdbc.meta.strats.XMLValueHandler&quot;)
-</programlisting>
-              <para>
-The default fetch type is EAGER but can be changed to LAZY by using:
-              </para>
-<programlisting>
-@Persistence(fetch=FetchType.LAZY)
-</programlisting>
-              <para>
-The entity property class is required to have
-jaxb binding annotations.  This is produced when the classes are generated
-from an xml schema using the jaxb generator XJC.Ensure that <classname>@XmlRootElement</classname>
-appears in the root class. In some case this annotation needs to be added manually if it is missing.
-              </para>
-              <para>
-The jaxb jar files must be on the application classpath (jaxb-api.jar,
-jaxb-impl.jar, jsr173_1.0_api.jar or equivalent).
-              </para>
-              <para>
-EJB Query path expressions can navigate into the mapped class and its
-subfields to any level.
-              </para>
-              <para>
-The path expression is rewritten into an equivalent XPATH expression using SQL
-XML functions.
-              </para>
-              <para>
-The path expression must be single valued.Path expressions over xml
-mapped classes can only be used in WHERE as an operand to a simple predicate
-(=  &lt;&gt;  &lt;  &gt;  &gt;=  &lt;=).
-              </para>
-              <para>
-Path expressions over XML mapped fields can not be:
-              </para>
-		      <itemizedlist>
-                  <listitem>
-                      <para>
-an input to a EJB query scalar function
-                      </para>
-                  </listitem>
-                  <listitem>
-                      <para>
-an operand of BETWEEN,  IS NULL, LIKE or IN predicate
-                      </para>
-                  </listitem>
-                  <listitem>
-                      <para>
-used to project out subfields in the SELECT clause
-                      </para>
-                  </listitem>
-                  <listitem>
-                      <para>
-used in the FROM , GROUP BY, HAVING, ORDER BY clauses
-                      </para>
-                  </listitem>
-              </itemizedlist>
-              <para>
-XML schema must not contain namespace declarations. The EJB query path
-expressions can not refer to java fields generated from XML ANY type or
-XML mixed element types.
-              </para>
-              <para>
-The datatype generated by JAXB must be a valid EJB query type
-to use the property in an EJB query predicate.
-              </para>
-              <para>
-Shown below is a sample XML schema <link linkend="ref_guide_xmlmapping_myaddress">myaddress.xsd</link>,
-in which the JPA entity Order has <classname>&lt;shipAddress&gt;</classname> persistent field that maps to an XML column.
-		      </para>
-              <example id="ref_guide_xmlmapping_myaddress">
-                   <title>
-                       myaddress.xsd
-                   </title>
-<programlisting>
-&lt;?xml version=&quot;1.0&quot; ?&gt;
-&lt;xs:schema xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; &gt;
-
-&lt;xs:complexType name=&quot;Address&quot;&gt;
- &lt;xs:sequence&gt;
-  &lt;xs:element name=&quot;Name&quot; type=&quot;xs:string&quot; /&gt;
-  &lt;xs:element name=&quot;Street&quot; type=&quot;xs:string&quot;
-  	minOccurs=&quot;1&quot; maxOccurs=&quot;3&quot; /&gt;
-  &lt;xs:element name=&quot;City&quot; type=&quot;xs:string&quot; /&gt;
-&lt;/xs:sequence&gt;
-&lt;/xs:complexType&gt;
-
-&lt;xs:complexType name=&quot;CAN_Address&quot;&gt;
- &lt;xs:complexContent&gt;
-  &lt;xs:extension base=&quot;Address&quot;&gt;
-   &lt;xs:sequence&gt;
-    &lt;xs:element name=&quot;Province&quot; type=&quot;xs:string&quot; /&gt;
-    &lt;xs:element name=&quot;PostalCode&quot; type=&quot;xs:string&quot; /&gt;
-   &lt;/xs:sequence&gt;
-  &lt;/xs:extension&gt;
-&lt;/xs:complexContent&gt;
-&lt;/xs:complexType&gt;
-
-&lt;xs:simpleType name=&quot;USPS_ZIP&quot;&gt;
- &lt;xs:restriction base=&quot;xs:integer&quot;&gt;
-  &lt;xs:minInclusive value=&quot;01000&quot; /&gt;
-  &lt;xs:maxInclusive value=&quot;99999&quot; /&gt;
- &lt;/xs:restriction&gt;
-&lt;/xs:simpleType&gt;
-
-&lt;xs:complexType name=&quot;USA_Address&quot;&gt;
- &lt;xs:complexContent&gt;
-  &lt;xs:extension base=&quot;Address&quot;&gt;
-   &lt;xs:sequence&gt;
-    &lt;xs:element name=&quot;State&quot; type=&quot;xs:string&quot; /&gt;
-    &lt;xs:element name=&quot;ZIP&quot; type=&quot;USPS_ZIP&quot; /&gt;
-   &lt;/xs:sequence&gt;
-  &lt;/xs:extension&gt;
- &lt;/xs:complexContent&gt;
-&lt;/xs:complexType&gt;
-
-&lt;xs:element name=&quot;MailAddress&quot; type=&quot;Address&quot; /&gt;
-&lt;xs:element name=&quot;AddrCAN&quot; type=&quot;CAN_Address&quot;
-   substitutionGroup=&quot;MailAddress&quot; /&gt;
-&lt;xs:element name=&quot;AddrUSA&quot; type=&quot;USA_Address&quot;
-   substitutionGroup=&quot;MailAddress&quot; /&gt;
-&lt;/xs:schema&gt;
-</programlisting>
-              </example>
-              <para>
-Java classes <link linkend="ref_guide_xmlmapping_address">Address</link>,
-<link linkend="ref_guide_xmlmapping_usaaddress">USAAddress</link> and
-<link linkend="ref_guide_xmlmapping_canaddress">CANAddress</link>
-are produced using jaxb XJC generator from myaddress schema.
-              </para>
-              <example id="ref_guide_xmlmapping_address">
-                  <title>
-                       Address.Java
-                  </title>
-<programlisting>
-    ...
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = &quot;Address&quot;, propOrder = {
-    &quot;name&quot;,
-    &quot;street&quot;,
-    &quot;city&quot;
-})
-public class Address {
-    @XmlElement(name = &quot;Name&quot;, required = true)
-    protected String name;
-    @XmlElement(name = &quot;Street&quot;, required = true)
-    protected List&lt;String&gt; street;
-    @XmlElement(name = &quot;City&quot;, required = true)
-    protected String city;
-
-   /**
-     * Getter and Setter methods.
-     *
-     */
-     ...
-}
-</programlisting>
-            </example>
-            <example id="ref_guide_xmlmapping_usaaddress">
-                <title>
-                    USAAddress.java
-                </title>
-<programlisting>
-    ...
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = &quot;USA_Address&quot;, propOrder = {
-    &quot;state&quot;,
-    &quot;zip&quot;
-})
-public class USAAddress
-    extends Address
-{
-
-    @XmlElement(name = &quot;State&quot;)
-    protected String state;
-    @XmlElement(name = &quot;ZIP&quot;)
-    protected int zip;
-
-   /**
-     * Getter and Setter methods.
-     *
-     */
-     ...
-}
-</programlisting>
-            </example>
-            <example id="ref_guide_xmlmapping_canaddress">
-                <title>
-                    CANAddress.java
-                </title>
-<programlisting>
-     ...
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = &quot;CAN_Address&quot;, propOrder = {
-    &quot;province&quot;,
-    &quot;postalCode&quot;
-})
-public class CANAddress
-    extends Address
-{
-
-    @XmlElement(name = &quot;Province&quot;)
-    protected String province;
-    @XmlElement(name = &quot;PostalCode&quot;)
-    protected String postalCode;
-
-   /**
-     * Getter and Setter methods.
-     *
-     */
-     ...
-}
-</programlisting>
-            </example>
-            <example id="ref_guide_xmlmapping_annorder">
-                <title>
-                    Showing annotated Order entity with XML mapping strategy
-                </title>
-<programlisting>
-@Entity
-public class Order {
-    @Id  private into id;
-    @Persistent
-    @Strategy (&quot;org.apache.openjpa.jdbc.meta.strats.XMLValueHandler&quot;)
-    private Address shipAddress;
-    ...
-}
-</programlisting>
-            </example>
-            <example id="ref_guide_xmlmapping_createorder">
-             <title>
-                 Showing creation of Order Entity having shipAddress mapped to XML column
-             </title>
-<programlisting>
-...
-myaddress.ObjectFactory addressFactory = new myaddress.ObjectFactory();
-Customer c1 = new Customer();
-c1.setCid( new Customer.CustomerKey(&quot;USA&quot;, 1) );
-c1.setName(&quot;Harry's Auto&quot;);
-Order o1 = new Order( 850, false, c1);
-USAAddress addr1 = addressFactory.createUSAAddress();
-addr1.setCity(&quot;San Jose&quot;);
-addr1.setState(&quot;CA&quot;);
-addr1.setZIP(new Integer(&quot;95141&quot;));
-addr1.getStreet().add(&quot;12500 Monterey&quot;);
-addr1.setName( c1.getName());
-o1.setShipAddress(addr1);
-em.persist(o1);
-...
-</programlisting>
-            </example>
-            <example id="ref_guide_xmlmapping_ejbquery">
-                <title>
-                    Sample EJB Queries for XML Column mapping
-                </title>
-<programlisting>
-. select o from Order o where o.shipAddress.city = &quot;San Jose&quot; or
-			      o.shipAddress.city = &quot;San Francisco&quot;  (OK)
-
-. select o.shipaAddress from Order o  (OK)
-
-. select o.shipAddress.city from Order o  (INVALID)
-
-. select o from Order o where o.shipAddress.street = &quot;San Jose&quot;  (INVALID multi valued)
-</programlisting>
-            </example>
-        </section>
-        <section id="ref_guide_streamsupport">
-            <title>
-              Stream LOB Support
-            </title>
-              <indexterm zone="ref_guide_streamsupport">
-                  <primary>
-                      stream support
-                  </primary>
-              </indexterm>
-              <indexterm zone="ref_guide_streamsupport">
-                  <primary>
-                      stream lob support
-                  </primary>
-              </indexterm>
-              <para>
-Since the 1.1.0 release Apache OpenJPA added support for Streams. This feature
-makes it possible to stream large amounts of data into and out of fields in
-objects managed by OpenJPA without ever holding all the data in memory at the
-same time.
-              </para>
-              <para>
-To persist a stream, use the 
-<ulink url="../javadoc/org/apache/openjpa/persistence/Persistent.html">
-<classname>org.apache.openjpa.persistence.Persistent</classname></ulink> 
-annotation.
-              </para>
-            <example id="ref_guide_streamsupport_example">
-                <title>
-                    Showing annotated InputStream
-                </title>
-<programlisting>
-@Entity
-public class Employee {
-    ...
-    @Persistent
-    private InputStream photoStream;
-    ...
-} 
-</programlisting>
-            </example>
-        </section>
-    </section>
-    <section id="ref_guide_mapping_jpa_map_keycols">
-        <title>Key Columns</title>
-        <indexterm zone="ref_guide_mapping_jpa_map_keycols">
-            <primary>KeyColumn</primary>
-            <seealso>mapping metadata</seealso>
-        </indexterm>
-        <para>
-        Key columns serve the same role for map keys as the element
-        columns described in
-        <xref linkend="ref_guide_mapping_jpa_coll_cols"/> serve for
-        collection elements.  OpenJPA's
-        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyColumn.html">
-        <classname>org.apache.openjpa.persistence.jdbc.KeyColumn</classname>
-        </ulink> annotation represents a map key.  To map custom
-        multi-column keys, use the
-        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyColumns.html">
-        <classname>org.apache.openjpa.persistence.jdbc.KeyColumns</classname>
-        </ulink> annotation, whose value is an array of <classname>KeyColumn</classname>s.
-        </para>
-        <para>
-        A <classname>KeyColumn</classname> always resides in
-        a container table, so it does not have the <literal>table</literal>
-        property of a standard <classname>Column</classname>.  Otherwise, the
-        <classname>KeyColumn</classname> and standard <classname>Column</classname>
-        annotations are equivalent.  See
-        <xref linkend="jpa_overview_mapping_column"/> in the JPA
-        Overview for a review of the <classname>Column</classname> annotation.
-        </para>
-    </section>
-    <section id="ref_guide_mapping_jpa_map_keyjoincols">
-        <title>Key Join Columns</title>
-        <indexterm zone="ref_guide_mapping_jpa_map_keyjoincols">
-            <primary>KeyJoinColumn</primary>
-            <seealso>mapping metadata</seealso>
-        </indexterm>
-        <para>
-        Key join columns are equivalent to standard JPA
-        join columns, except that they represent a join to a map key entity rather than a direct relation.  You represent
-        a key join column with OpenJPA's
-        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.html">
-        <classname>org.apache.openjpa.persistence.jdbc.KeyJoinColumn</classname></ulink> annotation.  To declare a compound join, enclose an
-        array of <classname>KeyJoinColumn</classname>s in the
-        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.html">
-        <classname>org.apache.openjpa.persistence.jdbc.KeyJoinColumns</classname>
-        </ulink> annotation.
-        </para>
-        <para>
-        A <classname>KeyJoinColumn</classname> always resides in
-        a container table, so it does not have the <literal>table</literal> property
-        of a standard <classname>JoinColumn</classname>.  Like <classname>XJoinColumn</classname>s above,
-        <classname>KeyJoinColumn</classname>s can reference a linked field
-        rather than a static linked column.  Otherwise, the <classname>KeyJoinColumn</classname>
-        and standard <classname>JoinColumn</classname> annotations are equivalent.  See
-        <xref linkend="jpa_overview_mapping_rel"/> in the JPA
-        Overview for a review of the <classname>JoinColumn</classname> annotation.
-        </para>
-    </section>
-    <section id="ref_guide_mapping_jpa_map_embedkey">
-        <title>Key Embedded Mapping</title>
-        <indexterm zone="ref_guide_mapping_jpa_map_embedkey">
-            <primary>KeyEmbeddedMapping</primary>
-            <seealso>mapping metadata</seealso>
-        </indexterm>
-        <para>
-        The
-        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.html">
-        <classname>org.apache.openjpa.persistence.jdbc.KeyEmbeddedMapping</classname>
-        </ulink> annotation allows you to map your map field's embedded
-        key type to your container table.  This annotation has exactly
-        the same properties as the
-        <classname>EmbeddedMapping</classname> annotation described
-        <link linkend="ref_guide_mapping_jpa_embed">above</link>.
-        </para>
-    </section>
-    <section id="ref_guide_mapping_jpa_map_ex">
-        <title>Examples</title>
-        <mediaobject>
-            <imageobject>
-                <!-- PNG image data, 410 x 266 (see README) -->
-                <imagedata fileref="img/string-rel-map.png" width="273px"/>
-            </imageobject>
-        </mediaobject>
-        <para>
-        Map mapping in OpenJPA uses the same principles you saw in
-        collection mapping.  The example below maps the <literal>
-        Article.authors</literal> map according to the diagram above.
-        </para>
-        <example id="ref_guide_mapping_jpa_map_stringrelmap">
-            <title>String Key, Entity Value Map Mapping</title>
-<programlisting>
-package org.mag.pub;
-
-import org.apache.openjpa.persistence.*;
-import org.apache.openjpa.persistence.jdbc.*;
-
-@Entity
-@Table(name="AUTH")
-@DataStoreIdColumn(name="AID" columnDefinition="INTEGER64")
-public class Author {
-    ...
-}
-
-package org.mag;
-
-@Entity
-@Table(name="ART")
-public class Article {
-    @Id private long id;
-
-    @PersistentMap
-    @ContainerTable(name="ART_AUTHS", joinColumns=@XJoinColumn(name="ART_ID"))
-    @KeyColumn(name="LNAME")
-    @ElementJoinColumn(name="AUTH_ID")
-    private Map&lt;String,Author&gt; authors;
-
-    ...
-}
-</programlisting>
-                </example>
-            </section>
-    <section id="ref_guide_mapping_limits">
-        <title>
-            Mapping Limitations
-        </title>
-        <indexterm zone="ref_guide_mapping_limits">
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                limitations
-            </secondary>
-        </indexterm>
-        <para>
-The following sections outline the limitations OpenJPA places on specific
-mapping strategies.
-        </para>
-        <section id="ref_guide_mapping_limits_tpc">
-            <title>
-                Table Per Class
-            </title>
-            <indexterm zone="ref_guide_mapping_limits">
-                <primary>
-                    mapping metadata
-                </primary>
-                <secondary>
-                    limitations
-                </secondary>
-                <tertiary>
-                    table-per-class
-                </tertiary>
-            </indexterm>
-            <para>
-Table-per-class inheritance mapping has the following limitations:
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-You cannot traverse polymorphic relations to non-leaf classes in a
-table-per-class inheritance hierarchy in queries.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-You cannot map a one-sided polymorphic relation to a non-leaf class in a
-table-per-class inheritance hierarchy using an inverse foreign key.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-You cannot use an order column in a polymorphic relation to a non-leaf class in
-a table-per-class inheritance hierarchy mapped with an inverse foreign key.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-Table-per-class hierarchies impose limitations on eager fetching. See
-<xref linkend="ref_guide_perfpack_eager_consider"/>.
-                    </para>
-                </listitem>
-            </itemizedlist>
-            <note>
-                <para>
-Non-polymorphic relations do not suffer from these limitations. You can declare
-a non-polymorphic relation using the extensions described in
-<xref linkend="nonpolymorphic"/>.
-                </para>
-            </note>
-        </section>
-    </section>
-    <section id="ref_guide_mapping_ext">
-        <title>
-            Mapping Extensions
-        </title>
-        <para>
-Mapping extensions allow you to access OpenJPA-specific functionality from your
-mappings. Note that all extensions below are specific to mappings. If you store
-your mappings separately from your persistence metadata, these extensions must
-be specified along with the mapping information, not the persistence metadata
-information.
-        </para>
-        <section id="ref_guide_mapping_ext_cls">
-            <title>
-                Class Extensions
-            </title>
-            <para>
-OpenJPA recognizes the following class extensions.
-            </para>
-            <section id="subclass-fetch-mode">
-                <title>
-                    Subclass Fetch Mode
-                </title>
-                <indexterm zone="subclass-fetch-mode">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        subclass fetch mode
-                    </tertiary>
-                    <seealso>
-                        eager fetching
-                    </seealso>
-                </indexterm>
-                <para>
-This extension specifies how to eagerly fetch subclass state. It overrides the
-global <link linkend="openjpa.jdbc.SubclassFetchMode"><literal>
-openjpa.jdbc.SubclassFetchMode</literal></link> property. Set the JPA
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/SubclassFetchMode.html">
-<classname>org.apache.openjpa.persistence.jdbc.SubclassFetchMode</classname>
-</ulink> annotation to a value from the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchType.html">
-<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname>
-</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or
-<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/>
- for a discussion of eager fetching.
-                </para>
-            </section>
-            <section id="class-strategy">
-                <title>
-                    Strategy
-                </title>
-                <indexterm zone="strategy">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        strategy
-                    </tertiary>
-                    <seealso>
-                        custom mapping
-                    </seealso>
-                </indexterm>
-                <para>
-The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
-class annotation allows you to specify a custom mapping strategy for your class.
-See <xref linkend="ref_guide_mapping_custom"/> for information on custom
-mappings.
-                </para>
-            </section>
-            <section id="discriminator-strategy">
-                <title>
-                    Discriminator Strategy
-                </title>
-                <indexterm zone="strategy">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        discriminator strategy
-                    </tertiary>
-                    <seealso>
-                        custom mapping
-                    </seealso>
-                </indexterm>
-                <para>
-The
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DiscriminatorStrategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.DiscriminatorStrategy</classname>
-</ulink> class annotation allows you to specify a custom discriminator strategy.
-See <xref linkend="ref_guide_mapping_custom"/> for information on custom
-mappings.
-                </para>
-            </section>
-            <section id="version-strategy">
-                <title>
-                    Version Strategy
-                </title>
-                <indexterm zone="strategy">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        version strategy
-                    </tertiary>
-                    <seealso>
-                        custom mapping
-                    </seealso>
-                </indexterm>
-                <para>
-The
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionStrategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.VersionStrategy</classname>
-</ulink> class annotation allows you to specify a custom version strategy. See
-<xref linkend="ref_guide_mapping_custom"/> for information on custom
-mappings.
-                </para>
-            </section>
-        </section>
-        <section id="ref_guide_mapping_ext_field">
-            <title>
-                Field Extensions
-            </title>
-            <para>
-OpenJPA recognizes the following field extensions.
-            </para>
-            <section id="eager-fetch-mode">
-                <title>
-                    Eager Fetch Mode
-                </title>
-                <indexterm zone="eager-fetch-mode">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        eager fetch mode
-                    </tertiary>
-                    <seealso>
-                        eager fetching
-                    </seealso>
-                </indexterm>
-                <para>
-This extension specifies how to eagerly fetch related objects. It overrides the
-global <link linkend="openjpa.jdbc.EagerFetchMode"><literal>
-openjpa.jdbc.EagerFetchMode</literal></link> property. Set the JPA
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchMode.html">
-<classname>org.apache.openjpa.persistence.jdbc.EagerFetchMode</classname>
-</ulink> annotation to a value from the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchType.html">
-<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname>
-</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or
-<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/>
- for a discussion of eager fetching.
-                </para>
-            </section>
-            <section id="nonpolymorphic">
-                <title>
-                    Nonpolymorphic
-                </title>
-                <indexterm zone="nonpolymorphic">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        nonpolymorphic
-                    </tertiary>
-                </indexterm>
-                <para>
-All fields in Java are polymorphic. If you declare a field of type <literal>T
-</literal>, you can assign any subclass of <literal>T</literal> to the field as
-well. This is very convenient, but can make relation traversal very inefficient
-under some inheritance strategies. It can even make querying across the field
-impossible. Often, you know that certain fields do not need to be entirely
-polymorphic. By telling OpenJPA about such fields, you can improve the
-efficiency of your relations.
-                </para>
-                <note>
-                    <para>
-OpenJPA also includes the <literal>type</literal> metadata extension for
-narrowing the declared type of a field. See <xref linkend="type"/>.
-                    </para>
-                </note>
-                <para>
-OpenJPA defines the following extensions for nonpolymorphic values:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Nonpolymorphic.html">
-<classname>org.apache.openjpa.persistence.jdbc.Nonpolymorphic</classname>
-</ulink>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementNonpolymorphic.html">
-<classname>org.apache.openjpa.persistence.jdbc.ElementNonpolymorphic</classname>
-</ulink>
-                        </para>
-                    </listitem>
-                </itemizedlist>
-                <para>
-The value of these extensions is a constant from the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/NonpolymorphicType.html">
-<classname>org.apache.openjpa.persistence.jdbc.NonpolymorphicType</classname>
-</ulink> enumeration. The default value, <literal>EXACT</literal>, indicates
-that the relation will always be of the exact declared type. A value of
-<literal>JOINABLE</literal>, on the other hand, means that the relation might
-be to any joinable subclass of the declared type. This value only excludes
-table-per-class subclasses.
-                </para>
-            </section>
-            <section id="class-criteria">
-                <title>
-                    Class Criteria
-                </title>
-                <indexterm zone="eager-fetch-mode">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        class criteria
-                    </tertiary>
-                    <seealso>
-                        joins
-                    </seealso>
-                </indexterm>
-                <indexterm zone="eager-fetch-mode">
-                    <primary>
-                        joins
-                    </primary>
-                    <secondary>
-                        class criteria
-                    </secondary>
-                </indexterm>
-                <para>
-This family of boolean extensions determines whether OpenJPA will use the
-expected class of related objects as criteria in the SQL it issues to load a
-relation field. Typically, this is not needed. The foreign key values uniquely
-identify the record for the related object. Under some rare mappings, however,
-you may need to consider both foreign key values and the expected class of the
-related object - for example, if you have an inverse relation that shares the
-foreign key with another inverse relation to an object of a different subclass.
-In these cases, set the proper class critera extension to <literal>true
-</literal> to force OpenJPA to append class criteria to its select SQL.
-                </para>
-                <para>
-OpenJPA defines the following class criteria annotations for field relations and
-array or collection element relations, respectively:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ClassCriteria.html">
-<classname>org.apache.openjpa.persistence.jdbc.ClassCriteria</classname></ulink>
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementClassCriteria.html">
-<classname>org.apache.openjpa.persistence.jdbc.ElementClassCriteria</classname>
-</ulink>
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </section>
-            <section id="strategy">
-                <title>
-                    Strategy
-                </title>
-                <indexterm zone="strategy">
-                    <primary>
-                        mapping metadata
-                    </primary>
-                    <secondary>
-                        extensions
-                    </secondary>
-                    <tertiary>
-                        strategy
-                    </tertiary>
-                    <seealso>
-                        custom mapping
-                    </seealso>
-                </indexterm>
-                <para>
-OpenJPA's
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
-extension allows you to specify a custom mapping
-strategy or value handler for a field. See
-<xref linkend="ref_guide_mapping_custom"/> for information on custom
-mappings.
-                </para>
-            </section>
-        </section>
-    </section>
-    <section id="ref_guide_mapping_custom">
-        <title>
-            Custom Mappings
-        </title>
-        <indexterm zone="ref_guide_mapping_custom">
-            <primary>
-                custom mapping
-            </primary>
-        </indexterm>
-        <indexterm>
-            <primary>
-                mapping metadata
-            </primary>
-            <secondary>
-                custom mapping
-            </secondary>
-            <see>
-                custom mapping
-            </see>
-        </indexterm>
-        <para>
-In OpenJPA, you are not limited to the set of standard mappings defined by the
-specification. OpenJPA allows you to define custom class, discriminator,
-version, and field mapping strategies with all the power of OpenJPA's built-in
-strategies.
-        </para>
-        <section id="ref_guide_mapping_custom_class">
-            <title>
-                Custom Class Mapping
-            </title>
-            <para>
-To create a custom class mapping, write an implementation of the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ClassStrategy.html">
-<classname>org.apache.openjpa.jdbc.meta.ClassStrategy</classname></ulink>
-interface. You will probably want to extend one of the existing abstract or
-concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats
-</literal> package.
-            </para>
-            <para>
-The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
-annotation allows you to declare a custom class mapping strategy in JPA mapping
-metadata. Set the value of the annotation to the full class name of your custom
-strategy. You can configure your strategy class' bean properties using
-OpenJPA's plugin syntax, detailed in <xref linkend="ref_guide_conf_plugins"/>.
-            </para>
-        </section>
-        <section id="ref_guide_mapping_custom_versdiscrim">
-            <title>
-                Custom Discriminator and Version Strategies
-            </title>
-            <para>
-To define a custom discriminator or version strategy, implement the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.html">
-<classname>org.apache.openjpa.jdbc.meta.DiscriminatorStrategy</classname>
-</ulink> or
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/VersionStrategy.html">
-<classname>org.apache.openjpa.jdbc.meta.VersionStrategy</classname></ulink>
-interface, respectively. You might extend one of the existing abstract or
-concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats
-</literal> package.
-            </para>
-            <para>
-OpenJPA includes the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DiscriminatorStrategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.DiscriminatorStrategy</classname>
-</ulink> and
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionStrategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.VersionStrategy</classname>
-</ulink> class annotations for declaring a custom discriminator or version
-strategy in JPA mapping metadata. Set the string value of these annotations to
-the full class name of your implementation, or to the class name or alias of an
-existing OpenJPA implementation.
-            </para>
-            <para>
-As with custom class mappings, you can configure your strategy class' bean
-properties using OpenJPA's plugin syntax, detailed in
-<xref linkend="ref_guide_conf_plugins"/>.
-            </para>
-        </section>
-        <section id="ref_guide_mapping_custom_field">
-            <title>
-                Custom Field Mapping
-            </title>
-            <indexterm zone="ref_guide_mapping_custom_field">
-                <primary>
-                    custom mapping
-                </primary>
-                <secondary>
-                    field mapping
-                </secondary>
-            </indexterm>
-            <para>
-While custom class, discriminator, and version mapping can be useful, custom
-field mappings are far more common. OpenJPA offers two types of custom field
-mappings: value handlers, and full custom field strategies. The following
-sections examine each.
-            </para>
-            <section id="ref_guide_mapping_custom_vhandler">
-                <title>
-                    Value Handlers
-                </title>
-                <indexterm zone="ref_guide_mapping_custom_fieldstrat">
-                    <primary>
-                        custom mapping
-                    </primary>
-                    <secondary>
-                        field mapping
-                    </secondary>
-                    <tertiary>
-                        value handler
-                    </tertiary>
-                </indexterm>
-                <para>
-Value handlers make it trivial to map any type that you can break down into one
-or more simple values. All value handlers implement the <classname>
-org.apache.openjpa.jdbc.meta.ValueHandler</classname> interface; see its
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ValueHandler.html"> Javadoc
-</ulink> for details.  Also, examine the built-in handlers in the <filename>
-src/openjpa/jdbc/meta/strats</filename> directory of your OpenJPA source
-distribution.  Use these functional implementations as examples when you
-create your own value handlers.
-                </para>
-            </section>
-            <section id="ref_guide_mapping_custom_fieldstrat">
-                <title>
-                    Field Strategies
-                </title>
-                <indexterm zone="ref_guide_mapping_custom_fieldstrat">
-                    <primary>
-                        custom mapping
-                    </primary>
-                    <secondary>
-                        field mapping
-                    </secondary>
-                    <tertiary>
-                        field strategy
-                    </tertiary>
-                </indexterm>
-                <para>
-OpenJPA interacts with persistent fields through the
-<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/FieldStrategy"><classname>
-org.apache.openjpa.jdbc.meta.FieldStrategy</classname></ulink> interface. You
-can implement this interface yourself to create a custom field strategy, or
-extend one of the existing abstract or concrete strategies in the <literal>
-org.apache.openjpa.jdbc.meta.strats</literal> package. Creating a custom field
-strategy is more difficult than writing a custom value handler, but gives you
-more freedom in how you interact with the database.
-                </para>
-            </section>
-            <section id="ref_guide_mapping_custom_field_conf">
-                <title>
-                    Configuration
-                </title>
-                <indexterm zone="ref_guide_mapping_custom_field_conf">
-                    <primary>
-                        custom mapping
-                    </primary>
-                    <secondary>
-                        field mapping
-                    </secondary>
-                    <tertiary>
-                        configuration
-                    </tertiary>
-                </indexterm>
-                <para>
-OpenJPA gives you two ways to configure your custom field mappings. The
-<literal>FieldStrategies</literal> property of the built-in <classname>
-MappingDefaults</classname> implementations allows you to globally associate
-field types with their corresponding custom value handler or strategy. OpenJPA
-will automatically use your custom strategies when it encounters a field of the
-associated type. OpenJPA will use your custom value handlers whenever it
-encounters a field of the associated type.
-<xref linkend="ref_guide_mapping_defaults"/> described mapping
-defaults in detail.
-                </para>
-                <para>
-Your other option is to explicitly install a custom value handler or strategy on
-a particular field. To do so, specify the full name of your implementation class
-in the proper mapping metadata extension. OpenJPA includes the
-<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
-<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
-annotation. You can configure the named strategy or handler's bean
-properties in these extensions using OpenJPA's plugin format (see
-<xref linkend="ref_guide_conf_plugins"/>).
-                </para>
-            </section>
-        </section>
-    </section>
-    <section id="ref_guide_orphan">
-        <title>
-            Orphaned Keys
-        </title>
-        <para>
-Unless you apply database foreign key constraints extensively, it is possible to
-end up with orphaned keys in your database. For example, suppose <classname>
-Magazine</classname><literal>m</literal> has a reference to <classname>Article
-</classname><literal>a</literal>. If you delete <literal>a</literal> without
-nulling <literal>m</literal>'s reference, <literal>m</literal>'s database
-record will wind up with an orphaned key to the non-existent <literal>a
-</literal> record.
-        </para>
-        <note>
-            <para>
-One way of avoiding orphaned keys is to use <emphasis>dependent</emphasis>
-fields.
-            </para>
-        </note>
-        <para>
-OpenJPA's <link linkend="openjpa.OrphanedKeyAction"><literal>
-openjpa.OrphanedKeyAction</literal></link> configuration property controls what
-action to take when OpenJPA encounters an orphaned key. You can set this plugin
-string (see <xref linkend="ref_guide_conf_plugins"/>) to a custom
-implementation of the
-<ulink url="../javadoc/org/apache/openjpa/event/OrphanedKeyAction.html">
-<classname> org.apache.openjpa.event.OrphanedKeyAction</classname></ulink>
-interface, or use one of the built-in options:
-        </para>
-        <itemizedlist>
-            <listitem>
-                <para>
-<literal>log</literal>: This is the default setting. This option logs a message
-for each orphaned key. It is an alias for the
-<ulink url="../javadoc/org/apache/openjpa/event/LogOrphanedKeyAction.html">
-<classname>org.apache.openjpa.event.LogOrphanedKeyAction</classname></ulink>
-class, which has the following additional properties:
-                </para>
-                <itemizedlist>
-                    <listitem>
-                        <para>
-<literal>Channel</literal>: The channel to log to. Defaults to <literal>
-openjpa.Runtime</literal>.
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-<literal>Level</literal>: The level to log at. Defaults to <literal>WARN
-</literal>.
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </listitem>
-            <listitem>
-                <para>
-<literal>exception</literal>: Throw an <classname>
-EntityNotFoundException</classname> when OpenJPA discovers an
-orphaned key. This is an alias for the
-<ulink url="../javadoc/org/apache/openjpa/event/ExceptionOrphanedKeyAction.html">
-<classname>org.apache.openjpa.event.ExceptionOrphanedKeyAction</classname>
-</ulink> class.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-<literal>none</literal>: Ignore orphaned keys. This is an alias for the
-<ulink url="../javadoc/org/apache/openjpa/event/NoneOrphanedKeyAction.html">
-<classname>org.apache.openjpa.event.NoneOrphanedKeyAction</classname></ulink>
-class.
-                </para>
-            </listitem>
-        </itemizedlist>
-        <example id="ref_guide_orphan_logex">
-            <title>
-                Custom Logging Orphaned Keys
-            </title>
-<programlisting>
-&lt;property name="openjpa.OrphanedKeyAction" value="log(Channel=Orphans, Level=DEBUG)"/&gt;
-</programlisting>
-        </example>
-    </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<chapter id="ref_guide_mapping">
+    <title>
+        Mapping
+    </title>
+    <indexterm zone="ref_guide_mapping">
+        <primary>
+            mapping metadata
+        </primary>
+    </indexterm>
+    <para>
+The JPA Overview's <xref linkend="jpa_overview_mapping"/> explains
+object-relational mapping under JPA. This chapter reviews the mapping utilities
+OpenJPA provides and examines OpenJPA features that go beyond the JPA
+specification.
+    </para>
+    <section id="ref_guide_mapping_mappingtool">
+        <title>
+            Forward Mapping
+        </title>
+        <indexterm zone="ref_guide_mapping_mappingtool">
+            <primary>
+                forward mapping
+            </primary>
+        </indexterm>
+        <indexterm zone="ref_guide_mapping_mappingtool">
+            <primary>
+                mapping tool
+            </primary>
+            <seealso>
+                forward mapping
+            </seealso>
+        </indexterm>
+        <indexterm>
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                forward mapping
+            </secondary>
+            <see>
+                forward mapping
+            </see>
+        </indexterm>
+        <para>
+<emphasis>Forward mapping</emphasis> is the process of creating mappings and
+their corresponding database schema from your object model. OpenJPA supports
+forward mapping through the <emphasis>mapping tool</emphasis>. The next section
+presents several common mapping tool use cases. You can invoke the tool through
+its Java class,
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingTool"><classname>
+org.apache.openjpa.jdbc.meta.MappingTool</classname></ulink>.
+        </para>
+        <note>
+            <para>
+<xref linkend="ref_guide_integration_mappingtool"/> describes the mapping
+tool Ant task.
+            </para>
+        </note>
+        <example id="ref_guide_mapping_mappingtool_typical">
+            <title>
+                Using the Mapping Tool
+            </title>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java
+</programlisting>
+        </example>
+        <para>
+In addition to the universal flags of the
+<link linkend="ref_guide_conf_devtools">configuration framework</link>, the
+mapping tool accepts the following command line arguments:
+        </para>
+        <itemizedlist>
+            <listitem>
+                <para>
+<literal>-schemaAction/-sa &lt;add | refresh | drop | build | retain | reflect | createDB | dropDB | import | export | none&gt;
+</literal>: The action to take on the schema. These options correspond to the
+same-named actions on the schema tool described in
+<xref linkend="ref_guide_schema_schematool"/>. Actions can be composed in a
+comma-separated list. Unless you are running the mapping tool on all of
+your persistent types at once or dropping a mapping, we strongly
+recommend you use the default <literal>add</literal> action or the
+<literal>build</literal> action. Otherwise you may end up inadvertently
+dropping schema components that are used by classes you are not
+currently running the tool over.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-schemaFile/-sf &lt;stdout | output file&gt;</literal>: Use this
+option to write the planned schema to an XML document rather than modify the
+database. The document can then be manipulated and committed to the database
+with the <link linkend="ref_guide_schema_schematool"> schema tool</link>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-sqlFile/-sql &lt;stdout | output file&gt;</literal>: Use this option
+to write the planned schema modifications to a SQL script rather than modify the
+database. Combine this with a <literal>schemaAction</literal> of <literal>build
+</literal> to generate a script that recreates the schema for the current
+mappings, even if the schema already exists.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-dropTables/-dt &lt;true/t | false/f&gt;</literal>: Corresponds to the
+same-named option on the schema tool.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-dropSequences/-dsq &lt;true/t | false/f&gt;</literal>: Corresponds to
+the same-named option on the schema tool.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-openjpaTables/-ot &lt;true/t | false/f&gt;</literal>: Corresponds to
+the same-named option on the schema tool.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-ignoreErrors/-i &lt;true/t | false/f&gt;</literal>: Corresponds to
+the same-named option on the schema tool.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-schemas/-s &lt;schema and table names&gt;</literal>: Corresponds to
+the same-named option on the schema tool. This option is ignored if <literal>
+readSchema</literal> is not set to <literal>true</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-readSchema/-rs &lt;true/t | false/f&gt;</literal>: Set this option to
+<literal>true</literal> to read the entire existing schema when the tool runs.
+Reading the existing schema ensures that OpenJPA does not generate any mappings
+that use table, index, primary key, or foreign key names that conflict with
+existing names. Depending on the JDBC driver, though, it can be a slow process
+for large schemas.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-primaryKeys/-pk &lt;true/t | false/f&gt;</literal>: Whether to read
+and manipulate primary key information of existing tables. Defaults to false.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-foreignKeys/-fk &lt;true/t | false/f&gt;</literal>: Whether to read
+and manipulate foreign key information of existing tables. Defaults to false.
+This means that to add any new foreign keys to a class that has already been
+mapped, you must explicitly set this flag to true.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-indexes/-ix &lt;true/t | false/f&gt;</literal>: Whether to read and
+manipulate index information of existing tables. Defaults to false. This means
+that to add any new indexes to a class that has already been mapped once, you
+must explicitly set this flag to true.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-sequences/-sq &lt;true/t | false/f&gt;</literal>: Whether to
+manipulate sequences. Defaults to true.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>-meta/-m &lt;true/t | false/f&gt;</literal>: Whether the given action
+applies to metadata rather than or in addition to mappings.
+                </para>
+            </listitem>
+        </itemizedlist>
+        <para>
+The mapping tool also uses an <literal>-action/-a</literal> argument to specify
+the action to take on each class. The available actions are:
+        </para>
+        <itemizedlist>
+            <listitem>
+                <para>
+<literal>buildSchema</literal>: This is the default action. It
+makes the database schema match your existing mappings. If your provided
+mappings conflict with your class definitions, OpenJPA will fail with an
+informative exception.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>validate</literal>: Ensure that the mappings for the given classes are
+valid and that they match the schema. No mappings or tables will be changed. An
+exception is thrown if any mappings are invalid.
+                </para>
+            </listitem>
+        </itemizedlist>
+        <para>
+Each additional argument to the tool should be one of:
+        </para>
+        <itemizedlist>
+            <listitem>
+                <para>
+The full name of a persistent class.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+The .java file for a persistent class.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+The <filename>.class</filename> file of a persistent class.
+                </para>
+            </listitem>
+        </itemizedlist>
+        <para>
+If you do not supply any arguments to the mapping tool, it will run on the
+classes in your persistent classes list (see
+<xref linkend="ref_guide_pc_pcclasses"/>).
+        </para>
+        <para>
+The mappings generated by the mapping tool are stored by the system <emphasis>
+mapping factory</emphasis>. <xref linkend="ref_guide_mapping_factory"/>
+discusses your mapping factory options.
+        </para>
+        <section id="ref_guide_mapping_mappingtool_examples">
+            <title>
+                Using the Mapping Tool
+            </title>
+            <indexterm zone="ref_guide_mapping_mappingtool_examples">
+                <primary>
+                    mapping tool
+                </primary>
+                <secondary>
+                    use cases
+                </secondary>
+            </indexterm>
+            <para>
+The JPA specification defines a comprehensive set of defaults for missing
+mapping information. Thus, forward mapping in JPA is virtually automatic. After
+using the mapping annotations covered in <xref linkend="jpa_overview_mapping"/>
+of the JPA Overview to override any unsatisfactory defaults, run the
+mapping tool on your persistent classes.  The default <literal>buildSchema
+</literal> mapping tool action manipulates the database schema to
+match your mappings. It fails if any of your mappings don't match your object
+model.
+            </para>
+            <example id="ref_guide_mapping_mappingtool_buildschema">
+                <title>
+                    Creating the Relational Schema from Mappings
+                </title>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java
+</programlisting>
+            </example>
+            <para>
+To drop the schema for a persistent class, set the mapping tool's <literal>
+schemaAction</literal> to <literal>drop</literal>.
+            </para>
+            <example id="ref_guide_mapping_mappingtool_cleanup_tables">
+                <title>
+                    Refreshing entire schema and cleaning out tables
+                </title>
+	            <indexterm zone="ref_guide_mapping_mappingtool_cleanup_tables">
+    	            <primary>
+        	            testing
+            	    </primary>
+                	<secondary>
+                    	Rebuild mappings and clean tables
+	                </secondary>
+    	        </indexterm>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction add,deleteTableContents
+</programlisting>
+            </example>
+            <example id="ref_guide_mapping_mappingtool_dropschema">
+                <title>
+                    Dropping Mappings and Association Schema
+                </title>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction drop Magazine.java
+</programlisting>
+            </example>
+        </section>
+        <section id="ref_guide_ddl_examples">
+            <title>
+                Generating DDL SQL
+            </title>
+            <indexterm zone="ref_guide_ddl_examples">
+                <primary>
+                    mapping tool
+                </primary>
+                <secondary>
+                    DDL generation
+                </secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_ddl_examples">
+                <primary>
+                    DDL
+                </primary>
+                <secondary>
+                    with mapping tool
+                </secondary>
+            </indexterm>
+            <para>
+The examples below show how to use the mapping tool to generate DDL SQL scripts,
+rather than modifying the database directly.
+            </para>
+            <example id="ref_guid_mapping_ddl_full_ddl">
+                <title>
+                    Create DDL for Current Mappings
+                </title>
+                <para>
+This example uses your existing mappings to determine the needed schema, then
+writes the SQL to create that schema to <filename>create.sql</filename>.
+                </para>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction build -sql create.sql Magazine.java
+</programlisting>
+            </example>
+            <example id="ref_guid_mapping_ddl_part_ddl">
+                <title>
+                    Create DDL to Update Database for Current Mappings
+                </title>
+                <para>
+This example uses your existing mappings to determine the needed schema. It then
+writes the SQL to add any missing tables and columns to the current schema to
+<filename>update.sql</filename>.
+                </para>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool -sql update.sql Magazine.java
+</programlisting>
+            </example>
+        </section>
+        <section id="ref_guide_mapping_synch">
+            <title>
+                Runtime Forward Mapping
+            </title>
+            <indexterm zone="ref_guide_mapping_synch">
+                <primary>
+                    forward mapping
+                </primary>
+                <secondary>
+                    automatic runtime mapping
+                </secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_synch">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    automatic runtime mapping
+                </secondary>
+            </indexterm>
+            <para>
+You can configure OpenJPA to automatically run the mapping tool at runtime
+through the <link linkend="openjpa.jdbc.SynchronizeMappings"><literal>
+openjpa.jdbc.SynchronizeMappings</literal></link> configuration property. Using
+this property saves you the trouble of running the mapping tool manually, and is
+meant for use during rapid test/debug cycles.
+            </para>
+            <para>
+In order to enable automatic runtime mapping, you must first list all your
+persistent classes as described in <xref linkend="ref_guide_pc_pcclasses"/>.
+            </para>
+            <para>
+OpenJPA will run the mapping tool on these classes when your application obtains
+its first <classname>EntityManager</classname>.
+            </para>
+            <para>
+The <literal>openjpa.jdbc.SynchronizeMappings</literal> property is a plugin
+string (see <xref linkend="ref_guide_conf_plugins"/>) where the class
+name is the mapping tool action to invoke, and the properties are the
+<classname>MappingTool</classname> class' JavaBean properties. These properties
+correspond go the long versions of the tool's command line flags.
+            </para>
+            <example id="ref_guide_mapping_synchex">
+                <title>
+                    Configuring Runtime Forward Mapping
+                </title>
+<programlisting>
+&lt;property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/&gt;
+</programlisting>
+                <para>
+The setting above corresponds to running the following command:
+                </para>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool -action buildSchema -foreignKeys true
+</programlisting>
+            </example>
+        </section>
+    </section>
+    <section id="ref_guide_pc_reverse">
+        <title>
+            Reverse Mapping
+        </title>
+        <indexterm zone="ref_guide_pc_reverse">
+            <primary>
+                reverse mapping
+            </primary>
+        </indexterm>
+        <indexterm zone="ref_guide_pc_reverse">
+            <primary>
+                reverse mapping tool
+            </primary>
+            <seealso>
+                reverse mapping
+            </seealso>
+        </indexterm>
+        <indexterm>
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                reverse mapping
+            </secondary>
+            <see>
+                reverse mapping
+            </see>
+        </indexterm>
+        <para>
+OpenJPA includes a <emphasis>reverse mapping</emphasis> tool for generating
+persistent class definitions, complete with metadata, from an existing database
+schema. You do not have to use the reverse mapping tool to access an existing
+schema; you are free to write your classes and mappings yourself, as described
+in <xref linkend="ref_guide_mapping_middle"/>. The reverse mapping tool,
+however, can give you an excellent starting point from which to grow your
+persistent classes.
+        </para>
+        <para>
+To use the reverse mapping tool, follow the steps below:
+        </para>
+        <orderedlist>
+            <listitem>
+                <para>
+Use the <link linkend="ref_guide_schema_schematool"> schema tool</link> to
+export your current schema to an XML schema file. You can skip this step and the
+next step if you want to run the reverse mapping tool directly against the
+database.
+                </para>
+                <example id="ref_guide_pc_reverse_schemagen">
+                    <title>
+                        Reflection with the Schema Tool
+                    </title>
+<programlisting>
+java org.apache.openjpa.jdbc.schema.SchemaTool -a reflect -f schema.xml
+</programlisting>
+                </example>
+            </listitem>
+            <listitem>
+                <para>
+Examine the generated schema file. JDBC drivers often provide incomplete or
+faulty metadata, in which case the file will not exactly match the actual
+schema. Alter the XML file to match the true schema. The XML format for the
+schema file is described in <xref linkend="ref_guide_schema_xml"/>.
+                </para>
+                <para>
+After fixing any errors in the schema file, modify the XML to include foreign
+keys between all relations. The schema tool will have automatically detected
+existing foreign key constraints; many schemas, however, do not employ database
+foreign keys for every relation. By manually adding any missing foreign keys,
+you will give the reverse mapping tool the information it needs to generate the
+proper relations between the persistent classes it creates.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+Run the reverse mapping tool on the finished schema file. If you do not supply
+the schema file to reverse map, the tool will run directly against the schema in
+the database. The tool can be run via its Java class,
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseMappingTool">
+<classname>org.apache.openjpa.jdbc.meta.ReverseMappingTool</classname></ulink>.
+                </para>
+                <example id="ref_guide_pc_reverse_reversemappingtool">
+                    <title>
+                        Using the Reverse Mapping Tool
+                    </title>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -d ~/src -cp customizer.properties schema.xml
+</programlisting>
+                </example>
+                <para>
+In addition to OpenJPA's <link linkend="ref_guide_conf_devtools">standard
+configuration flags</link>, including
+<link linkend="ref_guide_conf_devtools_format">code formatting options</link>,
+the reverse mapping tool recognizes the following command line arguments:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>-schemas/-s &lt;schema and table names&gt;</literal>: A
+comma-separated list of schema and table names to reverse map, if no XML schema
+file is supplied. Each element of the list must follow the naming conventions
+for the <literal>openjpa.jdbc.Schemas</literal> property described in
+<xref linkend="ref_guide_schema_info_list"/>. In fact, if this flag is
+omitted, it defaults to the value of the <literal>Schemas</literal> property. If
+the <literal>Schemas</literal> property is not defined, all schemas will be
+reverse-mapped.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-package/-pkg &lt;package name&gt;</literal>: The package name of the
+generated classes. If no package name is given, the generated code will not
+contain package declarations.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-directory/-d &lt;output directory&gt;</literal>: All generated code
+and metadata will be written to the directory at this path. If the path does not
+match the package of a class, the package structure will be created beneath this
+directory. Defaults to the current directory.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-metadata/-md &lt;class | package | none&gt;</literal>: Specify the
+level the metadata should be generated at. Defaults to generating a single
+package-level metadata file. Set to <literal>none</literal> to disable orm.xml
+generation.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-annotations/-ann &lt;true/t | false/f&gt;</literal>: Set to true to
+generate JPA annotations in generated java classes.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-accessType/-access &lt;field | property&gt;</literal>: Change access
+type for generated annotations. Defaults to field access.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-useSchemaName/-sn &lt;true/t | false/f&gt;</literal>: Set this flag
+to <literal>true</literal> to include the schema as well as table name in the
+name of each generated class. This can be useful when dealing with multiple
+schemas with same-named tables.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-useForeignKeyName/-fkn &lt;true/t | false/f&gt;</literal>: Set this
+flag to <literal>true</literal> if you would like field names for relations to
+be based on the database foreign key name. By default, relation field names are
+derived from the name of the related class.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-nullableAsObject/-no &lt;true/t | false/f&gt;</literal>: By default,
+all non-foreign key columns are mapped to primitives. Set this flag to <literal>
+true</literal> to generate primitive wrapper fields instead for columns that
+allow null values.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-blobAsObject/-bo &lt;true/t | false/f&gt;</literal>: By default, all
+binary columns are mapped to <classname>byte[]</classname> fields. Set this flag
+to <literal>true</literal> to map them to <classname>Object</classname> fields
+instead. Note that when mapped this way, the column is presumed to contain a
+serialized Java object.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-primaryKeyOnJoin/-pkj &lt;true/t | false/f&gt;</literal>: The
+standard reverse mapping tool behavior is to map all tables with primary keys to
+persistent classes. If your schema has primary keys on many-many join tables as
+well, set this flag to <literal>true</literal> to avoid creating classes for
+those tables.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-inverseRelations/-ir &lt;true/t | false/f&gt;</literal>: Set to
+<literal>false</literal> to prevent the creation of inverse 1-many/1-1 relations
+for every many-1/1-1 relation detected.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-useGenericCollections/-gc &lt;true/t | false/f&gt;</literal>: Set to
+true to use generic collections on OneToMany and ManyToMany relations (requires
+JDK 1.5 or higher).
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-useDatastoreIdentity/-ds &lt;true/t | false/f&gt;</literal>: Set to
+<literal>true</literal> to use datastore identity for tables that have single
+numeric primary key columns. The tool typically uses application identity for
+all generated classes.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-useBuiltinIdentityClass/-bic &lt;true/t | false/f&gt;</literal>: Set
+to <literal>false</literal> to prevent the tool from using built-in application
+identity classes when possible. This will force the tool to to create custom
+application identity classes even when there is only one primary key column.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-innerIdentityClasses/-inn &lt;true/t | false/f&gt;</literal>: Set to
+<literal>true</literal> to have any generated application identity classes be
+created as static inner classes within the persistent classes. Defaults to
+<literal>false</literal>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-identityClassSuffix/-is &lt;suffix&gt;</literal>: Suffix to append to
+class names to form application identity class names, or for inner identity
+classes, the inner class name. Defaults to <literal>Id</literal>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-typeMap/-typ &lt;type mapping&gt;</literal>: A string that specifies
+the default Java classes to generate for each SQL type that is seen in the
+schema. The format is <literal> SQLTYPE1=JavaClass1,SQLTYPE2=JavaClass2
+</literal>. The SQL type name first looks for a customization based on <literal>
+SQLTYPE(SIZE,PRECISION)</literal>, then <literal>SQLTYPE(SIZE)</literal>, then
+<literal>SQLTYPE(SIZE,PRECISION)</literal>. So if a column whose type name is
+<literal>CHAR</literal> is found, it will first look for the <literal>
+CHAR(50,0)</literal> type name specification, then it will look for <literal>
+CHAR(50)</literal>, and finally it will just look for <literal>CHAR</literal>.
+For example, to generate a char array for every <literal>CHAR</literal> column
+whose size is exactly 50, and to generate a <literal>short</literal> for every
+type name of <literal>INTEGER</literal>, you might specify: <literal>
+CHAR(50)=char[],INTEGER=short</literal>. Note that since various databases
+report different type names differently, one database's type name specification
+might not work for another database. Enable <literal>TRACE</literal> level
+logging on the <literal>MetaData</literal> channel to track which type names
+OpenJPA is examining.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-customizerClass/-cc &lt;class name&gt;</literal>: The full class name
+of a
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html">
+<classname>org.apache.openjpa.jdbc.meta.ReverseCustomizer</classname></ulink>
+customization plugin. If you do not specify a reverse customizer of your own,
+the system defaults to a
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html">
+<classname>PropertiesReverseCustomizer</classname></ulink>. This customizer
+allows you to specify simple customization options in the properties file given
+with the <literal>-customizerProperties</literal> flag below. We present the
+available property keys <link linkend="ref_guide_pc_reverse_custom">
+below</link>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-customizerProperties/-cp &lt;properties file or resource&gt;</literal>
+: The path or resource name of a properties file to pass to the reverse
+customizer on initialization.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>-customizer./-c.&lt;property name&gt; &lt;property value&gt;</literal>
+: The given property name will be matched with the corresponding Java bean
+property in the specified reverse customizer, and set to the given value.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+                <para>
+Running the tool will generate <filename>.java</filename> files for each
+generated class (and its application identity class, if applicable), along with
+JPA annotations (if enabled by setting <literal>-annotations true</literal>),
+or an <filename>orm.xml</filename> file (if not disabled with <literal>
+-metadata none</literal>) containing the corresponding persistence metadata.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+Examine the generated class, metadata, and mapping information, and modify it as
+necessary. Remember that the reverse mapping tool only provides a starting
+point, and you are free to make whatever modifications you like to the code it
+generates.
+                </para>
+                <para>
+After you are satisfied with the generated classes and their mappings, you
+should first compile the classes with <literal>javac</literal>, <literal>
+jikes</literal>, or your favorite Java compiler. Make sure the classes are
+located in the directory corresponding to the <literal>-package</literal> flag
+you gave the reverse mapping tool.  Next, if you have generated an <filename>
+orm.xml</filename>, move that file to a <filename>META-INF</filename> directory
+within a directory in your classpath.  Finally, enhance the classes
+if necessary (see <xref linkend="ref_guide_pc_enhance"/>).
+                </para>
+            </listitem>
+        </orderedlist>
+        <para>
+Your persistent classes are now ready to access your existing schema.
+        </para>
+        <section id="ref_guide_pc_reverse_custom">
+            <title>
+                Customizing Reverse Mapping
+            </title>
+            <para>
+The <classname>org.apache.openjpa.jdbc.meta.ReverseCustomizer</classname> plugin
+interface allows you to customze the reverse mapping process. See the class
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html">
+Javadoc</ulink> for details on the hooks that this interface provides. Specify
+the concrete plugin implementation to use with the <literal>
+-customizerClass/-cc</literal> command-line flag, described in the preceding
+section.
+            </para>
+            <para>
+By default, the reverse mapping tool uses a
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html">
+<classname>org.apache.openjpa.jdbc.meta.PropertiesReverseCustomizer</classname>
+</ulink>. This customizer allows you to perform relatively simple
+customizations through the properties file named with the <literal>
+-customizerProperties</literal> tool flag. The customizer recognizes the
+following properties:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+<literal>&lt;table name&gt;.table-type &lt;type&gt;</literal>: Override the
+default type of the table with name <literal>&lt;table name&gt;</literal>.
+Legal values are:
+                    </para>
+                    <itemizedlist>
+                        <listitem>
+                            <para>
+<literal>base</literal>: Primary table for a base class.
+                            </para>
+                        </listitem>
+                        <listitem>
+                            <para>
+<literal>secondary</literal>: Secondary table for a class. The table must have
+a foreign key joining to a class table.
+                            </para>
+                        </listitem>
+                        <listitem>
+                            <para>
+<literal>secondary-outer</literal>: Outer-joined secondary table for a class.
+The table must have a foreign key joining to a class table.
+                            </para>
+                        </listitem>
+                        <listitem>
+                            <para>
+<literal>association</literal>: Association table. The table must have two
+foreign keys to class tables.
+                            </para>
+                        </listitem>
+                        <listitem>
+                            <para>
+<literal>collection</literal>: Collection table. The table must have one
+foreign key to a class table and one data column.
+                            </para>
+                        </listitem>
+                        <listitem>
+                            <para>
+<literal>subclass</literal>: A joined subclass table. The table must have a
+foreign key to the superclass' table.
+                            </para>
+                        </listitem>
+                        <listitem>
+                            <para>
+<literal>none</literal>: The table should not be reverse-mapped.
+                            </para>
+                        </listitem>
+                    </itemizedlist>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;class name&gt;.rename &lt;new class name&gt;</literal>: Override
+the given tool-generated name <literal>&lt;class name&gt;</literal> with a new
+value. Use full class names, including package. You are free to rename a class
+to a new package. Specify a value of <literal>none</literal> to reject the class
+and leave the corresponding table unmapped.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;table name&gt;.class-name &lt;new class name&gt;</literal>: Assign
+the given fully-qualified class name to the type created from the table with
+name <literal>&lt;table name&gt;</literal>. Use a value of <literal>none
+</literal> to prevent reverse mapping this table. This property can be used in
+place of the <literal>rename</literal> property.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;class name&gt;.identity &lt;datastore | builtin | identity class
+name&gt;</literal>: Set this property to <literal>datastore</literal> to use
+datastore identity for the class <literal>&lt;class name&gt;</literal>,
+<literal>builtin</literal> to use a built-in identity class, or the desired
+application identity class name. Give full class names, including package. You
+are free to change the package of the identity class this way. If the persistent
+class has been renamed, use the new class name for this property key. Remember
+that datastore identity requires a table with a single numeric primary key
+column, and built-in identity requires a single primary key column of any type.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;class name&gt;.&lt;field name&gt;.rename &lt;new field name&gt;
+</literal>: Override the tool-generated <literal>&lt;field name&gt;</literal> in
+class <literal>&lt;class name&gt;</literal> with the given name. Use the field
+owner's full class name in the property key. If the field owner's class was
+renamed, use the new class name. The property value should be the new field
+name, without the preceding class name. Use a value of <literal>none</literal>
+to reject the generated mapping and remove the field from the class.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;table name&gt;.&lt;column name&gt;.field-name &lt;new field
+name&gt;</literal>: Set the generated field name for the <literal>&lt;table
+name&gt;</literal> table's <literal>&lt;column name&gt;</literal> column. If
+this is a multi-column mapping, any of the columns can be used. Use a value of
+<literal>none</literal> to prevent the column and its associated columns from
+being reverse-mapped.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;class name&gt;.&lt;field name&gt;.type &lt;field type&gt;</literal>
+: The type to give the named field. Use full class names. If the field or the
+field's owner class has been renamed, use the new name.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>&lt;class name&gt;.&lt;field name&gt;.value</literal>: The initial
+value for the named field. The given string will be placed as-is in the
+generated Java code, so be sure it is valid Java. If the field or the field's
+owner class has been renamed, use the new name.
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <para>
+All property keys are optional; if not specified, the customizer keeps the
+default value generated by the reverse mapping tool.
+            </para>
+            <example id="ref_guide_pc_reverse_custom_ex">
+                <title>
+                    Customizing Reverse Mapping with Properties
+                </title>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -cp custom.properties schema.xml
+</programlisting>
+                <para>
+Example <filename>custom.properties</filename>:
+                </para>
+<programlisting>
+com.xyz.TblMagazine.rename:             com.xyz.Magazine
+com.xyz.TblArticle.rename:              com.xyz.Article
+com.xyz.TblPubCompany.rename:           com.xyz.pub.Company
+com.xyz.TblSysInfo.rename:              none
+
+com.xyz.Magazine.allArticles.rename:    articles
+com.xyz.Magazine.articles.type:         java.util.Collection
+com.xyz.Magazine.articles.value:        new TreeSet()
+com.xyz.Magazine.identity:              datastore
+
+com.xyz.pub.Company.identity:           com.xyz.pub.CompanyId
+</programlisting>
+            </example>
+        </section>
+    </section>
+    <section id="ref_guide_mapping_middle">
+        <title>
+            Meet-in-the-Middle Mapping
+        </title>
+        <indexterm zone="ref_guide_pc_reverse">
+            <primary>
+                meet-in-the-middle mapping
+            </primary>
+        </indexterm>
+        <indexterm zone="ref_guide_pc_reverse">
+            <primary>
+                reverse mapping tool
+            </primary>
+            <seealso>
+                reverse mapping
+            </seealso>
+        </indexterm>
+        <indexterm>
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                meet-in-the-middle mapping
+            </secondary>
+            <see>
+                meet-in-the-middle mapping
+            </see>
+        </indexterm>
+        <para>
+In the <emphasis>meet-in-the-middle</emphasis>
+mapping approach, you control both the relational model and the object model. It
+is up to you to define the mappings between these models.  The mapping
+tool's <literal>validate</literal> action is useful to meet-in-the-middle
+mappers. This action verifies that the mapping information for a class matches
+the class definition and the existing schema. It throws an informative exception
+when your mappings are incorrect.
+        </para>
+        <example id="ref_guide_mapping_mappingtool_validate">
+            <title>
+                Validating Mappings
+            </title>
+<programlisting>
+java org.apache.openjpa.jdbc.meta.MappingTool -action validate Magazine.java
+</programlisting>
+        </example>
+        <para>
+The <literal>buildSchema</literal> action we discussed in
+<xref linkend="ref_guide_mapping_mappingtool"/> is also somewhat useful
+during meet-in-the-middle mapping. Unlike the <literal>validate</literal>
+action, which throws an exception if your mapping data does not match the
+existing schema, the <literal>buildSchema</literal> action assumes your mapping
+data is correct, and modifies the schema to match your mappings. This lets you
+modify your mapping data manually, but saves you the hassle of using your
+database's tools to bring the schema up-to-date.
+        </para>
+    </section>
+    <section id="ref_guide_mapping_defaults">
+        <title>
+            Mapping Defaults
+        </title>
+        <indexterm zone="ref_guide_mapping_defaults">
+            <primary>
+                MappingDefaults
+            </primary>
+        </indexterm>
+        <indexterm zone="ref_guide_mapping_defaults">
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                defaults
+            </secondary>
+            <see>
+                MappingDefaults
+            </see>
+        </indexterm>
+        <para>
+The previous sections showed how to use the mapping tool to generate default
+mappings. But how does the mapping tool know what mappings to generate? The
+answer lies in the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingDefaults.html">
+<classname>org.apache.openjpa.jdbc.meta.MappingDefaults</classname></ulink>
+interface. OpenJPA uses an instance of this interface to decide how to name
+tables and columns, where to put foreign keys, and generally how to create a
+schema that matches your object model.
+        </para>
+        <important>
+            <para>
+OpenJPA relies on foreign key constraint information at runtime to order SQL
+appropriately. Be sure to set your mapping defaults to reflect your existing
+database constraints, set the schema factory to reflect on the database for
+constraint information (see <xref linkend="ref_guide_schema_info_factory"/>),
+or use explicit foreign key mappings as described in
+<xref linkend="ref_guide_mapping_jpa_fk"/>.
+            </para>
+        </important>
+        <para>
+The <link linkend="openjpa.jdbc.MappingDefaults"><literal>
+openjpa.jdbc.MappingDefaults</literal></link> configuration property controls
+the <classname>MappingDefaults</classname> interface implementation in use. This
+is a plugin property (see <xref linkend="ref_guide_conf_plugins"/>), so
+you can substitute your own implementation or configure the existing ones.
+OpenJPA includes the following standard implementations:
+        </para>
+        <itemizedlist>
+            <listitem>
+                <para>
+<literal>jpa</literal>: Provides defaults in compliance with the JPA standard.
+This is an alias for the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.html">
+<classname>org.apache.openjpa.persistence.jdbc.PersistenceMappingDefaults
+</classname></ulink> class. This class extends the <classname>
+MappingDefaultsImpl</classname> class described below, so it has all the same
+properties (though with different default values), as well as:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>PrependFieldNameToJoinTableInverseJoinColumns</literal>: Whether to
+prepend the owning field name to the names of inverse join columns in join
+tables.  Defaults to true per the JPA specification.  Set to false for
+compatibility with older OpenJPA versions which did not prepend the field name.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </listitem>
+            <listitem>
+                <para>
+<literal>default</literal>: This is an alias for the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.html">
+<classname>org.apache.openjpa.jdbc.meta.MappingDefaultsImpl</classname></ulink>
+class. This default implementation is highly configurable. It has the following
+properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>DefaultMissingInfo</literal>: Whether to default missing column and
+table names rather than throw an exception. If set to false, full explicit
+mappings are required at runtime and when using mapping tool actions like
+<literal>buildSchema</literal> and <literal>validate</literal>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<indexterm><primary>Hungarian notation</primary></indexterm>
+<literal>RemoveHungarianNotation</literal>: Switches on/off removal of
+Hungarian notation when generating column names.
+Fields such as <literal>mFoobar</literal> and <literal>strBarFoo</literal>
+would become columns named <literal>foobar</literal> and
+<literal>barfoo</literal> respectively. OpenJPA will search for the first
+instance of a uppercase character in the field name and then truncate the
+column name to remove anything before it.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>BaseClassStrategy</literal>: The default mapping strategy for base
+classes. You can specify a built-in strategy alias or the full class name of a
+<link linkend="ref_guide_mapping_custom_class">custom class strategy</link>.
+You can also use OpenJPA's plugin format (see
+<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
+strategy instance. See the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
+<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for
+available strategies.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>SubclassStrategy</literal>: The default mapping strategy for
+subclasses. You can specify a builtin strategy alias or the full class name of a
+<link linkend="ref_guide_mapping_custom_class"> custom class strategy</link>.
+You can also use OpenJPA's plugin format (see
+<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
+strategy instance. Common strategies are <literal>vertical</literal> and
+<literal>flat</literal>, the default. See the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
+<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all
+available strategies.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>VersionStrategy</literal>: The default version strategy for classes
+without a version field. You can specify a builtin strategy alias or the full
+class name of a <link linkend="ref_guide_mapping_custom_versdiscrim"> custom
+version strategy</link>. You can also use OpenJPA's plugin format (see
+<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
+strategy instance. Common strategies are <literal>none</literal>, <literal>
+state-comparison</literal>, <literal> timestamp</literal>, and <literal>
+version-number</literal>, the default. See the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
+<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all
+available strategies.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>DiscriminatorStrategy</literal>: The default discriminator strategy
+when no discriminator value is given. You can specify a builtin strategy alias
+or the full class name of a
+<link linkend="ref_guide_mapping_custom_versdiscrim"> custom discriminator
+strategy</link>. You can also use OpenJPA's plugin format (see
+<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the
+strategy instance. Common strategies are <literal>final</literal> for a base
+class without subclasses, <literal>none</literal> to use joins to subclass
+tables rather than a discriminator column, and <literal> class-name</literal>,
+the default. See the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html">
+<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all
+available strategies.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>FieldStrategies</literal>: This property associates field types with
+custom strategies. The format of this property is similar to that of plugin
+strings (see <xref linkend="ref_guide_conf_plugins"/> ), without the class
+name. It is a comma-separated list of key/value pairs, where each key is a
+possible field type, and each value is itself a plugin string describing the
+strategy for that type. We present an example below. See
+<xref linkend="ref_guide_mapping_custom_field"/> for information on custum
+field strategies.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>ForeignKeyDeleteAction</literal>: The default delete action of foreign
+keys representing relations to other objects. Recognized values include
+<literal>restrict</literal>, <literal>cascade</literal>, <literal>null</literal>
+, <literal>default</literal>. These values correspond exactly to the standard
+database foreign key actions of the same names.
+                        </para>
+                        <para>
+The value <literal>none</literal> tells OpenJPA not to create database foreign
+keys on relation columns. This is the default.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>JoinForeignKeyDeleteAction</literal>: The defualt delete action of
+foreign keys that join join secondary, collection, map, or subclass tables to
+the primary table. Accepts the same values as the <literal>
+ForeignKeyDeleteAction</literal> property above.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>DeferConstraints</literal>: Whether to use deferred database
+constraints if possible. Defaults to false.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>IndexLogicalForeignKeys</literal>: Boolean property controlling
+whether to create indexes on logical foreign keys. Logical foreign keys are
+columns that represent a link between tables, but have been configured through
+the <literal>ForeignKey</literal> properties above not to use a physical
+database foreign key. Defaults to true.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>DataStoreIdColumnName</literal>: The default name of datastore
+identity columns.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>DiscriminatorColumnName</literal>: The default name of discriminator
+columns.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>IndexDiscriminator</literal>: Whether to index the discriminator
+column. Defaults to true.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>VersionColumnName</literal>: The default name of version columns.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>IndexVersion</literal>: Whether to index the version column. Defaults
+to false.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>AddNullIndicator</literal>: Whether to create a synthetic null
+indicator column for embedded mappings. The null indicator column allows OpenJPA
+to distinguish between a null embedded object and one with default values for
+all persistent fields.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>NullIndicatorColumnName</literal>: The default name of synthetic null
+indicator columns for embedded objects.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>OrderLists</literal>: Whether to create a database ordering column for
+maintaining the order of persistent lists and arrays.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>OrderColumnName</literal>: The default name of collection and array
+ordering columns.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>StoreEnumOrdinal</literal>: Set to true to store enum fields as
+numeric ordinal values in the database. The default is to store the enum value
+name as a string, which is more robust if the Java enum declaration might be
+rearranged.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>StoreUnmappedObjectIdString</literal>: Set to true to store the
+stringified identity of related objects when the declared related type is
+unmapped. By default, OpenJPA stores the related object's primary key value(s).
+However, this breaks down if different subclasses of the related type use
+incompatible primary key structures. In that case, stringifying the identity
+value is the better choice.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </listitem>
+        </itemizedlist>
+        <para>
+The example below turns on foreign key generation during schema creation and
+associates the <classname>org.mag.data.InfoStruct</classname> field type with
+the custom <classname>org.mag.mapping.InfoStructHandler</classname> value
+handler.
+        </para>
+        <example id="ref_guide_mapping_defaults_conf">
+            <title>
+                Configuring Mapping Defaults
+            </title>
+<programlisting>
+&lt;property name="openjpa.jdbc.MappingDefaults"
+    value="ForeignKeyDeleteAction=restrict,
+    FieldStrategies='org.mag.data.InfoStruct=org.mag.mapping.InfoStructHandler'"/&gt;
+</programlisting>
+        </example>
+    </section>
+    <section id="ref_guide_mapping_factory">
+        <title>
+            Mapping Factory
+        </title>
+        <indexterm zone="ref_guide_mapping_factory">
+            <primary>
+                MappingFactory
+            </primary>
+        </indexterm>
+        <indexterm>
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                loading and storing
+            </secondary>
+            <see>
+                MappingFactory
+            </see>
+        </indexterm>
+        <para>
+An important decision in the object-relational mapping process is how and where
+to store the data necessary to map your persistent classes to the database
+schema.
+        </para>
+        <para>
+<xref linkend="ref_guide_meta_factory"/> introduced OpenJPA's <classname>
+MetaDataFactory</classname> interface. OpenJPA uses this same interface to
+abstract the storage and retrieval of mapping information. OpenJPA includes the
+built-in mapping factories below, and you can create your own factory if you
+have custom needs. You control which mapping factory OpenJPA uses with the
+<link linkend="openjpa.jdbc.MappingFactory"><literal>
+openjpa.jdbc.MappingFactory</literal></link> configuration property.
+        </para>
+        <para>
+The bundled mapping factories are:
+        </para>
+        <itemizedlist>
+            <listitem>
+                <para>
+<literal>-</literal>: Leaving the <literal> openjpa.jdbc.MappingFactory
+</literal> property unset allows your metadata factory to take over mappings as
+well.  If you are using the default <literal>jpa</literal> metadata factory,
+OpenJPA will read mapping information from your annotations and
+<filename>orm.xml</filename> when you leave the mapping factory unspecified.
+                </para>
+            </listitem>
+        </itemizedlist>
+        <example id="ref_guide_mapping_factory_jpa">
+            <title>
+                Standard JPA Configuration
+            </title>
+            <para>
+In the standard JPA configuration, the mapping factory is left unset.
+            </para>
+<programlisting>
+&lt;property name="openjpa.MetaDataFactory" value="jpa"/&gt;
+</programlisting>
+        </example>
+    </section>
+    <section id="ref_guide_mapping_notes_nonstdjoins">
+        <title>
+            Non-Standard Joins
+        </title>
+        <indexterm zone="ref_guide_mapping_notes_nonstdjoins">
+            <primary>
+                joins
+            </primary>
+            <secondary>
+                non-standard
+            </secondary>
+        </indexterm>
+        <para>
+The JPA Overview's <xref linkend="jpa_overview_mapping"/> explains join
+mapping. All of the examples in that document, however, use "standard" joins, in
+that there is one foreign key column for each primary key column in the target
+table. OpenJPA supports additional join patterns, including partial primary key
+joins, non-primary key joins, and joins using constant values.
+        </para>
+        <para>
+        <indexterm>
+            <primary>
+                joins
+            </primary>
+            <secondary>
+                partial primary key
+            </secondary>
+        </indexterm>
+In a partial primary key join, the source table only has foreign key columns for
+a subset of the primary key columns in the target table. So long as this subset
+of columns correctly identifies the proper row(s) in the referenced table,
+OpenJPA will function properly. There is no special syntax for expressing a
+partial primary key join - just do not include column definitions for missing
+foreign key columns.
+        </para>
+        <para>
+        <indexterm>
+            <primary>
+                joins
+            </primary>
+            <secondary>
+                non-primary key
+            </secondary>
+        </indexterm>
+In a non-primary key join, at least one of the target columns is not a primary
+key. Once again, OpenJPA supports this join type with the same syntax as a
+primary key join. There is one restriction, however: each non-primary key column
+you are joining to must be controlled by a field mapping that implements the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/Joinable.html"><classname>
+org.apache.openjpa.jdbc.meta.Joinable</classname></ulink> interface. All built
+in basic mappings implement this interface, including basic fields of embedded
+objects. OpenJPA will also respect any custom mappings that implement this
+interface. See <xref linkend="ref_guide_mapping_custom"/> for an
+examination of custom mappings.
+        </para>
+        <para>
+        <indexterm>
+            <primary>
+                joins
+            </primary>
+            <secondary>
+                constant
+            </secondary>
+        </indexterm>
+Not all joins consist of only links between columns. In some cases you might
+have a schema in which one of the join criteria is that a column in the source
+or target table must have some constant value. OpenJPA calls joins involving
+constant values <emphasis>constant joins</emphasis>.
+        </para>
+        <para>
+To form a constant join in JPA mapping, first set the <literal>JoinColumn
+</literal>'s <literal>name</literal> attribute to the name of the column. If the
+column with the constant value is the target of the join, give its fully
+qualified name in the form <literal>&lt;table name&gt;.&lt;column name&gt;
+</literal>. Next, set the <literal>referencedColumnName</literal> attribute to
+the constant value. If the constant value is a string, place it in single quotes
+to differentiate it from a column name.
+        </para>
+        <mediaobject>
+            <imageobject>
+                <!-- PNG image data, 427 x 211 (see README) -->
+                <imagedata fileref="img/joins-constant.png" width="285px"/>
+
+            </imageobject>
+        </mediaobject>
+        <para>
+Consider the tables above. First, we want to join row <literal>T1.R1</literal>
+to row <literal>T2.R1</literal>. If we just join column <literal>T1.FK</literal>
+to <literal>T2.PK1</literal>, we will wind up matching both <literal>T2.R1
+</literal> and <literal> T2.R2</literal>. So in addition to joining <literal>
+T1.FK</literal> to <literal>T2.PK1</literal>, we also have to specify that
+<literal>T2.PK2</literal> has the value <literal>a</literal>. Here is how we'd
+accomplish this in mapping metadata.
+        </para>
+<programlisting>
+@Entity
+@Table(name="T1")
+public class ...  {
+
+    @ManyToOne
+    @JoinColumns({
+        @JoinColumn(name="FK" referencedColumnName="PK1"),
+        @JoinColumn(name="T2.PK2" referencedColumnName="'a'")
+    });
+    private ...;
+}
+</programlisting>
+        <para>
+Notice that we had to fully qualify the name of column <literal>PK2</literal>
+because it is in the target table. Also notice that we put single quotes around
+the constant value so that it won't be confused with a column name. You do not
+need single quotes for numeric constants. For example, the syntax to join
+<literal>T1.R2</literal> to <literal>T2.R4</literal> is:
+        </para>
+<programlisting>
+@Entity
+@Table(name="T1")
+public class ...  {
+
+    @ManyToOne
+    @JoinColumns({
+        @JoinColumn(name="FK" referencedColumnName="PK2"),
+        @JoinColumn(name="T2.PK1" referencedColumnName="2")
+    });
+    private ...;
+}
+</programlisting>
+        <para>
+Finally, from the inverse direction, these joins would look like this:
+        </para>
+<programlisting>
+@Entity
+@Table(name="T2")
+public class ...  {
+
+    @ManyToOne
+    @JoinColumns({
+        @JoinColumn(name="T1.FK" referencedColumnName="PK1"),
+        @JoinColumn(name="PK2" referencedColumnName="'a'")
+    });
+    private ...;
+
+    @ManyToOne
+    @JoinColumns({
+        @JoinColumn(name="T1.FK" referencedColumnName="PK2"),
+        @JoinColumn(name="PK1" referencedColumnName="2")
+    });
+    private ...;
+}
+</programlisting>
+    </section>
+    <section id="ref_guide_mapping_jpa">
+        <title>
+            Additional JPA Mappings
+        </title>
+        <indexterm zone="ref_guide_mapping_jpa">
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                JPA additions
+            </secondary>
+        </indexterm>
+        <para>
+OpenJPA supports many persistence strategies beyond those of the JPA
+specification. <xref linkend="ref_guide_meta_jpa"/> covered the logical
+metadata for OpenJPA's additional persistence strategies. We now demonstrate how
+to map entities using these strategies to the database.
+        </para>
+        <section id="ref_guide_mapping_jpa_datastoreid">
+            <title>
+                Datastore Identity Mapping
+            </title>
+            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
+                <primary>
+                    datastore identity
+                </primary>
+                <secondary>
+                    mapping
+                </secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    datastore identity
+                </secondary>
+                <seealso>
+                    identity
+                </seealso>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
+                <primary>
+                    DataStoreIdColumn
+                </primary>
+                <seealso>
+                    mapping metadata
+                </seealso>
+            </indexterm>
+            <indexterm>
+                <primary>
+                    primary key
+                </primary>
+            </indexterm>
+            <para>
+<xref linkend="ref_guide_pc_oid"/> describes how to use datastore identity
+in JPA. OpenJPA requires a single numeric primary key column to hold datastore
+identity values. The
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DataStoreIdColumn.html">
+<classname>org.apache.openjpa.persistence.jdbc.DataStoreIdColumn</classname>
+</ulink> annotation customizes the datastore identity column. This annotation
+has the following properties:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+<literal>String name</literal>: Defaults to <literal>ID</literal>.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>int precision</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>String columnDefinition</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>boolean insertable</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>boolean updatable</literal>
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <para>
+All properties correspond exactly to the same-named properties on the standard
+<classname>Column</classname> annotation, described in
+<xref linkend="jpa_overview_mapping_column"/>.
+            </para>
+            <example id="ref_guide_mapping_jpa_datastoreidex">
+                <title>
+                    Datastore Identity Mapping
+                </title>
+<programlisting>
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+@Entity
+@Table(name="LOGS")
+@DataStoreIdColumn(name="ENTRY")
+public class LogEntry {
+
+    @Lob
+    private String content;
+
+    ...
+}
+</programlisting>
+            </example>
+        </section>
+        <section id="ref_guide_mapping_jpa_version">
+            <title>
+                Surrogate Version Mapping
+            </title>
+            <indexterm zone="ref_guide_mapping_jpa_datastoreid">
+                <primary>
+                    version
+                </primary>
+                <secondary>
+                    mapping
+                </secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_jpa_version">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    version
+                </secondary>
+                <seealso>
+                    version
+                </seealso>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_jpa_version">
+                <primary>
+                    VersionColumn
+                </primary>
+                <seealso>
+                    mapping metadata
+                </seealso>
+            </indexterm>
+            <para>
+OpenJPA supports version fields as defined by the JPA specification, but allows
+you to use a surrogate version column in place of a version field if you like.
+You map the surrogate version column with the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumn.html">
+<classname>org.apache.openjpa.persistence.jdbc.VersionColumn</classname></ulink>
+annotation. You can also use the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumns.html">
+<classname>org.apache.openjpa.persistence.jdbc.VersionColumns</classname>
+</ulink> annotation to declare an array of <classname>VersionColumn</classname>
+values. Each <classname>VersionColumn</classname> has the following properties:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+<literal>String name</literal>: Defaults to <literal>VERSN</literal>.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>int length</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>int precision</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>int scale</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>String columnDefinition</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>boolean nullable</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>boolean insertable</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>boolean updatable</literal>
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <para>
+All properties correspond exactly to the same-named properties on the standard
+<classname>Column</classname> annotation, described in
+<xref linkend="jpa_overview_mapping_column"/>.
+            </para>
+            <para>
+By default, OpenJPA assumes that surrogate versioning uses a version number
+strategy. You can choose a different strategy with the <classname>
+VersionStrategy</classname> annotation described in
+<xref linkend="version-strategy"/>.
+            </para>
+        </section>
+        <section id="ref_guide_mapping_jpa_columns">
+            <title>
+                Multi-Column Mappings
+            </title>
+            <indexterm zone="ref_guide_mapping_jpa_columns">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    column
+                </secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_jpa_columns">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    multi-column mappings
+                </secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_mapping_jpa_columns">
+                <primary>
+                    Columns
+                </primary>
+                <seealso>
+                    mapping metadata
+                </seealso>
+            </indexterm>
+            <para>
+OpenJPA makes it easy to create multi-column
+<link linkend="ref_guide_mapping_custom_field">custom mappings</link>. The JPA
+specification includes a <classname>Column</classname> annotation, but is
+missing a way to declare multiple columns for a single field. OpenJPA remedies
+this with the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Columns.html">
+<classname>org.apache.openjpa.persistence.jdbc.Columns</classname></ulink>
+annotation, which contains an array of <classname>Column</classname> values.
+            </para>
+            <para>
+Remember to annotate custom field types with <classname>Persistent</classname>,
+as described in <xref linkend="ref_guide_meta_jpa_persistent"/>.
+            </para>
+        </section>
+        <section id="ref_guide_mapping_jpa_fieldjoin">
+            <title>
+                Join Column Attribute Targets
+            </title>
+            <para>
+<xref linkend="jpa_overview_mapping_rel"/> in the JPA Overview introduced
+you to the <classname>JoinColumn</classname> annotation. A <classname>
+JoinColumn</classname>'s <literal> referencedColumnName</literal> property
+declares which column in the table of the related type this join column links
+to. Suppose, however, that the related type is unmapped, or that it is part of a
+table-per-class inheritance hierarchy. Each subclass that might be assigned to
+the field could reside in a different table, and could use entirely different
+names for its primary key columns. It becomes impossible to supply a single
+<literal>referencedColumnName</literal> that works for all subclasses.
+            </para>
+            <para>
+OpenJPA rectifies this by allowing you to declare which <emphasis>attribute
+</emphasis> in the related type each join column links to, rather than which
+column. If the attribute is mapped differently in various subclass tables,
+OpenJPA automatically forms the proper join for the subclass record at hand. The
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumn.html">
+<classname>org.apache.openjpa.persistence.jdbc.XJoinColumn</classname></ulink>
+annotation has all the same properties as the standard <classname>JoinColumn
+</classname> annotation, but adds an additional <literal>
+referencedAttributeName</literal> property for this purpose. Simply use a
+<classname>XJoinColumn</classname> in place of a <classname>JoinColumn
+</classname> whenever you need to access this added functionality.
+            </para>
+            <para>
+For compound keys, use the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumns.html">
+<classname>org.apache.openjpa.persistence.jdbc.XJoinColumns</classname></ulink>
+annotation. The value of this annotation is an array of individual <classname>
+XJoinColumn</classname>s.
+            </para>
+        </section>
+        <section id="ref_guide_mapping_jpa_embed">
+            <title>
+                Embedded Mapping
+            </title>
+            <para>
+JPA uses the <classname>AttributeOverride</classname> annotation to override the
+default mappings of an embeddable class. The JPA Overview details this process
+in <xref linkend="jpa_overview_mapping_embed"/>. <classname>
+AttributeOverride</classname>s suffice for simple mappings, but do not allow
+you to override complex mappings. Also, JPA has no way to differentitate between
+a null embedded object and one with default values for all of its fields.
+            </para>
+            <para>
+OpenJPA overcomes these shortcomings with the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EmbeddedMapping.html">
+<classname>org.apache.openjpa.persistence.jdbc.EmbeddedMapping</classname>
+</ulink> annotation. This annotation has the following properties:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+<literal>String nullIndicatorColumnName</literal>: If the named column's value
+is <literal>NULL</literal>, then the embedded object is assumed to be null. If
+the named column has a non- <literal>NULL</literal> value, then the embedded
+object will get loaded and populated with data from the other embedded fields.
+This property is entirely optional. By default, OpenJPA always assumes the
+embedded object is non-null, just as in standard JPA mapping.
+                    </para>
+                    <para>
+If the column you name does not belong to any fields of the embedded object,
+OpenJPA will create a synthetic null-indicator column with this name. In fact,
+you can specify a value of <literal>true</literal> to simply indicate that you
+want a synthetic null-indicator column, without having to come up with a name
+for it. A value of <literal>false</literal> signals that you explicitly do not
+want a null-indicator column created for this mapping (in case you have
+configured your <link linkend="ref_guide_mapping_defaults">mapping defaults
+</link> to create one by default).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>String nullIndicatorFieldName</literal>: Rather than name a null
+indicator column, you can name a field of the embedded type. OpenJPA will use
+the column of this field as the null-indicator column.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>MappingOverride[] overrides</literal>: This array allows you to
+override any mapping of the embedded object.
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <para>
+The <classname>EmbeddedMapping</classname>'s <literal>overrides</literal> array
+serves the same purpose as standard JPA's <classname>AttributeOverride
+</classname>s and <classname>AssociationOverride</classname> s. In fact, you can
+also use the <classname>MappingOverride</classname> annotation on an entity
+class to override a complex mapping of its mapped superclass, just as you can
+with <classname> AttributeOverride</classname> and <classname>
+AssociationOverride</classname> s. The <classname>MappingOverrides</classname>
+annotation, whose value is an array of <classname>MappingOverride</classname> s,
+allows you to overide multiple mapped superclass mappings.
+            </para>
+            <para>
+Each
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/MappingOverride.html">
+<classname>org.apache.openjpa.persistence.jdbc.MappingOverride</classname>
+</ulink> annotation has the following properties:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+<literal>String name</literal>: The name of the field that is being overridden.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>Column[] columns</literal>: Columns for the new field mapping.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>XJoinColumn[] joinColumns</literal>: Join columns for the new field
+mapping, if it is a relation field.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>ContainerTable containerTable</literal>: Table for the new collection
+or map field mapping. We cover collection mappings in
+<xref linkend="ref_guide_mapping_jpa_coll"/>, and map mappings in
+<xref linkend="ref_guide_mapping_jpa_map"/>.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+<literal>ElementJoinColumn[] elementJoinColumns</literal>: Element join columns
+for the new collection or map field mapping. You will see how to use element
+join columns in <xref linkend="ref_guide_mapping_jpa_coll_joincols"/>.
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <para>
+The following example defines an embeddable <classname> PathCoordinate
+</classname> class with a custom mapping of a <classname>java.awt.Point
+</classname> field to two columns. It then defines an entity which embeds a
+<classname> PointCoordinate</classname> and overrides the default mapping for
+the point field. The entity also declares that if the <classname>PathCoordinate
+</classname>'s <literal>siteName</literal> field column is null, it means that
+no <classname>PathCoordinate</classname> is stored in the embedded record; the
+owning field will load as null.
+            </para>
+            <example id="ref_guide_mapping_jpa_embedex">
+                <title>
+                    Overriding Complex Mappings
+                </title>
+<programlisting>
+import org.apache.openjpa.persistence.jdbc.*;
+
+@Embeddable
+public class PathCoordinate {
+
+    private String siteName;
+
+    @Persistent
+    @Strategy("com.xyz.openjpa.PointValueHandler")
+    private Point point;
+
+    ...
+}
+
+@Entity
+public class Path {
+
+    @Embedded
+    @EmbeddedMapping(nullIndicatorFieldName="siteName", overrides={
+        @MappingOverride(name="siteName", columns=@Column(name="START_SITE")),
+        @MappingOverride(name="point", columns={
+            @Column(name="START_X"),
+            @Column(name="START_Y")
+        })
+    })
+    private PathCoordinate start;
+
+    ...
+}
+</programlisting>
+            </example>
+        </section>
+        <section id="ref_guide_mapping_jpa_coll">
+            <title>
+                Collections
+            </title>
+            <indexterm zone="ref_guide_mapping_jpa_coll">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    collections
+                </secondary>
+            </indexterm>
+            <para>
+In <xref linkend="ref_guide_meta_jpa_persistent_coll"/>, we explored the
+<classname>PersistentCollection</classname> annotation for persistent collection
+fields that aren't a standard <literal>OneToMany</literal> or <literal>
+ManyToMany</literal> relation. To map these non-standard collections, combine
+OpenJPA's <classname>ContainerTable</classname> annotation with
+<classname>ElementJoinColumn</classname>s.
+We explore the annotations below.
+            </para>
+            <section id="ref_guide_mapping_jpa_coll_table">
+                <title>
+                    Container Table
+                </title>
+                <indexterm zone="ref_guide_mapping_jpa_coll_table">
+                    <primary>
+                        ContainerTable
+                    </primary>
+                    <seealso>
+                        mapping metadata
+                    </seealso>
+                </indexterm>
+                <para>
+The
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ContainerTable.html">
+<classname>org.apache.openjpa.persistence.jdbc.ContainerTable</classname>
+</ulink> annotation describes a database table that holds collection (or map)
+elements. This annotation has the following properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>String name</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>String catalog</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>String schema</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>XJoinColumn[] joinColumns</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>ForeignKey joinForeignKey</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>Index joinIndex</literal>
+                        </para>
+                    </listitem>
+                </itemizedlist>
+                <para>
+The <literal>name</literal>, <literal>catalog</literal>, <literal>schema
+</literal>, and <literal>joinColumns</literal> properties describe the container
+table and how it joins to the owning entity's table. These properties correspond
+to the same-named properties on the standard <classname> JoinTable</classname>
+annotation, described in <xref linkend="jpa_overview_mapping_assoccoll"/>
+. If left unspecified, the name of the table defaults to the first five
+characters of the entity table name, plus an underscore, plus the field name.
+The <literal>joinForeignKey</literal> and <literal> joinIndex</literal>
+properties override default foreign key and index generation for the join
+columns. We explore foreign keys and indexes later in this chapter.
+                </para>
+                <para>
+You may notice that the container table does not define how to store the
+collection elements. That is left to separate annotations, which are the subject
+of the next sections.
+                </para>
+            </section>
+            <section id="ref_guide_mapping_jpa_coll_joincols">
+                <title>
+                    Element Join Columns
+                </title>
+                <indexterm zone="ref_guide_mapping_jpa_coll_joincols">
+                    <primary>
+                        ElementJoinColumn
+                    </primary>
+                    <seealso>
+                        mapping metadata
+                    </seealso>
+                </indexterm>
+                <para>
+Element join columns are equivalent to standard JPA join columns, except that
+they represent a join to a collection or map element entity rather than a direct
+relation. You represent an element join column with OpenJPA's
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumn.html">
+<classname>org.apache.openjpa.persistence.jdbc.ElementJoinColumn</classname>
+</ulink> annotation. To declare a compound join, enclose an array of <classname>
+ElementJoinColumn</classname>s in the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumns.html">
+<classname>org.apache.openjpa.persistence.jdbc.ElementJoinColumns</classname>
+</ulink> annotation.
+                </para>
+                <para>
+An <classname>ElementJoinColumn</classname> always resides in a container table,
+so it does not have the <literal> table</literal> property of a standard
+<classname> JoinColumn</classname>. Like <classname> XJoinColumn</classname>s
+above, <classname> ElementJoinColumn</classname>s can reference a linked
+attribute rather than a static linked column. Otherwise, the <classname>
+ElementJoinColumn</classname> and standard <classname>JoinColumn</classname>
+annotations are equivalent. See <xref linkend="jpa_overview_mapping_rel"/>
+in the JPA Overview for a review of the <classname>JoinColumn</classname>
+annotation.
+                </para>
+            </section>
+            <section id="ref_guide_mapping_jpa_coll_order">
+                <title>
+                    Order Column
+                </title>
+                <indexterm zone="ref_guide_mapping_jpa_coll_order">
+                    <primary>
+                        OrderColumn
+                    </primary>
+                    <seealso>
+                        mapping metadata
+                    </seealso>
+                </indexterm>
+                <para>
+Relational databases do not guarantee that records are returned in insertion
+order. If you want to make sure that your collection elements are loaded in the
+same order they were in when last stored, you must declare an order column.
+OpenJPA's
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/OrderColumn">
+<classname>org.apache.openjpa.persistence.jdbc.OrderColumn</classname></ulink>
+annotation has the following properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>String name</literal>: Defaults to <literal>ORDR</literal>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>boolean enabled</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>int precision</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>String columnDefinition</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>boolean insertable</literal>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>boolean updatable</literal>
+                        </para>
+                    </listitem>
+                </itemizedlist>
+                <para>
+Order columns are always in the container table. You can explicitly turn off
+ordering (if you have enabled it by default via your
+<link linkend="ref_guide_mapping_defaults"> mapping defaults</link>) by setting
+the <literal>enabled</literal> property to <literal>false</literal>. All other
+properties correspond exactly to the same-named properties on the standard
+<classname>Column</classname> annotation, described in
+<xref linkend="jpa_overview_mapping_column"/>.
+                </para>
+            </section>
+        </section>
+        <section id="ref_guide_mapping_jpa_onemany">
+            <title>
+                One-Sided One-Many Mapping
+            </title>
+            <indexterm zone="ref_guide_mapping_jpa_onemany">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    collections
+                </secondary>
+                <tertiary>
+                    JPA one-sided one-many
+                </tertiary>
+            </indexterm>
+            <para>
+The previous section covered the use of <classname>ElementJoinColumn</classname>
+annotations in conjunction with a <classname>ContainerTable</classname> for
+mapping collections to dedicate tables. <classname>ElementJoinColumn</classname>
+s, however, have one additional use: to create a one-sided one-many mapping.
+Standard JPA supports <classname>OneToMany</classname> fields without a
+<literal>mappedBy</literal> inverse, but only by mapping these fields to a
+<classname>JoinTable</classname> (see
+<xref linkend="jpa_overview_mapping_assoccoll"/> in the JPA Overview for
+details). Often, you'd like to create a one-many association based on an inverse
+foreign key (logical or actual) in the table of the related type.
+            </para>
+            <mediaobject>
+                <imageobject>
+                    <!-- PNG image data, 392 x 192 (see README) -->
+                    <imagedata fileref="img/inv-key-coll.png" width="261"/>
+
+                </imageobject>
+            </mediaobject>
+            <para>
+Consider the model above. <classname>Subscription</classname> has a collection
+of <classname>LineItem</classname> s, but <classname>LineItem</classname> has
+no inverse relation to <classname>Subscription</classname>. To retrieve all of
+the <classname>LineItem</classname> records for a <classname>Subscription
+</classname>, we join the <literal>SUB_ID</literal> inverse foreign key column
+in the <literal>LINE_ITEM</literal> table to the primary key column of the
+<literal>SUB</literal> table. The example below shows how to represent this
+model in mapping annotations. Note that OpenJPA automatically assumes an inverse
+foreign key mapping when element join columns are given, but no container or
+join table is given.
+            </para>
+            <example id="ref_guide_mapping_jpa_onemanyex">
+                <title>
+                    One-Sided One-Many Mapping
+                </title>
+<programlisting>
+package org.mag.subscribe;
+
+import org.apache.openjpa.persistence.jdbc.*;
+
+@Entity
+@Table(name="LINE_ITEM", schema="CNTRCT")
+public class LineItem {
+    ...
+}
+
+@Entity
+@Table(name="SUB", schema="CNTRCT")
+public class Subscription {
+
+    @Id private long id;
+
+    @OneToMany
+    @ElementJoinColumn(name="SUB_ID", referencedColumnName="ID")
+    private Collection&lt;LineItem&gt; items;
+
+    ...
+}
+</programlisting>
+            </example>
+        </section>
+        <section id="ref_guide_mapping_jpa_map">
+            <title>
+                Maps
+            </title>
+            <indexterm zone="ref_guide_mapping_jpa_map">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    maps
+                </secondary>
+            </indexterm>
+            <para>
+We detailed the <literal>ContainerTable</literal> annotation in
+<xref linkend="ref_guide_mapping_jpa_coll_table"/>. Custom map mappings may
+also use this annotation to represent a map table.
+            </para>
+        </section>
+        <section id="ref_guide_mapping_jpa_constraints">
+            <title>
+                Indexes and Constraints
+            </title>
+            <para>
+OpenJPA uses index information during schema generation to index the proper
+columns. OpenJPA uses foreign key and unique constraint information during
+schema creation to generate the proper database constraints, and also at runtime
+to order SQL statements to avoid constraint violations while maximizing SQL
+batch size.
+            </para>
+            <para>
+OpenJPA assumes certain columns have indexes or constraints based on your
+mapping defaults, as detailed in <xref linkend="ref_guide_mapping_defaults"/>.
+You can override the configured defaults on individual joins, field
+values, collection elements, map keys, or map values using the annotations
+presented in the following sections.
+            </para>
+            <section id="ref_guide_mapping_jpa_index">
+                <title>
+                    Indexes
+                </title>
+                <indexterm zone="ref_guide_mapping_jpa_index">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        indexes
+                    </secondary>
+                </indexterm>
+                <indexterm zone="ref_guide_mapping_jpa_index">
+                    <primary>
+                        indexes
+                    </primary>
+                </indexterm>
+                <para>
+The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Index.html">
+<classname>org.apache.openjpa.persistence.jdbc.Index</classname></ulink>
+annotation represents an index on the columns of a field. It is also used within
+the <link linkend="ref_guide_mapping_jpa_coll_table"><classname>ContainerTable
+</classname></link> annotation to index join columns.
+To index the columns of a collection element, use the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementIndex.html">
+<classname> org.apache.openjpa.persistence.jdbc.ElementIndex</classname></ulink>
+annotation. These annotations have the following properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>boolean enabled</literal>: Set this property to <literal>false
+</literal> to explicitly tell OpenJPA not to index these columns, when OpenJPA
+would otherwise do so.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>String name</literal>: The name of the index. OpenJPA will choose a
+name if you do not provide one.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>boolean unique</literal>: Whether to create a unique index. Defaults
+to false.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </section>
+            <section id="ref_guide_mapping_jpa_fk">
+                <title>
+                    Foreign Keys
+                </title>
+                <indexterm zone="ref_guide_mapping_jpa_fk">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        foreign keys
+                    </secondary>
+                </indexterm>
+                <indexterm zone="ref_guide_mapping_jpa_fk">
+                    <primary>
+                        foreign keys
+                    </primary>
+                </indexterm>
+                <para>
+The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKey.html">
+<classname>org.apache.openjpa.persistence.jdbc.ForeignKey</classname></ulink>
+annotation represents a foreign key on the columns of a field. It is also used
+within the <link linkend="ref_guide_mapping_jpa_coll_table"><classname>
+ContainerTable</classname></link> annotation to set a database foreign key on
+join columns.  To set a constraint to the columns of a collection element, use
+the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementForeignKey.html">
+<classname> org.apache.openjpa.persistence.jdbc.ElementForeignKey</classname>
+</ulink> annotation. These annotations have the following properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>boolean enabled</literal>: Set this property to <literal>false
+</literal> to explicitly tell OpenJPA not to set a foreign key on these columns,
+when OpenJPA would otherwise do so.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>String name</literal>: The name of the foreign key. OpenJPA will
+choose a name if you do not provide one, or will create an anonymous key.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>boolean deferred</literal>: Whether to create a deferred key if
+supported by the database.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>ForeignKeyAction deleteAction</literal>: Value from the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html">
+<classname>org.apache.openjpa.persistence.jdbc.ForeignKeyAction</classname>
+</ulink> enum identifying the desired delete action. Defaults to <literal>
+RESTRICT</literal>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>ForeignKeyAction updateAction</literal>: Value from the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html">
+<classname>org.apache.openjpa.persistence.jdbc.ForeignKeyAction</classname>
+</ulink> enum identifying the desired update action. Defaults to <literal>
+RESTRICT</literal>.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+                <para>
+Keep in mind that OpenJPA uses foreign key information at runtime to avoid
+constraint violations; it is important, therefore, that your
+<link linkend="ref_guide_mapping_defaults">mapping defaults</link> and foreign
+key annotations combine to accurately reflect your existing database
+constraints, or that  you configure OpenJPA to reflect on your database schema
+to discover existing foreign keys (see
+<xref linkend="ref_guide_schema_info_factory"/>).
+                </para>
+            </section>
+            <section id="ref_guide_mapping_jpa_unique">
+                <title>
+                    Unique Constraints
+                </title>
+                <indexterm zone="ref_guide_mapping_jpa_unique">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        unique constraints
+                    </secondary>
+                </indexterm>
+                <indexterm zone="ref_guide_mapping_jpa_unique">
+                    <primary>
+                        unique constraints
+                    </primary>
+                </indexterm>
+                <para>
+The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Unique.html">
+<classname>org.apache.openjpa.persistence.jdbc.Unique</classname></ulink>
+annotation represents a unqiue constraint on the columns of a field. It is more
+convenient than using the <literal>uniqueConstraints</literal> property of
+standard JPA <classname>Table</classname> and <classname>SecondaryTable
+</classname> annotations, because you can apply it directly to the constrained
+field. The <classname>Unique</classname> annotation has the following
+properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>boolean enabled</literal>: Set this property to <literal>false
+</literal> to explicitly tell OpenJPA not to constrain these columns, when
+OpenJPA would otherwise do so.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>String name</literal>: The name of the constraint. OpenJPA will choose
+a name if you do not provide one, or will create an anonymous constraint.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>boolean deferred</literal>: Whether to create a deferred constraint if
+supported by the database.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </section>
+        </section>
+        <section id="ref_guide_xmlmapping">
+		    <title>
+              XML Column Mapping
+            </title>
+              <indexterm zone="ref_guide_xmlmapping">
+                  <primary>
+                      mapping metadata
+                  </primary>
+                  <secondary>
+                      xml column mapping
+                  </secondary>
+              </indexterm>
+              <indexterm zone="ref_guide_xmlmapping">
+                  <primary>
+                      xml mapping column
+                  </primary>
+              </indexterm>
+              <para>
+DB2, Oracle and SQLServer support XML column types and
+XPath queries and indexes over these columns.OpenJPA supports mapping of an
+entity property mapped to an XML column.
+              </para>
+              <para>
+Annotate the entity property using the XMLValueHandler strategy:
+		      </para>
+<programlisting>
+@Persistent
+@Strategy(&quot;org.apache.openjpa.jdbc.meta.strats.XMLValueHandler&quot;)
+</programlisting>
+              <para>
+The default fetch type is EAGER but can be changed to LAZY by using:
+              </para>
+<programlisting>
+@Persistence(fetch=FetchType.LAZY)
+</programlisting>
+              <para>
+The entity property class is required to have
+jaxb binding annotations.  This is produced when the classes are generated
+from an xml schema using the jaxb generator XJC.Ensure that <classname>@XmlRootElement</classname>
+appears in the root class. In some case this annotation needs to be added manually if it is missing.
+              </para>
+              <para>
+The jaxb jar files must be on the application classpath (jaxb-api.jar,
+jaxb-impl.jar, jsr173_1.0_api.jar or equivalent).
+              </para>
+              <para>
+EJB Query path expressions can navigate into the mapped class and its
+subfields to any level.
+              </para>
+              <para>
+The path expression is rewritten into an equivalent XPATH expression using SQL
+XML functions.
+              </para>
+              <para>
+The path expression must be single valued.Path expressions over xml
+mapped classes can only be used in WHERE as an operand to a simple predicate
+(=  &lt;&gt;  &lt;  &gt;  &gt;=  &lt;=).
+              </para>
+              <para>
+Path expressions over XML mapped fields can not be:
+              </para>
+		      <itemizedlist>
+                  <listitem>
+                      <para>
+an input to a EJB query scalar function
+                      </para>
+                  </listitem>
+                  <listitem>
+                      <para>
+an operand of BETWEEN,  IS NULL, LIKE or IN predicate
+                      </para>
+                  </listitem>
+                  <listitem>
+                      <para>
+used to project out subfields in the SELECT clause
+                      </para>
+                  </listitem>
+                  <listitem>
+                      <para>
+used in the FROM , GROUP BY, HAVING, ORDER BY clauses
+                      </para>
+                  </listitem>
+              </itemizedlist>
+              <para>
+XML schema must not contain namespace declarations. The EJB query path
+expressions can not refer to java fields generated from XML ANY type or
+XML mixed element types.
+              </para>
+              <para>
+The datatype generated by JAXB must be a valid EJB query type
+to use the property in an EJB query predicate.
+              </para>
+              <para>
+Shown below is a sample XML schema <link linkend="ref_guide_xmlmapping_myaddress">myaddress.xsd</link>,
+in which the JPA entity Order has <classname>&lt;shipAddress&gt;</classname> persistent field that maps to an XML column.
+		      </para>
+              <example id="ref_guide_xmlmapping_myaddress">
+                   <title>
+                       myaddress.xsd
+                   </title>
+<programlisting>
+&lt;?xml version=&quot;1.0&quot; ?&gt;
+&lt;xs:schema xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; &gt;
+
+&lt;xs:complexType name=&quot;Address&quot;&gt;
+ &lt;xs:sequence&gt;
+  &lt;xs:element name=&quot;Name&quot; type=&quot;xs:string&quot; /&gt;
+  &lt;xs:element name=&quot;Street&quot; type=&quot;xs:string&quot;
+  	minOccurs=&quot;1&quot; maxOccurs=&quot;3&quot; /&gt;
+  &lt;xs:element name=&quot;City&quot; type=&quot;xs:string&quot; /&gt;
+&lt;/xs:sequence&gt;
+&lt;/xs:complexType&gt;
+
+&lt;xs:complexType name=&quot;CAN_Address&quot;&gt;
+ &lt;xs:complexContent&gt;
+  &lt;xs:extension base=&quot;Address&quot;&gt;
+   &lt;xs:sequence&gt;
+    &lt;xs:element name=&quot;Province&quot; type=&quot;xs:string&quot; /&gt;
+    &lt;xs:element name=&quot;PostalCode&quot; type=&quot;xs:string&quot; /&gt;
+   &lt;/xs:sequence&gt;
+  &lt;/xs:extension&gt;
+&lt;/xs:complexContent&gt;
+&lt;/xs:complexType&gt;
+
+&lt;xs:simpleType name=&quot;USPS_ZIP&quot;&gt;
+ &lt;xs:restriction base=&quot;xs:integer&quot;&gt;
+  &lt;xs:minInclusive value=&quot;01000&quot; /&gt;
+  &lt;xs:maxInclusive value=&quot;99999&quot; /&gt;
+ &lt;/xs:restriction&gt;
+&lt;/xs:simpleType&gt;
+
+&lt;xs:complexType name=&quot;USA_Address&quot;&gt;
+ &lt;xs:complexContent&gt;
+  &lt;xs:extension base=&quot;Address&quot;&gt;
+   &lt;xs:sequence&gt;
+    &lt;xs:element name=&quot;State&quot; type=&quot;xs:string&quot; /&gt;
+    &lt;xs:element name=&quot;ZIP&quot; type=&quot;USPS_ZIP&quot; /&gt;
+   &lt;/xs:sequence&gt;
+  &lt;/xs:extension&gt;
+ &lt;/xs:complexContent&gt;
+&lt;/xs:complexType&gt;
+
+&lt;xs:element name=&quot;MailAddress&quot; type=&quot;Address&quot; /&gt;
+&lt;xs:element name=&quot;AddrCAN&quot; type=&quot;CAN_Address&quot;
+   substitutionGroup=&quot;MailAddress&quot; /&gt;
+&lt;xs:element name=&quot;AddrUSA&quot; type=&quot;USA_Address&quot;
+   substitutionGroup=&quot;MailAddress&quot; /&gt;
+&lt;/xs:schema&gt;
+</programlisting>
+              </example>
+              <para>
+Java classes <link linkend="ref_guide_xmlmapping_address">Address</link>,
+<link linkend="ref_guide_xmlmapping_usaaddress">USAAddress</link> and
+<link linkend="ref_guide_xmlmapping_canaddress">CANAddress</link>
+are produced using jaxb XJC generator from myaddress schema.
+              </para>
+              <example id="ref_guide_xmlmapping_address">
+                  <title>
+                       Address.Java
+                  </title>
+<programlisting>
+    ...
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = &quot;Address&quot;, propOrder = {
+    &quot;name&quot;,
+    &quot;street&quot;,
+    &quot;city&quot;
+})
+public class Address {
+    @XmlElement(name = &quot;Name&quot;, required = true)
+    protected String name;
+    @XmlElement(name = &quot;Street&quot;, required = true)
+    protected List&lt;String&gt; street;
+    @XmlElement(name = &quot;City&quot;, required = true)
+    protected String city;
+
+   /**
+     * Getter and Setter methods.
+     *
+     */
+     ...
+}
+</programlisting>
+            </example>
+            <example id="ref_guide_xmlmapping_usaaddress">
+                <title>
+                    USAAddress.java
+                </title>
+<programlisting>
+    ...
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = &quot;USA_Address&quot;, propOrder = {
+    &quot;state&quot;,
+    &quot;zip&quot;
+})
+public class USAAddress
+    extends Address
+{
+
+    @XmlElement(name = &quot;State&quot;)
+    protected String state;
+    @XmlElement(name = &quot;ZIP&quot;)
+    protected int zip;
+
+   /**
+     * Getter and Setter methods.
+     *
+     */
+     ...
+}
+</programlisting>
+            </example>
+            <example id="ref_guide_xmlmapping_canaddress">
+                <title>
+                    CANAddress.java
+                </title>
+<programlisting>
+     ...
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = &quot;CAN_Address&quot;, propOrder = {
+    &quot;province&quot;,
+    &quot;postalCode&quot;
+})
+public class CANAddress
+    extends Address
+{
+
+    @XmlElement(name = &quot;Province&quot;)
+    protected String province;
+    @XmlElement(name = &quot;PostalCode&quot;)
+    protected String postalCode;
+
+   /**
+     * Getter and Setter methods.
+     *
+     */
+     ...
+}
+</programlisting>
+            </example>
+            <example id="ref_guide_xmlmapping_annorder">
+                <title>
+                    Showing annotated Order entity with XML mapping strategy
+                </title>
+<programlisting>
+@Entity
+public class Order {
+    @Id  private into id;
+    @Persistent
+    @Strategy (&quot;org.apache.openjpa.jdbc.meta.strats.XMLValueHandler&quot;)
+    private Address shipAddress;
+    ...
+}
+</programlisting>
+            </example>
+            <example id="ref_guide_xmlmapping_createorder">
+             <title>
+                 Showing creation of Order Entity having shipAddress mapped to XML column
+             </title>
+<programlisting>
+...
+myaddress.ObjectFactory addressFactory = new myaddress.ObjectFactory();
+Customer c1 = new Customer();
+c1.setCid( new Customer.CustomerKey(&quot;USA&quot;, 1) );
+c1.setName(&quot;Harry's Auto&quot;);
+Order o1 = new Order( 850, false, c1);
+USAAddress addr1 = addressFactory.createUSAAddress();
+addr1.setCity(&quot;San Jose&quot;);
+addr1.setState(&quot;CA&quot;);
+addr1.setZIP(new Integer(&quot;95141&quot;));
+addr1.getStreet().add(&quot;12500 Monterey&quot;);
+addr1.setName( c1.getName());
+o1.setShipAddress(addr1);
+em.persist(o1);
+...
+</programlisting>
+            </example>
+            <example id="ref_guide_xmlmapping_ejbquery">
+                <title>
+                    Sample EJB Queries for XML Column mapping
+                </title>
+<programlisting>
+. select o from Order o where o.shipAddress.city = &quot;San Jose&quot; or
+			      o.shipAddress.city = &quot;San Francisco&quot;  (OK)
+
+. select o.shipaAddress from Order o  (OK)
+
+. select o.shipAddress.city from Order o  (INVALID)
+
+. select o from Order o where o.shipAddress.street = &quot;San Jose&quot;  (INVALID multi valued)
+</programlisting>
+            </example>
+        </section>
+        <section id="ref_guide_streamsupport">
+            <title>
+              Stream LOB Support
+            </title>
+              <indexterm zone="ref_guide_streamsupport">
+                  <primary>
+                      stream support
+                  </primary>
+              </indexterm>
+              <indexterm zone="ref_guide_streamsupport">
+                  <primary>
+                      stream lob support
+                  </primary>
+              </indexterm>
+              <para>
+Since the 1.1.0 release Apache OpenJPA added support for Streams. This feature
+makes it possible to stream large amounts of data into and out of fields in
+objects managed by OpenJPA without ever holding all the data in memory at the
+same time.
+              </para>
+              <para>
+To persist a stream, use the 
+<ulink url="../javadoc/org/apache/openjpa/persistence/Persistent.html">
+<classname>org.apache.openjpa.persistence.Persistent</classname></ulink> 
+annotation.
+              </para>
+            <example id="ref_guide_streamsupport_example">
+                <title>
+                    Showing annotated InputStream
+                </title>
+<programlisting>
+@Entity
+public class Employee {
+    ...
+    @Persistent
+    private InputStream photoStream;
+    ...
+} 
+</programlisting>
+            </example>
+        </section>
+    </section>
+    <section id="ref_guide_mapping_jpa_map_keycols">
+        <title>Key Columns</title>
+        <indexterm zone="ref_guide_mapping_jpa_map_keycols">
+            <primary>KeyColumn</primary>
+            <seealso>mapping metadata</seealso>
+        </indexterm>
+        <para>
+        Key columns serve the same role for map keys as the element
+        columns described in
+        <xref linkend="ref_guide_mapping_jpa_coll_cols"/> serve for
+        collection elements.  OpenJPA's
+        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyColumn.html">
+        <classname>org.apache.openjpa.persistence.jdbc.KeyColumn</classname>
+        </ulink> annotation represents a map key.  To map custom
+        multi-column keys, use the
+        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyColumns.html">
+        <classname>org.apache.openjpa.persistence.jdbc.KeyColumns</classname>
+        </ulink> annotation, whose value is an array of <classname>KeyColumn</classname>s.
+        </para>
+        <para>
+        A <classname>KeyColumn</classname> always resides in
+        a container table, so it does not have the <literal>table</literal>
+        property of a standard <classname>Column</classname>.  Otherwise, the
+        <classname>KeyColumn</classname> and standard <classname>Column</classname>
+        annotations are equivalent.  See
+        <xref linkend="jpa_overview_mapping_column"/> in the JPA
+        Overview for a review of the <classname>Column</classname> annotation.
+        </para>
+    </section>
+    <section id="ref_guide_mapping_jpa_map_keyjoincols">
+        <title>Key Join Columns</title>
+        <indexterm zone="ref_guide_mapping_jpa_map_keyjoincols">
+            <primary>KeyJoinColumn</primary>
+            <seealso>mapping metadata</seealso>
+        </indexterm>
+        <para>
+        Key join columns are equivalent to standard JPA
+        join columns, except that they represent a join to a map key entity rather than a direct relation.  You represent
+        a key join column with OpenJPA's
+        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.html">
+        <classname>org.apache.openjpa.persistence.jdbc.KeyJoinColumn</classname></ulink> annotation.  To declare a compound join, enclose an
+        array of <classname>KeyJoinColumn</classname>s in the
+        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.html">
+        <classname>org.apache.openjpa.persistence.jdbc.KeyJoinColumns</classname>
+        </ulink> annotation.
+        </para>
+        <para>
+        A <classname>KeyJoinColumn</classname> always resides in
+        a container table, so it does not have the <literal>table</literal> property
+        of a standard <classname>JoinColumn</classname>.  Like <classname>XJoinColumn</classname>s above,
+        <classname>KeyJoinColumn</classname>s can reference a linked field
+        rather than a static linked column.  Otherwise, the <classname>KeyJoinColumn</classname>
+        and standard <classname>JoinColumn</classname> annotations are equivalent.  See
+        <xref linkend="jpa_overview_mapping_rel"/> in the JPA
+        Overview for a review of the <classname>JoinColumn</classname> annotation.
+        </para>
+    </section>
+    <section id="ref_guide_mapping_jpa_map_embedkey">
+        <title>Key Embedded Mapping</title>
+        <indexterm zone="ref_guide_mapping_jpa_map_embedkey">
+            <primary>KeyEmbeddedMapping</primary>
+            <seealso>mapping metadata</seealso>
+        </indexterm>
+        <para>
+        The
+        <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.html">
+        <classname>org.apache.openjpa.persistence.jdbc.KeyEmbeddedMapping</classname>
+        </ulink> annotation allows you to map your map field's embedded
+        key type to your container table.  This annotation has exactly
+        the same properties as the
+        <classname>EmbeddedMapping</classname> annotation described
+        <link linkend="ref_guide_mapping_jpa_embed">above</link>.
+        </para>
+    </section>
+    <section id="ref_guide_mapping_jpa_map_ex">
+        <title>Examples</title>
+        <mediaobject>
+            <imageobject>
+                <!-- PNG image data, 410 x 266 (see README) -->
+                <imagedata fileref="img/string-rel-map.png" width="273px"/>
+            </imageobject>
+        </mediaobject>
+        <para>
+        Map mapping in OpenJPA uses the same principles you saw in
+        collection mapping.  The example below maps the <literal>
+        Article.authors</literal> map according to the diagram above.
+        </para>
+        <example id="ref_guide_mapping_jpa_map_stringrelmap">
+            <title>String Key, Entity Value Map Mapping</title>
+<programlisting>
+package org.mag.pub;
+
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+@Entity
+@Table(name="AUTH")
+@DataStoreIdColumn(name="AID" columnDefinition="INTEGER64")
+public class Author {
+    ...
+}
+
+package org.mag;
+
+@Entity
+@Table(name="ART")
+public class Article {
+    @Id private long id;
+
+    @PersistentMap
+    @ContainerTable(name="ART_AUTHS", joinColumns=@XJoinColumn(name="ART_ID"))
+    @KeyColumn(name="LNAME")
+    @ElementJoinColumn(name="AUTH_ID")
+    private Map&lt;String,Author&gt; authors;
+
+    ...
+}
+</programlisting>
+                </example>
+            </section>
+    <section id="ref_guide_mapping_limits">
+        <title>
+            Mapping Limitations
+        </title>
+        <indexterm zone="ref_guide_mapping_limits">
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                limitations
+            </secondary>
+        </indexterm>
+        <para>
+The following sections outline the limitations OpenJPA places on specific
+mapping strategies.
+        </para>
+        <section id="ref_guide_mapping_limits_tpc">
+            <title>
+                Table Per Class
+            </title>
+            <indexterm zone="ref_guide_mapping_limits">
+                <primary>
+                    mapping metadata
+                </primary>
+                <secondary>
+                    limitations
+                </secondary>
+                <tertiary>
+                    table-per-class
+                </tertiary>
+            </indexterm>
+            <para>
+Table-per-class inheritance mapping has the following limitations:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+You cannot traverse polymorphic relations to non-leaf classes in a
+table-per-class inheritance hierarchy in queries.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+You cannot map a one-sided polymorphic relation to a non-leaf class in a
+table-per-class inheritance hierarchy using an inverse foreign key.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+You cannot use an order column in a polymorphic relation to a non-leaf class in
+a table-per-class inheritance hierarchy mapped with an inverse foreign key.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+Table-per-class hierarchies impose limitations on eager fetching. See
+<xref linkend="ref_guide_perfpack_eager_consider"/>.
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <note>
+                <para>
+Non-polymorphic relations do not suffer from these limitations. You can declare
+a non-polymorphic relation using the extensions described in
+<xref linkend="nonpolymorphic"/>.
+                </para>
+            </note>
+        </section>
+    </section>
+    <section id="ref_guide_mapping_ext">
+        <title>
+            Mapping Extensions
+        </title>
+        <para>
+Mapping extensions allow you to access OpenJPA-specific functionality from your
+mappings. Note that all extensions below are specific to mappings. If you store
+your mappings separately from your persistence metadata, these extensions must
+be specified along with the mapping information, not the persistence metadata
+information.
+        </para>
+        <section id="ref_guide_mapping_ext_cls">
+            <title>
+                Class Extensions
+            </title>
+            <para>
+OpenJPA recognizes the following class extensions.
+            </para>
+            <section id="subclass-fetch-mode">
+                <title>
+                    Subclass Fetch Mode
+                </title>
+                <indexterm zone="subclass-fetch-mode">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        subclass fetch mode
+                    </tertiary>
+                    <seealso>
+                        eager fetching
+                    </seealso>
+                </indexterm>
+                <para>
+This extension specifies how to eagerly fetch subclass state. It overrides the
+global <link linkend="openjpa.jdbc.SubclassFetchMode"><literal>
+openjpa.jdbc.SubclassFetchMode</literal></link> property. Set the JPA
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/SubclassFetchMode.html">
+<classname>org.apache.openjpa.persistence.jdbc.SubclassFetchMode</classname>
+</ulink> annotation to a value from the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchType.html">
+<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname>
+</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or
+<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/>
+ for a discussion of eager fetching.
+                </para>
+            </section>
+            <section id="class-strategy">
+                <title>
+                    Strategy
+                </title>
+                <indexterm zone="strategy">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        strategy
+                    </tertiary>
+                    <seealso>
+                        custom mapping
+                    </seealso>
+                </indexterm>
+                <para>
+The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
+class annotation allows you to specify a custom mapping strategy for your class.
+See <xref linkend="ref_guide_mapping_custom"/> for information on custom
+mappings.
+                </para>
+            </section>
+            <section id="discriminator-strategy">
+                <title>
+                    Discriminator Strategy
+                </title>
+                <indexterm zone="strategy">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        discriminator strategy
+                    </tertiary>
+                    <seealso>
+                        custom mapping
+                    </seealso>
+                </indexterm>
+                <para>
+The
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DiscriminatorStrategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.DiscriminatorStrategy</classname>
+</ulink> class annotation allows you to specify a custom discriminator strategy.
+See <xref linkend="ref_guide_mapping_custom"/> for information on custom
+mappings.
+                </para>
+            </section>
+            <section id="version-strategy">
+                <title>
+                    Version Strategy
+                </title>
+                <indexterm zone="strategy">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        version strategy
+                    </tertiary>
+                    <seealso>
+                        custom mapping
+                    </seealso>
+                </indexterm>
+                <para>
+The
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionStrategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.VersionStrategy</classname>
+</ulink> class annotation allows you to specify a custom version strategy. See
+<xref linkend="ref_guide_mapping_custom"/> for information on custom
+mappings.
+                </para>
+            </section>
+        </section>
+        <section id="ref_guide_mapping_ext_field">
+            <title>
+                Field Extensions
+            </title>
+            <para>
+OpenJPA recognizes the following field extensions.
+            </para>
+            <section id="eager-fetch-mode">
+                <title>
+                    Eager Fetch Mode
+                </title>
+                <indexterm zone="eager-fetch-mode">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        eager fetch mode
+                    </tertiary>
+                    <seealso>
+                        eager fetching
+                    </seealso>
+                </indexterm>
+                <para>
+This extension specifies how to eagerly fetch related objects. It overrides the
+global <link linkend="openjpa.jdbc.EagerFetchMode"><literal>
+openjpa.jdbc.EagerFetchMode</literal></link> property. Set the JPA
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchMode.html">
+<classname>org.apache.openjpa.persistence.jdbc.EagerFetchMode</classname>
+</ulink> annotation to a value from the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchType.html">
+<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname>
+</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or
+<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/>
+ for a discussion of eager fetching.
+                </para>
+            </section>
+            <section id="nonpolymorphic">
+                <title>
+                    Nonpolymorphic
+                </title>
+                <indexterm zone="nonpolymorphic">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        nonpolymorphic
+                    </tertiary>
+                </indexterm>
+                <para>
+All fields in Java are polymorphic. If you declare a field of type <literal>T
+</literal>, you can assign any subclass of <literal>T</literal> to the field as
+well. This is very convenient, but can make relation traversal very inefficient
+under some inheritance strategies. It can even make querying across the field
+impossible. Often, you know that certain fields do not need to be entirely
+polymorphic. By telling OpenJPA about such fields, you can improve the
+efficiency of your relations.
+                </para>
+                <note>
+                    <para>
+OpenJPA also includes the <literal>type</literal> metadata extension for
+narrowing the declared type of a field. See <xref linkend="type"/>.
+                    </para>
+                </note>
+                <para>
+OpenJPA defines the following extensions for nonpolymorphic values:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Nonpolymorphic.html">
+<classname>org.apache.openjpa.persistence.jdbc.Nonpolymorphic</classname>
+</ulink>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementNonpolymorphic.html">
+<classname>org.apache.openjpa.persistence.jdbc.ElementNonpolymorphic</classname>
+</ulink>
+                        </para>
+                    </listitem>
+                </itemizedlist>
+                <para>
+The value of these extensions is a constant from the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/NonpolymorphicType.html">
+<classname>org.apache.openjpa.persistence.jdbc.NonpolymorphicType</classname>
+</ulink> enumeration. The default value, <literal>EXACT</literal>, indicates
+that the relation will always be of the exact declared type. A value of
+<literal>JOINABLE</literal>, on the other hand, means that the relation might
+be to any joinable subclass of the declared type. This value only excludes
+table-per-class subclasses.
+                </para>
+            </section>
+            <section id="class-criteria">
+                <title>
+                    Class Criteria
+                </title>
+                <indexterm zone="eager-fetch-mode">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        class criteria
+                    </tertiary>
+                    <seealso>
+                        joins
+                    </seealso>
+                </indexterm>
+                <indexterm zone="eager-fetch-mode">
+                    <primary>
+                        joins
+                    </primary>
+                    <secondary>
+                        class criteria
+                    </secondary>
+                </indexterm>
+                <para>
+This family of boolean extensions determines whether OpenJPA will use the
+expected class of related objects as criteria in the SQL it issues to load a
+relation field. Typically, this is not needed. The foreign key values uniquely
+identify the record for the related object. Under some rare mappings, however,
+you may need to consider both foreign key values and the expected class of the
+related object - for example, if you have an inverse relation that shares the
+foreign key with another inverse relation to an object of a different subclass.
+In these cases, set the proper class critera extension to <literal>true
+</literal> to force OpenJPA to append class criteria to its select SQL.
+                </para>
+                <para>
+OpenJPA defines the following class criteria annotations for field relations and
+array or collection element relations, respectively:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ClassCriteria.html">
+<classname>org.apache.openjpa.persistence.jdbc.ClassCriteria</classname></ulink>
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementClassCriteria.html">
+<classname>org.apache.openjpa.persistence.jdbc.ElementClassCriteria</classname>
+</ulink>
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </section>
+            <section id="strategy">
+                <title>
+                    Strategy
+                </title>
+                <indexterm zone="strategy">
+                    <primary>
+                        mapping metadata
+                    </primary>
+                    <secondary>
+                        extensions
+                    </secondary>
+                    <tertiary>
+                        strategy
+                    </tertiary>
+                    <seealso>
+                        custom mapping
+                    </seealso>
+                </indexterm>
+                <para>
+OpenJPA's
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
+extension allows you to specify a custom mapping
+strategy or value handler for a field. See
+<xref linkend="ref_guide_mapping_custom"/> for information on custom
+mappings.
+                </para>
+            </section>
+        </section>
+    </section>
+    <section id="ref_guide_mapping_custom">
+        <title>
+            Custom Mappings
+        </title>
+        <indexterm zone="ref_guide_mapping_custom">
+            <primary>
+                custom mapping
+            </primary>
+        </indexterm>
+        <indexterm>
+            <primary>
+                mapping metadata
+            </primary>
+            <secondary>
+                custom mapping
+            </secondary>
+            <see>
+                custom mapping
+            </see>
+        </indexterm>
+        <para>
+In OpenJPA, you are not limited to the set of standard mappings defined by the
+specification. OpenJPA allows you to define custom class, discriminator,
+version, and field mapping strategies with all the power of OpenJPA's built-in
+strategies.
+        </para>
+        <section id="ref_guide_mapping_custom_class">
+            <title>
+                Custom Class Mapping
+            </title>
+            <para>
+To create a custom class mapping, write an implementation of the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ClassStrategy.html">
+<classname>org.apache.openjpa.jdbc.meta.ClassStrategy</classname></ulink>
+interface. You will probably want to extend one of the existing abstract or
+concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats
+</literal> package.
+            </para>
+            <para>
+The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
+annotation allows you to declare a custom class mapping strategy in JPA mapping
+metadata. Set the value of the annotation to the full class name of your custom
+strategy. You can configure your strategy class' bean properties using
+OpenJPA's plugin syntax, detailed in <xref linkend="ref_guide_conf_plugins"/>.
+            </para>
+        </section>
+        <section id="ref_guide_mapping_custom_versdiscrim">
+            <title>
+                Custom Discriminator and Version Strategies
+            </title>
+            <para>
+To define a custom discriminator or version strategy, implement the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.html">
+<classname>org.apache.openjpa.jdbc.meta.DiscriminatorStrategy</classname>
+</ulink> or
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/VersionStrategy.html">
+<classname>org.apache.openjpa.jdbc.meta.VersionStrategy</classname></ulink>
+interface, respectively. You might extend one of the existing abstract or
+concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats
+</literal> package.
+            </para>
+            <para>
+OpenJPA includes the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DiscriminatorStrategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.DiscriminatorStrategy</classname>
+</ulink> and
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionStrategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.VersionStrategy</classname>
+</ulink> class annotations for declaring a custom discriminator or version
+strategy in JPA mapping metadata. Set the string value of these annotations to
+the full class name of your implementation, or to the class name or alias of an
+existing OpenJPA implementation.
+            </para>
+            <para>
+As with custom class mappings, you can configure your strategy class' bean
+properties using OpenJPA's plugin syntax, detailed in
+<xref linkend="ref_guide_conf_plugins"/>.
+            </para>
+        </section>
+        <section id="ref_guide_mapping_custom_field">
+            <title>
+                Custom Field Mapping
+            </title>
+            <indexterm zone="ref_guide_mapping_custom_field">
+                <primary>
+                    custom mapping
+                </primary>
+                <secondary>
+                    field mapping
+                </secondary>
+            </indexterm>
+            <para>
+While custom class, discriminator, and version mapping can be useful, custom
+field mappings are far more common. OpenJPA offers two types of custom field
+mappings: value handlers, and full custom field strategies. The following
+sections examine each.
+            </para>
+            <section id="ref_guide_mapping_custom_vhandler">
+                <title>
+                    Value Handlers
+                </title>
+                <indexterm zone="ref_guide_mapping_custom_fieldstrat">
+                    <primary>
+                        custom mapping
+                    </primary>
+                    <secondary>
+                        field mapping
+                    </secondary>
+                    <tertiary>
+                        value handler
+                    </tertiary>
+                </indexterm>
+                <para>
+Value handlers make it trivial to map any type that you can break down into one
+or more simple values. All value handlers implement the <classname>
+org.apache.openjpa.jdbc.meta.ValueHandler</classname> interface; see its
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ValueHandler.html"> Javadoc
+</ulink> for details.  Also, examine the built-in handlers in the <filename>
+src/openjpa/jdbc/meta/strats</filename> directory of your OpenJPA source
+distribution.  Use these functional implementations as examples when you
+create your own value handlers.
+                </para>
+            </section>
+            <section id="ref_guide_mapping_custom_fieldstrat">
+                <title>
+                    Field Strategies
+                </title>
+                <indexterm zone="ref_guide_mapping_custom_fieldstrat">
+                    <primary>
+                        custom mapping
+                    </primary>
+                    <secondary>
+                        field mapping
+                    </secondary>
+                    <tertiary>
+                        field strategy
+                    </tertiary>
+                </indexterm>
+                <para>
+OpenJPA interacts with persistent fields through the
+<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/FieldStrategy"><classname>
+org.apache.openjpa.jdbc.meta.FieldStrategy</classname></ulink> interface. You
+can implement this interface yourself to create a custom field strategy, or
+extend one of the existing abstract or concrete strategies in the <literal>
+org.apache.openjpa.jdbc.meta.strats</literal> package. Creating a custom field
+strategy is more difficult than writing a custom value handler, but gives you
+more freedom in how you interact with the database.
+                </para>
+            </section>
+            <section id="ref_guide_mapping_custom_field_conf">
+                <title>
+                    Configuration
+                </title>
+                <indexterm zone="ref_guide_mapping_custom_field_conf">
+                    <primary>
+                        custom mapping
+                    </primary>
+                    <secondary>
+                        field mapping
+                    </secondary>
+                    <tertiary>
+                        configuration
+                    </tertiary>
+                </indexterm>
+                <para>
+OpenJPA gives you two ways to configure your custom field mappings. The
+<literal>FieldStrategies</literal> property of the built-in <classname>
+MappingDefaults</classname> implementations allows you to globally associate
+field types with their corresponding custom value handler or strategy. OpenJPA
+will automatically use your custom strategies when it encounters a field of the
+associated type. OpenJPA will use your custom value handlers whenever it
+encounters a field of the associated type.
+<xref linkend="ref_guide_mapping_defaults"/> described mapping
+defaults in detail.
+                </para>
+                <para>
+Your other option is to explicitly install a custom value handler or strategy on
+a particular field. To do so, specify the full name of your implementation class
+in the proper mapping metadata extension. OpenJPA includes the
+<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html">
+<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
+annotation. You can configure the named strategy or handler's bean
+properties in these extensions using OpenJPA's plugin format (see
+<xref linkend="ref_guide_conf_plugins"/>).
+                </para>
+            </section>
+        </section>
+    </section>
+    <section id="ref_guide_orphan">
+        <title>
+            Orphaned Keys
+        </title>
+        <para>
+Unless you apply database foreign key constraints extensively, it is possible to
+end up with orphaned keys in your database. For example, suppose <classname>
+Magazine</classname><literal>m</literal> has a reference to <classname>Article
+</classname><literal>a</literal>. If you delete <literal>a</literal> without
+nulling <literal>m</literal>'s reference, <literal>m</literal>'s database
+record will wind up with an orphaned key to the non-existent <literal>a
+</literal> record.
+        </para>
+        <note>
+            <para>
+One way of avoiding orphaned keys is to use <emphasis>dependent</emphasis>
+fields.
+            </para>
+        </note>
+        <para>
+OpenJPA's <link linkend="openjpa.OrphanedKeyAction"><literal>
+openjpa.OrphanedKeyAction</literal></link> configuration property controls what
+action to take when OpenJPA encounters an orphaned key. You can set this plugin
+string (see <xref linkend="ref_guide_conf_plugins"/>) to a custom
+implementation of the
+<ulink url="../javadoc/org/apache/openjpa/event/OrphanedKeyAction.html">
+<classname> org.apache.openjpa.event.OrphanedKeyAction</classname></ulink>
+interface, or use one of the built-in options:
+        </para>
+        <itemizedlist>
+            <listitem>
+                <para>
+<literal>log</literal>: This is the default setting. This option logs a message
+for each orphaned key. It is an alias for the
+<ulink url="../javadoc/org/apache/openjpa/event/LogOrphanedKeyAction.html">
+<classname>org.apache.openjpa.event.LogOrphanedKeyAction</classname></ulink>
+class, which has the following additional properties:
+                </para>
+                <itemizedlist>
+                    <listitem>
+                        <para>
+<literal>Channel</literal>: The channel to log to. Defaults to <literal>
+openjpa.Runtime</literal>.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+<literal>Level</literal>: The level to log at. Defaults to <literal>WARN
+</literal>.
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </listitem>
+            <listitem>
+                <para>
+<literal>exception</literal>: Throw an <classname>
+EntityNotFoundException</classname> when OpenJPA discovers an
+orphaned key. This is an alias for the
+<ulink url="../javadoc/org/apache/openjpa/event/ExceptionOrphanedKeyAction.html">
+<classname>org.apache.openjpa.event.ExceptionOrphanedKeyAction</classname>
+</ulink> class.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+<literal>none</literal>: Ignore orphaned keys. This is an alias for the
+<ulink url="../javadoc/org/apache/openjpa/event/NoneOrphanedKeyAction.html">
+<classname>org.apache.openjpa.event.NoneOrphanedKeyAction</classname></ulink>
+class.
+                </para>
+            </listitem>
+        </itemizedlist>
+        <example id="ref_guide_orphan_logex">
+            <title>
+                Custom Logging Orphaned Keys
+            </title>
+<programlisting>
+&lt;property name="openjpa.OrphanedKeyAction" value="log(Channel=Orphans, Level=DEBUG)"/&gt;
+</programlisting>
+        </example>
+    </section>
+</chapter>
diff --git a/openjpa-project/src/doc/manual/ref_guide_slice.xml b/openjpa-project/src/doc/manual/ref_guide_slice.xml
index 8298bfe..e222cb2 100644
--- a/openjpa-project/src/doc/manual/ref_guide_slice.xml
+++ b/openjpa-project/src/doc/manual/ref_guide_slice.xml
@@ -1,543 +1,543 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
- http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.   
--->
-<chapter id="ref_guide_slice">
-  <title>
-    Distributed Persistence
-  </title>
-  <para>
-  The standard JPA runtime environment works with a <emphasis>single</emphasis>
-  database instance. OpenJPA can be extended via plug-in to work with 
-  multiple databases within the same transaction without any change to the 
-  existing application. This capability of OpenJPA for distributed 
-  database environment is called <emphasis>Slice</emphasis> and is explained in 
-  the following sections.
-  </para>
-  
-  <section id="slice_overview">
-    <title>Overview</title>
-    <para>
-    Enterprise applications are increasingly deployed for distributed database
-    environments. The reasons for distributed, often horizontally-partitioned 
-    database environment can be to counter massive data growth, to 
-    support multiple external clients on a hosted platform or many other 
-    practical scenarios that can benefit from data partitioning.
-    </para>
-    
-    <para>
-    Any JPA-based user application has to address serious technical and conceptual
-    challenges to directly interact with a set of physical databases
-    within a single transaction. 
-    Slice encapsulates the complexity of distributed database environment 
-    via the abstraction of <emphasis>virtual</emphasis> database which internally 
-    manages multiple physical databases. We refer each physical database instance 
-    as <emphasis>slice</emphasis>. 
-    <emphasis>Virtualization</emphasis> of distributed databases 
-    makes OpenJPA object management kernel and 
-    the user application to work in the same way as in the case of a single physical 
-    database.
-    </para>
-  </section>
-  
-    <section id="Features and Limitations">
-       <title>Salient Features</title>
-         <section><title>Transparency</title>
-            <para>
-              The existing application or the persistent domain model requires 
-              <emphasis>no change</emphasis> to upgrade from a single database 
-              to a distributed database environment. 
-            </para>
-         </section>
-         
-         <section><title>Custom Distribution Policy</title>
-            <para>
-             User application decides how the newly persistent instances be 
-             distributed across the database slices. The data
-             distribution policy across the slices may be based on the attribute 
-             of the data itself. For example, all Customer whose first name begins with
-             character 'A' to 'M' will be stored in one slice while names
-             beginning with 'N' to 'Z' will be stored in another slice. 
-             </para>
-             <para>
-             This custom data distribution policy is specified by implementing  
-             <classname>org.apache.openjpa.slice.DistributionPolicy</classname>
-             interface by the user application.
-             </para>
-          
-             <para> 
-             Slice tracks the original database for existing instances. When
-             an application issues a query, the resultant instances can be loaded 
-             from different slices. This tracking is important as subsequent
-             update to any of these instances is committed to the appropriate 
-             original database slice. 
-            </para>
-            
-            <note>
-            <para>
-            You can find the original slice of an instance <code>pc</code> by 
-            the static utility method  
-            <methodname>SlicePersistence.getSlice(pc)</methodname>.
-            This method returns the slice identifier string associated with the
-            given <emphasis>managed</emphasis> instance. If the instance is not
-            being managed then the method return null because any unmanaged or
-            detached instance is not associated with any slice. 
-            </para>
-            </note>
-            
-            <para>
-            <warning>Currently, there is no provision for migrating an 
-            existing instance from one slice to another.
-            </warning>
-            </para>
-         </section>
-         
-         <section><title>Heterogeneous Database</title>
-            <para> 
-              Each slice can be configured independently with its own JDBC 
-              driver and other connection parameters. Hence the target database 
-              environment can constitute of heterogeneous databases. 
-            </para>
-        </section>
-        
-        <section><title>Parallel Execution</title>
-            <para> 
-              All database operations such as query, commit or flush operates
-              in parallel across the database slices. The execution threading
-              policy is configurable. 
-            </para>
-         </section>
-         
-         <section><title>Distributed Query</title>
-            <para>
-            The queries are executed across all slices and the results are
-            merged into a single list. The query result that includes 
-            <code>ORDER BY</code> clause are sorted correctly by merging 
-            results from each individual slice. 
-            </para>
-            The queries that specify an aggregate projection such as 
-            <code>COUNT()</code>, <code>MAX()</code>, <code>MIN()</code> 
-            and <code>SUM()</code>
-            are correctly evaluated <emphasis>only if</emphasis> they 
-            return a single result.
-            <para>
-            </para>
-            <para>
-            <warning>
-            The aggregate operation <code>AVG()</code> is not supported.
-            </warning>
-            </para>
-            
-         </section>
-         
-         <section><title>Targeted Query</title>
-            <para>
-            You can target the query only to a subset of slices rather than
-            all slices by setting a <emphasis>hint</emphasis>. The hint key
-            <code>openjpa.hint.slice.Target</code> is set on any query and 
-            hint value is
-            comma-separated list of slice identifiers. The following 
-            example shows how to target a query only to slice <code>"One"</code>
-                          
-            <programlisting>
-              <![CDATA[EntityManager em = ...;
-              em.getTransaction().begin();
-              String hint = "openjpa.hint.slice.Target";
-              Query query = em.createQuery("SELECT p FROM PObject").setHint(hint, "One");
-              List result = query.getResultList();
-              // verify that each instance is originaing from the given slice
-              for (Object pc : result) {
-                 String sliceOrigin = SlicePersistence.getSlice(pc);
-                 assertTrue ("One", sliceOrigin);
-              }
-              ]]>
-            </programlisting> 
-            </para>
-         </section>
-         
-         
-         <section><title>Distributed Transaction</title>
-            <para> 
-            The database slices participate in a global transaction provided
-            each slice is configured with a XA-compliant JDBC driver, even
-            when the persistence unit is configured for <code>RESOURCE_LOCAL</code>
-            transaction.
-            </para>
-            <para>
-            <warning>
-            If any of the configured slices is not XA-compliant <emphasis>and</emphasis> 
-            the persistence unit is configured for <code>RESOURCE_LOCAL</code>
-            transaction then each slice is committed without any two-phase
-            commit protocol. If commit on any slice fails, then atomic nature of
-            the transaction is not ensured.
-            </warning>
-            </para>
-          </section>
-   
-    
-    
-        
-         <section id="collocation_constraint"><title>Collocation Constraint</title>
-            <para> 
-            No relationship can exist across database slices. In O-R mapping parlance,
-            this condition translates to the limitation that the closure of an object graph must be 
-            <emphasis>collocated</emphasis> in the same database.
-            For example, consider a domain model where Person relates to Adress.
-            Person X refers to Address A while Person Y refers to Address B. 
-            Collocation Constraint means that <emphasis>both</emphasis> X and A 
-            must be stored in the same
-            database slice. Similarly Y and B must be stored in a single slice.
-            </para>
-            <para>
-            Slice, however, helps to maintain collocation constraint automatically.
-            The instances in the closure set of any newly persistent instance 
-            reachable via cascaded relationship is stored in the same slice.
-            The user-defined distribution policy requires to supply the slice 
-            for the root instance only.
-            </para>
-         </section>
-    </section>
-  
-  <section id="slice_configuration">
-    <title>Usage</title>
-    <para>
-     Slice is activated via the following property settings:
-    </para>
-    <section>
-      <title>How to activate Slice Runtime?</title>
-      <para>
-       The basic configuration property is 
-       <programlisting> 
-        <![CDATA[ <property name="openjpa.BrokerFactory" value="slice"/>]]>
-       </programlisting> 
-       This critical configuration activates a specialized factory class aliased
-       as <code>slice</code> to create object management kernel that
-       can work against multiple databases.  
-      </para>
-    </section> 
-    
-    <section>
-      <title>How to configure each database slice?</title>
-      <para>
-      Each database slice is identified by a logical name unique within a
-      persistent unit. The list of the slices is specified by 
-      <code>openjpa.slice.Names</code> property.
-      For example, specify three slices named <code>"One"</code>, 
-      <code>"Two"</code> and <code>"Three"</code> as follows:
-      <programlisting>
-      <![CDATA[ <property name="openjpa.slice.Names" value="One, Two, Three"/>]]>
-      </programlisting>
-      </para>
-      <para>
-      This property is not mandatory. If this property is not specified then
-      the configuration is scanned for logical slice names. Any property
-      <code>"abc"</code> of the form <code>openjpa.slice.XYZ.abc</code> will 
-      register a slice with logical
-      name <code>"XYZ"</code>.
-      </para>
-      <para>
-      The order of the names is significant when no <code>openjpa.slice.Master</code> 
-      property is not specified. Then the persistence unit is scanned to find
-      all configured slice names and they are ordered alphabetically.  
-      </para>
-      
-      <para>
-       Each database slice properties can be configured independently. 
-       For example, the
-       following configuration will register two slices with logical name 
-       <code>One</code> and <code>Two</code>.
-       <programlisting> 
-        <![CDATA[<property name="openjpa.slice.One.ConnectionURL" value="jdbc:mysql:localhost//slice1"/>
-        <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:mysql:localhost//slice2"/>]]>
-       </programlisting> 
-      </para>
-      
-      <para>
-       Any OpenJPA specific property can be configured per slice basis. 
-       For example, the following configuration will use two different JDBC 
-       drivers for slice <code>One</code> and <code>Two</code>.
-       <programlisting> 
-        <![CDATA[<property name="openjpa.slice.One.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
-        <property name="openjpa.slice.Two.ConnectionDriverName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>]]>
-       </programlisting> 
-      </para>
-      
-      <para>
-        Any property if unspecified for a particular slice will be defaulted by
-        corresponding OpenJPA property. For example, consider following three slices
-        <programlisting> 
-         <![CDATA[<property name="openjpa.slice.One.ConnectionURL"          value="jdbc:mysql:localhost//slice1"/>
-         <property name="openjpa.slice.Two.ConnectionURL"          value="jdbc:mysql:localhost//slice2"/>
-         <property name="openjpa.slice.Three.ConnectionURL"        value="jdbc:oracle:localhost//slice3"/>
-
-         <property name="openjpa.ConnectionDriverName"     value="com.mysql.jdbc.Driver"/>
-         <property name="openjpa.slice.Three.ConnectionDriverName" value="oracle.jdbc.Driver"/>]]>
-        </programlisting> 
-        In this example, <code>Three</code> will use slice-specific
-        <code>oracle.jdbc.Driver</code> driver while slice
-        <code>One</code> and <code>Two</code> will use
-        the driver <code>com.mysql.jdbc.Driver</code> as 
-        specified by <code>openjpa.ConnectionDriverName</code> 
-        property value.
-      </para>
-    </section>
-     
-    <section id="distribution_policy">
-       <title>Implement DistributionPolicy interface</title>
-       <para>
-        Slice needs to determine which slice will persist a new instance. 
-        The application can only decide this policy (for example, 
-        all PurchaseOrders before April 30 goes to slice <code>One</code>,
-        all the rest goes to slice <code>Two</code>). This is why
-        the application has to implement 
-        <code>org.apache.openjpa.slice.DistributionPolicy</code> and
-        specify the implementation class in configuration
-        <programlisting> 
-         <![CDATA[ <property name="openjpa.slice.DistributionPolicy" value="com.acme.foo.MyOptimialDistributionPolicy"/>]]>
-        </programlisting>
-       </para>
-       
-       <para>
-        The interface <code>org.apache.openjpa.slice.DistributionPolicy</code>
-        is simple with a single method. The complete listing of the
-        documented interface follows:
-       <programlisting> 
-       <![CDATA[ 
-public interface DistributionPolicy {
-    /**
-     * Gets the name of the slice where a given instance will be stored.
-     *  
-     * @param pc The newly persistent or to-be-merged object. 
-     * @param slices name of the configured slices.
-     * @param context persistence context managing the given instance.
-     * 
-     * @return identifier of the slice. This name must match one of the
-     * configured slice names. 
-     * @see DistributedConfiguration#getSliceNames()
-     */
-    String distribute(Object pc, List<String> slices, Object context);
-}
-]]>
-       </programlisting>
-        </para>
-        
-        <para>
-        While implementing a distribution policy the most important thing to
-        remember is <link linkend="collocation_constraint">collocation constraint</link>.
-        Because Slice can not establish or query any cross-database relationship, all the
-        related instances must be stored in the same database slice. 
- 
-        Slice can determine the closure of a root object by traversal of 
-        cascaded relationships. Hence user-defined policy has to only decide the
-        database for the root instance that is the explicit argument to 
-        <methodname>EntityManager.persist()</methodname> call.
-        Slice will ensure that all other related instances that gets persisted by cascade
-        is assigned to the same database slice as that of the root instance.
-        However, the user-defined distribution policy must return the
-        same slice identifier for the instances that are logically related but
-        not cascaded for persist. 
-        </para>
-    </section>
-    
-    <section>
-    </section>
-  </section>
-  
-  <title>Configuration Properties</title>
-    <para>
-    The properties to configure Slice can be classified in two broad groups.
-The <emphasis>global</emphasis> properties apply to all the slices, for example,
-the thread pool used to execute the queries in parallel or the transaction 
-manager used to coordinate transaction across multiple slices. 
-The <emphasis>per-slice</emphasis> properties apply to individual slice, for example,
-the JDBC connection URL of a slice.
-   </para>
-   
-   <section>
-     <title>Global Properties</title>
-     
-     <section>
-        <title>openjpa.slice.DistributionPolicy</title>
-        <para>
-         This <emphasis>mandatory</emphasis> plug-in property determines how newly
-         persistent instances are distributed across individual slices. 
-         The value of this property is a fully-qualified class name that implements
-         <ulink url="../javadoc/org/apache/openjpa/slice/DistributionPolicy.html">
-         <classname>org.apache.openjpa.slice.DistributionPolicy</classname>
-         </ulink> interface.
-        </para>
-     </section>
-     
-     <section><title>openjpa.slice.Lenient</title>
-      <para>
-        This boolean plug-in property controls the behavior when one or more slice 
-        can not be connected or unavailable for some other reasons.
-        If <code>true</code>, the unreachable slices are ignored. If 
-        <code>false</code> then any unreachable slice will raise an exception
-        during startup.
-        </para>
-        <para>
-        By default this value is set to <code>false</code> i.e. all configured
-        slices must be available.
-        </para> 
-     </section>
-
-     <section>
-      <title>openjpa.slice.Master</title>
-      <para>
-       This plug-in property can be used to identify the name of the master slice. 
-       Master slice is used when a primary key is to be generated from a database sequence. 
-       </para>
-       <para>
-        By default the master slice is the first slice in the list of configured slice names. 
-       </para>
-       <para>
-              <warning>
-              Currently, there is no provision to use sequence from 
-              multiple database slices.
-              </warning>
-       </para>
-     </section>
-    
-     <section>
-        <title>openjpa.slice.Names</title>
-        <para>
-         This plug-in property can be used to register the logical slice names.
-         The value of this property is comma-separated list of slice names. 
-         The ordering of the names in this list is 
-         <emphasis>significant</emphasis> because 
-         <link linkend="distribution_policy">DistributionPolicy</link> receives 
-         the input argument of the slice names in the same order.
-        </para>
-        <para>
-        If logical slice names are not registered explicitly via this property,
-        then all logical slice names available in the persistence unit are 
-        registered. The ordering of the slice names in this case is alphabetical.  
-        </para>
-        <para>
-        If logical slice names are registered explicitly via this property, then
-        any logical slice that is available in the persistence unit but excluded
-        from this list is ignored. 
-        </para>
-     </section>
-    
-     <section>
-        <title>openjpa.slice.ThreadingPolicy</title>
-        <para>
-        This plug-in property determines the nature of thread pool being used 
-        for database operations such as query or flush on individual slices. 
-        The value of the property is a 
-        fully-qualified class name that implements 
-        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html">
-        <classname>java.util.concurrent.ExecutorService</classname>
-        </ulink> interface.  
-        Two pre-defined pools can be chosen via their aliases namely 
-        <code>fixed</code> or <code>cached</code>.
-        </para>
-        <para>
-        The pre-defined alias <code>cached</code> activates a 
-        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()">cached thread pool</ulink>. 
-        A cached thread pool creates new threads as needed, but will reuse 
-        previously constructed threads when they are available. This pool 
-        is suitable in scenarios that execute many short-lived asynchronous tasks.
-        The way Slice uses the thread pool to execute database operations is 
-        akin to such scenario and hence <code>cached</code> is the default 
-        value for this plug-in property.  
-        </para>
-        <para>
-        The <code>fixed</code> alias activates a 
-        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)">fixed thread pool</ulink>.
-        The fixed thread pool can be further parameterized with 
-        <code>CorePoolSize</code>, <code>MaximumPoolSize</code>, 
-        <code>KeepAliveTime</code> and <code>RejectedExecutionHandler</code>. 
-        The meaning of these parameters are described in 
-        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html">JavaDoc</ulink>.
-        The users can exercise finer control on thread pool behavior via these
-        parameters.
-        By default, the core pool size is <code>10</code>, maximum pool size is
-        also <code>10</code>, keep alive time is <code>60</code> seconds and 
-        rejected execution is 
-        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.AbortPolicy.html">aborted</ulink>.
-        </para>
-        <para>
-        Both of the pre-defined aliases can be parameterized with a fully-qualified
-        class name that implements 
-        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadFactory.html">
-        <classname>java.util.concurrent.ThreadFactory</classname>
-        </ulink> interface.
-        </para>
-     </section>
-      
-     <section>
-      <title>openjpa.slice.TransactionPolicy</title>
-      <para>
-      This plug-in property determines the policy for transaction commit 
-      across multiple slices. The value of this property is a fully-qualified 
-      class name that implements 
-      <ulink url="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/transaction/TransactionManager.html">
-      <classname>javax.transaction.TransactionManager</classname> 
-      </ulink> interface. 
-      </para>
-      <para>
-      Three pre-defined policies can be chosen
-      by their aliases namely <code>default</code>,
-      <code>xa</code> and <code>jndi</code>. 
-      </para>
-      <para>
-      The <code>default</code> policy employs 
-      a Transaction Manager that commits or rolls back transaction on individual
-      slices <emphasis>without</emphasis> a two-phase commit protocol. 
-      It does <emphasis>not</emphasis>
-      guarantee atomic nature of transaction across all the slices because if
-      one or more slice fails to commit, there is no way to rollback the transaction
-      on other slices that committed successfully.
-      </para>
-      <para>
-      The <code>xa</code> policy employs a Transaction Manager that that commits 
-      or rolls back transaction on individual
-      slices using a two-phase commit protocol. The prerequisite to use this scheme
-      is, of course, that all the slices must be configured to use
-      XA-compliant JDBC driver. 
-      </para>
-      <para>
-      The <code>jndi</code> policy employs a Transaction Manager by looking up the
-      JNDI context. The prerequisite to use this transaction
-      manager is, of course, that all the slices must be configured to use
-      XA-compliant JDBC driver. 
-      <warning>This JNDI based policy is not available currently.</warning>
-      </para>
-    </section>
-   </section>
-   
-   <section>
-     <title>Per-Slice Properties</title>
-     <para>
-     Any OpenJPA property can be configured for each individual slice. The property name
-     is of the form <code>openjpa.slice.[Logical slice name].[OpenJPA Property Name]</code>.
-     For example, <code>openjpa.slice.One.ConnectionURL</code> where <code>One</code>
-     is the logical slice name and <code>ConnectionURL</code> is an OpenJPA property
-     name. 
-     </para>
-     <para>
-     If a property is not configured for a specific slice, then the value for
-     the property equals to the corresponding <code>openjpa.*</code> property.
-     </para>
-   </section>
-  
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.   
+-->
+<chapter id="ref_guide_slice">
+  <title>
+    Distributed Persistence
+  </title>
+  <para>
+  The standard JPA runtime environment works with a <emphasis>single</emphasis>
+  database instance. OpenJPA can be extended via plug-in to work with 
+  multiple databases within the same transaction without any change to the 
+  existing application. This capability of OpenJPA for distributed 
+  database environment is called <emphasis>Slice</emphasis> and is explained in 
+  the following sections.
+  </para>
+  
+  <section id="slice_overview">
+    <title>Overview</title>
+    <para>
+    Enterprise applications are increasingly deployed for distributed database
+    environments. The reasons for distributed, often horizontally-partitioned 
+    database environment can be to counter massive data growth, to 
+    support multiple external clients on a hosted platform or many other 
+    practical scenarios that can benefit from data partitioning.
+    </para>
+    
+    <para>
+    Any JPA-based user application has to address serious technical and conceptual
+    challenges to directly interact with a set of physical databases
+    within a single transaction. 
+    Slice encapsulates the complexity of distributed database environment 
+    via the abstraction of <emphasis>virtual</emphasis> database which internally 
+    manages multiple physical databases. We refer each physical database instance 
+    as <emphasis>slice</emphasis>. 
+    <emphasis>Virtualization</emphasis> of distributed databases 
+    makes OpenJPA object management kernel and 
+    the user application to work in the same way as in the case of a single physical 
+    database.
+    </para>
+  </section>
+  
+    <section id="Features and Limitations">
+       <title>Salient Features</title>
+         <section><title>Transparency</title>
+            <para>
+              The existing application or the persistent domain model requires 
+              <emphasis>no change</emphasis> to upgrade from a single database 
+              to a distributed database environment. 
+            </para>
+         </section>
+         
+         <section><title>Custom Distribution Policy</title>
+            <para>
+             User application decides how the newly persistent instances be 
+             distributed across the database slices. The data
+             distribution policy across the slices may be based on the attribute 
+             of the data itself. For example, all Customer whose first name begins with
+             character 'A' to 'M' will be stored in one slice while names
+             beginning with 'N' to 'Z' will be stored in another slice. 
+             </para>
+             <para>
+             This custom data distribution policy is specified by implementing  
+             <classname>org.apache.openjpa.slice.DistributionPolicy</classname>
+             interface by the user application.
+             </para>
+          
+             <para> 
+             Slice tracks the original database for existing instances. When
+             an application issues a query, the resultant instances can be loaded 
+             from different slices. This tracking is important as subsequent
+             update to any of these instances is committed to the appropriate 
+             original database slice. 
+            </para>
+            
+            <note>
+            <para>
+            You can find the original slice of an instance <code>pc</code> by 
+            the static utility method  
+            <methodname>SlicePersistence.getSlice(pc)</methodname>.
+            This method returns the slice identifier string associated with the
+            given <emphasis>managed</emphasis> instance. If the instance is not
+            being managed then the method return null because any unmanaged or
+            detached instance is not associated with any slice. 
+            </para>
+            </note>
+            
+            <para>
+            <warning>Currently, there is no provision for migrating an 
+            existing instance from one slice to another.
+            </warning>
+            </para>
+         </section>
+         
+         <section><title>Heterogeneous Database</title>
+            <para> 
+              Each slice can be configured independently with its own JDBC 
+              driver and other connection parameters. Hence the target database 
+              environment can constitute of heterogeneous databases. 
+            </para>
+        </section>
+        
+        <section><title>Parallel Execution</title>
+            <para> 
+              All database operations such as query, commit or flush operates
+              in parallel across the database slices. The execution threading
+              policy is configurable. 
+            </para>
+         </section>
+         
+         <section><title>Distributed Query</title>
+            <para>
+            The queries are executed across all slices and the results are
+            merged into a single list. The query result that includes 
+            <code>ORDER BY</code> clause are sorted correctly by merging 
+            results from each individual slice. 
+            </para>
+            The queries that specify an aggregate projection such as 
+            <code>COUNT()</code>, <code>MAX()</code>, <code>MIN()</code> 
+            and <code>SUM()</code>
+            are correctly evaluated <emphasis>only if</emphasis> they 
+            return a single result.
+            <para>
+            </para>
+            <para>
+            <warning>
+            The aggregate operation <code>AVG()</code> is not supported.
+            </warning>
+            </para>
+            
+         </section>
+         
+         <section><title>Targeted Query</title>
+            <para>
+            You can target the query only to a subset of slices rather than
+            all slices by setting a <emphasis>hint</emphasis>. The hint key
+            <code>openjpa.hint.slice.Target</code> is set on any query and 
+            hint value is
+            comma-separated list of slice identifiers. The following 
+            example shows how to target a query only to slice <code>"One"</code>
+                          
+            <programlisting>
+              <![CDATA[EntityManager em = ...;
+              em.getTransaction().begin();
+              String hint = "openjpa.hint.slice.Target";
+              Query query = em.createQuery("SELECT p FROM PObject").setHint(hint, "One");
+              List result = query.getResultList();
+              // verify that each instance is originaing from the given slice
+              for (Object pc : result) {
+                 String sliceOrigin = SlicePersistence.getSlice(pc);
+                 assertTrue ("One", sliceOrigin);
+              }
+              ]]>
+            </programlisting> 
+            </para>
+         </section>
+         
+         
+         <section><title>Distributed Transaction</title>
+            <para> 
+            The database slices participate in a global transaction provided
+            each slice is configured with a XA-compliant JDBC driver, even
+            when the persistence unit is configured for <code>RESOURCE_LOCAL</code>
+            transaction.
+            </para>
+            <para>
+            <warning>
+            If any of the configured slices is not XA-compliant <emphasis>and</emphasis> 
+            the persistence unit is configured for <code>RESOURCE_LOCAL</code>
+            transaction then each slice is committed without any two-phase
+            commit protocol. If commit on any slice fails, then atomic nature of
+            the transaction is not ensured.
+            </warning>
+            </para>
+          </section>
+   
+    
+    
+        
+         <section id="collocation_constraint"><title>Collocation Constraint</title>
+            <para> 
+            No relationship can exist across database slices. In O-R mapping parlance,
+            this condition translates to the limitation that the closure of an object graph must be 
+            <emphasis>collocated</emphasis> in the same database.
+            For example, consider a domain model where Person relates to Adress.
+            Person X refers to Address A while Person Y refers to Address B. 
+            Collocation Constraint means that <emphasis>both</emphasis> X and A 
+            must be stored in the same
+            database slice. Similarly Y and B must be stored in a single slice.
+            </para>
+            <para>
+            Slice, however, helps to maintain collocation constraint automatically.
+            The instances in the closure set of any newly persistent instance 
+            reachable via cascaded relationship is stored in the same slice.
+            The user-defined distribution policy requires to supply the slice 
+            for the root instance only.
+            </para>
+         </section>
+    </section>
+  
+  <section id="slice_configuration">
+    <title>Usage</title>
+    <para>
+     Slice is activated via the following property settings:
+    </para>
+    <section>
+      <title>How to activate Slice Runtime?</title>
+      <para>
+       The basic configuration property is 
+       <programlisting> 
+        <![CDATA[ <property name="openjpa.BrokerFactory" value="slice"/>]]>
+       </programlisting> 
+       This critical configuration activates a specialized factory class aliased
+       as <code>slice</code> to create object management kernel that
+       can work against multiple databases.  
+      </para>
+    </section> 
+    
+    <section>
+      <title>How to configure each database slice?</title>
+      <para>
+      Each database slice is identified by a logical name unique within a
+      persistent unit. The list of the slices is specified by 
+      <code>openjpa.slice.Names</code> property.
+      For example, specify three slices named <code>"One"</code>, 
+      <code>"Two"</code> and <code>"Three"</code> as follows:
+      <programlisting>
+      <![CDATA[ <property name="openjpa.slice.Names" value="One, Two, Three"/>]]>
+      </programlisting>
+      </para>
+      <para>
+      This property is not mandatory. If this property is not specified then
+      the configuration is scanned for logical slice names. Any property
+      <code>"abc"</code> of the form <code>openjpa.slice.XYZ.abc</code> will 
+      register a slice with logical
+      name <code>"XYZ"</code>.
+      </para>
+      <para>
+      The order of the names is significant when no <code>openjpa.slice.Master</code> 
+      property is not specified. Then the persistence unit is scanned to find
+      all configured slice names and they are ordered alphabetically.  
+      </para>
+      
+      <para>
+       Each database slice properties can be configured independently. 
+       For example, the
+       following configuration will register two slices with logical name 
+       <code>One</code> and <code>Two</code>.
+       <programlisting> 
+        <![CDATA[<property name="openjpa.slice.One.ConnectionURL" value="jdbc:mysql:localhost//slice1"/>
+        <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:mysql:localhost//slice2"/>]]>
+       </programlisting> 
+      </para>
+      
+      <para>
+       Any OpenJPA specific property can be configured per slice basis. 
+       For example, the following configuration will use two different JDBC 
+       drivers for slice <code>One</code> and <code>Two</code>.
+       <programlisting> 
+        <![CDATA[<property name="openjpa.slice.One.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
+        <property name="openjpa.slice.Two.ConnectionDriverName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>]]>
+       </programlisting> 
+      </para>
+      
+      <para>
+        Any property if unspecified for a particular slice will be defaulted by
+        corresponding OpenJPA property. For example, consider following three slices
+        <programlisting> 
+         <![CDATA[<property name="openjpa.slice.One.ConnectionURL"          value="jdbc:mysql:localhost//slice1"/>
+         <property name="openjpa.slice.Two.ConnectionURL"          value="jdbc:mysql:localhost//slice2"/>
+         <property name="openjpa.slice.Three.ConnectionURL"        value="jdbc:oracle:localhost//slice3"/>
+
+         <property name="openjpa.ConnectionDriverName"     value="com.mysql.jdbc.Driver"/>
+         <property name="openjpa.slice.Three.ConnectionDriverName" value="oracle.jdbc.Driver"/>]]>
+        </programlisting> 
+        In this example, <code>Three</code> will use slice-specific
+        <code>oracle.jdbc.Driver</code> driver while slice
+        <code>One</code> and <code>Two</code> will use
+        the driver <code>com.mysql.jdbc.Driver</code> as 
+        specified by <code>openjpa.ConnectionDriverName</code> 
+        property value.
+      </para>
+    </section>
+     
+    <section id="distribution_policy">
+       <title>Implement DistributionPolicy interface</title>
+       <para>
+        Slice needs to determine which slice will persist a new instance. 
+        The application can only decide this policy (for example, 
+        all PurchaseOrders before April 30 goes to slice <code>One</code>,
+        all the rest goes to slice <code>Two</code>). This is why
+        the application has to implement 
+        <code>org.apache.openjpa.slice.DistributionPolicy</code> and
+        specify the implementation class in configuration
+        <programlisting> 
+         <![CDATA[ <property name="openjpa.slice.DistributionPolicy" value="com.acme.foo.MyOptimialDistributionPolicy"/>]]>
+        </programlisting>
+       </para>
+       
+       <para>
+        The interface <code>org.apache.openjpa.slice.DistributionPolicy</code>
+        is simple with a single method. The complete listing of the
+        documented interface follows:
+       <programlisting> 
+       <![CDATA[ 
+public interface DistributionPolicy {
+    /**
+     * Gets the name of the slice where a given instance will be stored.
+     *  
+     * @param pc The newly persistent or to-be-merged object. 
+     * @param slices name of the configured slices.
+     * @param context persistence context managing the given instance.
+     * 
+     * @return identifier of the slice. This name must match one of the
+     * configured slice names. 
+     * @see DistributedConfiguration#getSliceNames()
+     */
+    String distribute(Object pc, List<String> slices, Object context);
+}
+]]>
+       </programlisting>
+        </para>
+        
+        <para>
+        While implementing a distribution policy the most important thing to
+        remember is <link linkend="collocation_constraint">collocation constraint</link>.
+        Because Slice can not establish or query any cross-database relationship, all the
+        related instances must be stored in the same database slice. 
+ 
+        Slice can determine the closure of a root object by traversal of 
+        cascaded relationships. Hence user-defined policy has to only decide the
+        database for the root instance that is the explicit argument to 
+        <methodname>EntityManager.persist()</methodname> call.
+        Slice will ensure that all other related instances that gets persisted by cascade
+        is assigned to the same database slice as that of the root instance.
+        However, the user-defined distribution policy must return the
+        same slice identifier for the instances that are logically related but
+        not cascaded for persist. 
+        </para>
+    </section>
+    
+    <section>
+    </section>
+  </section>
+  
+  <title>Configuration Properties</title>
+    <para>
+    The properties to configure Slice can be classified in two broad groups.
+The <emphasis>global</emphasis> properties apply to all the slices, for example,
+the thread pool used to execute the queries in parallel or the transaction 
+manager used to coordinate transaction across multiple slices. 
+The <emphasis>per-slice</emphasis> properties apply to individual slice, for example,
+the JDBC connection URL of a slice.
+   </para>
+   
+   <section>
+     <title>Global Properties</title>
+     
+     <section>
+        <title>openjpa.slice.DistributionPolicy</title>
+        <para>
+         This <emphasis>mandatory</emphasis> plug-in property determines how newly
+         persistent instances are distributed across individual slices. 
+         The value of this property is a fully-qualified class name that implements
+         <ulink url="../javadoc/org/apache/openjpa/slice/DistributionPolicy.html">
+         <classname>org.apache.openjpa.slice.DistributionPolicy</classname>
+         </ulink> interface.
+        </para>
+     </section>
+     
+     <section><title>openjpa.slice.Lenient</title>
+      <para>
+        This boolean plug-in property controls the behavior when one or more slice 
+        can not be connected or unavailable for some other reasons.
+        If <code>true</code>, the unreachable slices are ignored. If 
+        <code>false</code> then any unreachable slice will raise an exception
+        during startup.
+        </para>
+        <para>
+        By default this value is set to <code>false</code> i.e. all configured
+        slices must be available.
+        </para> 
+     </section>
+
+     <section>
+      <title>openjpa.slice.Master</title>
+      <para>
+       This plug-in property can be used to identify the name of the master slice. 
+       Master slice is used when a primary key is to be generated from a database sequence. 
+       </para>
+       <para>
+        By default the master slice is the first slice in the list of configured slice names. 
+       </para>
+       <para>
+              <warning>
+              Currently, there is no provision to use sequence from 
+              multiple database slices.
+              </warning>
+       </para>
+     </section>
+    
+     <section>
+        <title>openjpa.slice.Names</title>
+        <para>
+         This plug-in property can be used to register the logical slice names.
+         The value of this property is comma-separated list of slice names. 
+         The ordering of the names in this list is 
+         <emphasis>significant</emphasis> because 
+         <link linkend="distribution_policy">DistributionPolicy</link> receives 
+         the input argument of the slice names in the same order.
+        </para>
+        <para>
+        If logical slice names are not registered explicitly via this property,
+        then all logical slice names available in the persistence unit are 
+        registered. The ordering of the slice names in this case is alphabetical.  
+        </para>
+        <para>
+        If logical slice names are registered explicitly via this property, then
+        any logical slice that is available in the persistence unit but excluded
+        from this list is ignored. 
+        </para>
+     </section>
+    
+     <section>
+        <title>openjpa.slice.ThreadingPolicy</title>
+        <para>
+        This plug-in property determines the nature of thread pool being used 
+        for database operations such as query or flush on individual slices. 
+        The value of the property is a 
+        fully-qualified class name that implements 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html">
+        <classname>java.util.concurrent.ExecutorService</classname>
+        </ulink> interface.  
+        Two pre-defined pools can be chosen via their aliases namely 
+        <code>fixed</code> or <code>cached</code>.
+        </para>
+        <para>
+        The pre-defined alias <code>cached</code> activates a 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()">cached thread pool</ulink>. 
+        A cached thread pool creates new threads as needed, but will reuse 
+        previously constructed threads when they are available. This pool 
+        is suitable in scenarios that execute many short-lived asynchronous tasks.
+        The way Slice uses the thread pool to execute database operations is 
+        akin to such scenario and hence <code>cached</code> is the default 
+        value for this plug-in property.  
+        </para>
+        <para>
+        The <code>fixed</code> alias activates a 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)">fixed thread pool</ulink>.
+        The fixed thread pool can be further parameterized with 
+        <code>CorePoolSize</code>, <code>MaximumPoolSize</code>, 
+        <code>KeepAliveTime</code> and <code>RejectedExecutionHandler</code>. 
+        The meaning of these parameters are described in 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html">JavaDoc</ulink>.
+        The users can exercise finer control on thread pool behavior via these
+        parameters.
+        By default, the core pool size is <code>10</code>, maximum pool size is
+        also <code>10</code>, keep alive time is <code>60</code> seconds and 
+        rejected execution is 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.AbortPolicy.html">aborted</ulink>.
+        </para>
+        <para>
+        Both of the pre-defined aliases can be parameterized with a fully-qualified
+        class name that implements 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadFactory.html">
+        <classname>java.util.concurrent.ThreadFactory</classname>
+        </ulink> interface.
+        </para>
+     </section>
+      
+     <section>
+      <title>openjpa.slice.TransactionPolicy</title>
+      <para>
+      This plug-in property determines the policy for transaction commit 
+      across multiple slices. The value of this property is a fully-qualified 
+      class name that implements 
+      <ulink url="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/transaction/TransactionManager.html">
+      <classname>javax.transaction.TransactionManager</classname> 
+      </ulink> interface. 
+      </para>
+      <para>
+      Three pre-defined policies can be chosen
+      by their aliases namely <code>default</code>,
+      <code>xa</code> and <code>jndi</code>. 
+      </para>
+      <para>
+      The <code>default</code> policy employs 
+      a Transaction Manager that commits or rolls back transaction on individual
+      slices <emphasis>without</emphasis> a two-phase commit protocol. 
+      It does <emphasis>not</emphasis>
+      guarantee atomic nature of transaction across all the slices because if
+      one or more slice fails to commit, there is no way to rollback the transaction
+      on other slices that committed successfully.
+      </para>
+      <para>
+      The <code>xa</code> policy employs a Transaction Manager that that commits 
+      or rolls back transaction on individual
+      slices using a two-phase commit protocol. The prerequisite to use this scheme
+      is, of course, that all the slices must be configured to use
+      XA-compliant JDBC driver. 
+      </para>
+      <para>
+      The <code>jndi</code> policy employs a Transaction Manager by looking up the
+      JNDI context. The prerequisite to use this transaction
+      manager is, of course, that all the slices must be configured to use
+      XA-compliant JDBC driver. 
+      <warning>This JNDI based policy is not available currently.</warning>
+      </para>
+    </section>
+   </section>
+   
+   <section>
+     <title>Per-Slice Properties</title>
+     <para>
+     Any OpenJPA property can be configured for each individual slice. The property name
+     is of the form <code>openjpa.slice.[Logical slice name].[OpenJPA Property Name]</code>.
+     For example, <code>openjpa.slice.One.ConnectionURL</code> where <code>One</code>
+     is the logical slice name and <code>ConnectionURL</code> is an OpenJPA property
+     name. 
+     </para>
+     <para>
+     If a property is not configured for a specific slice, then the value for
+     the property equals to the corresponding <code>openjpa.*</code> property.
+     </para>
+   </section>
+  
+</chapter>
   
\ No newline at end of file
diff --git a/openjpa-slice/pom.xml b/openjpa-slice/pom.xml
index 6b14ef4..de9a15e 100644
--- a/openjpa-slice/pom.xml
+++ b/openjpa-slice/pom.xml
@@ -31,7 +31,7 @@
 	<parent>
 		<groupId>org.apache.openjpa</groupId>
 		<artifactId>openjpa-parent</artifactId>
-		<version>1.2.1</version>
+		<version>1.2.2</version>
 	</parent>
 	<properties>
 		<openjpa.loglevel>INFO</openjpa.loglevel>
diff --git a/openjpa-slice/src/main/ant/enhancer.xml b/openjpa-slice/src/main/ant/enhancer.xml
index 0c9ec64..a493c3e 100644
--- a/openjpa-slice/src/main/ant/enhancer.xml
+++ b/openjpa-slice/src/main/ant/enhancer.xml
@@ -1,82 +1,82 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-    
-    http://www.apache.org/licenses/LICENSE-2.0
-    
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.   
--->
-<project name="enhance" basedir=".">
-    <!--
-        This build file executes the PCEnhancer on the test entities. It's in a
-        separate file instead of nested in pom.xml to make some conditional 
-        processing easier.
-        
-        Test classes will not be compiled if maven is invoked with 
-        -Dmaven.tests.skip=true. 
-    -->
-
-    <condition property="maven.test.skip.istrue">
-        <istrue value="${maven.test.skip}" />
-    </condition>
-
-    <condition property="test.isfalse">
-        <equals arg1="${test}" arg2="false" />
-    </condition>
-
-    <!-- ================================= 
-          target: enhance              
-         ================================= -->
-    <target name="enhance"
-            description="--> run the enhancer unless test=false"
-            unless="test.isfalse">
-        <antcall target="enhance.all.entities"
-                 inheritall="true"
-                 inheritrefs="true" />
-    </target>
-
-    <!-- ================================= 
-          target: enhance.all.entities              
-         ================================= -->
-    <target name="enhance.all.entities"
-            description="--> enhance the test entities"
-            unless="maven.test.skip.istrue">
-        <echo> running enhancer</echo>
-        <!-- 
-            Inherited references won't be present until the task is called. 
-            Therefore the path definition needs to stay inside the task.
-          -->
-        <path id="cp">
-            <path refid="maven.test.classpath" />
-        </path>
-
-        <taskdef name="openjpac"
-                 classname="org.apache.openjpa.ant.PCEnhancerTask">
-            <classpath refid="cp" />
-        </taskdef>
-
-        <fileset id="enhance.path.ref"
-                 dir="${project.build.testOutputDirectory}">
-            <include name="**/Address.class" />
-            <include name="**/Person.class" />
-            <include name="**/PObject.class" />
-            <exclude name="**/Test*.class" />
-        </fileset>
-        <openjpac>
-            <classpath refid="cp" />
-            <fileset refid="enhance.path.ref" />
-            <config log="DefaultLevel=${openjpa.loglevel}" />
-        </openjpac>
-    </target>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.   
+-->
+<project name="enhance" basedir=".">
+    <!--
+        This build file executes the PCEnhancer on the test entities. It's in a
+        separate file instead of nested in pom.xml to make some conditional 
+        processing easier.
+        
+        Test classes will not be compiled if maven is invoked with 
+        -Dmaven.tests.skip=true. 
+    -->
+
+    <condition property="maven.test.skip.istrue">
+        <istrue value="${maven.test.skip}" />
+    </condition>
+
+    <condition property="test.isfalse">
+        <equals arg1="${test}" arg2="false" />
+    </condition>
+
+    <!-- ================================= 
+          target: enhance              
+         ================================= -->
+    <target name="enhance"
+            description="--> run the enhancer unless test=false"
+            unless="test.isfalse">
+        <antcall target="enhance.all.entities"
+                 inheritall="true"
+                 inheritrefs="true" />
+    </target>
+
+    <!-- ================================= 
+          target: enhance.all.entities              
+         ================================= -->
+    <target name="enhance.all.entities"
+            description="--> enhance the test entities"
+            unless="maven.test.skip.istrue">
+        <echo> running enhancer</echo>
+        <!-- 
+            Inherited references won't be present until the task is called. 
+            Therefore the path definition needs to stay inside the task.
+          -->
+        <path id="cp">
+            <path refid="maven.test.classpath" />
+        </path>
+
+        <taskdef name="openjpac"
+                 classname="org.apache.openjpa.ant.PCEnhancerTask">
+            <classpath refid="cp" />
+        </taskdef>
+
+        <fileset id="enhance.path.ref"
+                 dir="${project.build.testOutputDirectory}">
+            <include name="**/Address.class" />
+            <include name="**/Person.class" />
+            <include name="**/PObject.class" />
+            <exclude name="**/Test*.class" />
+        </fileset>
+        <openjpac>
+            <classpath refid="cp" />
+            <fileset refid="enhance.path.ref" />
+            <config log="DefaultLevel=${openjpa.loglevel}" />
+        </openjpac>
+    </target>
 </project>
\ No newline at end of file
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
index fa86836..15f7506 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
@@ -1,93 +1,93 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import org.apache.openjpa.kernel.FinalizingBrokerImpl;
-import org.apache.openjpa.kernel.OpCallbacks;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.UserException;
-
-/**
- * A specialized Broker to associate slice identifiers with the StateManagers as
- * they are persisted in a cascade. This intervention helps the user to define
- * distribution policy only for root instances i.e. the instances that are
- * explicit argument to persist() call. The cascaded instances are assigned the
- * same slice to honor collocation constraint.
- * 
- * @author Pinaki Poddar
- * 
- */
-@SuppressWarnings("serial")
-public class DistributedBrokerImpl extends FinalizingBrokerImpl {
-	private transient String slice;
-
-	private static final Localizer _loc =
-			Localizer.forPackage(DistributedBrokerImpl.class);
-
-	/**
-	 * Assigns slice identifier to the resultant StateManager as initialized by
-	 * the super class implementation. The slice identifier is decided by
-	 * {@link DistributionPolicy} for given <code>pc</code> if it is a root
-	 * instance i.e. the argument of the user application's persist() call. The
-	 * cascaded instances are detected by non-empty status of the current
-	 * operating set. The slice is assigned only if a StateManager has never
-	 * been assigned before.
-	 */
-	@Override
-	public OpenJPAStateManager persist(Object pc, Object id, boolean explicit,
-			OpCallbacks call) {
-		OpenJPAStateManager sm = getStateManager(pc);
-		if (getOperatingSet().isEmpty()
-				&& (sm == null || sm.getImplData() == null)) {
-			slice = getSlice(pc);
-		}
-		sm = super.persist(pc, id, explicit, call);
-		if (sm.getImplData() == null)
-			sm.setImplData(slice, true);
-
-		return sm;
-	}
-
-	/**
-	 * Gets the slice by the user-defined distribution policy.
-	 */
-	String getSlice(Object pc) {
-		DistributedConfiguration conf =
-				(DistributedConfiguration) getConfiguration();
-		String slice =
-				(conf.getDistributionPolicyInstance().distribute(pc, conf
-						.getActiveSliceNames(), this));
-		if (!conf.getActiveSliceNames().contains(slice))
-			throw new UserException(_loc.get("bad-policy-slice", new Object[] {
-					conf.getDistributionPolicyInstance().getClass().getName(),
-					slice, pc, conf.getActiveSliceNames() }));
-		return slice;
-	}
-	
-	@Override
-	public boolean endOperation() {
-	    try {
-	        return super.endOperation();
-	    } catch (Exception ex) {
-	        
-	    }
-	    return true;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.kernel.FinalizingBrokerImpl;
+import org.apache.openjpa.kernel.OpCallbacks;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * A specialized Broker to associate slice identifiers with the StateManagers as
+ * they are persisted in a cascade. This intervention helps the user to define
+ * distribution policy only for root instances i.e. the instances that are
+ * explicit argument to persist() call. The cascaded instances are assigned the
+ * same slice to honor collocation constraint.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+@SuppressWarnings("serial")
+public class DistributedBrokerImpl extends FinalizingBrokerImpl {
+	private transient String slice;
+
+	private static final Localizer _loc =
+			Localizer.forPackage(DistributedBrokerImpl.class);
+
+	/**
+	 * Assigns slice identifier to the resultant StateManager as initialized by
+	 * the super class implementation. The slice identifier is decided by
+	 * {@link DistributionPolicy} for given <code>pc</code> if it is a root
+	 * instance i.e. the argument of the user application's persist() call. The
+	 * cascaded instances are detected by non-empty status of the current
+	 * operating set. The slice is assigned only if a StateManager has never
+	 * been assigned before.
+	 */
+	@Override
+	public OpenJPAStateManager persist(Object pc, Object id, boolean explicit,
+			OpCallbacks call) {
+		OpenJPAStateManager sm = getStateManager(pc);
+		if (getOperatingSet().isEmpty()
+				&& (sm == null || sm.getImplData() == null)) {
+			slice = getSlice(pc);
+		}
+		sm = super.persist(pc, id, explicit, call);
+		if (sm.getImplData() == null)
+			sm.setImplData(slice, true);
+
+		return sm;
+	}
+
+	/**
+	 * Gets the slice by the user-defined distribution policy.
+	 */
+	String getSlice(Object pc) {
+		DistributedConfiguration conf =
+				(DistributedConfiguration) getConfiguration();
+		String slice =
+				(conf.getDistributionPolicyInstance().distribute(pc, conf
+						.getActiveSliceNames(), this));
+		if (!conf.getActiveSliceNames().contains(slice))
+			throw new UserException(_loc.get("bad-policy-slice", new Object[] {
+					conf.getDistributionPolicyInstance().getClass().getName(),
+					slice, pc, conf.getActiveSliceNames() }));
+		return slice;
+	}
+	
+	@Override
+	public boolean endOperation() {
+	    try {
+	        return super.endOperation();
+	    } catch (Exception ex) {
+	        
+	    }
+	    return true;
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
index 75c2026..1c58a73 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.List;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-
-/**
- * A configuration for multiple data stores, each referred as <em>slice</em>.
- * This configuration allows each underlying slice be configured with its
- * own specific configuration properties such as JDBC Driver or connection
- * user/password etc. <br>
- * This configuration also extends by adding a {@link DistributionPolicy 
- * DistributionPolicy} that governs how new instances be distributed
- * among the slices.
- * 
- * @author Pinaki Poddar 
- *
- */
-public interface DistributedConfiguration extends OpenJPAConfiguration {
-	/**
-	 * Gets the active slice identifiers. This list is determined by the
-	 * configuration properties either by explicit listing in 
-	 * <code>openjpa.slice.Names</code> property or by scanning 
-	 * <code>openjpa.slice.*.*</code> properties.
-	 * <br> 
-	 * The ordering of the slice identifiers is determined when they are
-	 * specified explicitly in <code>openjpa.slice.Names</code> property or 
-	 * ordered alphabetically when found by scanning the properties.
-	 * <br>
-	 * This list always returns the identifiers that are <em>active</em>, slices
-	 * that can not be connected to are not included in this list.
-	 */
-	List<String> getActiveSliceNames();
-	
-	/**
-	 * Gets the available slice identifiers irrespective of their status.
-	 * @return
-	 */
-    List<String> getAvailableSliceNames();
-
-	
-	/**
-	 * Gets the slices of given status.
-	 * @param statuses list of status flags. If null, returns all slices 
-	 * irrespective of status.
-	 */
-	List<Slice> getSlices(Slice.Status...statuses);
-	
-	/**
-	 * Gets the Slice for a given name.
-	 * Exception is raised if the given slice is not configured.
-	 */
-	Slice getSlice(String sliceName);
-	
-	/**
-	 * Gets the policy that governs how new instances will be distributed across
-	 * the available slices.
-	 */
-	DistributionPolicy getDistributionPolicyInstance();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.List;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * A configuration for multiple data stores, each referred as <em>slice</em>.
+ * This configuration allows each underlying slice be configured with its
+ * own specific configuration properties such as JDBC Driver or connection
+ * user/password etc. <br>
+ * This configuration also extends by adding a {@link DistributionPolicy 
+ * DistributionPolicy} that governs how new instances be distributed
+ * among the slices.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributedConfiguration extends OpenJPAConfiguration {
+	/**
+	 * Gets the active slice identifiers. This list is determined by the
+	 * configuration properties either by explicit listing in 
+	 * <code>openjpa.slice.Names</code> property or by scanning 
+	 * <code>openjpa.slice.*.*</code> properties.
+	 * <br> 
+	 * The ordering of the slice identifiers is determined when they are
+	 * specified explicitly in <code>openjpa.slice.Names</code> property or 
+	 * ordered alphabetically when found by scanning the properties.
+	 * <br>
+	 * This list always returns the identifiers that are <em>active</em>, slices
+	 * that can not be connected to are not included in this list.
+	 */
+	List<String> getActiveSliceNames();
+	
+	/**
+	 * Gets the available slice identifiers irrespective of their status.
+	 * @return
+	 */
+    List<String> getAvailableSliceNames();
+
+	
+	/**
+	 * Gets the slices of given status.
+	 * @param statuses list of status flags. If null, returns all slices 
+	 * irrespective of status.
+	 */
+	List<Slice> getSlices(Slice.Status...statuses);
+	
+	/**
+	 * Gets the Slice for a given name.
+	 * Exception is raised if the given slice is not configured.
+	 */
+	Slice getSlice(String sliceName);
+	
+	/**
+	 * Gets the policy that governs how new instances will be distributed across
+	 * the available slices.
+	 */
+	DistributionPolicy getDistributionPolicyInstance();
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
index f5750fe..b7a48dc 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
@@ -1,47 +1,47 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.List;
-
-
-/**
- * Policy to select one of the physical databases referred as <em>slice</em>
- * in which a given persistent instance will be stored.
- *  
- * @author Pinaki Poddar 
- *
- */
-public interface DistributionPolicy {
-	/**
-	 * Gets the name of the slice where a given instance will be stored.
-	 *  
-	 * @param pc The newly persistent or to-be-merged object. 
-	 * @param slices list of names of the active slices. The ordering of 
-	 * the list is either explicit <code>openjpa.slice.Names</code> property
-	 * or implicit i.e. alphabetic order of available identifiers if 
-	 * <code>openjpa.slice.Names</code> is unspecified.  
-	 * @param context generic persistence context managing the given instance.
-	 * 
-	 * @return identifier of the slice. This name must match one of the
-	 * given slice names. 
-	 * @see DistributedConfiguration#getActiveSliceNames()
-	 */
-	String distribute(Object pc, List<String> slices, Object context);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.List;
+
+
+/**
+ * Policy to select one of the physical databases referred as <em>slice</em>
+ * in which a given persistent instance will be stored.
+ *  
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributionPolicy {
+	/**
+	 * Gets the name of the slice where a given instance will be stored.
+	 *  
+	 * @param pc The newly persistent or to-be-merged object. 
+	 * @param slices list of names of the active slices. The ordering of 
+	 * the list is either explicit <code>openjpa.slice.Names</code> property
+	 * or implicit i.e. alphabetic order of available identifiers if 
+	 * <code>openjpa.slice.Names</code> is unspecified.  
+	 * @param context generic persistence context managing the given instance.
+	 * 
+	 * @return identifier of the slice. This name must match one of the
+	 * given slice names. 
+	 * @see DistributedConfiguration#getActiveSliceNames()
+	 */
+	String distribute(Object pc, List<String> slices, Object context);
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java
index f8a56dd..5044ba0 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java
@@ -1,108 +1,108 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.openjpa.lib.conf.Configuration;
-import org.apache.openjpa.lib.conf.Configurations;
-import org.apache.openjpa.lib.conf.PluginValue;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Value type used to represent a {@link ExecutorService}.
- * This value controls the thread pool parameters. The thread pool is used
- * to execute the queries.
- * 
- * @author Pinaki Poddar
- * @nojavadoc
- */
-
-public class ExecutorServiceValue extends PluginValue {
-    private static List<String> known =
-            Arrays.asList(new String[] { "cached", "fixed" });
-
-    private static Localizer _loc =
-            Localizer.forPackage(ExecutorServiceValue.class);
-
-    public ExecutorServiceValue() {
-        super("ThreadingPolicy", true);
-        setDefault("cached");
-    }
-
-    public void setProperties(String props) {
-        super.setProperties(props);
-    }
-
-    /**
-     * Configures a cached or fixed thread pool.
-     */
-    @Override
-    public Object instantiate(Class type, Configuration conf, boolean fatal) {
-        Object obj = null;
-        int defaultSize = 10;
-        String cls = getClassName();
-        if (!known.contains(cls))
-            cls = "cached";
-
-        Options opts = Configurations.parseProperties(getProperties());
-
-        ThreadFactory factory = null;
-        if (opts.containsKey("ThreadFactory")) {
-            String fName = opts.getProperty("ThreadFactory");
-            try {
-                factory = (ThreadFactory) Class.forName(fName).newInstance();
-                Configurations.configureInstance(factory, conf, opts,
-                        getProperty());
-            } catch (Throwable t) {
-                throw new UserException(_loc.get("bad-thread-factory", fName), t);
-            } finally {
-                opts.removeProperty("ThreadFactory");
-            }
-        } else {
-            factory = Executors.defaultThreadFactory();
-        }
-        if ("cached".equals(cls)) {
-            obj = Executors.newCachedThreadPool(factory);
-        } else if ("fixed".equals(cls)) {
-            long keepAliveTime = 60L;
-            if (opts.containsKey("KeepAliveTime")) {
-                keepAliveTime = opts.getLongProperty("KeepAliveTime");
-                opts.removeLongProperty("KeepAliveTime");
-            }
-            obj = new ThreadPoolExecutor(defaultSize, defaultSize,
-                            keepAliveTime, TimeUnit.SECONDS,
-                            new SynchronousQueue<Runnable>(), factory);
-
-            Configurations.configureInstance(obj, conf, opts, getProperty());
-        }
-        set(obj, true);
-        return obj;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Value type used to represent a {@link ExecutorService}.
+ * This value controls the thread pool parameters. The thread pool is used
+ * to execute the queries.
+ * 
+ * @author Pinaki Poddar
+ * @nojavadoc
+ */
+
+public class ExecutorServiceValue extends PluginValue {
+    private static List<String> known =
+            Arrays.asList(new String[] { "cached", "fixed" });
+
+    private static Localizer _loc =
+            Localizer.forPackage(ExecutorServiceValue.class);
+
+    public ExecutorServiceValue() {
+        super("ThreadingPolicy", true);
+        setDefault("cached");
+    }
+
+    public void setProperties(String props) {
+        super.setProperties(props);
+    }
+
+    /**
+     * Configures a cached or fixed thread pool.
+     */
+    @Override
+    public Object instantiate(Class type, Configuration conf, boolean fatal) {
+        Object obj = null;
+        int defaultSize = 10;
+        String cls = getClassName();
+        if (!known.contains(cls))
+            cls = "cached";
+
+        Options opts = Configurations.parseProperties(getProperties());
+
+        ThreadFactory factory = null;
+        if (opts.containsKey("ThreadFactory")) {
+            String fName = opts.getProperty("ThreadFactory");
+            try {
+                factory = (ThreadFactory) Class.forName(fName).newInstance();
+                Configurations.configureInstance(factory, conf, opts,
+                        getProperty());
+            } catch (Throwable t) {
+                throw new UserException(_loc.get("bad-thread-factory", fName), t);
+            } finally {
+                opts.removeProperty("ThreadFactory");
+            }
+        } else {
+            factory = Executors.defaultThreadFactory();
+        }
+        if ("cached".equals(cls)) {
+            obj = Executors.newCachedThreadPool(factory);
+        } else if ("fixed".equals(cls)) {
+            long keepAliveTime = 60L;
+            if (opts.containsKey("KeepAliveTime")) {
+                keepAliveTime = opts.getLongProperty("KeepAliveTime");
+                opts.removeLongProperty("KeepAliveTime");
+            }
+            obj = new ThreadPoolExecutor(defaultSize, defaultSize,
+                            keepAliveTime, TimeUnit.SECONDS,
+                            new SynchronousQueue<Runnable>(), factory);
+
+            Configurations.configureInstance(obj, conf, opts, getProperty());
+        }
+        set(obj, true);
+        return obj;
+    }
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
index 4f4a89d..2ed25c8 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.Map;
-
-import org.apache.openjpa.conf.OpenJPAProductDerivation;
-import org.apache.openjpa.lib.conf.AbstractProductDerivation;
-import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
-
-/**
- * Derives configuration for Slice.
- * Introduces a specialized BrokerFactory aliased as <code>slice</code>.
- * All Slice specific configuration is prefixed as 
- * <code>openjpa.slice.*.*</code>
- * 
- * @author Pinaki Poddar 
- *
- */
-public class ProductDerivation extends AbstractProductDerivation implements
-		OpenJPAProductDerivation {
-    /**
-     * Prefix for all Slice-specific configuration properties. 
-     */
-    public static final String PREFIX_SLICE = "openjpa.slice";
-    
-    /**
-     * Hint key <code>openjpa.hint.slice.Target </code> to specify a subset of 
-     * slices for query. The value corresponding to the key is comma-separated
-     * list of slice identifiers.
-     *  
-     */
-    public static final String HINT_TARGET  = "openjpa.hint.slice.Target";
-    
-	@SuppressWarnings("unchecked")
-	public void putBrokerFactoryAliases(Map m) {
-		m.put("slice", DistributedJDBCBrokerFactory.class.getName());
-	}
-
-	public String getConfigurationPrefix() {
-		return PREFIX_SLICE;
-	}
-
-	public int getType() {
-		return TYPE_FEATURE;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Map;
+
+import org.apache.openjpa.conf.OpenJPAProductDerivation;
+import org.apache.openjpa.lib.conf.AbstractProductDerivation;
+import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
+
+/**
+ * Derives configuration for Slice.
+ * Introduces a specialized BrokerFactory aliased as <code>slice</code>.
+ * All Slice specific configuration is prefixed as 
+ * <code>openjpa.slice.*.*</code>
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class ProductDerivation extends AbstractProductDerivation implements
+		OpenJPAProductDerivation {
+    /**
+     * Prefix for all Slice-specific configuration properties. 
+     */
+    public static final String PREFIX_SLICE = "openjpa.slice";
+    
+    /**
+     * Hint key <code>openjpa.hint.slice.Target </code> to specify a subset of 
+     * slices for query. The value corresponding to the key is comma-separated
+     * list of slice identifiers.
+     *  
+     */
+    public static final String HINT_TARGET  = "openjpa.hint.slice.Target";
+    
+	@SuppressWarnings("unchecked")
+	public void putBrokerFactoryAliases(Map m) {
+		m.put("slice", DistributedJDBCBrokerFactory.class.getName());
+	}
+
+	public String getConfigurationPrefix() {
+		return PREFIX_SLICE;
+	}
+
+	public int getType() {
+		return TYPE_FEATURE;
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java
index 9aa8ed9..9587a86 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java
@@ -1,99 +1,99 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-
-/**
- * Represents a database slice of immutable logical name, a configuration and
- * status.
- * 
- * @author Pinaki Poddar 
- *
- */
-public class Slice implements Comparable<Slice> {
-    public enum Status {
-        NOT_INITIALIZED, 
-        ACTIVE, 
-        INACTIVE, // configured but not available
-        EXCLUDED  // configured but not used
-    }; 
-    
-    private final String name;
-    private transient final OpenJPAConfiguration conf;
-    private transient Status status;
-    
-    /**
-     * Supply the logical name and configuration.
-     */
-    public Slice(String name, OpenJPAConfiguration conf) {
-        this.name = name;
-        this.conf = conf;
-        this.status = Status.NOT_INITIALIZED;
-    }
-    
-    /**
-     * Gets the immutable logical name.
-     */
-    public String getName() {
-        return name;
-    }
-    
-    public OpenJPAConfiguration getConfiguration() {
-        return conf;
-    }
-    
-    public Status getStatus() {
-        return status;
-    }
-    
-    public void setStatus(Status status) {
-        this.status = status;
-    }
-    
-    public boolean isActive() {
-        return status == Status.ACTIVE;
-    }
-    
-    public String toString() {
-        return name;
-    }
-    
-    public int compareTo(Slice other) {
-        return name.compareTo(other.name);
-    }
-    
-    /**
-     * Equals by name.
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) return true;
-        if (other == null) return false;
-        if (other instanceof Slice) {
-            return name.equals(((Slice)other).getName());
-        }
-        return false;
-    }
-    
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * Represents a database slice of immutable logical name, a configuration and
+ * status.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class Slice implements Comparable<Slice> {
+    public enum Status {
+        NOT_INITIALIZED, 
+        ACTIVE, 
+        INACTIVE, // configured but not available
+        EXCLUDED  // configured but not used
+    }; 
+    
+    private final String name;
+    private transient final OpenJPAConfiguration conf;
+    private transient Status status;
+    
+    /**
+     * Supply the logical name and configuration.
+     */
+    public Slice(String name, OpenJPAConfiguration conf) {
+        this.name = name;
+        this.conf = conf;
+        this.status = Status.NOT_INITIALIZED;
+    }
+    
+    /**
+     * Gets the immutable logical name.
+     */
+    public String getName() {
+        return name;
+    }
+    
+    public OpenJPAConfiguration getConfiguration() {
+        return conf;
+    }
+    
+    public Status getStatus() {
+        return status;
+    }
+    
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+    
+    public boolean isActive() {
+        return status == Status.ACTIVE;
+    }
+    
+    public String toString() {
+        return name;
+    }
+    
+    public int compareTo(Slice other) {
+        return name.compareTo(other.name);
+    }
+    
+    /**
+     * Equals by name.
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) return true;
+        if (other == null) return false;
+        if (other instanceof Slice) {
+            return name.equals(((Slice)other).getName());
+        }
+        return false;
+    }
+    
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
index aee3a4d..e04f09a 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.kernel.StateManagerImpl;
-import org.apache.openjpa.util.ImplHelper;
-
-/**
- * A helper to determine the slice identifier of an instance.
- * 
- * @author Pinaki Poddar 
- *
- */
-public class SlicePersistence {
-	/**
-	 * Get the slice identifier for the given instance if it is a managed
-	 * instance and has been assigned to a slice.
-	 * 
-	 * @return name of the slice, if any. null otherwise.
-	 */
-	public static String getSlice(Object obj) {
-		if (obj == null)
-			return null;
-		PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, null);
-		if (pc == null)
-			return null;
-		StateManagerImpl sm = (StateManagerImpl)pc.pcGetStateManager();
-		if (sm == null)
-			return null;
-		Object slice = sm.getImplData();
-		return (slice instanceof String) ? (String)slice : null;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.StateManagerImpl;
+import org.apache.openjpa.util.ImplHelper;
+
+/**
+ * A helper to determine the slice identifier of an instance.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class SlicePersistence {
+	/**
+	 * Get the slice identifier for the given instance if it is a managed
+	 * instance and has been assigned to a slice.
+	 * 
+	 * @return name of the slice, if any. null otherwise.
+	 */
+	public static String getSlice(Object obj) {
+		if (obj == null)
+			return null;
+		PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, null);
+		if (pc == null)
+			return null;
+		StateManagerImpl sm = (StateManagerImpl)pc.pcGetStateManager();
+		if (sm == null)
+			return null;
+		Object slice = sm.getImplData();
+		return (slice instanceof String) ? (String)slice : null;
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
index f06b6f3..4129f23 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
@@ -1,263 +1,263 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A virtual connection that contains multiple physical connections.
- * 
- * @author Pinaki Poddar
- * 
- */
-class DistributedConnection implements Connection {
-	private final List<Connection> real;
-	private final Connection master;
-
-	public DistributedConnection(List<Connection> connections) {
-		if (connections == null || connections.isEmpty())
-			throw new NullPointerException();
-		real = connections;
-		master = connections.get(0);
-	}
-	
-	public boolean contains(Connection c) {
-		return real.contains(c);
-	}
-
-	public void clearWarnings() throws SQLException {
-		for (Connection c : real)
-			c.clearWarnings();
-	}
-
-	public void close() throws SQLException {
-		for (Connection c : real)
-			c.close();
-	}
-
-	public void commit() throws SQLException {
-		for (Connection c : real)
-			c.commit();
-	}
-
-	public Statement createStatement() throws SQLException {
-		DistributedStatement ret = new DistributedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.createStatement());
-		}
-		return ret;
-	}
-
-	public Statement createStatement(int arg0, int arg1) throws SQLException {
-		DistributedStatement ret = new DistributedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.createStatement(arg0, arg1));
-		}
-		return ret;
-	}
-
-	public Statement createStatement(int arg0, int arg1, int arg2)
-			throws SQLException {
-		DistributedStatement ret = new DistributedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.createStatement(arg0, arg1, arg2));
-		}
-		return ret;
-	}
-
-	public boolean getAutoCommit() throws SQLException {
-		return master.getAutoCommit();
-	}
-
-	public String getCatalog() throws SQLException {
-		return master.getCatalog();
-	}
-
-	public int getHoldability() throws SQLException {
-		return master.getHoldability();
-	}
-
-	public DatabaseMetaData getMetaData() throws SQLException {
-		return master.getMetaData();
-	}
-
-	public int getTransactionIsolation() throws SQLException {
-		return master.getTransactionIsolation();
-	}
-
-	public Map<String, Class<?>> getTypeMap() throws SQLException {
-		return master.getTypeMap();
-	}
-
-	public SQLWarning getWarnings() throws SQLException {
-		return master.getWarnings();
-	}
-
-	public boolean isClosed() throws SQLException {
-		boolean ret = true;
-		for (Connection c : real) {
-			ret &= c.isClosed();
-		}
-		return ret;
-	}
-
-	public boolean isReadOnly() throws SQLException {
-		boolean ret = true;
-		for (Connection c : real) {
-			ret &= c.isReadOnly();
-		}
-		return ret;
-	}
-
-	public String nativeSQL(String arg0) throws SQLException {
-		return master.nativeSQL(arg0);
-	}
-
-	public CallableStatement prepareCall(String arg0) throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public CallableStatement prepareCall(String arg0, int arg1, int arg2)
-			throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public CallableStatement prepareCall(String arg0, int arg1, int arg2,
-			int arg3) throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public PreparedStatement prepareStatement(String arg0) throws SQLException {
-		// TODO: Big hack
-		if (arg0.startsWith("SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE"))
-			return master.prepareStatement(arg0);
-		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.prepareStatement(arg0));
-		}
-		return ret;
-	}
-
-	public PreparedStatement prepareStatement(String arg0, int arg1)
-			throws SQLException {
-		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.prepareStatement(arg0, arg1));
-		}
-		return ret;
-	}
-
-	public PreparedStatement prepareStatement(String arg0, int[] arg1)
-			throws SQLException {
-		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.prepareStatement(arg0, arg1));
-		}
-		return ret;
-	}
-
-	public PreparedStatement prepareStatement(String arg0, String[] arg1)
-			throws SQLException {
-		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.prepareStatement(arg0, arg1));
-		}
-		return ret;
-	}
-
-	public PreparedStatement prepareStatement(String arg0, int arg1, int arg2)
-			throws SQLException {
-		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.prepareStatement(arg0, arg1, arg2));
-		}
-		return ret;
-	}
-
-	public PreparedStatement prepareStatement(String arg0, int arg1, int arg2,
-			int arg3) throws SQLException {
-		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
-		for (Connection c : real) {
-			ret.add(c.prepareStatement(arg0, arg1, arg2));
-		}
-		return ret;
-	}
-
-	public void releaseSavepoint(Savepoint arg0) throws SQLException {
-		for (Connection c : real)
-			c.releaseSavepoint(arg0);
-	}
-
-	public void rollback() throws SQLException {
-		for (Connection c : real)
-			c.rollback();
-	}
-
-	public void rollback(Savepoint arg0) throws SQLException {
-		for (Connection c : real)
-			c.rollback(arg0);
-	}
-
-	public void setAutoCommit(boolean arg0) throws SQLException {
-		for (Connection c : real)
-			c.setAutoCommit(arg0);
-	}
-
-	public void setCatalog(String arg0) throws SQLException {
-		for (Connection c : real)
-			c.setCatalog(arg0);
-	}
-
-	public void setHoldability(int arg0) throws SQLException {
-		for (Connection c : real)
-			c.setHoldability(arg0);
-	}
-
-	public void setReadOnly(boolean arg0) throws SQLException {
-		for (Connection c : real)
-			c.setReadOnly(arg0);
-	}
-
-	public Savepoint setSavepoint() throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public Savepoint setSavepoint(String arg0) throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public void setTransactionIsolation(int arg0) throws SQLException {
-		for (Connection c : real)
-			c.setTransactionIsolation(arg0);
-	}
-
-	public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException {
-		for (Connection c : real)
-			c.setTypeMap(arg0);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A virtual connection that contains multiple physical connections.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+class DistributedConnection implements Connection {
+	private final List<Connection> real;
+	private final Connection master;
+
+	public DistributedConnection(List<Connection> connections) {
+		if (connections == null || connections.isEmpty())
+			throw new NullPointerException();
+		real = connections;
+		master = connections.get(0);
+	}
+	
+	public boolean contains(Connection c) {
+		return real.contains(c);
+	}
+
+	public void clearWarnings() throws SQLException {
+		for (Connection c : real)
+			c.clearWarnings();
+	}
+
+	public void close() throws SQLException {
+		for (Connection c : real)
+			c.close();
+	}
+
+	public void commit() throws SQLException {
+		for (Connection c : real)
+			c.commit();
+	}
+
+	public Statement createStatement() throws SQLException {
+		DistributedStatement ret = new DistributedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.createStatement());
+		}
+		return ret;
+	}
+
+	public Statement createStatement(int arg0, int arg1) throws SQLException {
+		DistributedStatement ret = new DistributedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.createStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public Statement createStatement(int arg0, int arg1, int arg2)
+			throws SQLException {
+		DistributedStatement ret = new DistributedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.createStatement(arg0, arg1, arg2));
+		}
+		return ret;
+	}
+
+	public boolean getAutoCommit() throws SQLException {
+		return master.getAutoCommit();
+	}
+
+	public String getCatalog() throws SQLException {
+		return master.getCatalog();
+	}
+
+	public int getHoldability() throws SQLException {
+		return master.getHoldability();
+	}
+
+	public DatabaseMetaData getMetaData() throws SQLException {
+		return master.getMetaData();
+	}
+
+	public int getTransactionIsolation() throws SQLException {
+		return master.getTransactionIsolation();
+	}
+
+	public Map<String, Class<?>> getTypeMap() throws SQLException {
+		return master.getTypeMap();
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		return master.getWarnings();
+	}
+
+	public boolean isClosed() throws SQLException {
+		boolean ret = true;
+		for (Connection c : real) {
+			ret &= c.isClosed();
+		}
+		return ret;
+	}
+
+	public boolean isReadOnly() throws SQLException {
+		boolean ret = true;
+		for (Connection c : real) {
+			ret &= c.isReadOnly();
+		}
+		return ret;
+	}
+
+	public String nativeSQL(String arg0) throws SQLException {
+		return master.nativeSQL(arg0);
+	}
+
+	public CallableStatement prepareCall(String arg0) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public CallableStatement prepareCall(String arg0, int arg1, int arg2)
+			throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public CallableStatement prepareCall(String arg0, int arg1, int arg2,
+			int arg3) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public PreparedStatement prepareStatement(String arg0) throws SQLException {
+		// TODO: Big hack
+		if (arg0.startsWith("SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE"))
+			return master.prepareStatement(arg0);
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int arg1)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int[] arg1)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, String[] arg1)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int arg1, int arg2)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1, arg2));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int arg1, int arg2,
+			int arg3) throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1, arg2));
+		}
+		return ret;
+	}
+
+	public void releaseSavepoint(Savepoint arg0) throws SQLException {
+		for (Connection c : real)
+			c.releaseSavepoint(arg0);
+	}
+
+	public void rollback() throws SQLException {
+		for (Connection c : real)
+			c.rollback();
+	}
+
+	public void rollback(Savepoint arg0) throws SQLException {
+		for (Connection c : real)
+			c.rollback(arg0);
+	}
+
+	public void setAutoCommit(boolean arg0) throws SQLException {
+		for (Connection c : real)
+			c.setAutoCommit(arg0);
+	}
+
+	public void setCatalog(String arg0) throws SQLException {
+		for (Connection c : real)
+			c.setCatalog(arg0);
+	}
+
+	public void setHoldability(int arg0) throws SQLException {
+		for (Connection c : real)
+			c.setHoldability(arg0);
+	}
+
+	public void setReadOnly(boolean arg0) throws SQLException {
+		for (Connection c : real)
+			c.setReadOnly(arg0);
+	}
+
+	public Savepoint setSavepoint() throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public Savepoint setSavepoint(String arg0) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setTransactionIsolation(int arg0) throws SQLException {
+		for (Connection c : real)
+			c.setTransactionIsolation(arg0);
+	}
+
+	public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException {
+		for (Connection c : real)
+			c.setTypeMap(arg0);
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
index d382621..c1be06d 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
@@ -1,102 +1,102 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.sql.DataSource;
-import javax.sql.XADataSource;
-
-import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
-
-/**
- * A virtual datasource that contains many physical datasources.
- * 
- * @author Pinaki Poddar 
- *
- */
-class DistributedDataSource extends DecoratingDataSource implements
-		Iterable<DataSource> {
-	private List<DataSource> real = new ArrayList<DataSource>();
-	private DataSource master;
-	
-	public DistributedDataSource(List<DataSource> dataSources) {
-		super(dataSources.get(0));
-		real = dataSources;
-		master = dataSources.get(0);
-	}
-	
-	Connection getConnection(DataSource ds) throws SQLException {
-		if (ds instanceof DecoratingDataSource)
-			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate());
-		if (ds instanceof XADataSource)
-			return ((XADataSource)ds).getXAConnection().getConnection();
-		return ds.getConnection();
-	}
-	
-	Connection getConnection(DataSource ds, String user, String pwd) throws SQLException {
-		if (ds instanceof DecoratingDataSource)
-			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate(), user, pwd);
-		if (ds instanceof XADataSource)
-			return ((XADataSource)ds).getXAConnection(user, pwd).getConnection();
-		return ds.getConnection(user, pwd);
-	}
-
-	public Iterator<DataSource> iterator() {
-		return real.iterator();
-	}
-
-	public Connection getConnection() throws SQLException {
-		List<Connection> c = new ArrayList<Connection>();
-		for (DataSource ds : real)
-			c.add(ds.getConnection());
-		return new DistributedConnection(c);
-	}
-
-	public Connection getConnection(String username, String password)
-			throws SQLException {
-		List<Connection> c = new ArrayList<Connection>();
-		for (DataSource ds : real)
-			c.add(ds.getConnection(username, password));
-		return new DistributedConnection(c);
-	}
-
-	public PrintWriter getLogWriter() throws SQLException {
-		return master.getLogWriter();
-	}
-
-	public int getLoginTimeout() throws SQLException {
-		return master.getLoginTimeout();
-	}
-
-	public void setLogWriter(PrintWriter out) throws SQLException {
-		for (DataSource ds:real)
-			ds.setLogWriter(out);
-	}
-
-	public void setLoginTimeout(int seconds) throws SQLException {
-		for (DataSource ds:real)
-			ds.setLoginTimeout(seconds);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sql.DataSource;
+import javax.sql.XADataSource;
+
+import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
+
+/**
+ * A virtual datasource that contains many physical datasources.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+class DistributedDataSource extends DecoratingDataSource implements
+		Iterable<DataSource> {
+	private List<DataSource> real = new ArrayList<DataSource>();
+	private DataSource master;
+	
+	public DistributedDataSource(List<DataSource> dataSources) {
+		super(dataSources.get(0));
+		real = dataSources;
+		master = dataSources.get(0);
+	}
+	
+	Connection getConnection(DataSource ds) throws SQLException {
+		if (ds instanceof DecoratingDataSource)
+			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate());
+		if (ds instanceof XADataSource)
+			return ((XADataSource)ds).getXAConnection().getConnection();
+		return ds.getConnection();
+	}
+	
+	Connection getConnection(DataSource ds, String user, String pwd) throws SQLException {
+		if (ds instanceof DecoratingDataSource)
+			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate(), user, pwd);
+		if (ds instanceof XADataSource)
+			return ((XADataSource)ds).getXAConnection(user, pwd).getConnection();
+		return ds.getConnection(user, pwd);
+	}
+
+	public Iterator<DataSource> iterator() {
+		return real.iterator();
+	}
+
+	public Connection getConnection() throws SQLException {
+		List<Connection> c = new ArrayList<Connection>();
+		for (DataSource ds : real)
+			c.add(ds.getConnection());
+		return new DistributedConnection(c);
+	}
+
+	public Connection getConnection(String username, String password)
+			throws SQLException {
+		List<Connection> c = new ArrayList<Connection>();
+		for (DataSource ds : real)
+			c.add(ds.getConnection(username, password));
+		return new DistributedConnection(c);
+	}
+
+	public PrintWriter getLogWriter() throws SQLException {
+		return master.getLogWriter();
+	}
+
+	public int getLoginTimeout() throws SQLException {
+		return master.getLoginTimeout();
+	}
+
+	public void setLogWriter(PrintWriter out) throws SQLException {
+		for (DataSource ds:real)
+			ds.setLogWriter(out);
+	}
+
+	public void setLoginTimeout(int seconds) throws SQLException {
+		for (DataSource ds:real)
+			ds.setLoginTimeout(seconds);
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
index ab3a479..98d1563 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
@@ -1,106 +1,106 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.util.Map;
-
-import org.apache.openjpa.conf.OpenJPAVersion;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory;
-import org.apache.openjpa.kernel.Bootstrap;
-import org.apache.openjpa.kernel.StoreManager;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.util.Localizer;
-
-/**
- * A factory for distributed JDBC datastores.
- * 
- * @author Pinaki Poddar
- * 
- */
-@SuppressWarnings("serial")
-public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory {
-	private static final Localizer _loc = 
-	    Localizer.forPackage(DistributedJDBCBrokerFactory.class);
-	/**
-	 * Factory method for constructing a factory from properties. Invoked from
-	 * {@link Bootstrap#newBrokerFactory}.
-	 */
-	public static DistributedJDBCBrokerFactory newInstance(
-			ConfigurationProvider cp) {
-		DistributedJDBCConfigurationImpl conf =
-				new DistributedJDBCConfigurationImpl(cp);
-		cp.setInto(conf);
-		return new DistributedJDBCBrokerFactory(conf);
-	}
-
-	/**
-	 * Factory method for obtaining a possibly-pooled factory from properties.
-	 * Invoked from {@link Bootstrap#getBrokerFactory}.
-	 */
-	public static JDBCBrokerFactory getInstance(ConfigurationProvider cp) {
-	    Map properties = cp.getProperties();
-	    Object key = toPoolKey(properties);
-		DistributedJDBCBrokerFactory factory =
-				(DistributedJDBCBrokerFactory) getPooledFactoryForKey(key);
-		if (factory != null)
-			return factory;
-
-		factory = newInstance(cp);
-		pool(key, factory);
-		return factory;
-	}
-
-	/**
-	 * Factory method for constructing a factory from a configuration.
-	 */
-	public static synchronized JDBCBrokerFactory getInstance(
-			JDBCConfiguration conf) {
-	    Map properties = conf.toProperties(false);
-	    Object key = toPoolKey(properties);
-		DistributedJDBCBrokerFactory factory =
-				(DistributedJDBCBrokerFactory) getPooledFactoryForKey(key);
-		if (factory != null)
-			return factory;
-
-		factory = new DistributedJDBCBrokerFactory(
-		        (DistributedJDBCConfiguration) conf);
-		pool(key, factory);
-		return factory;
-	}
-
-	public DistributedJDBCBrokerFactory(DistributedJDBCConfiguration conf) {
-		super(conf);
-	}
-	
-	@Override
-	public DistributedJDBCConfiguration getConfiguration() {
-	    return (DistributedJDBCConfiguration)super.getConfiguration();
-	}
-
-	@Override
-	protected StoreManager newStoreManager() {
-		return new DistributedStoreManager(getConfiguration());
-	}
-	
-    @Override
-    protected Object getFactoryInitializationBanner() {
-        return _loc.get("factory-init", OpenJPAVersion.VERSION_NUMBER);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.Map;
+
+import org.apache.openjpa.conf.OpenJPAVersion;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory;
+import org.apache.openjpa.kernel.Bootstrap;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * A factory for distributed JDBC datastores.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+@SuppressWarnings("serial")
+public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory {
+	private static final Localizer _loc = 
+	    Localizer.forPackage(DistributedJDBCBrokerFactory.class);
+	/**
+	 * Factory method for constructing a factory from properties. Invoked from
+	 * {@link Bootstrap#newBrokerFactory}.
+	 */
+	public static DistributedJDBCBrokerFactory newInstance(
+			ConfigurationProvider cp) {
+		DistributedJDBCConfigurationImpl conf =
+				new DistributedJDBCConfigurationImpl(cp);
+		cp.setInto(conf);
+		return new DistributedJDBCBrokerFactory(conf);
+	}
+
+	/**
+	 * Factory method for obtaining a possibly-pooled factory from properties.
+	 * Invoked from {@link Bootstrap#getBrokerFactory}.
+	 */
+	public static JDBCBrokerFactory getInstance(ConfigurationProvider cp) {
+	    Map properties = cp.getProperties();
+	    Object key = toPoolKey(properties);
+		DistributedJDBCBrokerFactory factory =
+				(DistributedJDBCBrokerFactory) getPooledFactoryForKey(key);
+		if (factory != null)
+			return factory;
+
+		factory = newInstance(cp);
+		pool(key, factory);
+		return factory;
+	}
+
+	/**
+	 * Factory method for constructing a factory from a configuration.
+	 */
+	public static synchronized JDBCBrokerFactory getInstance(
+			JDBCConfiguration conf) {
+	    Map properties = conf.toProperties(false);
+	    Object key = toPoolKey(properties);
+		DistributedJDBCBrokerFactory factory =
+				(DistributedJDBCBrokerFactory) getPooledFactoryForKey(key);
+		if (factory != null)
+			return factory;
+
+		factory = new DistributedJDBCBrokerFactory(
+		        (DistributedJDBCConfiguration) conf);
+		pool(key, factory);
+		return factory;
+	}
+
+	public DistributedJDBCBrokerFactory(DistributedJDBCConfiguration conf) {
+		super(conf);
+	}
+	
+	@Override
+	public DistributedJDBCConfiguration getConfiguration() {
+	    return (DistributedJDBCConfiguration)super.getConfiguration();
+	}
+
+	@Override
+	protected StoreManager newStoreManager() {
+		return new DistributedStoreManager(getConfiguration());
+	}
+	
+    @Override
+    protected Object getFactoryInitializationBanner() {
+        return _loc.get("factory-init", OpenJPAVersion.VERSION_NUMBER);
+    }
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
index 665befb..e3f665b 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
@@ -1,51 +1,51 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.util.concurrent.ExecutorService;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.slice.DistributedConfiguration;
-import org.apache.openjpa.slice.Slice;
-
-/**
- * A distributed configuration that is a ordered collection of 
- * JDBCConfigurations.
- * 
- * @author Pinaki Poddar 
- *
- */
-public interface DistributedJDBCConfiguration extends JDBCConfiguration, 
-	DistributedConfiguration {
-    /**
-     * Gets the master slice.
-     */
-    Slice getMaster();
-    
-    /**
-     * Gets the alias for ExecutorService being used.
-     */
-    
-    String getExecutorService();
-    
-    /**
-     * Gets the ExecutorService being used.
-     */
-    ExecutorService getExecutorServiceInstance();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.concurrent.ExecutorService;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.slice.DistributedConfiguration;
+import org.apache.openjpa.slice.Slice;
+
+/**
+ * A distributed configuration that is a ordered collection of 
+ * JDBCConfigurations.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributedJDBCConfiguration extends JDBCConfiguration, 
+	DistributedConfiguration {
+    /**
+     * Gets the master slice.
+     */
+    Slice getMaster();
+    
+    /**
+     * Gets the alias for ExecutorService being used.
+     */
+    
+    String getExecutorService();
+    
+    /**
+     * Gets the ExecutorService being used.
+     */
+    ExecutorService getExecutorServiceInstance();
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
index 4b066a3..9ad06a1 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
@@ -1,468 +1,468 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ExecutorService;
-
-import javax.sql.DataSource;
-import javax.sql.XADataSource;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
-import org.apache.openjpa.jdbc.schema.DataSourceFactory;
-import org.apache.openjpa.lib.conf.BooleanValue;
-import org.apache.openjpa.lib.conf.ConfigurationProvider;
-import org.apache.openjpa.lib.conf.PluginValue;
-import org.apache.openjpa.lib.conf.StringListValue;
-import org.apache.openjpa.lib.conf.StringValue;
-import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
-import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.log.LogFactory;
-import org.apache.openjpa.lib.log.LogFactoryImpl;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.slice.DistributedBrokerImpl;
-import org.apache.openjpa.slice.DistributionPolicy;
-import org.apache.openjpa.slice.ExecutorServiceValue;
-import org.apache.openjpa.slice.ProductDerivation;
-import org.apache.openjpa.slice.Slice;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Implements a distributed configuration of JDBCStoreManagers.
- * The original configuration properties are analyzed to create a set of
- * Slice specific properties with defaulting rules. 
- * 
- * @author Pinaki Poddar
- * 
- */
-public class DistributedJDBCConfigurationImpl extends JDBCConfigurationImpl
-        implements DistributedJDBCConfiguration {
-
-    private final List<Slice> _slices = new ArrayList<Slice>();
-    private List<String> _activeSliceNames = new ArrayList<String>();
-    private Slice _master;
-    
-    private DecoratingDataSource virtualDataSource;
-    
-    protected BooleanValue lenientPlugin;
-    protected StringValue masterPlugin;
-    protected StringListValue namesPlugin;
-    protected ExecutorServiceValue executorServicePlugin;
-    protected PluginValue distributionPolicyPlugin;
-
-    public static final String DOT = ".";
-    public static final String REGEX_DOT = "\\.";
-    public static final String PREFIX_SLICE = ProductDerivation.PREFIX_SLICE + DOT;
-    public static final String PREFIX_OPENJPA = "openjpa.";
-    private static Localizer _loc =
-            Localizer.forPackage(DistributedJDBCConfigurationImpl.class);
-
-    /**
-     * Configure itself as well as underlying slices.
-     * 
-     */
-    public DistributedJDBCConfigurationImpl(ConfigurationProvider cp) {
-        super(true, false);
-        Map p = cp.getProperties();
-        String pUnit = getPersistenceUnitName(p);
-        setDiagnosticContext(pUnit);
-        
-        brokerPlugin.setString(DistributedBrokerImpl.class.getName());
-        
-        distributionPolicyPlugin = addPlugin("DistributionPolicy", true);
-        distributionPolicyPlugin.setDynamic(true);
-        
-        lenientPlugin = addBoolean("Lenient");
-        
-        masterPlugin = addString("Master");
-        
-        namesPlugin = addStringList("Names");
-        
-        executorServicePlugin = new ExecutorServiceValue();
-        addValue(executorServicePlugin);
-        
-        setSlices(p);
-    }
-    
-    private String getPersistenceUnitName(Map p) {
-        Object unit = p.get(PREFIX_OPENJPA+id.getProperty());
-        return (unit == null) ? "?" : unit.toString();
-    }
-    
-    private void setDiagnosticContext(String unit) {
-        LogFactory logFactory = getLogFactory();
-        if (logFactory instanceof LogFactoryImpl) {
-            ((LogFactoryImpl)logFactory).setDiagnosticContext(unit);
-        }
-    }
-
-    /**
-     * Gets the name of the active slices.
-     */
-    public List<String> getActiveSliceNames() {
-        if (_activeSliceNames.isEmpty()) {
-            for (Slice slice:_slices)
-                if (slice.isActive())
-                    _activeSliceNames.add(slice.getName());
-        }
-        return _activeSliceNames;
-    }
-    
-    /**
-     * Gets the name of the available slices.
-     */
-    public List<String> getAvailableSliceNames() {
-        List<String> result = new ArrayList<String>();
-        for (Slice slice:_slices)
-            result.add(slice.getName());
-        return result;
-    }
-    
-    /**
-     * Gets the slices of given status. Null returns all irrespective of status.
-     */
-    public List<Slice> getSlices(Slice.Status...statuses) {
-        if (statuses == null)
-            return Collections.unmodifiableList(_slices);
-        List<Slice> result = new ArrayList<Slice>();
-        for (Slice slice:_slices) {
-            for (Slice.Status status:statuses)
-                if (slice.getStatus().equals(status))
-                    result.add(slice);
-        }
-        return result;
-    }
-    
-    /**
-     * Gets the master slice. 
-     */
-    public Slice getMaster() {
-        return _master;
-    }
-
-    /**
-     * Get the configuration for given slice.
-     */
-    public Slice getSlice(String name) {
-        for (Slice slice:_slices)
-            if (slice.getName().equals(name))
-                return slice;
-        throw new UserException(_loc.get("slice-not-found", name,
-                    getActiveSliceNames()));
-    }
-
-    public DistributionPolicy getDistributionPolicyInstance() {
-        if (distributionPolicyPlugin.get() == null) {
-            distributionPolicyPlugin.instantiate(DistributionPolicy.class,
-                    this, true);
-        }
-        return (DistributionPolicy) distributionPolicyPlugin.get();
-    }
-
-    public void setDistributionPolicyInstance(String val) {
-        distributionPolicyPlugin.set(val);
-    }
-
-    public Object getConnectionFactory() {
-        if (virtualDataSource == null) {
-            DistributedDataSource ds = createDistributedDataStore();
-            virtualDataSource =
-                    DataSourceFactory.installDBDictionary(
-                            getDBDictionaryInstance(), ds, this, false);
-        }
-        return virtualDataSource;
-    }
-
-    /**
-     * Create a virtual DistributedDataSource as a composite of individual
-     * slices as per configuration, optionally ignoring slices that can not be
-     * connected.
-     */
-    private DistributedDataSource createDistributedDataStore() {
-        List<DataSource> dataSources = new ArrayList<DataSource>();
-        boolean isLenient = lenientPlugin.get();
-        boolean isXA = true;
-        for (Slice slice : _slices) {
-            JDBCConfiguration conf = (JDBCConfiguration)slice.getConfiguration();
-            Log log = conf.getConfigurationLog();
-            String url = getConnectionInfo(conf);
-            if (log.isInfoEnabled())
-                log.info(_loc.get("slice-connect", slice, url));
-            try {
-                DataSource ds = DataSourceFactory.newDataSource(conf, false);
-                DecoratingDataSource dds = new DecoratingDataSource(ds);
-                ds = DataSourceFactory.installDBDictionary(
-                        conf.getDBDictionaryInstance(), dds, conf, false);
-                if (verifyDataSource(slice, ds)) {
-                    dataSources.add(ds);
-                    isXA &= isXACompliant(ds);
-                }
-            } catch (Throwable ex) {
-                handleBadConnection(isLenient, slice, ex);
-            }
-        }
-        if (dataSources.isEmpty())
-            throw new UserException(_loc.get("no-slice"));
-        DistributedDataSource result = new DistributedDataSource(dataSources);
-        return result;
-    }
-
-    String getConnectionInfo(OpenJPAConfiguration conf) {
-        String result = conf.getConnectionURL();
-        if (result == null) {
-            result = conf.getConnectionDriverName();
-            String props = conf.getConnectionProperties();
-            if (props != null)
-                result += "(" + props + ")";
-        }
-        return result;
-    }
-
-    boolean isXACompliant(DataSource ds) {
-        if (ds instanceof DelegatingDataSource)
-            return ((DelegatingDataSource) ds).getInnermostDelegate() 
-               instanceof XADataSource;
-        return ds instanceof XADataSource;
-    }
-
-    /**
-     * Verify that a connection can be established to the given slice. If
-     * connection can not be established then slice is set to INACTIVE state.
-     */
-    private boolean verifyDataSource(Slice slice, DataSource ds) {
-        Connection con = null;
-        try {
-            con = ds.getConnection();
-            slice.setStatus(Slice.Status.ACTIVE);
-            if (con == null) {
-                slice.setStatus(Slice.Status.INACTIVE);
-                return false;
-            }
-            return true;
-        } catch (SQLException ex) {
-            slice.setStatus(Slice.Status.INACTIVE);
-            return false;
-        } finally {
-            if (con != null)
-                try {
-                    con.close();
-                } catch (SQLException ex) {
-                    // ignore
-                }
-        }
-    }
-
-    /**
-     * Either throw a user exception or add the configuration to the given list,
-     * based on <code>isLenient</code>.
-     */
-    private void handleBadConnection(boolean isLenient, Slice slice,
-            Throwable ex) {
-        OpenJPAConfiguration conf = slice.getConfiguration();
-        String url = conf.getConnectionURL();
-        Log log = getLog(LOG_RUNTIME);
-        if (isLenient) {
-            if (ex != null) {
-                log.warn(_loc.get("slice-connect-known-warn", slice, url, ex
-                        .getCause()));
-            } else {
-                log.warn(_loc.get("slice-connect-warn", slice, url));
-            }
-        } else if (ex != null) {
-            throw new UserException(_loc.get("slice-connect-known-error",
-                    slice, url, ex), ex.getCause());
-        } else {
-            throw new UserException(_loc.get("slice-connect-error", slice, url));
-        }
-    }
-
-    /**
-     * Create individual slices with configurations from the given properties.
-     */
-    void setSlices(Map original) {
-        List<String> sliceNames = findSlices(original);
-        Log log = getConfigurationLog();
-        if (sliceNames.isEmpty()) {
-            throw new UserException(_loc.get("slice-none-configured"));
-        } 
-        String unit = getPersistenceUnitName(original);
-        for (String key : sliceNames) {
-            JDBCConfiguration child = new JDBCConfigurationImpl();
-            child.fromProperties(createSliceProperties(original, key));
-            child.setId(unit+DOT+key);
-            Slice slice = new Slice(key, child);
-            _slices.add(slice);
-            if (log.isTraceEnabled())
-                log.trace(_loc.get("slice-configuration", key, child
-                        .toProperties(false)));
-        }
-        setMaster(original);
-    }
-
-    /**
-     * Finds the slices. If <code>openjpa.slice.Names</code> property is 
-     * specified then the slices are ordered in the way they are listed. 
-     * Otherwise scans all available slices by looking for property of the form
-     * <code>openjpa.slice.XYZ.abc</code> where <code>XYZ</code> is the slice
-     * identifier and <code>abc</code> is any openjpa property name. The slices
-     * are then ordered alphabetically by their identifier.
-     */
-    private List<String> findSlices(Map p) {
-        List<String> sliceNames = new ArrayList<String>();
-        
-        Log log = getConfigurationLog();
-        String key = PREFIX_SLICE + namesPlugin.getProperty();
-        boolean explicit = p.containsKey(key);
-        if (explicit) {
-            String[] values = p.get(key).toString().split("\\,");
-            for (String name:values)
-                if (!sliceNames.contains(name.trim()))
-                    sliceNames.add(name.trim());
-        } else {
-            if (log.isWarnEnabled())
-                log.warn(_loc.get("no-slice-names", key));
-            sliceNames = scanForSliceNames(p);
-            Collections.sort(sliceNames);
-        }
-        if (log.isInfoEnabled()) {
-            log.info(_loc.get("slice-available", sliceNames));
-        }
-        return sliceNames;
-    }
-    
-    /**
-     * Scan the given map for slice-specific property of the form 
-     * <code>openjpa.slice.XYZ.abc</code> (while ignoring 
-     * <code>openjpa.slice.XYZ</code> as they refer to slice-wide property)
-     * to determine the names of all available slices.
-     */
-    private List<String> scanForSliceNames(Map p) {
-        List<String> sliceNames = new ArrayList<String>();
-        for (Object o : p.keySet()) {
-            String key = o.toString();
-            if (key.startsWith(PREFIX_SLICE) && getPartCount(key) > 3) {
-                String sliceName =
-                    chopTail(chopHead(o.toString(), PREFIX_SLICE), DOT);
-                if (!sliceNames.contains(sliceName))
-                    sliceNames.add(sliceName);
-            }
-        }
-        return sliceNames;
-    }
-
-    private static int getPartCount(String s) {
-        return (s == null) ? 0 : s.split(REGEX_DOT).length;
-    }
-    
-    private static String chopHead(String s, String head) {
-        if (s.startsWith(head))
-            return s.substring(head.length());
-        return s;
-    }
-
-    private static String chopTail(String s, String tail) {
-        int i = s.lastIndexOf(tail);
-        if (i == -1)
-            return s;
-        return s.substring(0, i);
-    }
-
-    /**
-     * Creates given <code>slice</code> specific configuration properties from
-     * given <code>original</code> key-value map. The rules are
-     * <LI> if key begins with <code>"slice.XXX."</code> where
-     * <code>XXX</code> is the given slice name, then replace
-     * <code>"slice.XXX.</code> with <code>openjpa.</code>.
-     * <LI>if key begins with <code>"slice."</code> but not with
-     * <code>"slice.XXX."</code>, the ignore i.e. any property of other
-     * slices or global slice property e.g.
-     * <code>slice.DistributionPolicy</code>
-     * <code>if key starts with <code>"openjpa."</code> and a corresponding
-     * <code>"slice.XXX."</code> property does not exist, then use this as
-     * default property
-     * <code>property with any other prefix is simply copied
-     *
-     */
-    Map createSliceProperties(Map original, String slice) {
-        Map result = new Properties();
-        String prefix = PREFIX_SLICE + slice + DOT;
-        for (Object o : original.keySet()) {
-            String key = o.toString();
-            if (key.startsWith(prefix)) {
-                String newKey = PREFIX_OPENJPA + key.substring(prefix.length());
-                result.put(newKey, original.get(o));
-            } else if (key.startsWith(PREFIX_SLICE)) {
-                // ignore keys that are in 'slice.' namespace but not this slice
-            } else if (key.startsWith(PREFIX_OPENJPA)) {
-                String newKey = prefix + key.substring(PREFIX_OPENJPA.length());
-                if (!original.containsKey(newKey))
-                    result.put(key, original.get(o));
-            } else { // keys that are neither "openjpa" nor "slice" namespace
-                result.put(key, original.get(o));
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Determine the master slice.
-     */
-    private void setMaster(Map original) {
-        String key = PREFIX_SLICE + masterPlugin.getProperty();
-        Object masterSlice = original.get(key);
-        Log log = getConfigurationLog();
-        List<Slice> activeSlices = getSlices(null);
-        if (masterSlice == null) {
-            _master = activeSlices.get(0);
-            if (log.isWarnEnabled())
-                log.warn(_loc.get("no-master-slice", key, _master));
-            return;
-        }
-        for (Slice slice:activeSlices)
-            if (slice.getName().equals(masterSlice))
-                _master = slice;
-        if (_master == null) {
-            _master = activeSlices.get(0);
-        }
-    }
-    
-    public String getExecutorService() {
-        return executorServicePlugin.getString();
-    }
-
-    public void setExecutorService(ExecutorService txnManager) {
-        executorServicePlugin.set(txnManager);
-    }
-
-    public ExecutorService getExecutorServiceInstance() {
-        if (executorServicePlugin.get() == null) {
-            executorServicePlugin.instantiate(ExecutorService.class, this);
-        }
-        return (ExecutorService) executorServicePlugin.get();
-    }    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+
+import javax.sql.DataSource;
+import javax.sql.XADataSource;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.schema.DataSourceFactory;
+import org.apache.openjpa.lib.conf.BooleanValue;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.conf.StringListValue;
+import org.apache.openjpa.lib.conf.StringValue;
+import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
+import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.log.LogFactory;
+import org.apache.openjpa.lib.log.LogFactoryImpl;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.slice.DistributedBrokerImpl;
+import org.apache.openjpa.slice.DistributionPolicy;
+import org.apache.openjpa.slice.ExecutorServiceValue;
+import org.apache.openjpa.slice.ProductDerivation;
+import org.apache.openjpa.slice.Slice;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Implements a distributed configuration of JDBCStoreManagers.
+ * The original configuration properties are analyzed to create a set of
+ * Slice specific properties with defaulting rules. 
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class DistributedJDBCConfigurationImpl extends JDBCConfigurationImpl
+        implements DistributedJDBCConfiguration {
+
+    private final List<Slice> _slices = new ArrayList<Slice>();
+    private List<String> _activeSliceNames = new ArrayList<String>();
+    private Slice _master;
+    
+    private DecoratingDataSource virtualDataSource;
+    
+    protected BooleanValue lenientPlugin;
+    protected StringValue masterPlugin;
+    protected StringListValue namesPlugin;
+    protected ExecutorServiceValue executorServicePlugin;
+    protected PluginValue distributionPolicyPlugin;
+
+    public static final String DOT = ".";
+    public static final String REGEX_DOT = "\\.";
+    public static final String PREFIX_SLICE = ProductDerivation.PREFIX_SLICE + DOT;
+    public static final String PREFIX_OPENJPA = "openjpa.";
+    private static Localizer _loc =
+            Localizer.forPackage(DistributedJDBCConfigurationImpl.class);
+
+    /**
+     * Configure itself as well as underlying slices.
+     * 
+     */
+    public DistributedJDBCConfigurationImpl(ConfigurationProvider cp) {
+        super(true, false);
+        Map p = cp.getProperties();
+        String pUnit = getPersistenceUnitName(p);
+        setDiagnosticContext(pUnit);
+        
+        brokerPlugin.setString(DistributedBrokerImpl.class.getName());
+        
+        distributionPolicyPlugin = addPlugin("DistributionPolicy", true);
+        distributionPolicyPlugin.setDynamic(true);
+        
+        lenientPlugin = addBoolean("Lenient");
+        
+        masterPlugin = addString("Master");
+        
+        namesPlugin = addStringList("Names");
+        
+        executorServicePlugin = new ExecutorServiceValue();
+        addValue(executorServicePlugin);
+        
+        setSlices(p);
+    }
+    
+    private String getPersistenceUnitName(Map p) {
+        Object unit = p.get(PREFIX_OPENJPA+id.getProperty());
+        return (unit == null) ? "?" : unit.toString();
+    }
+    
+    private void setDiagnosticContext(String unit) {
+        LogFactory logFactory = getLogFactory();
+        if (logFactory instanceof LogFactoryImpl) {
+            ((LogFactoryImpl)logFactory).setDiagnosticContext(unit);
+        }
+    }
+
+    /**
+     * Gets the name of the active slices.
+     */
+    public List<String> getActiveSliceNames() {
+        if (_activeSliceNames.isEmpty()) {
+            for (Slice slice:_slices)
+                if (slice.isActive())
+                    _activeSliceNames.add(slice.getName());
+        }
+        return _activeSliceNames;
+    }
+    
+    /**
+     * Gets the name of the available slices.
+     */
+    public List<String> getAvailableSliceNames() {
+        List<String> result = new ArrayList<String>();
+        for (Slice slice:_slices)
+            result.add(slice.getName());
+        return result;
+    }
+    
+    /**
+     * Gets the slices of given status. Null returns all irrespective of status.
+     */
+    public List<Slice> getSlices(Slice.Status...statuses) {
+        if (statuses == null)
+            return Collections.unmodifiableList(_slices);
+        List<Slice> result = new ArrayList<Slice>();
+        for (Slice slice:_slices) {
+            for (Slice.Status status:statuses)
+                if (slice.getStatus().equals(status))
+                    result.add(slice);
+        }
+        return result;
+    }
+    
+    /**
+     * Gets the master slice. 
+     */
+    public Slice getMaster() {
+        return _master;
+    }
+
+    /**
+     * Get the configuration for given slice.
+     */
+    public Slice getSlice(String name) {
+        for (Slice slice:_slices)
+            if (slice.getName().equals(name))
+                return slice;
+        throw new UserException(_loc.get("slice-not-found", name,
+                    getActiveSliceNames()));
+    }
+
+    public DistributionPolicy getDistributionPolicyInstance() {
+        if (distributionPolicyPlugin.get() == null) {
+            distributionPolicyPlugin.instantiate(DistributionPolicy.class,
+                    this, true);
+        }
+        return (DistributionPolicy) distributionPolicyPlugin.get();
+    }
+
+    public void setDistributionPolicyInstance(String val) {
+        distributionPolicyPlugin.set(val);
+    }
+
+    public Object getConnectionFactory() {
+        if (virtualDataSource == null) {
+            DistributedDataSource ds = createDistributedDataStore();
+            virtualDataSource =
+                    DataSourceFactory.installDBDictionary(
+                            getDBDictionaryInstance(), ds, this, false);
+        }
+        return virtualDataSource;
+    }
+
+    /**
+     * Create a virtual DistributedDataSource as a composite of individual
+     * slices as per configuration, optionally ignoring slices that can not be
+     * connected.
+     */
+    private DistributedDataSource createDistributedDataStore() {
+        List<DataSource> dataSources = new ArrayList<DataSource>();
+        boolean isLenient = lenientPlugin.get();
+        boolean isXA = true;
+        for (Slice slice : _slices) {
+            JDBCConfiguration conf = (JDBCConfiguration)slice.getConfiguration();
+            Log log = conf.getConfigurationLog();
+            String url = getConnectionInfo(conf);
+            if (log.isInfoEnabled())
+                log.info(_loc.get("slice-connect", slice, url));
+            try {
+                DataSource ds = DataSourceFactory.newDataSource(conf, false);
+                DecoratingDataSource dds = new DecoratingDataSource(ds);
+                ds = DataSourceFactory.installDBDictionary(
+                        conf.getDBDictionaryInstance(), dds, conf, false);
+                if (verifyDataSource(slice, ds)) {
+                    dataSources.add(ds);
+                    isXA &= isXACompliant(ds);
+                }
+            } catch (Throwable ex) {
+                handleBadConnection(isLenient, slice, ex);
+            }
+        }
+        if (dataSources.isEmpty())
+            throw new UserException(_loc.get("no-slice"));
+        DistributedDataSource result = new DistributedDataSource(dataSources);
+        return result;
+    }
+
+    String getConnectionInfo(OpenJPAConfiguration conf) {
+        String result = conf.getConnectionURL();
+        if (result == null) {
+            result = conf.getConnectionDriverName();
+            String props = conf.getConnectionProperties();
+            if (props != null)
+                result += "(" + props + ")";
+        }
+        return result;
+    }
+
+    boolean isXACompliant(DataSource ds) {
+        if (ds instanceof DelegatingDataSource)
+            return ((DelegatingDataSource) ds).getInnermostDelegate() 
+               instanceof XADataSource;
+        return ds instanceof XADataSource;
+    }
+
+    /**
+     * Verify that a connection can be established to the given slice. If
+     * connection can not be established then slice is set to INACTIVE state.
+     */
+    private boolean verifyDataSource(Slice slice, DataSource ds) {
+        Connection con = null;
+        try {
+            con = ds.getConnection();
+            slice.setStatus(Slice.Status.ACTIVE);
+            if (con == null) {
+                slice.setStatus(Slice.Status.INACTIVE);
+                return false;
+            }
+            return true;
+        } catch (SQLException ex) {
+            slice.setStatus(Slice.Status.INACTIVE);
+            return false;
+        } finally {
+            if (con != null)
+                try {
+                    con.close();
+                } catch (SQLException ex) {
+                    // ignore
+                }
+        }
+    }
+
+    /**
+     * Either throw a user exception or add the configuration to the given list,
+     * based on <code>isLenient</code>.
+     */
+    private void handleBadConnection(boolean isLenient, Slice slice,
+            Throwable ex) {
+        OpenJPAConfiguration conf = slice.getConfiguration();
+        String url = conf.getConnectionURL();
+        Log log = getLog(LOG_RUNTIME);
+        if (isLenient) {
+            if (ex != null) {
+                log.warn(_loc.get("slice-connect-known-warn", slice, url, ex
+                        .getCause()));
+            } else {
+                log.warn(_loc.get("slice-connect-warn", slice, url));
+            }
+        } else if (ex != null) {
+            throw new UserException(_loc.get("slice-connect-known-error",
+                    slice, url, ex), ex.getCause());
+        } else {
+            throw new UserException(_loc.get("slice-connect-error", slice, url));
+        }
+    }
+
+    /**
+     * Create individual slices with configurations from the given properties.
+     */
+    void setSlices(Map original) {
+        List<String> sliceNames = findSlices(original);
+        Log log = getConfigurationLog();
+        if (sliceNames.isEmpty()) {
+            throw new UserException(_loc.get("slice-none-configured"));
+        } 
+        String unit = getPersistenceUnitName(original);
+        for (String key : sliceNames) {
+            JDBCConfiguration child = new JDBCConfigurationImpl();
+            child.fromProperties(createSliceProperties(original, key));
+            child.setId(unit+DOT+key);
+            Slice slice = new Slice(key, child);
+            _slices.add(slice);
+            if (log.isTraceEnabled())
+                log.trace(_loc.get("slice-configuration", key, child
+                        .toProperties(false)));
+        }
+        setMaster(original);
+    }
+
+    /**
+     * Finds the slices. If <code>openjpa.slice.Names</code> property is 
+     * specified then the slices are ordered in the way they are listed. 
+     * Otherwise scans all available slices by looking for property of the form
+     * <code>openjpa.slice.XYZ.abc</code> where <code>XYZ</code> is the slice
+     * identifier and <code>abc</code> is any openjpa property name. The slices
+     * are then ordered alphabetically by their identifier.
+     */
+    private List<String> findSlices(Map p) {
+        List<String> sliceNames = new ArrayList<String>();
+        
+        Log log = getConfigurationLog();
+        String key = PREFIX_SLICE + namesPlugin.getProperty();
+        boolean explicit = p.containsKey(key);
+        if (explicit) {
+            String[] values = p.get(key).toString().split("\\,");
+            for (String name:values)
+                if (!sliceNames.contains(name.trim()))
+                    sliceNames.add(name.trim());
+        } else {
+            if (log.isWarnEnabled())
+                log.warn(_loc.get("no-slice-names", key));
+            sliceNames = scanForSliceNames(p);
+            Collections.sort(sliceNames);
+        }
+        if (log.isInfoEnabled()) {
+            log.info(_loc.get("slice-available", sliceNames));
+        }
+        return sliceNames;
+    }
+    
+    /**
+     * Scan the given map for slice-specific property of the form 
+     * <code>openjpa.slice.XYZ.abc</code> (while ignoring 
+     * <code>openjpa.slice.XYZ</code> as they refer to slice-wide property)
+     * to determine the names of all available slices.
+     */
+    private List<String> scanForSliceNames(Map p) {
+        List<String> sliceNames = new ArrayList<String>();
+        for (Object o : p.keySet()) {
+            String key = o.toString();
+            if (key.startsWith(PREFIX_SLICE) && getPartCount(key) > 3) {
+                String sliceName =
+                    chopTail(chopHead(o.toString(), PREFIX_SLICE), DOT);
+                if (!sliceNames.contains(sliceName))
+                    sliceNames.add(sliceName);
+            }
+        }
+        return sliceNames;
+    }
+
+    private static int getPartCount(String s) {
+        return (s == null) ? 0 : s.split(REGEX_DOT).length;
+    }
+    
+    private static String chopHead(String s, String head) {
+        if (s.startsWith(head))
+            return s.substring(head.length());
+        return s;
+    }
+
+    private static String chopTail(String s, String tail) {
+        int i = s.lastIndexOf(tail);
+        if (i == -1)
+            return s;
+        return s.substring(0, i);
+    }
+
+    /**
+     * Creates given <code>slice</code> specific configuration properties from
+     * given <code>original</code> key-value map. The rules are
+     * <LI> if key begins with <code>"slice.XXX."</code> where
+     * <code>XXX</code> is the given slice name, then replace
+     * <code>"slice.XXX.</code> with <code>openjpa.</code>.
+     * <LI>if key begins with <code>"slice."</code> but not with
+     * <code>"slice.XXX."</code>, the ignore i.e. any property of other
+     * slices or global slice property e.g.
+     * <code>slice.DistributionPolicy</code>
+     * <code>if key starts with <code>"openjpa."</code> and a corresponding
+     * <code>"slice.XXX."</code> property does not exist, then use this as
+     * default property
+     * <code>property with any other prefix is simply copied
+     *
+     */
+    Map createSliceProperties(Map original, String slice) {
+        Map result = new Properties();
+        String prefix = PREFIX_SLICE + slice + DOT;
+        for (Object o : original.keySet()) {
+            String key = o.toString();
+            if (key.startsWith(prefix)) {
+                String newKey = PREFIX_OPENJPA + key.substring(prefix.length());
+                result.put(newKey, original.get(o));
+            } else if (key.startsWith(PREFIX_SLICE)) {
+                // ignore keys that are in 'slice.' namespace but not this slice
+            } else if (key.startsWith(PREFIX_OPENJPA)) {
+                String newKey = prefix + key.substring(PREFIX_OPENJPA.length());
+                if (!original.containsKey(newKey))
+                    result.put(key, original.get(o));
+            } else { // keys that are neither "openjpa" nor "slice" namespace
+                result.put(key, original.get(o));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Determine the master slice.
+     */
+    private void setMaster(Map original) {
+        String key = PREFIX_SLICE + masterPlugin.getProperty();
+        Object masterSlice = original.get(key);
+        Log log = getConfigurationLog();
+        List<Slice> activeSlices = getSlices(null);
+        if (masterSlice == null) {
+            _master = activeSlices.get(0);
+            if (log.isWarnEnabled())
+                log.warn(_loc.get("no-master-slice", key, _master));
+            return;
+        }
+        for (Slice slice:activeSlices)
+            if (slice.getName().equals(masterSlice))
+                _master = slice;
+        if (_master == null) {
+            _master = activeSlices.get(0);
+        }
+    }
+    
+    public String getExecutorService() {
+        return executorServicePlugin.getString();
+    }
+
+    public void setExecutorService(ExecutorService txnManager) {
+        executorServicePlugin.set(txnManager);
+    }
+
+    public ExecutorService getExecutorServiceInstance() {
+        if (executorServicePlugin.get() == null) {
+            executorServicePlugin.instantiate(ExecutorService.class, this);
+        }
+        return (ExecutorService) executorServicePlugin.get();
+    }    
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java
index 85270de..49776e2 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java
@@ -1,247 +1,247 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-
-/**
- * A virtual PreparedStaement that delegates to a set of actual PreparedStatements.
- * 
- * @author Pinaki Poddar 
- *
- */
-class DistributedPreparedStatement extends DistributedTemplate<PreparedStatement>
-		implements PreparedStatement {
-
-	DistributedPreparedStatement(DistributedConnection c) {
-		super(c);
-	}
-
-	public void clearParameters() throws SQLException {
-		for (PreparedStatement s : this)
-			s.clearParameters();
-	}
-
-	public boolean execute() throws SQLException {
-		boolean ret = true;
-		for (PreparedStatement s : this)
-			ret = s.execute() & ret;
-		return ret;
-	}
-
-	public ResultSet executeQuery() throws SQLException {
-		DistributedResultSet mrs = new DistributedResultSet();
-		for (PreparedStatement t : this)
-			mrs.add(t.executeQuery());
-		return mrs;
-	}
-
-	public int executeUpdate() throws SQLException {
-		int ret = 0;
-		for (PreparedStatement t : this)
-			ret += t.executeUpdate();
-		return ret;
-	}
-
-	public ResultSetMetaData getMetaData() throws SQLException {
-		return master.getMetaData();
-	}
-
-	public ParameterMetaData getParameterMetaData() throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public void setArray(int i, Array x) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setArray(i, x);
-	}
-
-	public void setAsciiStream(int arg0, InputStream arg1, int arg2)
-			throws SQLException {
-		for (PreparedStatement t : this)
-			t.setAsciiStream(arg0, arg1, arg2);
-	}
-
-	public void setBigDecimal(int arg0, BigDecimal arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setBigDecimal(arg0, arg1);
-	}
-
-	public void setBinaryStream(int arg0, InputStream arg1, int arg2)
-			throws SQLException {
-		for (PreparedStatement t : this)
-			t.setBinaryStream(arg0, arg1, arg2);
-	}
-
-	public void setBlob(int arg0, Blob arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setBlob(arg0, arg1);
-	}
-
-	public void setBoolean(int arg0, boolean arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setBoolean(arg0, arg1);
-	}
-
-	public void setByte(int arg0, byte arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setByte(arg0, arg1);
-	}
-
-	public void setBytes(int arg0, byte[] arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setBytes(arg0, arg1);
-	}
-
-	public void setCharacterStream(int arg0, Reader arg1, int arg2)
-			throws SQLException {
-		for (PreparedStatement t : this)
-			t.setCharacterStream(arg0, arg1, arg2);
-	}
-
-	public void setClob(int arg0, Clob arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setClob(arg0, arg1);
-	}
-
-	public void setDate(int arg0, Date arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setDate(arg0, arg1);
-	}
-
-	public void setDate(int arg0, Date arg1, Calendar arg2) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setDate(arg0, arg1, arg2);
-	}
-
-	public void setDouble(int arg0, double arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setDouble(arg0, arg1);
-	}
-
-	public void setFloat(int arg0, float arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setFloat(arg0, arg1);
-	}
-
-	public void setInt(int arg0, int arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setInt(arg0, arg1);
-	}
-
-	public void setLong(int arg0, long arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setLong(arg0, arg1);
-	}
-
-	public void setNull(int arg0, int arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setNull(arg0, arg1);
-	}
-
-	public void setNull(int arg0, int arg1, String arg2) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setNull(arg0, arg1, arg2);
-	}
-
-	public void setObject(int arg0, Object arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setObject(arg0, arg1);
-	}
-
-	public void setObject(int arg0, Object arg1, int arg2) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setObject(arg0, arg1, arg2);
-	}
-
-	public void setObject(int arg0, Object arg1, int arg2, int arg3)
-			throws SQLException {
-		for (PreparedStatement t : this)
-			t.setObject(arg0, arg1, arg2, arg3);
-	}
-
-	public void setRef(int arg0, Ref arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setRef(arg0, arg1);
-	}
-
-	public void setShort(int arg0, short arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setShort(arg0, arg1);
-	}
-
-	public void setString(int arg0, String arg1) throws SQLException {
-		for (PreparedStatement t : this)
-			t.setString(arg0, arg1);
-	}
-
-	 public void setTime(int arg0, Time arg1) throws SQLException {
-			for (PreparedStatement t : this)
-				t.setTime(arg0, arg1);
-	 }
-	
-	 public void setTime(int arg0, Time arg1, Calendar arg2) throws
-	 SQLException {
-			for (PreparedStatement t : this)
-				t.setTime(arg0, arg1, arg2);
-	 }
-	
-	 public void setTimestamp(int arg0, Timestamp arg1) throws SQLException {
-			for (PreparedStatement t : this)
-				t.setTimestamp(arg0, arg1);
-	 }
-	
-	 public void setTimestamp(int arg0, Timestamp arg1, Calendar arg2)
-	 throws SQLException {
-			for (PreparedStatement t : this)
-				t.setTimestamp(arg0, arg1, arg2);
-	 }
-	
-	 public void setURL(int arg0, URL arg1) throws SQLException {
-			for (PreparedStatement t : this)
-				t.setURL(arg0, arg1);
-	 }
-	
-	 public void setUnicodeStream(int arg0, InputStream arg1, int arg2)
-	     throws SQLException {
-			for (PreparedStatement t : this)
-				t.setUnicodeStream(arg0, arg1, arg2);
-	 }
-	
-	 public void addBatch() throws SQLException {
-		for (PreparedStatement t:this)
-		    t.addBatch();
-	 }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+/**
+ * A virtual PreparedStaement that delegates to a set of actual PreparedStatements.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+class DistributedPreparedStatement extends DistributedTemplate<PreparedStatement>
+		implements PreparedStatement {
+
+	DistributedPreparedStatement(DistributedConnection c) {
+		super(c);
+	}
+
+	public void clearParameters() throws SQLException {
+		for (PreparedStatement s : this)
+			s.clearParameters();
+	}
+
+	public boolean execute() throws SQLException {
+		boolean ret = true;
+		for (PreparedStatement s : this)
+			ret = s.execute() & ret;
+		return ret;
+	}
+
+	public ResultSet executeQuery() throws SQLException {
+		DistributedResultSet mrs = new DistributedResultSet();
+		for (PreparedStatement t : this)
+			mrs.add(t.executeQuery());
+		return mrs;
+	}
+
+	public int executeUpdate() throws SQLException {
+		int ret = 0;
+		for (PreparedStatement t : this)
+			ret += t.executeUpdate();
+		return ret;
+	}
+
+	public ResultSetMetaData getMetaData() throws SQLException {
+		return master.getMetaData();
+	}
+
+	public ParameterMetaData getParameterMetaData() throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setArray(int i, Array x) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setArray(i, x);
+	}
+
+	public void setAsciiStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setAsciiStream(arg0, arg1, arg2);
+	}
+
+	public void setBigDecimal(int arg0, BigDecimal arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBigDecimal(arg0, arg1);
+	}
+
+	public void setBinaryStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBinaryStream(arg0, arg1, arg2);
+	}
+
+	public void setBlob(int arg0, Blob arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBlob(arg0, arg1);
+	}
+
+	public void setBoolean(int arg0, boolean arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBoolean(arg0, arg1);
+	}
+
+	public void setByte(int arg0, byte arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setByte(arg0, arg1);
+	}
+
+	public void setBytes(int arg0, byte[] arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBytes(arg0, arg1);
+	}
+
+	public void setCharacterStream(int arg0, Reader arg1, int arg2)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setCharacterStream(arg0, arg1, arg2);
+	}
+
+	public void setClob(int arg0, Clob arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setClob(arg0, arg1);
+	}
+
+	public void setDate(int arg0, Date arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setDate(arg0, arg1);
+	}
+
+	public void setDate(int arg0, Date arg1, Calendar arg2) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setDate(arg0, arg1, arg2);
+	}
+
+	public void setDouble(int arg0, double arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setDouble(arg0, arg1);
+	}
+
+	public void setFloat(int arg0, float arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setFloat(arg0, arg1);
+	}
+
+	public void setInt(int arg0, int arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setInt(arg0, arg1);
+	}
+
+	public void setLong(int arg0, long arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setLong(arg0, arg1);
+	}
+
+	public void setNull(int arg0, int arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setNull(arg0, arg1);
+	}
+
+	public void setNull(int arg0, int arg1, String arg2) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setNull(arg0, arg1, arg2);
+	}
+
+	public void setObject(int arg0, Object arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setObject(arg0, arg1);
+	}
+
+	public void setObject(int arg0, Object arg1, int arg2) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setObject(arg0, arg1, arg2);
+	}
+
+	public void setObject(int arg0, Object arg1, int arg2, int arg3)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setObject(arg0, arg1, arg2, arg3);
+	}
+
+	public void setRef(int arg0, Ref arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setRef(arg0, arg1);
+	}
+
+	public void setShort(int arg0, short arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setShort(arg0, arg1);
+	}
+
+	public void setString(int arg0, String arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setString(arg0, arg1);
+	}
+
+	 public void setTime(int arg0, Time arg1) throws SQLException {
+			for (PreparedStatement t : this)
+				t.setTime(arg0, arg1);
+	 }
+	
+	 public void setTime(int arg0, Time arg1, Calendar arg2) throws
+	 SQLException {
+			for (PreparedStatement t : this)
+				t.setTime(arg0, arg1, arg2);
+	 }
+	
+	 public void setTimestamp(int arg0, Timestamp arg1) throws SQLException {
+			for (PreparedStatement t : this)
+				t.setTimestamp(arg0, arg1);
+	 }
+	
+	 public void setTimestamp(int arg0, Timestamp arg1, Calendar arg2)
+	 throws SQLException {
+			for (PreparedStatement t : this)
+				t.setTimestamp(arg0, arg1, arg2);
+	 }
+	
+	 public void setURL(int arg0, URL arg1) throws SQLException {
+			for (PreparedStatement t : this)
+				t.setURL(arg0, arg1);
+	 }
+	
+	 public void setUnicodeStream(int arg0, InputStream arg1, int arg2)
+	     throws SQLException {
+			for (PreparedStatement t : this)
+				t.setUnicodeStream(arg0, arg1, arg2);
+	 }
+	
+	 public void addBatch() throws SQLException {
+		for (PreparedStatement t:this)
+		    t.addBatch();
+	 }
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java
index 58cf5e2..55acc19 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java
@@ -1,763 +1,763 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.LinkedList;
-import java.util.Map;
-
-/**
- * A chain of ResultSet.
- * 
- * @author Pinaki Poddar 
- *
- */
-class DistributedResultSet implements ResultSet {
-	LinkedList<ResultSet> comps = new LinkedList<ResultSet>();
-	ResultSet current;
-	int cursor = -1;
-	
-	/**
-	 * Adds the ResultSet only if it has rows.
-	 */
-	public void add(ResultSet rs) {
-		try {
-			if (rs.first())
-				comps.add(rs);
-		} catch (SQLException e) {
-			// ignore
-		}
-	}
-	
-	public boolean absolute(int arg0) throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public void afterLast() throws SQLException {
-		current = null;
-		cursor  = comps.size();
-	}
-
-	public void beforeFirst() throws SQLException {
-		current = null;
-		cursor  = -1;
-	}
-
-	public void cancelRowUpdates() throws SQLException {
-		throw new UnsupportedOperationException();
-	}
-
-	public void clearWarnings() throws SQLException {
-		for (ResultSet rs:comps)
-			rs.clearWarnings();
-	}
-
-	public void close() throws SQLException {
-		for (ResultSet rs:comps)
-			rs.close();
-	}
-
-	public void deleteRow() throws SQLException {
-		current.deleteRow();
-	}
-
-	public int findColumn(String arg0) throws SQLException {
-		return 0;
-	}
-
-	public boolean first() throws SQLException {
-		if (comps.isEmpty()) return false;
-		cursor = 0;
-		current = comps.get(0);
-		return true;
-	}
-
-	public Array getArray(int arg0) throws SQLException {
-		return current.getArray(arg0);
-	}
-
-	public Array getArray(String arg0) throws SQLException {
-		return current.getArray(arg0);
-	}
-
-	public InputStream getAsciiStream(int arg0) throws SQLException {
-		return current.getAsciiStream(arg0);
-	}
-
-	public InputStream getAsciiStream(String arg0) throws SQLException {
-		return current.getAsciiStream(arg0);
-	}
-
-	public BigDecimal getBigDecimal(int arg0) throws SQLException {
-		return current.getBigDecimal(arg0);
-	}
-
-	public BigDecimal getBigDecimal(String arg0) throws SQLException {
-		return current.getBigDecimal(arg0);
-	}
-
-	public BigDecimal getBigDecimal(int arg0, int arg1) throws SQLException {
-		return current.getBigDecimal(arg0, arg1);
-	}
-
-	public BigDecimal getBigDecimal(String arg0, int arg1) throws SQLException {
-		return current.getBigDecimal(arg0, arg1);
-	}
-
-	public InputStream getBinaryStream(int arg0) throws SQLException {
-		return current.getBinaryStream(arg0);
-	}
-
-	public InputStream getBinaryStream(String arg0) throws SQLException {
-		return current.getBinaryStream(arg0);
-	}
-
-	public Blob getBlob(int arg0) throws SQLException {
-		return current.getBlob(arg0);
-	}
-
-	public Blob getBlob(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public boolean getBoolean(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	public boolean getBoolean(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	public byte getByte(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public byte getByte(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public byte[] getBytes(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public byte[] getBytes(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Reader getCharacterStream(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Reader getCharacterStream(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Clob getClob(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Clob getClob(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public int getConcurrency() throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public String getCursorName() throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Date getDate(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Date getDate(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Date getDate(int arg0, Calendar arg1) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Date getDate(String arg0, Calendar arg1) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public double getDouble(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public double getDouble(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public int getFetchDirection() throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public int getFetchSize() throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public float getFloat(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public float getFloat(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public int getInt(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public int getInt(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public long getLong(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public long getLong(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public ResultSetMetaData getMetaData() throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Object getObject(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Object getObject(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Object getObject(int arg0, Map<String, Class<?>> arg1)
-			throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Object getObject(String arg0, Map<String, Class<?>> arg1)
-			throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Ref getRef(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Ref getRef(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public int getRow() throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public short getShort(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public short getShort(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public Statement getStatement() throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public String getString(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public String getString(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Time getTime(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Time getTime(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Time getTime(int arg0, Calendar arg1) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Time getTime(String arg0, Calendar arg1) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Timestamp getTimestamp(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Timestamp getTimestamp(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Timestamp getTimestamp(int arg0, Calendar arg1) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public Timestamp getTimestamp(String arg0, Calendar arg1)
-			throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public int getType() throws SQLException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public URL getURL(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public URL getURL(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public InputStream getUnicodeStream(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public InputStream getUnicodeStream(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public SQLWarning getWarnings() throws SQLException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public void insertRow() throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public boolean isAfterLast() throws SQLException {
-		return current == null && cursor >= comps.size();
-	}
-
-	public boolean isBeforeFirst() throws SQLException {
-		return current == null && cursor<0;
-	}
-
-	public boolean isFirst() throws SQLException {
-		return current != null && current.isFirst() && cursor==0;
-	}
-
-	public boolean isLast() throws SQLException {
-		return current != null && current.isLast() && cursor==comps.size()-1;
-	}
-
-	public boolean last() throws SQLException {
-		if (comps.isEmpty()) return false;
-		cursor = comps.size()-1;
-		return false;
-	}
-
-	public void moveToCurrentRow() throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void moveToInsertRow() throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public boolean next() throws SQLException {
-		if (current == null) {
-			current = comps.get(0);
-			cursor = 0;
-		}
-		if (current.next())
-			return true;
-		cursor++;
-		if (cursor<comps.size())
-			current = comps.get(cursor);
-		return cursor<comps.size();
-	}
-
-	public boolean previous() throws SQLException {
-		return current.previous();
-	}
-
-	public void refreshRow() throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public boolean relative(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	public boolean rowDeleted() throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	public boolean rowInserted() throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	public boolean rowUpdated() throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	public void setFetchDirection(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void setFetchSize(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateArray(int arg0, Array arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateArray(String arg0, Array arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateAsciiStream(int arg0, InputStream arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateAsciiStream(String arg0, InputStream arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBigDecimal(int arg0, BigDecimal arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBigDecimal(String arg0, BigDecimal arg1)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBinaryStream(int arg0, InputStream arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBinaryStream(String arg0, InputStream arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBlob(int arg0, Blob arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBlob(String arg0, Blob arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBoolean(int arg0, boolean arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBoolean(String arg0, boolean arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateByte(int arg0, byte arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateByte(String arg0, byte arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBytes(int arg0, byte[] arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateBytes(String arg0, byte[] arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateCharacterStream(int arg0, Reader arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateCharacterStream(String arg0, Reader arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateClob(int arg0, Clob arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateClob(String arg0, Clob arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateDate(int arg0, Date arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateDate(String arg0, Date arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateDouble(int arg0, double arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateDouble(String arg0, double arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateFloat(int arg0, float arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateFloat(String arg0, float arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateInt(int arg0, int arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateInt(String arg0, int arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateLong(int arg0, long arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateLong(String arg0, long arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateNull(int arg0) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateNull(String arg0) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateObject(int arg0, Object arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateObject(String arg0, Object arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateObject(int arg0, Object arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateObject(String arg0, Object arg1, int arg2)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateRef(int arg0, Ref arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateRef(String arg0, Ref arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateRow() throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateShort(int arg0, short arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateShort(String arg0, short arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateString(int arg0, String arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateString(String arg0, String arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateTime(int arg0, Time arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateTime(String arg0, Time arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateTimestamp(int arg0, Timestamp arg1) throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void updateTimestamp(String arg0, Timestamp arg1)
-			throws SQLException {
-		// TODO Auto-generated method stub
-
-	}
-
-	public boolean wasNull() throws SQLException {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * A chain of ResultSet.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+class DistributedResultSet implements ResultSet {
+	LinkedList<ResultSet> comps = new LinkedList<ResultSet>();
+	ResultSet current;
+	int cursor = -1;
+	
+	/**
+	 * Adds the ResultSet only if it has rows.
+	 */
+	public void add(ResultSet rs) {
+		try {
+			if (rs.first())
+				comps.add(rs);
+		} catch (SQLException e) {
+			// ignore
+		}
+	}
+	
+	public boolean absolute(int arg0) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void afterLast() throws SQLException {
+		current = null;
+		cursor  = comps.size();
+	}
+
+	public void beforeFirst() throws SQLException {
+		current = null;
+		cursor  = -1;
+	}
+
+	public void cancelRowUpdates() throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void clearWarnings() throws SQLException {
+		for (ResultSet rs:comps)
+			rs.clearWarnings();
+	}
+
+	public void close() throws SQLException {
+		for (ResultSet rs:comps)
+			rs.close();
+	}
+
+	public void deleteRow() throws SQLException {
+		current.deleteRow();
+	}
+
+	public int findColumn(String arg0) throws SQLException {
+		return 0;
+	}
+
+	public boolean first() throws SQLException {
+		if (comps.isEmpty()) return false;
+		cursor = 0;
+		current = comps.get(0);
+		return true;
+	}
+
+	public Array getArray(int arg0) throws SQLException {
+		return current.getArray(arg0);
+	}
+
+	public Array getArray(String arg0) throws SQLException {
+		return current.getArray(arg0);
+	}
+
+	public InputStream getAsciiStream(int arg0) throws SQLException {
+		return current.getAsciiStream(arg0);
+	}
+
+	public InputStream getAsciiStream(String arg0) throws SQLException {
+		return current.getAsciiStream(arg0);
+	}
+
+	public BigDecimal getBigDecimal(int arg0) throws SQLException {
+		return current.getBigDecimal(arg0);
+	}
+
+	public BigDecimal getBigDecimal(String arg0) throws SQLException {
+		return current.getBigDecimal(arg0);
+	}
+
+	public BigDecimal getBigDecimal(int arg0, int arg1) throws SQLException {
+		return current.getBigDecimal(arg0, arg1);
+	}
+
+	public BigDecimal getBigDecimal(String arg0, int arg1) throws SQLException {
+		return current.getBigDecimal(arg0, arg1);
+	}
+
+	public InputStream getBinaryStream(int arg0) throws SQLException {
+		return current.getBinaryStream(arg0);
+	}
+
+	public InputStream getBinaryStream(String arg0) throws SQLException {
+		return current.getBinaryStream(arg0);
+	}
+
+	public Blob getBlob(int arg0) throws SQLException {
+		return current.getBlob(arg0);
+	}
+
+	public Blob getBlob(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public boolean getBoolean(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean getBoolean(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public byte getByte(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public byte getByte(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public byte[] getBytes(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public byte[] getBytes(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Reader getCharacterStream(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Reader getCharacterStream(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Clob getClob(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Clob getClob(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getConcurrency() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public String getCursorName() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(int arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(String arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public double getDouble(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public double getDouble(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getFetchDirection() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getFetchSize() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public float getFloat(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public float getFloat(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getInt(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getInt(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public long getLong(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public long getLong(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public ResultSetMetaData getMetaData() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(int arg0, Map<String, Class<?>> arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(String arg0, Map<String, Class<?>> arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Ref getRef(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Ref getRef(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getRow() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public short getShort(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public short getShort(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public Statement getStatement() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String getString(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String getString(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(int arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(String arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(int arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(String arg0, Calendar arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getType() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public URL getURL(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public URL getURL(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public InputStream getUnicodeStream(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public InputStream getUnicodeStream(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void insertRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean isAfterLast() throws SQLException {
+		return current == null && cursor >= comps.size();
+	}
+
+	public boolean isBeforeFirst() throws SQLException {
+		return current == null && cursor<0;
+	}
+
+	public boolean isFirst() throws SQLException {
+		return current != null && current.isFirst() && cursor==0;
+	}
+
+	public boolean isLast() throws SQLException {
+		return current != null && current.isLast() && cursor==comps.size()-1;
+	}
+
+	public boolean last() throws SQLException {
+		if (comps.isEmpty()) return false;
+		cursor = comps.size()-1;
+		return false;
+	}
+
+	public void moveToCurrentRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void moveToInsertRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean next() throws SQLException {
+		if (current == null) {
+			current = comps.get(0);
+			cursor = 0;
+		}
+		if (current.next())
+			return true;
+		cursor++;
+		if (cursor<comps.size())
+			current = comps.get(cursor);
+		return cursor<comps.size();
+	}
+
+	public boolean previous() throws SQLException {
+		return current.previous();
+	}
+
+	public void refreshRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean relative(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean rowDeleted() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean rowInserted() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean rowUpdated() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public void setFetchDirection(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void setFetchSize(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateArray(int arg0, Array arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateArray(String arg0, Array arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateAsciiStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateAsciiStream(String arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBigDecimal(int arg0, BigDecimal arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBigDecimal(String arg0, BigDecimal arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBinaryStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBinaryStream(String arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBlob(int arg0, Blob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBlob(String arg0, Blob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBoolean(int arg0, boolean arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBoolean(String arg0, boolean arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateByte(int arg0, byte arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateByte(String arg0, byte arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBytes(int arg0, byte[] arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBytes(String arg0, byte[] arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateCharacterStream(int arg0, Reader arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateCharacterStream(String arg0, Reader arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateClob(int arg0, Clob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateClob(String arg0, Clob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDate(int arg0, Date arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDate(String arg0, Date arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDouble(int arg0, double arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDouble(String arg0, double arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateFloat(int arg0, float arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateFloat(String arg0, float arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateInt(int arg0, int arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateInt(String arg0, int arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateLong(int arg0, long arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateLong(String arg0, long arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateNull(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateNull(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(int arg0, Object arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(String arg0, Object arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(int arg0, Object arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(String arg0, Object arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateRef(int arg0, Ref arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateRef(String arg0, Ref arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateShort(int arg0, short arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateShort(String arg0, short arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateString(int arg0, String arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateString(String arg0, String arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTime(int arg0, Time arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTime(String arg0, Time arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTimestamp(int arg0, Timestamp arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTimestamp(String arg0, Timestamp arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean wasNull() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java
index 5a75a5b..6b680a8 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.sql.Statement;
-
-/**
- * A virtual Statement that delegates to many actual Statements.
- * 
- * @author Pinaki Poddar 
- *
- */
-class DistributedStatement extends DistributedTemplate<Statement>  {
-	public DistributedStatement(DistributedConnection c) {
-		super(c);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.Statement;
+
+/**
+ * A virtual Statement that delegates to many actual Statements.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+class DistributedStatement extends DistributedTemplate<Statement>  {
+	public DistributedStatement(DistributedConnection c) {
+		super(c);
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
index 0fefc75..7cbfe3a 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
@@ -1,435 +1,435 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.kernel.ConnectionInfo;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
-import org.apache.openjpa.jdbc.sql.Result;
-import org.apache.openjpa.jdbc.sql.ResultSetResult;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.kernel.PCState;
-import org.apache.openjpa.kernel.QueryLanguages;
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.kernel.StoreManager;
-import org.apache.openjpa.kernel.StoreQuery;
-import org.apache.openjpa.kernel.exps.ExpressionParser;
-import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.slice.DistributionPolicy;
-import org.apache.openjpa.slice.ProductDerivation;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.StoreException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * A Store manager for multiple physical databases referred as <em>slice</em>.
- * This receiver behaves like a Transaction Manager as it implements two-phase
- * commit protocol if all the component slices is XA-complaint. The actions are
- * delegated to the underlying slices. The actions are executed in parallel
- * threads whenever possible such as flushing or query. <br>
- * 
- * @author Pinaki Poddar
- * 
- */
-class DistributedStoreManager extends JDBCStoreManager {
-    private final List<SliceStoreManager> _slices;
-    private JDBCStoreManager _master;
-    private final DistributedJDBCConfiguration _conf;
-    private static final Localizer _loc =
-            Localizer.forPackage(DistributedStoreManager.class);
-    private static ExecutorService threadPool = Executors.newCachedThreadPool();
-
-    /**
-     * Constructs a set of child StoreManagers each connected to a physical
-     * DataSource.
-     * 
-     * The supplied configuration carries multiple URL for underlying physical
-     * slices. The first slice is referred as <em>master</em> and is used to
-     * get Sequence based entity identifiers.
-     */
-    public DistributedStoreManager(DistributedJDBCConfiguration conf) {
-        super();
-        _conf = conf;
-        _slices = new ArrayList<SliceStoreManager>();
-        List<String> sliceNames = conf.getActiveSliceNames();
-        for (String name : sliceNames) {
-            SliceStoreManager slice = new SliceStoreManager
-                (conf.getSlice(name));
-            _slices.add(slice);
-            if (name.equals(conf.getMaster().getName()))
-                _master = slice;
-        }
-    }
-
-    public DistributedJDBCConfiguration getConfiguration() {
-        return _conf;
-    }
-
-    /**
-     * Decides the index of the StoreManager by first looking at the
-     * implementation data. If not found then {@link DistributionPolicy
-     * DistributionPolicy} determines the target store for new instances and
-     * additional connection info is used to estimate for the existing
-     * instances.
-     */
-    protected String findSliceName(OpenJPAStateManager sm, Object info) {
-        boolean hasIndex = hasSlice(sm);
-        if (hasIndex)
-            return sm.getImplData().toString();
-        String slice = estimateSlice(sm, info);
-        if (slice == null)
-            return assignSlice(sm);
-        return slice;
-    }
-
-    private boolean hasSlice(OpenJPAStateManager sm) {
-        return sm.getImplData() != null;
-    }
-
-    private String assignSlice(OpenJPAStateManager sm) {
-        Object pc = sm.getPersistenceCapable();
-        DistributionPolicy policy = _conf.getDistributionPolicyInstance();
-        List<String> sliceNames = _conf.getActiveSliceNames();
-        String slice =policy.distribute(pc, sliceNames, getContext());
-        if (!sliceNames.contains(slice)) {
-            throw new UserException(_loc.get("bad-policy-slice", new Object[] {
-                    policy.getClass().getName(), slice, pc, sliceNames }));
-        }
-        sm.setImplData(slice, true);
-        return slice;
-    }
-
-    /**
-     * The additional edata is used, if possible, to find the StoreManager
-     * managing the given StateManager. If the additional data is unavailable
-     * then return null.
-     * 
-     */
-    private String estimateSlice(OpenJPAStateManager sm, Object edata) {
-        if (edata == null || !(edata instanceof ConnectionInfo))
-            return null;
-
-        Result result = ((ConnectionInfo) edata).result;
-        if (result instanceof ResultSetResult) {
-            JDBCStore store = ((ResultSetResult) result).getStore();
-            for (SliceStoreManager slice : _slices) {
-                if (slice == store) {
-                    String sliceId = slice.getName();
-                    sm.setImplData(sliceId, true);
-                    return sliceId;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Selects a child StoreManager where the given instance resides.
-     */
-    private StoreManager selectStore(OpenJPAStateManager sm, Object edata) {
-        String name = findSliceName(sm, edata);
-        SliceStoreManager slice = lookup(name);
-        if (slice == null)
-            throw new InternalException(_loc.get("wrong-slice", name, sm));
-        return slice;
-    }
-
-    public boolean assignField(OpenJPAStateManager sm, int field,
-            boolean preFlush) {
-        return selectStore(sm, null).assignField(sm, field, preFlush);
-    }
-
-    public boolean assignObjectId(OpenJPAStateManager sm, boolean preFlush) {
-        return _master.assignObjectId(sm, preFlush);
-    }
-
-    public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
-            PCState toState) {
-        _master.beforeStateChange(sm, fromState, toState);
-    }
-
-    public void beginOptimistic() {
-        for (SliceStoreManager slice : _slices)
-            slice.beginOptimistic();
-    }
-
-    public boolean cancelAll() {
-        boolean ret = true;
-        for (SliceStoreManager slice : _slices)
-            ret = slice.cancelAll() & ret;
-        return ret;
-    }
-
-    public int compareVersion(OpenJPAStateManager sm, Object v1, Object v2) {
-        return selectStore(sm, null).compareVersion(sm, v1, v2);
-    }
-
-    public Object copyDataStoreId(Object oid, ClassMetaData meta) {
-        return _master.copyDataStoreId(oid, meta);
-    }
-
-    public ResultObjectProvider executeExtent(ClassMetaData meta,
-            boolean subclasses, FetchConfiguration fetch) {
-        int i = 0;
-        List<SliceStoreManager> targets = getTargets(fetch);
-        ResultObjectProvider[] tmp = new ResultObjectProvider[targets.size()];
-        for (SliceStoreManager slice : targets) {
-            tmp[i++] = slice.executeExtent(meta, subclasses, fetch);
-        }
-        return new MergedResultObjectProvider(tmp);
-    }
-
-    public boolean exists(OpenJPAStateManager sm, Object edata) {
-        for (SliceStoreManager slice : _slices) {
-            if (slice.exists(sm, edata)) {
-                sm.setImplData(slice.getName(), true);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    
-    /**
-     * Flush the given StateManagers after binning them to respective physical
-     * slices.
-     */
-    public Collection flush(Collection sms) {
-        Collection exceptions = new ArrayList();
-        List<Future<Collection>> futures = new ArrayList<Future<Collection>>();
-        Map<String, List<OpenJPAStateManager>> subsets = bin(sms, null);
-        for (SliceStoreManager slice : _slices) {
-            List<OpenJPAStateManager> subset = subsets.get(slice.getName());
-            if (subset.isEmpty())
-                continue;
-            futures.add(threadPool.submit(new Flusher(slice, subset)));
-        }
-        for (Future<Collection> future : futures) {
-            Collection error;
-            try {
-                error = future.get();
-                if (!(error == null || error.isEmpty())) {
-                    exceptions.addAll(error);
-                }
-            } catch (InterruptedException e) {
-                throw new StoreException(e);
-            } catch (ExecutionException e) {
-                throw new StoreException(e.getCause());
-            }
-        }
-        return exceptions;
-    }
-    
-    /**
-     * Separate the given list of StateManagers in separate lists for each slice 
-     * by the associated slice identifier of each StateManager.
-     * @param sms
-     * @param edata
-     * @return
-     */
-    private Map<String, List<OpenJPAStateManager>> bin(
-            Collection/*<StateManage>*/ sms, Object edata) {
-        Map<String, List<OpenJPAStateManager>> subsets =
-                new HashMap<String, List<OpenJPAStateManager>>();
-        for (SliceStoreManager slice : _slices)
-            subsets.put(slice.getName(), new ArrayList<OpenJPAStateManager>());
-        for (Object x : sms) {
-            OpenJPAStateManager sm = (OpenJPAStateManager) x;
-            String slice = findSliceName(sm, edata);
-            subsets.get(slice).add(sm);
-        }
-        return subsets;
-    }
-
-    public Object getClientConnection() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Seq getDataStoreIdSequence(ClassMetaData forClass) {
-        return _master.getDataStoreIdSequence(forClass);
-    }
-
-    public Class getDataStoreIdType(ClassMetaData meta) {
-        return _master.getDataStoreIdType(meta);
-    }
-
-    public Class getManagedType(Object oid) {
-        return _master.getManagedType(oid);
-    }
-
-    public Seq getValueSequence(FieldMetaData forField) {
-        return _master.getValueSequence(forField);
-    }
-
-    public boolean initialize(OpenJPAStateManager sm, PCState state,
-            FetchConfiguration fetch, Object edata) {
-        if (edata instanceof ConnectionInfo) {
-            String slice = findSliceName(sm, (ConnectionInfo) edata);
-            if (slice != null)
-                return lookup(slice).initialize(sm, state, fetch, edata);
-        }
-        // not a part of Query result load. Look into the slices till found
-        List<SliceStoreManager> targets = getTargets(fetch);
-        for (SliceStoreManager slice : targets) {
-            if (slice.initialize(sm, state, fetch, edata)) {
-                sm.setImplData(slice.getName(), true);
-                return true;
-            }
-        }
-        return false;
-
-    }
-
-    public boolean load(OpenJPAStateManager sm, BitSet fields,
-            FetchConfiguration fetch, int lockLevel, Object edata) {
-        return selectStore(sm, edata).load(sm, fields, fetch, lockLevel, edata);
-    }
-
-    public Collection loadAll(Collection sms, PCState state, int load,
-            FetchConfiguration fetch, Object edata) {
-        Map<String, List<OpenJPAStateManager>> subsets = bin(sms, edata);
-        Collection result = new ArrayList();
-        for (SliceStoreManager slice : _slices) {
-            List<OpenJPAStateManager> subset = subsets.get(slice.getName());
-            if (subset.isEmpty())
-                continue;
-            Collection tmp = slice.loadAll(subset, state, load, fetch, edata);
-            if (tmp != null && !tmp.isEmpty())
-                result.addAll(tmp);
-        }
-        return result;
-    }
-
-    public Object newDataStoreId(Object oidVal, ClassMetaData meta) {
-        return _master.newDataStoreId(oidVal, meta);
-    }
-
-    public FetchConfiguration newFetchConfiguration() {
-        return _master.newFetchConfiguration();
-    }
-
-    /**
-     * Construct a distributed query to be executed against all the slices.
-     */
-    public StoreQuery newQuery(String language) {
-        ExpressionParser parser = QueryLanguages.parserForLanguage(language);
-        DistributedStoreQuery ret = new DistributedStoreQuery(this, parser);
-        for (SliceStoreManager slice : _slices) {
-            ret.add(slice.newQuery(language));
-        }
-        return ret;
-    }
-
-    /**
-     * Sets the context for this receiver and all its underlying slices.
-     */
-    public void setContext(StoreContext ctx) {
-        super.setContext(ctx);
-        for (SliceStoreManager store : _slices) {
-            store.setContext(ctx, 
-                    (JDBCConfiguration)store.getSlice().getConfiguration());
-        }
-    }
-
-    private SliceStoreManager lookup(String name) {
-        for (SliceStoreManager slice : _slices)
-            if (slice.getName().equals(name))
-                return slice;
-        return null;
-    }
-
-    public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
-        return selectStore(sm, edata).syncVersion(sm, edata);
-    }
-
-    @Override
-    protected RefCountConnection connectInternal() throws SQLException {
-        List<Connection> list = new ArrayList<Connection>();
-        for (SliceStoreManager slice : _slices)
-            list.add(slice.getConnection());
-        DistributedConnection con = new DistributedConnection(list);
-        return new RefCountConnection(con);
-    }
-    
-    /**
-     * Gets the list of slices mentioned as  
-     * {@link ProductDerivation#HINT_TARGET hint} of the given
-     * {@link FetchConfiguration#getHint(String) fetch configuration}. 
-     * 
-     * @return all active slices if a) the hint is not specified or b) a null 
-     * value or c) a non-String or d) matches no active slice.
-     */
-    List<SliceStoreManager> getTargets(FetchConfiguration fetch) {
-        if (fetch == null)
-            return _slices;
-        Object hint = fetch.getHint(ProductDerivation.HINT_TARGET);
-        if (hint == null || !(hint instanceof String)) 
-            return _slices;
-        List<String> targetNames = Arrays.asList(hint.toString().split("\\,"));
-        List<SliceStoreManager> targets = new ArrayList<SliceStoreManager>();
-        for (SliceStoreManager slice : _slices) {
-           if (targetNames.contains(slice.getName()))
-              targets.add(slice);
-           }
-          if (targets.isEmpty())
-            return _slices;
-        return targets;
-    }
-    
-    void log(String s) {
-        System.out.println("["+Thread.currentThread().getName()+"] " + this + s);
-    }
-
-    private static class Flusher implements Callable<Collection> {
-        final SliceStoreManager store;
-        final Collection toFlush;
-
-        Flusher(SliceStoreManager store, Collection toFlush) {
-            this.store = store;
-            this.toFlush = toFlush;
-        }
-
-        public Collection call() throws Exception {
-            return store.flush(toFlush);
-        }
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.kernel.ConnectionInfo;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.ResultSetResult;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.kernel.QueryLanguages;
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.ExpressionParser;
+import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.slice.DistributionPolicy;
+import org.apache.openjpa.slice.ProductDerivation;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.StoreException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * A Store manager for multiple physical databases referred as <em>slice</em>.
+ * This receiver behaves like a Transaction Manager as it implements two-phase
+ * commit protocol if all the component slices is XA-complaint. The actions are
+ * delegated to the underlying slices. The actions are executed in parallel
+ * threads whenever possible such as flushing or query. <br>
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+class DistributedStoreManager extends JDBCStoreManager {
+    private final List<SliceStoreManager> _slices;
+    private JDBCStoreManager _master;
+    private final DistributedJDBCConfiguration _conf;
+    private static final Localizer _loc =
+            Localizer.forPackage(DistributedStoreManager.class);
+    private static ExecutorService threadPool = Executors.newCachedThreadPool();
+
+    /**
+     * Constructs a set of child StoreManagers each connected to a physical
+     * DataSource.
+     * 
+     * The supplied configuration carries multiple URL for underlying physical
+     * slices. The first slice is referred as <em>master</em> and is used to
+     * get Sequence based entity identifiers.
+     */
+    public DistributedStoreManager(DistributedJDBCConfiguration conf) {
+        super();
+        _conf = conf;
+        _slices = new ArrayList<SliceStoreManager>();
+        List<String> sliceNames = conf.getActiveSliceNames();
+        for (String name : sliceNames) {
+            SliceStoreManager slice = new SliceStoreManager
+                (conf.getSlice(name));
+            _slices.add(slice);
+            if (name.equals(conf.getMaster().getName()))
+                _master = slice;
+        }
+    }
+
+    public DistributedJDBCConfiguration getConfiguration() {
+        return _conf;
+    }
+
+    /**
+     * Decides the index of the StoreManager by first looking at the
+     * implementation data. If not found then {@link DistributionPolicy
+     * DistributionPolicy} determines the target store for new instances and
+     * additional connection info is used to estimate for the existing
+     * instances.
+     */
+    protected String findSliceName(OpenJPAStateManager sm, Object info) {
+        boolean hasIndex = hasSlice(sm);
+        if (hasIndex)
+            return sm.getImplData().toString();
+        String slice = estimateSlice(sm, info);
+        if (slice == null)
+            return assignSlice(sm);
+        return slice;
+    }
+
+    private boolean hasSlice(OpenJPAStateManager sm) {
+        return sm.getImplData() != null;
+    }
+
+    private String assignSlice(OpenJPAStateManager sm) {
+        Object pc = sm.getPersistenceCapable();
+        DistributionPolicy policy = _conf.getDistributionPolicyInstance();
+        List<String> sliceNames = _conf.getActiveSliceNames();
+        String slice =policy.distribute(pc, sliceNames, getContext());
+        if (!sliceNames.contains(slice)) {
+            throw new UserException(_loc.get("bad-policy-slice", new Object[] {
+                    policy.getClass().getName(), slice, pc, sliceNames }));
+        }
+        sm.setImplData(slice, true);
+        return slice;
+    }
+
+    /**
+     * The additional edata is used, if possible, to find the StoreManager
+     * managing the given StateManager. If the additional data is unavailable
+     * then return null.
+     * 
+     */
+    private String estimateSlice(OpenJPAStateManager sm, Object edata) {
+        if (edata == null || !(edata instanceof ConnectionInfo))
+            return null;
+
+        Result result = ((ConnectionInfo) edata).result;
+        if (result instanceof ResultSetResult) {
+            JDBCStore store = ((ResultSetResult) result).getStore();
+            for (SliceStoreManager slice : _slices) {
+                if (slice == store) {
+                    String sliceId = slice.getName();
+                    sm.setImplData(sliceId, true);
+                    return sliceId;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Selects a child StoreManager where the given instance resides.
+     */
+    private StoreManager selectStore(OpenJPAStateManager sm, Object edata) {
+        String name = findSliceName(sm, edata);
+        SliceStoreManager slice = lookup(name);
+        if (slice == null)
+            throw new InternalException(_loc.get("wrong-slice", name, sm));
+        return slice;
+    }
+
+    public boolean assignField(OpenJPAStateManager sm, int field,
+            boolean preFlush) {
+        return selectStore(sm, null).assignField(sm, field, preFlush);
+    }
+
+    public boolean assignObjectId(OpenJPAStateManager sm, boolean preFlush) {
+        return _master.assignObjectId(sm, preFlush);
+    }
+
+    public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
+            PCState toState) {
+        _master.beforeStateChange(sm, fromState, toState);
+    }
+
+    public void beginOptimistic() {
+        for (SliceStoreManager slice : _slices)
+            slice.beginOptimistic();
+    }
+
+    public boolean cancelAll() {
+        boolean ret = true;
+        for (SliceStoreManager slice : _slices)
+            ret = slice.cancelAll() & ret;
+        return ret;
+    }
+
+    public int compareVersion(OpenJPAStateManager sm, Object v1, Object v2) {
+        return selectStore(sm, null).compareVersion(sm, v1, v2);
+    }
+
+    public Object copyDataStoreId(Object oid, ClassMetaData meta) {
+        return _master.copyDataStoreId(oid, meta);
+    }
+
+    public ResultObjectProvider executeExtent(ClassMetaData meta,
+            boolean subclasses, FetchConfiguration fetch) {
+        int i = 0;
+        List<SliceStoreManager> targets = getTargets(fetch);
+        ResultObjectProvider[] tmp = new ResultObjectProvider[targets.size()];
+        for (SliceStoreManager slice : targets) {
+            tmp[i++] = slice.executeExtent(meta, subclasses, fetch);
+        }
+        return new MergedResultObjectProvider(tmp);
+    }
+
+    public boolean exists(OpenJPAStateManager sm, Object edata) {
+        for (SliceStoreManager slice : _slices) {
+            if (slice.exists(sm, edata)) {
+                sm.setImplData(slice.getName(), true);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    
+    /**
+     * Flush the given StateManagers after binning them to respective physical
+     * slices.
+     */
+    public Collection flush(Collection sms) {
+        Collection exceptions = new ArrayList();
+        List<Future<Collection>> futures = new ArrayList<Future<Collection>>();
+        Map<String, List<OpenJPAStateManager>> subsets = bin(sms, null);
+        for (SliceStoreManager slice : _slices) {
+            List<OpenJPAStateManager> subset = subsets.get(slice.getName());
+            if (subset.isEmpty())
+                continue;
+            futures.add(threadPool.submit(new Flusher(slice, subset)));
+        }
+        for (Future<Collection> future : futures) {
+            Collection error;
+            try {
+                error = future.get();
+                if (!(error == null || error.isEmpty())) {
+                    exceptions.addAll(error);
+                }
+            } catch (InterruptedException e) {
+                throw new StoreException(e);
+            } catch (ExecutionException e) {
+                throw new StoreException(e.getCause());
+            }
+        }
+        return exceptions;
+    }
+    
+    /**
+     * Separate the given list of StateManagers in separate lists for each slice 
+     * by the associated slice identifier of each StateManager.
+     * @param sms
+     * @param edata
+     * @return
+     */
+    private Map<String, List<OpenJPAStateManager>> bin(
+            Collection/*<StateManage>*/ sms, Object edata) {
+        Map<String, List<OpenJPAStateManager>> subsets =
+                new HashMap<String, List<OpenJPAStateManager>>();
+        for (SliceStoreManager slice : _slices)
+            subsets.put(slice.getName(), new ArrayList<OpenJPAStateManager>());
+        for (Object x : sms) {
+            OpenJPAStateManager sm = (OpenJPAStateManager) x;
+            String slice = findSliceName(sm, edata);
+            subsets.get(slice).add(sm);
+        }
+        return subsets;
+    }
+
+    public Object getClientConnection() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Seq getDataStoreIdSequence(ClassMetaData forClass) {
+        return _master.getDataStoreIdSequence(forClass);
+    }
+
+    public Class getDataStoreIdType(ClassMetaData meta) {
+        return _master.getDataStoreIdType(meta);
+    }
+
+    public Class getManagedType(Object oid) {
+        return _master.getManagedType(oid);
+    }
+
+    public Seq getValueSequence(FieldMetaData forField) {
+        return _master.getValueSequence(forField);
+    }
+
+    public boolean initialize(OpenJPAStateManager sm, PCState state,
+            FetchConfiguration fetch, Object edata) {
+        if (edata instanceof ConnectionInfo) {
+            String slice = findSliceName(sm, (ConnectionInfo) edata);
+            if (slice != null)
+                return lookup(slice).initialize(sm, state, fetch, edata);
+        }
+        // not a part of Query result load. Look into the slices till found
+        List<SliceStoreManager> targets = getTargets(fetch);
+        for (SliceStoreManager slice : targets) {
+            if (slice.initialize(sm, state, fetch, edata)) {
+                sm.setImplData(slice.getName(), true);
+                return true;
+            }
+        }
+        return false;
+
+    }
+
+    public boolean load(OpenJPAStateManager sm, BitSet fields,
+            FetchConfiguration fetch, int lockLevel, Object edata) {
+        return selectStore(sm, edata).load(sm, fields, fetch, lockLevel, edata);
+    }
+
+    public Collection loadAll(Collection sms, PCState state, int load,
+            FetchConfiguration fetch, Object edata) {
+        Map<String, List<OpenJPAStateManager>> subsets = bin(sms, edata);
+        Collection result = new ArrayList();
+        for (SliceStoreManager slice : _slices) {
+            List<OpenJPAStateManager> subset = subsets.get(slice.getName());
+            if (subset.isEmpty())
+                continue;
+            Collection tmp = slice.loadAll(subset, state, load, fetch, edata);
+            if (tmp != null && !tmp.isEmpty())
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    public Object newDataStoreId(Object oidVal, ClassMetaData meta) {
+        return _master.newDataStoreId(oidVal, meta);
+    }
+
+    public FetchConfiguration newFetchConfiguration() {
+        return _master.newFetchConfiguration();
+    }
+
+    /**
+     * Construct a distributed query to be executed against all the slices.
+     */
+    public StoreQuery newQuery(String language) {
+        ExpressionParser parser = QueryLanguages.parserForLanguage(language);
+        DistributedStoreQuery ret = new DistributedStoreQuery(this, parser);
+        for (SliceStoreManager slice : _slices) {
+            ret.add(slice.newQuery(language));
+        }
+        return ret;
+    }
+
+    /**
+     * Sets the context for this receiver and all its underlying slices.
+     */
+    public void setContext(StoreContext ctx) {
+        super.setContext(ctx);
+        for (SliceStoreManager store : _slices) {
+            store.setContext(ctx, 
+                    (JDBCConfiguration)store.getSlice().getConfiguration());
+        }
+    }
+
+    private SliceStoreManager lookup(String name) {
+        for (SliceStoreManager slice : _slices)
+            if (slice.getName().equals(name))
+                return slice;
+        return null;
+    }
+
+    public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
+        return selectStore(sm, edata).syncVersion(sm, edata);
+    }
+
+    @Override
+    protected RefCountConnection connectInternal() throws SQLException {
+        List<Connection> list = new ArrayList<Connection>();
+        for (SliceStoreManager slice : _slices)
+            list.add(slice.getConnection());
+        DistributedConnection con = new DistributedConnection(list);
+        return new RefCountConnection(con);
+    }
+    
+    /**
+     * Gets the list of slices mentioned as  
+     * {@link ProductDerivation#HINT_TARGET hint} of the given
+     * {@link FetchConfiguration#getHint(String) fetch configuration}. 
+     * 
+     * @return all active slices if a) the hint is not specified or b) a null 
+     * value or c) a non-String or d) matches no active slice.
+     */
+    List<SliceStoreManager> getTargets(FetchConfiguration fetch) {
+        if (fetch == null)
+            return _slices;
+        Object hint = fetch.getHint(ProductDerivation.HINT_TARGET);
+        if (hint == null || !(hint instanceof String)) 
+            return _slices;
+        List<String> targetNames = Arrays.asList(hint.toString().split("\\,"));
+        List<SliceStoreManager> targets = new ArrayList<SliceStoreManager>();
+        for (SliceStoreManager slice : _slices) {
+           if (targetNames.contains(slice.getName()))
+              targets.add(slice);
+           }
+          if (targets.isEmpty())
+            return _slices;
+        return targets;
+    }
+    
+    void log(String s) {
+        System.out.println("["+Thread.currentThread().getName()+"] " + this + s);
+    }
+
+    private static class Flusher implements Callable<Collection> {
+        final SliceStoreManager store;
+        final Collection toFlush;
+
+        Flusher(SliceStoreManager store, Collection toFlush) {
+            this.store = store;
+            this.toFlush = toFlush;
+        }
+
+        public Collection call() throws Exception {
+            return store.flush(toFlush);
+        }
+    }
+
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
index b245065..f8f70ff 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
@@ -1,244 +1,244 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.kernel.JDBCStoreQuery;
-import org.apache.openjpa.kernel.ExpressionStoreQuery;
-import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.OrderingMergedResultObjectProvider;
-import org.apache.openjpa.kernel.QueryContext;
-import org.apache.openjpa.kernel.StoreQuery;
-import org.apache.openjpa.kernel.exps.ExpressionParser;
-import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
-import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.util.StoreException;
-
-/**
- * A query for distributed databases.
- * 
- * @author Pinaki Poddar 
- *
- */
-@SuppressWarnings("serial")
-class DistributedStoreQuery extends JDBCStoreQuery {
-	private List<StoreQuery> _queries = new ArrayList<StoreQuery>();
-	private ExpressionParser _parser;
-	
-	public DistributedStoreQuery(JDBCStore store, ExpressionParser parser) {
-		super(store, parser);
-		_parser = parser;
-		
-	}
-	
-	void add(StoreQuery q) {
-		_queries.add(q);
-	}
-	
-    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
-    	ParallelExecutor ex = new ParallelExecutor(this, meta, subs, _parser, 
-    			ctx.getCompilation());
-    	
-    	FetchConfiguration fetch = getContext().getFetchConfiguration();
-    	DistributedStoreManager store = (DistributedStoreManager)getContext()
-    	    .getStoreContext().getStoreManager().getInnermostDelegate();
-        List<SliceStoreManager> targets = store.getTargets(fetch);
-        for (StoreQuery q:_queries) {
-            if (targets.contains(((JDBCStoreQuery)q).getStore()))
-                ex.addExecutor(q.newDataStoreExecutor(meta, subs));
-        }
-        return ex;
-    }
-    
-    public void setContext(QueryContext ctx) {
-    	super.setContext(ctx);
-    	for (StoreQuery q:_queries) 
-    		q.setContext(ctx); 
-    }
-    
-    public ExecutorService getExecutorServiceInstance() {
-        DistributedJDBCConfiguration conf = 
-            ((DistributedJDBCConfiguration)getStore().getConfiguration());
-        return conf.getExecutorServiceInstance();
-    }
-    
-	/**
-	 * Executes queries on multiple databases.
-	 * 
-	 * @author Pinaki Poddar 
-	 *
-	 */
-	public static class ParallelExecutor extends 
-		ExpressionStoreQuery.DataStoreExecutor {
-		private List<Executor> executors = new ArrayList<Executor>();
-		private DistributedStoreQuery owner = null;
-		private ExecutorService threadPool = null;
-		
-		public void addExecutor(Executor ex) {
-			executors.add(ex);
-		}
-		
-        public ParallelExecutor(DistributedStoreQuery dsq, ClassMetaData meta, 
-        		boolean subclasses, ExpressionParser parser, Object parsed) {
-        	super(dsq, meta, subclasses, parser, parsed);
-        	owner = dsq;
-        	threadPool = dsq.getExecutorServiceInstance();
-        }
-        
-        /**
-         * Each child query must be executed with slice context and not the 
-         * given query context.
-         */
-        public ResultObjectProvider executeQuery(StoreQuery q,
-                final Object[] params, final Range range) {
-        	ResultObjectProvider[] tmp = new ResultObjectProvider[executors.size()];
-        	final Iterator<StoreQuery> qs = owner._queries.iterator();
-        	final List<Future<ResultObjectProvider>> futures = 
-        		new ArrayList<Future<ResultObjectProvider>>();
-        	int i = 0;
-        	for (Executor ex:executors)  {
-        		QueryExecutor call = new QueryExecutor();
-        		call.executor = ex;
-        		call.query    = qs.next();
-        		call.params   = params;
-        		call.range    = range;
-        		futures.add(threadPool.submit(call)); 
-        	}
-        	for (Future<ResultObjectProvider> future:futures) {
-        		try {
-					tmp[i++] = future.get();
-				} catch (InterruptedException e) {
-					throw new RuntimeException(e);
-				} catch (ExecutionException e) {
-					throw new StoreException(e.getCause());
-				}
-        	}
-        	boolean[] ascending = getAscending(q);
-        	boolean isAscending = ascending.length > 0;
-        	boolean isUnique    = q.getContext().isUnique();
-        	boolean hasRange    = q.getContext().getEndRange() != Long.MAX_VALUE;
-        	ResultObjectProvider result = null;
-        	if (isUnique) {
-        	    result = new UniqueResultObjectProvider(tmp, q, 
-        	            getQueryExpressions());
-        	} else if (isAscending) {
-        	    result = new OrderingMergedResultObjectProvider(tmp, ascending, 
-                  (Executor[])executors.toArray(new Executor[executors.size()]),
-                  q, params);
-        	} else {
-        	    result = new MergedResultObjectProvider(tmp);
-        	}
-        	if (hasRange)
-        	    result = new RangeResultObjectProvider(result, 
-        	            q.getContext().getStartRange(), 
-        	            q.getContext().getEndRange());
-        	return result;
-        }
-        
-        public Number executeDelete(StoreQuery q, Object[] params) {
-        	Iterator<StoreQuery> qs = owner._queries.iterator();
-        	final List<Future<Number>> futures = new ArrayList<Future<Number>>();
-        	for (Executor ex:executors) {
-        		DeleteExecutor call = new DeleteExecutor();
-        		call.executor = ex;
-        		call.query    = qs.next();
-        		call.params   = params;
-        		futures.add(threadPool.submit(call)); 
-        	}
-        	int N = 0;
-        	for (Future<Number> future:futures) {
-        		try {
-            		Number n = future.get();
-            		if (n != null) 
-            			N += n.intValue();
-				} catch (InterruptedException e) {
-					throw new RuntimeException(e);
-				} catch (ExecutionException e) {
-					throw new StoreException(e.getCause());
-				}
-        	}
-        	return new Integer(N);
-        }
-        
-        public Number executeUpdate(StoreQuery q, Object[] params) {
-        	Iterator<StoreQuery> qs = owner._queries.iterator();
-        	final List<Future<Number>> futures = new ArrayList<Future<Number>>();
-        	for (Executor ex:executors) {
-        		UpdateExecutor call = new UpdateExecutor();
-        		call.executor = ex;
-        		call.query    = qs.next();
-        		call.params   = params;
-        		futures.add(threadPool.submit(call)); 
-        	}
-        	int N = 0;
-        	for (Future<Number> future:futures) {
-        		try {
-            		Number n = future.get();
-            		if (n != null) 
-            			N += n.intValue();
-				} catch (InterruptedException e) {
-					throw new RuntimeException(e);
-				} catch (ExecutionException e) {
-					throw new StoreException(e.getCause());
-				}
-        	}
-        	return new Integer(N);
-        }
-
-	}
-	
-	static  class QueryExecutor implements Callable<ResultObjectProvider> {
-		StoreQuery query;
-		Executor executor;
-		Object[] params;
-		Range range;
-		public ResultObjectProvider call() throws Exception {
-			return executor.executeQuery(query, params, range);
-		}
-	}
-	
-	static  class DeleteExecutor implements Callable<Number> {
-		StoreQuery query;
-		Executor executor;
-		Object[] params;
-		public Number call() throws Exception {
-			return executor.executeDelete(query, params);
-		}
-	}
-	
-	static  class UpdateExecutor implements Callable<Number> {
-		StoreQuery query;
-		Executor executor;
-		Object[] params;
-		public Number call() throws Exception {
-			return executor.executeDelete(query, params);
-		}
-	}
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.kernel.JDBCStoreQuery;
+import org.apache.openjpa.kernel.ExpressionStoreQuery;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OrderingMergedResultObjectProvider;
+import org.apache.openjpa.kernel.QueryContext;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.ExpressionParser;
+import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
+import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.StoreException;
+
+/**
+ * A query for distributed databases.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+@SuppressWarnings("serial")
+class DistributedStoreQuery extends JDBCStoreQuery {
+	private List<StoreQuery> _queries = new ArrayList<StoreQuery>();
+	private ExpressionParser _parser;
+	
+	public DistributedStoreQuery(JDBCStore store, ExpressionParser parser) {
+		super(store, parser);
+		_parser = parser;
+		
+	}
+	
+	void add(StoreQuery q) {
+		_queries.add(q);
+	}
+	
+    public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
+    	ParallelExecutor ex = new ParallelExecutor(this, meta, subs, _parser, 
+    			ctx.getCompilation());
+    	
+    	FetchConfiguration fetch = getContext().getFetchConfiguration();
+    	DistributedStoreManager store = (DistributedStoreManager)getContext()
+    	    .getStoreContext().getStoreManager().getInnermostDelegate();
+        List<SliceStoreManager> targets = store.getTargets(fetch);
+        for (StoreQuery q:_queries) {
+            if (targets.contains(((JDBCStoreQuery)q).getStore()))
+                ex.addExecutor(q.newDataStoreExecutor(meta, subs));
+        }
+        return ex;
+    }
+    
+    public void setContext(QueryContext ctx) {
+    	super.setContext(ctx);
+    	for (StoreQuery q:_queries) 
+    		q.setContext(ctx); 
+    }
+    
+    public ExecutorService getExecutorServiceInstance() {
+        DistributedJDBCConfiguration conf = 
+            ((DistributedJDBCConfiguration)getStore().getConfiguration());
+        return conf.getExecutorServiceInstance();
+    }
+    
+	/**
+	 * Executes queries on multiple databases.
+	 * 
+	 * @author Pinaki Poddar 
+	 *
+	 */
+	public static class ParallelExecutor extends 
+		ExpressionStoreQuery.DataStoreExecutor {
+		private List<Executor> executors = new ArrayList<Executor>();
+		private DistributedStoreQuery owner = null;
+		private ExecutorService threadPool = null;
+		
+		public void addExecutor(Executor ex) {
+			executors.add(ex);
+		}
+		
+        public ParallelExecutor(DistributedStoreQuery dsq, ClassMetaData meta, 
+        		boolean subclasses, ExpressionParser parser, Object parsed) {
+        	super(dsq, meta, subclasses, parser, parsed);
+        	owner = dsq;
+        	threadPool = dsq.getExecutorServiceInstance();
+        }
+        
+        /**
+         * Each child query must be executed with slice context and not the 
+         * given query context.
+         */
+        public ResultObjectProvider executeQuery(StoreQuery q,
+                final Object[] params, final Range range) {
+        	ResultObjectProvider[] tmp = new ResultObjectProvider[executors.size()];
+        	final Iterator<StoreQuery> qs = owner._queries.iterator();
+        	final List<Future<ResultObjectProvider>> futures = 
+        		new ArrayList<Future<ResultObjectProvider>>();
+        	int i = 0;
+        	for (Executor ex:executors)  {
+        		QueryExecutor call = new QueryExecutor();
+        		call.executor = ex;
+        		call.query    = qs.next();
+        		call.params   = params;
+        		call.range    = range;
+        		futures.add(threadPool.submit(call)); 
+        	}
+        	for (Future<ResultObjectProvider> future:futures) {
+        		try {
+					tmp[i++] = future.get();
+				} catch (InterruptedException e) {
+					throw new RuntimeException(e);
+				} catch (ExecutionException e) {
+					throw new StoreException(e.getCause());
+				}
+        	}
+        	boolean[] ascending = getAscending(q);
+        	boolean isAscending = ascending.length > 0;
+        	boolean isUnique    = q.getContext().isUnique();
+        	boolean hasRange    = q.getContext().getEndRange() != Long.MAX_VALUE;
+        	ResultObjectProvider result = null;
+        	if (isUnique) {
+        	    result = new UniqueResultObjectProvider(tmp, q, 
+        	            getQueryExpressions());
+        	} else if (isAscending) {
+        	    result = new OrderingMergedResultObjectProvider(tmp, ascending, 
+                  (Executor[])executors.toArray(new Executor[executors.size()]),
+                  q, params);
+        	} else {
+        	    result = new MergedResultObjectProvider(tmp);
+        	}
+        	if (hasRange)
+        	    result = new RangeResultObjectProvider(result, 
+        	            q.getContext().getStartRange(), 
+        	            q.getContext().getEndRange());
+        	return result;
+        }
+        
+        public Number executeDelete(StoreQuery q, Object[] params) {
+        	Iterator<StoreQuery> qs = owner._queries.iterator();
+        	final List<Future<Number>> futures = new ArrayList<Future<Number>>();
+        	for (Executor ex:executors) {
+        		DeleteExecutor call = new DeleteExecutor();
+        		call.executor = ex;
+        		call.query    = qs.next();
+        		call.params   = params;
+        		futures.add(threadPool.submit(call)); 
+        	}
+        	int N = 0;
+        	for (Future<Number> future:futures) {
+        		try {
+            		Number n = future.get();
+            		if (n != null) 
+            			N += n.intValue();
+				} catch (InterruptedException e) {
+					throw new RuntimeException(e);
+				} catch (ExecutionException e) {
+					throw new StoreException(e.getCause());
+				}
+        	}
+        	return new Integer(N);
+        }
+        
+        public Number executeUpdate(StoreQuery q, Object[] params) {
+        	Iterator<StoreQuery> qs = owner._queries.iterator();
+        	final List<Future<Number>> futures = new ArrayList<Future<Number>>();
+        	for (Executor ex:executors) {
+        		UpdateExecutor call = new UpdateExecutor();
+        		call.executor = ex;
+        		call.query    = qs.next();
+        		call.params   = params;
+        		futures.add(threadPool.submit(call)); 
+        	}
+        	int N = 0;
+        	for (Future<Number> future:futures) {
+        		try {
+            		Number n = future.get();
+            		if (n != null) 
+            			N += n.intValue();
+				} catch (InterruptedException e) {
+					throw new RuntimeException(e);
+				} catch (ExecutionException e) {
+					throw new StoreException(e.getCause());
+				}
+        	}
+        	return new Integer(N);
+        }
+
+	}
+	
+	static  class QueryExecutor implements Callable<ResultObjectProvider> {
+		StoreQuery query;
+		Executor executor;
+		Object[] params;
+		Range range;
+		public ResultObjectProvider call() throws Exception {
+			return executor.executeQuery(query, params, range);
+		}
+	}
+	
+	static  class DeleteExecutor implements Callable<Number> {
+		StoreQuery query;
+		Executor executor;
+		Object[] params;
+		public Number call() throws Exception {
+			return executor.executeDelete(query, params);
+		}
+	}
+	
+	static  class UpdateExecutor implements Callable<Number> {
+		StoreQuery query;
+		Executor executor;
+		Object[] params;
+		public Number call() throws Exception {
+			return executor.executeDelete(query, params);
+		}
+	}
+}
+
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedTemplate.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedTemplate.java
index b44aa55..33836ed 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedTemplate.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedTemplate.java
@@ -1,273 +1,273 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A template for multiple Statements being executed by multiple connections.
- * 
- * @author Pinaki Poddar 
- *
- */
-class DistributedTemplate<T extends Statement> 
-	implements Statement, Iterable<T> {
-	protected List<T> stmts = new ArrayList<T>();
-	protected final DistributedConnection con;
-	protected T master;
-	
-	public DistributedTemplate(DistributedConnection c) {
-		con = c;
-	}
-	
-	public Iterator<T> iterator() {
-		return stmts.iterator();
-	}
-	
-	public void add(T s) {
-		if (stmts.isEmpty())
-			master = s;
-		try {
-			if (!con.contains(s.getConnection()))
-				throw new IllegalArgumentException(s + " has different connection");
-			stmts.add(s);
-		} catch (SQLException e) {
-			e.printStackTrace();
-		}
-	}
-	
-	public void addBatch(String sql) throws SQLException {
-		for (T s:this)
-			s.addBatch(sql);
-	}
-
-	public void cancel() throws SQLException {
-		for (T s:this)
-			s.cancel();
-	}
-
-	public void clearBatch() throws SQLException {
-		for (T s:this)
-			s.clearBatch();
-	}
-
-	public void clearWarnings() throws SQLException {
-		for (T s:this)
-			s.clearWarnings();
-	}
-
-	public void close() throws SQLException {
-		for (T s:this)
-			s.close();
-	}
-
-	public boolean execute(String arg0) throws SQLException {
-		boolean ret = true;
-		for (T s:this)
-			ret = s.execute(arg0) & ret;
-		return ret;
-	}
-
-	public boolean execute(String arg0, int arg1) throws SQLException {
-		boolean ret = true;
-		for (T s:this)
-			ret = s.execute(arg0, arg1) & ret;
-		return ret;
-	}
-
-	public boolean execute(String arg0, int[] arg1) throws SQLException {
-		boolean ret = true;
-		for (T s:this)
-			ret = s.execute(arg0, arg1) & ret;
-		return ret;
-	}
-
-	public boolean execute(String arg0, String[] arg1) throws SQLException {
-		boolean ret = true;
-		for (T s:this)
-			ret = s.execute(arg0, arg1) & ret;
-		return ret;
-	}
-
-	public int[] executeBatch() throws SQLException {
-		int[] ret = new int[0];
-		for (Statement s:this) {
-			int[] tmp = s.executeBatch();
-			ret = new int[ret.length + tmp.length];
-			System.arraycopy(tmp, 0, ret, ret.length-tmp.length, tmp.length);
-		}
-		return ret;
-	}
-
-	public ResultSet executeQuery() throws SQLException {
-		DistributedResultSet rs = new DistributedResultSet();
-		for (T s:this)
-			rs.add(s.executeQuery(null));
-		return rs;
-	}
-
-	public ResultSet executeQuery(String arg0) throws SQLException {
-		DistributedResultSet rs = new DistributedResultSet();
-		for (T s:this)
-			rs.add(s.executeQuery(arg0));
-		return rs;
-	}
-
-	public int executeUpdate(String arg0) throws SQLException {
-		int ret = 0;
-		for (T s:this)
-			ret += s.executeUpdate(arg0);
-		return ret;
-	}
-
-	public int executeUpdate(String arg0, int arg1) throws SQLException {
-		int ret = 0;
-		for (T s:this)
-			ret += s.executeUpdate(arg0, arg1);
-		return ret;
-	}
-
-	public int executeUpdate(String arg0, int[] arg1) throws SQLException {
-		int ret = 0;
-		for (T s:this)
-			ret += s.executeUpdate(arg0, arg1);
-		return ret;
-	}
-
-	public int executeUpdate(String arg0, String[] arg1) throws SQLException {
-		int ret = 0;
-		for (T s:this)
-			ret += s.executeUpdate(arg0, arg1);
-		return ret;
-	}
-
-	public Connection getConnection() throws SQLException {
-		return con;
-	}
-
-	public int getFetchDirection() throws SQLException {
-		return master.getFetchDirection();
-	}
-
-	public int getFetchSize() throws SQLException {
-		return master.getFetchSize();
-	}
-
-	public ResultSet getGeneratedKeys() throws SQLException {
-		DistributedResultSet mrs = new DistributedResultSet();
-		for (T s:this)
-			mrs.add(s.getGeneratedKeys());
-		return mrs;
-	}
-
-	public int getMaxFieldSize() throws SQLException {
-		return master.getMaxFieldSize();
-	}
-
-	public int getMaxRows() throws SQLException {
-		return master.getMaxRows();
-	}
-
-	public boolean getMoreResults() throws SQLException {
-		for (T s:this)
-			if (s.getMoreResults())
-				return true;
-		return false;
-	}
-
-	public boolean getMoreResults(int arg0) throws SQLException {
-		for (T s:this)
-			if (s.getMoreResults(arg0))
-				return true;
-		return false;
-	}
-
-	public int getQueryTimeout() throws SQLException {
-		return master.getQueryTimeout();
-	}
-
-	public ResultSet getResultSet() throws SQLException {
-		DistributedResultSet rs = new DistributedResultSet();
-		for (T s:this)
-			rs.add(s.getResultSet());
-		return rs;
-	}
-
-	public int getResultSetConcurrency() throws SQLException {
-		return master.getResultSetConcurrency();
-	}
-
-	public int getResultSetHoldability() throws SQLException {
-		return master.getResultSetHoldability();
-	}
-
-	public int getResultSetType() throws SQLException {
-		return master.getResultSetType();
-	}
-
-	public int getUpdateCount() throws SQLException {
-		return master.getUpdateCount();
-	}
-
-	public SQLWarning getWarnings() throws SQLException {
-		return master.getWarnings();
-	}
-
-	public void setCursorName(String name) throws SQLException {
-		for (T s:this)
-			s.setCursorName(name);
-	}
-
-	public void setEscapeProcessing(boolean flag) throws SQLException {
-		for (T s:this)
-			s.setEscapeProcessing(flag);
-	}
-
-	public void setFetchDirection(int dir) throws SQLException {
-		for (T s:this)
-			s.setFetchDirection(dir);
-	}
-
-	public void setFetchSize(int size) throws SQLException {
-		for (T s:this)
-			s.setFetchSize(size);
-	}
-
-	public void setMaxFieldSize(int size) throws SQLException {
-		for (T s:this)
-			s.setMaxFieldSize(size);
-	}
-
-	public void setMaxRows(int n) throws SQLException {
-		for (T s:this)
-			s.setMaxFieldSize(n);
-	}
-	
-	public void setQueryTimeout(int n) throws SQLException {
-		for (T s:this)
-			s.setMaxFieldSize(n);
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A template for multiple Statements being executed by multiple connections.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+class DistributedTemplate<T extends Statement> 
+	implements Statement, Iterable<T> {
+	protected List<T> stmts = new ArrayList<T>();
+	protected final DistributedConnection con;
+	protected T master;
+	
+	public DistributedTemplate(DistributedConnection c) {
+		con = c;
+	}
+	
+	public Iterator<T> iterator() {
+		return stmts.iterator();
+	}
+	
+	public void add(T s) {
+		if (stmts.isEmpty())
+			master = s;
+		try {
+			if (!con.contains(s.getConnection()))
+				throw new IllegalArgumentException(s + " has different connection");
+			stmts.add(s);
+		} catch (SQLException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void addBatch(String sql) throws SQLException {
+		for (T s:this)
+			s.addBatch(sql);
+	}
+
+	public void cancel() throws SQLException {
+		for (T s:this)
+			s.cancel();
+	}
+
+	public void clearBatch() throws SQLException {
+		for (T s:this)
+			s.clearBatch();
+	}
+
+	public void clearWarnings() throws SQLException {
+		for (T s:this)
+			s.clearWarnings();
+	}
+
+	public void close() throws SQLException {
+		for (T s:this)
+			s.close();
+	}
+
+	public boolean execute(String arg0) throws SQLException {
+		boolean ret = true;
+		for (T s:this)
+			ret = s.execute(arg0) & ret;
+		return ret;
+	}
+
+	public boolean execute(String arg0, int arg1) throws SQLException {
+		boolean ret = true;
+		for (T s:this)
+			ret = s.execute(arg0, arg1) & ret;
+		return ret;
+	}
+
+	public boolean execute(String arg0, int[] arg1) throws SQLException {
+		boolean ret = true;
+		for (T s:this)
+			ret = s.execute(arg0, arg1) & ret;
+		return ret;
+	}
+
+	public boolean execute(String arg0, String[] arg1) throws SQLException {
+		boolean ret = true;
+		for (T s:this)
+			ret = s.execute(arg0, arg1) & ret;
+		return ret;
+	}
+
+	public int[] executeBatch() throws SQLException {
+		int[] ret = new int[0];
+		for (Statement s:this) {
+			int[] tmp = s.executeBatch();
+			ret = new int[ret.length + tmp.length];
+			System.arraycopy(tmp, 0, ret, ret.length-tmp.length, tmp.length);
+		}
+		return ret;
+	}
+
+	public ResultSet executeQuery() throws SQLException {
+		DistributedResultSet rs = new DistributedResultSet();
+		for (T s:this)
+			rs.add(s.executeQuery(null));
+		return rs;
+	}
+
+	public ResultSet executeQuery(String arg0) throws SQLException {
+		DistributedResultSet rs = new DistributedResultSet();
+		for (T s:this)
+			rs.add(s.executeQuery(arg0));
+		return rs;
+	}
+
+	public int executeUpdate(String arg0) throws SQLException {
+		int ret = 0;
+		for (T s:this)
+			ret += s.executeUpdate(arg0);
+		return ret;
+	}
+
+	public int executeUpdate(String arg0, int arg1) throws SQLException {
+		int ret = 0;
+		for (T s:this)
+			ret += s.executeUpdate(arg0, arg1);
+		return ret;
+	}
+
+	public int executeUpdate(String arg0, int[] arg1) throws SQLException {
+		int ret = 0;
+		for (T s:this)
+			ret += s.executeUpdate(arg0, arg1);
+		return ret;
+	}
+
+	public int executeUpdate(String arg0, String[] arg1) throws SQLException {
+		int ret = 0;
+		for (T s:this)
+			ret += s.executeUpdate(arg0, arg1);
+		return ret;
+	}
+
+	public Connection getConnection() throws SQLException {
+		return con;
+	}
+
+	public int getFetchDirection() throws SQLException {
+		return master.getFetchDirection();
+	}
+
+	public int getFetchSize() throws SQLException {
+		return master.getFetchSize();
+	}
+
+	public ResultSet getGeneratedKeys() throws SQLException {
+		DistributedResultSet mrs = new DistributedResultSet();
+		for (T s:this)
+			mrs.add(s.getGeneratedKeys());
+		return mrs;
+	}
+
+	public int getMaxFieldSize() throws SQLException {
+		return master.getMaxFieldSize();
+	}
+
+	public int getMaxRows() throws SQLException {
+		return master.getMaxRows();
+	}
+
+	public boolean getMoreResults() throws SQLException {
+		for (T s:this)
+			if (s.getMoreResults())
+				return true;
+		return false;
+	}
+
+	public boolean getMoreResults(int arg0) throws SQLException {
+		for (T s:this)
+			if (s.getMoreResults(arg0))
+				return true;
+		return false;
+	}
+
+	public int getQueryTimeout() throws SQLException {
+		return master.getQueryTimeout();
+	}
+
+	public ResultSet getResultSet() throws SQLException {
+		DistributedResultSet rs = new DistributedResultSet();
+		for (T s:this)
+			rs.add(s.getResultSet());
+		return rs;
+	}
+
+	public int getResultSetConcurrency() throws SQLException {
+		return master.getResultSetConcurrency();
+	}
+
+	public int getResultSetHoldability() throws SQLException {
+		return master.getResultSetHoldability();
+	}
+
+	public int getResultSetType() throws SQLException {
+		return master.getResultSetType();
+	}
+
+	public int getUpdateCount() throws SQLException {
+		return master.getUpdateCount();
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		return master.getWarnings();
+	}
+
+	public void setCursorName(String name) throws SQLException {
+		for (T s:this)
+			s.setCursorName(name);
+	}
+
+	public void setEscapeProcessing(boolean flag) throws SQLException {
+		for (T s:this)
+			s.setEscapeProcessing(flag);
+	}
+
+	public void setFetchDirection(int dir) throws SQLException {
+		for (T s:this)
+			s.setFetchDirection(dir);
+	}
+
+	public void setFetchSize(int size) throws SQLException {
+		for (T s:this)
+			s.setFetchSize(size);
+	}
+
+	public void setMaxFieldSize(int size) throws SQLException {
+		for (T s:this)
+			s.setMaxFieldSize(size);
+	}
+
+	public void setMaxRows(int n) throws SQLException {
+		for (T s:this)
+			s.setMaxFieldSize(n);
+	}
+	
+	public void setQueryTimeout(int n) throws SQLException {
+		for (T s:this)
+			s.setMaxFieldSize(n);
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
index fb36b50..c62aed5 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
-import org.apache.openjpa.slice.Slice;
-
-/**
- * A specialized JDBCStoreManager for a slice.
- * 
- * @author Pinaki Poddar 
- *
- */
-public class SliceStoreManager extends JDBCStoreManager {
-	private final Slice _slice;
-	
-	/**
-	 * Construct with immutable logical name of the slice. 
-	 */
-	public SliceStoreManager(Slice slice) {
-		_slice = slice;
-	}
-	
-	/**
-	 * Gets the slice for which this receiver is working.
-	 */
-	public Slice getSlice() {
-	    return _slice;
-	}
-	
-	public String getName() {
-	    return _slice.getName();
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
+import org.apache.openjpa.slice.Slice;
+
+/**
+ * A specialized JDBCStoreManager for a slice.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class SliceStoreManager extends JDBCStoreManager {
+	private final Slice _slice;
+	
+	/**
+	 * Construct with immutable logical name of the slice. 
+	 */
+	public SliceStoreManager(Slice slice) {
+		_slice = slice;
+	}
+	
+	/**
+	 * Gets the slice for which this receiver is working.
+	 */
+	public Slice getSlice() {
+	    return _slice;
+	}
+	
+	public String getName() {
+	    return _slice.getName();
+	}
+}
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
index 932dcf8..6814709 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
@@ -1,165 +1,165 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.jdbc;
-
-import org.apache.openjpa.kernel.StoreQuery;
-import org.apache.openjpa.kernel.exps.QueryExpressions;
-import org.apache.openjpa.kernel.exps.Value;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.InternalException;
-
-/**
- * Aggregates individual single query results from different databases.
- * 
- * @author Pinaki Poddar 
- *
- */
-public class UniqueResultObjectProvider implements ResultObjectProvider {
-    private final ResultObjectProvider[] _rops;
-    private final StoreQuery _query;
-    private final QueryExpressions[] _exps;
-    private Object _single;
-    private boolean _opened;
-    
-    private static final String COUNT = "Count";
-    private static final String MAX   = "Max";
-    private static final String MIN   = "Min";
-    private static final String SUM   = "Sum";
-    
-    private static final Localizer _loc =
-        Localizer.forPackage(UniqueResultObjectProvider.class);
-    
-    public UniqueResultObjectProvider(ResultObjectProvider[] rops, 
-            StoreQuery q, QueryExpressions[] exps) {
-        _rops = rops;
-        _query = q;
-        _exps = exps;
-    }
-    
-    public boolean absolute(int pos) throws Exception {
-        return false;
-    }
-
-    public void close() throws Exception {
-        _opened = false;
-        for (ResultObjectProvider rop:_rops)
-            rop.close();
-    }
-
-    public Object getResultObject() throws Exception {
-        if (!_opened)
-            throw new InternalException(_loc.get("not-open"));
-        return _single;
-    }
-
-    public void handleCheckedException(Exception e) {
-        _rops[0].handleCheckedException(e);
-    }
-
-    public boolean next() throws Exception {
-        if (!_opened) {
-            open();
-        }
-            
-        if (_single != null)
-            return false;
-        
-        Value[] values = _exps[0].projections;
-        Object[] single = new Object[values.length]; 
-        for (int i=0; i<values.length; i++) {
-            Value v = values[i];
-            boolean isAggregate = v.isAggregate();
-            String op = v.getClass().getSimpleName();
-            for (ResultObjectProvider rop:_rops) {
-                rop.next();
-                Object[] row = (Object[]) rop.getResultObject();
-                if (isAggregate) {
-                    if (COUNT.equals(op)) {
-                        single[i] = count(single[i], row[i]);
-                    } else if (MAX.equals(op)) {
-                        single[i] = max(single[i], row[i]);
-                    } else if (MIN.equals(op)) {
-                        single[i] = min(single[i], row[i]);
-                    } else if (SUM.equals(op)) {
-                        single[i] = sum(single[i], row[i]);
-                    } else {
-                        throw new UnsupportedOperationException
-                            (_loc.get("aggregate-unsupported", op).toString());
-                    }
-                } else {
-                    single[i] = row[i];
-                }
-            }
-        }
-        _single = single;
-        return true;
-    }
-    
-    Object count(Object current, Object other) {
-        if (current == null)
-            return other;
-        return ((Number)current).longValue() + ((Number)other).longValue();
-    }
-    
-    Object max(Object current, Object other) {
-        if (current == null)
-            return other;
-        
-        return Math.max(((Number)current).doubleValue(), 
-                ((Number)other).doubleValue());
-    }
-    
-    Object min(Object current, Object other) {
-        if (current == null)
-            return other;
-        return Math.min(((Number)current).doubleValue(), 
-                ((Number)other).doubleValue());
-    }
-    
-    Object sum(Object current, Object other) {
-        if (current == null)
-            return other;
-        return (((Number)current).doubleValue() +
-                ((Number)other).doubleValue());
-    }
-
-
-
-    public void open() throws Exception {
-        for (ResultObjectProvider rop:_rops)
-            rop.open();
-        _opened = true;
-    }
-
-    public void reset() throws Exception {
-        _single = null;
-        for (ResultObjectProvider rop : _rops) {
-            rop.reset();
-        }
-    }
-
-    public int size() throws Exception {
-        return 1;
-    }
-
-    public boolean supportsRandomAccess() {
-         return false;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
+import org.apache.openjpa.kernel.exps.Value;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Aggregates individual single query results from different databases.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class UniqueResultObjectProvider implements ResultObjectProvider {
+    private final ResultObjectProvider[] _rops;
+    private final StoreQuery _query;
+    private final QueryExpressions[] _exps;
+    private Object _single;
+    private boolean _opened;
+    
+    private static final String COUNT = "Count";
+    private static final String MAX   = "Max";
+    private static final String MIN   = "Min";
+    private static final String SUM   = "Sum";
+    
+    private static final Localizer _loc =
+        Localizer.forPackage(UniqueResultObjectProvider.class);
+    
+    public UniqueResultObjectProvider(ResultObjectProvider[] rops, 
+            StoreQuery q, QueryExpressions[] exps) {
+        _rops = rops;
+        _query = q;
+        _exps = exps;
+    }
+    
+    public boolean absolute(int pos) throws Exception {
+        return false;
+    }
+
+    public void close() throws Exception {
+        _opened = false;
+        for (ResultObjectProvider rop:_rops)
+            rop.close();
+    }
+
+    public Object getResultObject() throws Exception {
+        if (!_opened)
+            throw new InternalException(_loc.get("not-open"));
+        return _single;
+    }
+
+    public void handleCheckedException(Exception e) {
+        _rops[0].handleCheckedException(e);
+    }
+
+    public boolean next() throws Exception {
+        if (!_opened) {
+            open();
+        }
+            
+        if (_single != null)
+            return false;
+        
+        Value[] values = _exps[0].projections;
+        Object[] single = new Object[values.length]; 
+        for (int i=0; i<values.length; i++) {
+            Value v = values[i];
+            boolean isAggregate = v.isAggregate();
+            String op = v.getClass().getSimpleName();
+            for (ResultObjectProvider rop:_rops) {
+                rop.next();
+                Object[] row = (Object[]) rop.getResultObject();
+                if (isAggregate) {
+                    if (COUNT.equals(op)) {
+                        single[i] = count(single[i], row[i]);
+                    } else if (MAX.equals(op)) {
+                        single[i] = max(single[i], row[i]);
+                    } else if (MIN.equals(op)) {
+                        single[i] = min(single[i], row[i]);
+                    } else if (SUM.equals(op)) {
+                        single[i] = sum(single[i], row[i]);
+                    } else {
+                        throw new UnsupportedOperationException
+                            (_loc.get("aggregate-unsupported", op).toString());
+                    }
+                } else {
+                    single[i] = row[i];
+                }
+            }
+        }
+        _single = single;
+        return true;
+    }
+    
+    Object count(Object current, Object other) {
+        if (current == null)
+            return other;
+        return ((Number)current).longValue() + ((Number)other).longValue();
+    }
+    
+    Object max(Object current, Object other) {
+        if (current == null)
+            return other;
+        
+        return Math.max(((Number)current).doubleValue(), 
+                ((Number)other).doubleValue());
+    }
+    
+    Object min(Object current, Object other) {
+        if (current == null)
+            return other;
+        return Math.min(((Number)current).doubleValue(), 
+                ((Number)other).doubleValue());
+    }
+    
+    Object sum(Object current, Object other) {
+        if (current == null)
+            return other;
+        return (((Number)current).doubleValue() +
+                ((Number)other).doubleValue());
+    }
+
+
+
+    public void open() throws Exception {
+        for (ResultObjectProvider rop:_rops)
+            rop.open();
+        _opened = true;
+    }
+
+    public void reset() throws Exception {
+        _single = null;
+        for (ResultObjectProvider rop : _rops) {
+            rop.reset();
+        }
+    }
+
+    public int size() throws Exception {
+        return 1;
+    }
+
+    public boolean supportsRandomAccess() {
+         return false;
+    }
+}
diff --git a/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties b/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
index ed7bb8c..e705051 100644
--- a/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
+++ b/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
@@ -1,67 +1,67 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.  
-
-slice-not-found: No slice named "{0}" can be found. Available slices are "{1}"
-slice-no-url: Slice "{0}" has no database URL. Specify a valid database URL \
-	as the value of "slice.{0}.ConnectionURL" property. ConnectionURL is the \
-	only mandatory property of a slice. If any other slice property \
-	is not specified, then the corresponding openjpa.* property value is used \
-	as default.
-slice-none-configured: No slice has been configured. Specify slice.XYZ as \
-	property name to register a slice named XYZ.
-slice-configuration: Slice "{0}" configured with "{1}"
-slice-available: Detected slices "{0}" in configuration.
-no-url: No ConnectionURL property has been specified.
-wrong-url: URL "{0}" is invalid as database URL.
-wrong-slice: Wrong slice "{0}" for "{1}"
-slice-connect: Connecting to slice "{0}" at URL "{1}"
-slice-connect-warn: Failed to connect to slice "{0}". Slice "{0}" will be \
-	ignored as configuration is set as lenient.
-slice-connect-known-warn: Failed to connect to URL "{1}" due to {2}. \
-	Slice "{0}" will be ignored as configuration is set as lenient.
-slice-connect-error: Failed to connect slice "{0}" to URL "{1}".
-slice-connect-known-error: Failed to connect to URL "{1}" due to {2}.
-bad-policy-slice:Distribution policy "{0}" has returned invalid slice \
-	"{1}" for "{2}". The valid slices are {3}. This error may happen \
-	when one or more of the originally configured slices are unavailable \
-	and Lenient property is set to true.
-slice-xa-enabled: All slices "{0}" is XA-complaint and hence store transaction \
-	will use a two-phase commit protocol even if the persistent unit is \
-	configured for non-JTA transaction.
-slice-xa-disabled: Not all active slices "{0}" is XA-complaint and hence store \
-	transaction will not use a two-phase commit protocol. If persistent unit \
-	is configured for JTA transaction then the slices will participate in \
-	global transaction but otherwise the atomic nature of commit across all \
-	slices is not guaranteed.  
-two-phase: "{3}".{0}"(xid=[{4}]] Connection={1} XAConnection={2} 
-factory-init: Starting OpenJPA Slice {0}
-config-init: Configuring Slice {0}
-no-slice-names: Slice identifiers are not explicitly listed via "{0}" property.\
-	The configuration will be scanned to determine slice identifiers.
-no-slice: No slices are configured or available
-no-master-slice: No master slice has been configured explicitly in \
-	"{0}" property. The first slice "{1}" in the list of configured \
-	slices will be used as master. 
-resource-xa-tm-not-2pc: All slices is using XA-complaint driver but the \
-	configured "{0}" transaction manager is not capable of enlisting XA-aware \
-	resources. See slice.TransactionManager property documentation to  \
-	configure XA-aware Transaction Manager capable for two-phase commit.
-resource-not-xa-tm-2pc: One or more slices is not using XA-complaint driver \
-	but the configured "{0}" transaction manager can only enlist XA-aware \
-	resource. 
-not-open: The underlying result sets are not open.
-aggregate-unsupported: The query uses unsupported aggregate operation "{0}".  
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.  
+
+slice-not-found: No slice named "{0}" can be found. Available slices are "{1}"
+slice-no-url: Slice "{0}" has no database URL. Specify a valid database URL \
+	as the value of "slice.{0}.ConnectionURL" property. ConnectionURL is the \
+	only mandatory property of a slice. If any other slice property \
+	is not specified, then the corresponding openjpa.* property value is used \
+	as default.
+slice-none-configured: No slice has been configured. Specify slice.XYZ as \
+	property name to register a slice named XYZ.
+slice-configuration: Slice "{0}" configured with "{1}"
+slice-available: Detected slices "{0}" in configuration.
+no-url: No ConnectionURL property has been specified.
+wrong-url: URL "{0}" is invalid as database URL.
+wrong-slice: Wrong slice "{0}" for "{1}"
+slice-connect: Connecting to slice "{0}" at URL "{1}"
+slice-connect-warn: Failed to connect to slice "{0}". Slice "{0}" will be \
+	ignored as configuration is set as lenient.
+slice-connect-known-warn: Failed to connect to URL "{1}" due to {2}. \
+	Slice "{0}" will be ignored as configuration is set as lenient.
+slice-connect-error: Failed to connect slice "{0}" to URL "{1}".
+slice-connect-known-error: Failed to connect to URL "{1}" due to {2}.
+bad-policy-slice:Distribution policy "{0}" has returned invalid slice \
+	"{1}" for "{2}". The valid slices are {3}. This error may happen \
+	when one or more of the originally configured slices are unavailable \
+	and Lenient property is set to true.
+slice-xa-enabled: All slices "{0}" is XA-complaint and hence store transaction \
+	will use a two-phase commit protocol even if the persistent unit is \
+	configured for non-JTA transaction.
+slice-xa-disabled: Not all active slices "{0}" is XA-complaint and hence store \
+	transaction will not use a two-phase commit protocol. If persistent unit \
+	is configured for JTA transaction then the slices will participate in \
+	global transaction but otherwise the atomic nature of commit across all \
+	slices is not guaranteed.  
+two-phase: "{3}".{0}"(xid=[{4}]] Connection={1} XAConnection={2} 
+factory-init: Starting OpenJPA Slice {0}
+config-init: Configuring Slice {0}
+no-slice-names: Slice identifiers are not explicitly listed via "{0}" property.\
+	The configuration will be scanned to determine slice identifiers.
+no-slice: No slices are configured or available
+no-master-slice: No master slice has been configured explicitly in \
+	"{0}" property. The first slice "{1}" in the list of configured \
+	slices will be used as master. 
+resource-xa-tm-not-2pc: All slices is using XA-complaint driver but the \
+	configured "{0}" transaction manager is not capable of enlisting XA-aware \
+	resources. See slice.TransactionManager property documentation to  \
+	configure XA-aware Transaction Manager capable for two-phase commit.
+resource-not-xa-tm-2pc: One or more slices is not using XA-complaint driver \
+	but the configured "{0}" transaction manager can only enlist XA-aware \
+	resource. 
+not-open: The underlying result sets are not open.
+aggregate-unsupported: The query uses unsupported aggregate operation "{0}".  
diff --git a/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties b/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
index 9d81452..2c1b804 100644
--- a/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
+++ b/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
@@ -1,20 +1,20 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.  
-bad-policy-slice:Distribution policy "{0}" has returned invalid slice \
-	"{1}" for "{2}". The valid slices are {3}. This error may happen \
-	when one or more of the originally configured slices are unavailable \
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.  
+bad-policy-slice:Distribution policy "{0}" has returned invalid slice \
+	"{1}" for "{2}". The valid slices are {3}. This error may happen \
+	when one or more of the originally configured slices are unavailable \
 	and Lenient property is set to true.
\ No newline at end of file
diff --git a/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties b/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
index 0ce6309..ca73757 100644
--- a/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
+++ b/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
@@ -1,19 +1,19 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.  
-no-txn-on-thread: No transaction is associated with current thread "{0}"
-prepare-failed: One or more XA-complaint resources have failed to prepare for \
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.  
+no-txn-on-thread: No transaction is associated with current thread "{0}"
+prepare-failed: One or more XA-complaint resources have failed to prepare for \
 	commit during the first phase of a two-phase commit protocol due to {0}
\ No newline at end of file
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java
index 4fdbe50..d04efb8 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java
@@ -1,82 +1,82 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import javax.persistence.*;
-
-@Entity
-public class Address {
-    @Id
-    @GeneratedValue
-    private long id;
-
-    private String city;
-    private int zip;
-
-    @OneToOne(mappedBy = "address")
-    Person owner;
-
-    @Version
-    private long version;
-
-    public long getVersion() {
-        return version;
-    }
-
-    public Address() {
-        this("?", 0);
-    }
-
-    public Address(String city, int zip) {
-        setCity(city);
-        setZip(zip);
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public int getZip() {
-        return zip;
-    }
-
-    public void setZip(int zip) {
-        this.zip = zip;
-    }
-
-    public Person getOwner() {
-        return owner;
-    }
-
-    public void setOwner(Person owner) {
-        this.owner = owner;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public String toString() {
-        return city;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import javax.persistence.*;
+
+@Entity
+public class Address {
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String city;
+    private int zip;
+
+    @OneToOne(mappedBy = "address")
+    Person owner;
+
+    @Version
+    private long version;
+
+    public long getVersion() {
+        return version;
+    }
+
+    public Address() {
+        this("?", 0);
+    }
+
+    public Address(String city, int zip) {
+        setCity(city);
+        setZip(zip);
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public int getZip() {
+        return zip;
+    }
+
+    public void setZip(int zip) {
+        this.zip = zip;
+    }
+
+    public Person getOwner() {
+        return owner;
+    }
+
+    public void setOwner(Person owner) {
+        this.owner = owner;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public String toString() {
+        return city;
+    }
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/PObject.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/PObject.java
index 7a0fc6e..818e624 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/PObject.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/PObject.java
@@ -1,48 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class PObject {
-	@Id
-	private long id;
-	
-	private int value;
-	
-	private static long idCounter = System.currentTimeMillis();
-	
-	public PObject() {
-		id = ++idCounter;
-	}
-	
-	public long getId() {
-		return id;
-	}
-	
-	public int getValue() {
-		return value;
-	}
-	
-	public void setValue(int i) {
-		value = i;
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class PObject {
+	@Id
+	private long id;
+	
+	private int value;
+	
+	private static long idCounter = System.currentTimeMillis();
+	
+	public PObject() {
+		id = ++idCounter;
+	}
+	
+	public long getId() {
+		return id;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public void setValue(int i) {
+		value = i;
+	}
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/PersistenceTestCase.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/PersistenceTestCase.java
index e61ca7c..53dc4a9 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/PersistenceTestCase.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/PersistenceTestCase.java
@@ -1,241 +1,241 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import org.apache.openjpa.kernel.AbstractBrokerFactory;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-
-/**
- * Base test class providing persistence utilities.
- */
-public abstract class PersistenceTestCase
-    extends TestCase {
-
-    /**
-     * Marker object you an pass to {@link #setUp} to indicate that the
-     * database tables should be cleared.
-     */
-    protected static final Object CLEAR_TABLES = new Object();
-
-    /**
-     * The {@link TestResult} instance for the current test run.
-     */
-    protected TestResult testResult;
-
-    /**
-     * Create an entity manager factory. Put {@link #CLEAR_TABLES} in
-     * this list to tell the test framework to delete all table contents
-     * before running the tests.
-     *
-     * @param props list of persistent types used in testing and/or
-     * configuration values in the form key,value,key,value...
-     */
-    protected OpenJPAEntityManagerFactorySPI createEMF(Object... props) {
-        return createNamedEMF(getPersistenceUnitName(), props);
-    }
-
-    /**
-     * The name of the persistence unit that this test class should use
-     * by default. This defaults to "test".
-     */
-    protected String getPersistenceUnitName() {
-        return "test";
-    }
-
-    /**
-     * Create an entity manager factory for persistence unit <code>pu</code>.
-     * Put {@link #CLEAR_TABLES} in
-     * this list to tell the test framework to delete all table contents
-     * before running the tests.
-     *
-     * @param props list of persistent types used in testing and/or
-     * configuration values in the form key,value,key,value...
-     */
-    protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu,
-        Object... props) {
-        Map map = new HashMap(System.getProperties());
-        List<Class> types = new ArrayList<Class>();
-        boolean prop = false;
-        for (int i = 0; i < props.length; i++) {
-            if (prop) {
-                map.put(props[i - 1], props[i]);
-                prop = false;
-            } else if (props[i] == CLEAR_TABLES) {
-                map.put("openjpa.jdbc.SynchronizeMappings",
-                    "buildSchema(ForeignKeys=true," 
-                    + "SchemaAction='add,deleteTableContents')");
-            } else if (props[i] instanceof Class)
-                types.add((Class) props[i]);
-            else if (props[i] != null)
-                prop = true;
-        }
-
-        if (!types.isEmpty()) {
-            StringBuffer buf = new StringBuffer();
-            for (Class c : types) {
-                if (buf.length() > 0)
-                    buf.append(";");
-                buf.append(c.getName());
-            }
-            map.put("openjpa.MetaDataFactory",
-                "jpa(Types=" + buf.toString() + ")");
-        }
-
-        return (OpenJPAEntityManagerFactorySPI) Persistence.
-            createEntityManagerFactory(pu, map);
-    }
-
-    @Override
-    public void run(TestResult testResult) {
-        this.testResult = testResult;
-        super.run(testResult);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        try {
-            super.tearDown();
-        } catch (Exception e) {
-            // if a test failed, swallow any exceptions that happen
-            // during tear-down, as these just mask the original problem.
-            if (testResult.wasSuccessful())
-                throw e;
-        }
-    }
-
-    /**
-     * Safely close the given factory.
-     */
-    protected boolean closeEMF(EntityManagerFactory emf) {
-        if (emf == null || !emf.isOpen())
-            return false;
-        
-        closeAllOpenEMs(emf);
-        emf.close();
-        return !emf.isOpen();
-    }
-
-    /**
-     * Closes all open entity managers after first rolling back any open transactions
-     */
-    protected void closeAllOpenEMs(EntityManagerFactory emf) {
-        if (emf == null || !emf.isOpen())
-            return;
-
-        for (Iterator iter = ((AbstractBrokerFactory) JPAFacadeHelper
-            .toBrokerFactory(emf)).getOpenBrokers().iterator();
-            iter.hasNext(); ) {
-            Broker b = (Broker) iter.next();
-            if (b != null && !b.isClosed()) {
-                EntityManager em = JPAFacadeHelper.toEntityManager(b);
-                if (em.getTransaction().isActive())
-                    em.getTransaction().rollback();
-                em.close();
-            }
-        }
-    }
-
-    /**
-     * Delete all instances of the given types using bulk delete queries,
-     * but do not close any open entity managers.
-     */
-    protected void clear(EntityManagerFactory emf, Class... types) {
-        if (emf == null || types.length == 0)
-            return;
-
-        List<ClassMetaData> metas = new ArrayList<ClassMetaData>(types.length);
-        for (Class c : types) {
-            ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c);
-            if (meta != null)
-                metas.add(meta);
-        }
-        clear(emf, false, metas.toArray(new ClassMetaData[metas.size()]));
-    }
-
-    /**
-     * Delete all instances of the persistent types registered with the given
-     * factory using bulk delete queries, after first closing all open entity
-     * managers (and rolling back any open transactions).
-     */
-    protected void clear(EntityManagerFactory emf) {
-        if (emf == null)
-            return;
-        clear(emf, true, ((OpenJPAEntityManagerFactorySPI) emf).getConfiguration().
-            getMetaDataRepositoryInstance().getMetaDatas());
-    }
-
-    /**
-     * Delete all instances of the given types using bulk delete queries.
-     * @param closeEMs TODO
-     */
-    private void clear(EntityManagerFactory emf, boolean closeEMs, ClassMetaData... types) {
-        if (emf == null || types.length == 0)
-            return;
-        
-        // prevent deadlock by closing the open entity managers 
-        // and rolling back any open transactions 
-        // before issuing delete statements on a new entity manager.
-        if (closeEMs)
-            closeAllOpenEMs(emf);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        for (ClassMetaData meta : types) {
-            if (!meta.isMapped() || meta.isEmbeddedOnly() 
-                || Modifier.isAbstract(meta.getDescribedType().getModifiers()))
-                continue;
-//            em.createQuery("DELETE FROM " + meta.getTypeAlias() + " o").
-//                executeUpdate();
-        }
-        em.getTransaction().commit();
-        em.close();
-    }
-
-    /**
-     * Return the entity name for the given type.   
-     */
-    protected String entityName(EntityManagerFactory emf, Class c) {
-        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c);
-        return (meta == null) ? null : meta.getTypeAlias();
-    }
-
-    public static void assertNotEquals(Object o1, Object o2) {
-        if (o1 == o2)
-            fail("expected args to be different; were the same instance.");
-        else if (o1 == null || o2 == null)
-            return;
-        else if (o1.equals(o2))
-            fail("expected args to be different; compared equal.");
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+
+/**
+ * Base test class providing persistence utilities.
+ */
+public abstract class PersistenceTestCase
+    extends TestCase {
+
+    /**
+     * Marker object you an pass to {@link #setUp} to indicate that the
+     * database tables should be cleared.
+     */
+    protected static final Object CLEAR_TABLES = new Object();
+
+    /**
+     * The {@link TestResult} instance for the current test run.
+     */
+    protected TestResult testResult;
+
+    /**
+     * Create an entity manager factory. Put {@link #CLEAR_TABLES} in
+     * this list to tell the test framework to delete all table contents
+     * before running the tests.
+     *
+     * @param props list of persistent types used in testing and/or
+     * configuration values in the form key,value,key,value...
+     */
+    protected OpenJPAEntityManagerFactorySPI createEMF(Object... props) {
+        return createNamedEMF(getPersistenceUnitName(), props);
+    }
+
+    /**
+     * The name of the persistence unit that this test class should use
+     * by default. This defaults to "test".
+     */
+    protected String getPersistenceUnitName() {
+        return "test";
+    }
+
+    /**
+     * Create an entity manager factory for persistence unit <code>pu</code>.
+     * Put {@link #CLEAR_TABLES} in
+     * this list to tell the test framework to delete all table contents
+     * before running the tests.
+     *
+     * @param props list of persistent types used in testing and/or
+     * configuration values in the form key,value,key,value...
+     */
+    protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu,
+        Object... props) {
+        Map map = new HashMap(System.getProperties());
+        List<Class> types = new ArrayList<Class>();
+        boolean prop = false;
+        for (int i = 0; i < props.length; i++) {
+            if (prop) {
+                map.put(props[i - 1], props[i]);
+                prop = false;
+            } else if (props[i] == CLEAR_TABLES) {
+                map.put("openjpa.jdbc.SynchronizeMappings",
+                    "buildSchema(ForeignKeys=true," 
+                    + "SchemaAction='add,deleteTableContents')");
+            } else if (props[i] instanceof Class)
+                types.add((Class) props[i]);
+            else if (props[i] != null)
+                prop = true;
+        }
+
+        if (!types.isEmpty()) {
+            StringBuffer buf = new StringBuffer();
+            for (Class c : types) {
+                if (buf.length() > 0)
+                    buf.append(";");
+                buf.append(c.getName());
+            }
+            map.put("openjpa.MetaDataFactory",
+                "jpa(Types=" + buf.toString() + ")");
+        }
+
+        return (OpenJPAEntityManagerFactorySPI) Persistence.
+            createEntityManagerFactory(pu, map);
+    }
+
+    @Override
+    public void run(TestResult testResult) {
+        this.testResult = testResult;
+        super.run(testResult);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            super.tearDown();
+        } catch (Exception e) {
+            // if a test failed, swallow any exceptions that happen
+            // during tear-down, as these just mask the original problem.
+            if (testResult.wasSuccessful())
+                throw e;
+        }
+    }
+
+    /**
+     * Safely close the given factory.
+     */
+    protected boolean closeEMF(EntityManagerFactory emf) {
+        if (emf == null || !emf.isOpen())
+            return false;
+        
+        closeAllOpenEMs(emf);
+        emf.close();
+        return !emf.isOpen();
+    }
+
+    /**
+     * Closes all open entity managers after first rolling back any open transactions
+     */
+    protected void closeAllOpenEMs(EntityManagerFactory emf) {
+        if (emf == null || !emf.isOpen())
+            return;
+
+        for (Iterator iter = ((AbstractBrokerFactory) JPAFacadeHelper
+            .toBrokerFactory(emf)).getOpenBrokers().iterator();
+            iter.hasNext(); ) {
+            Broker b = (Broker) iter.next();
+            if (b != null && !b.isClosed()) {
+                EntityManager em = JPAFacadeHelper.toEntityManager(b);
+                if (em.getTransaction().isActive())
+                    em.getTransaction().rollback();
+                em.close();
+            }
+        }
+    }
+
+    /**
+     * Delete all instances of the given types using bulk delete queries,
+     * but do not close any open entity managers.
+     */
+    protected void clear(EntityManagerFactory emf, Class... types) {
+        if (emf == null || types.length == 0)
+            return;
+
+        List<ClassMetaData> metas = new ArrayList<ClassMetaData>(types.length);
+        for (Class c : types) {
+            ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c);
+            if (meta != null)
+                metas.add(meta);
+        }
+        clear(emf, false, metas.toArray(new ClassMetaData[metas.size()]));
+    }
+
+    /**
+     * Delete all instances of the persistent types registered with the given
+     * factory using bulk delete queries, after first closing all open entity
+     * managers (and rolling back any open transactions).
+     */
+    protected void clear(EntityManagerFactory emf) {
+        if (emf == null)
+            return;
+        clear(emf, true, ((OpenJPAEntityManagerFactorySPI) emf).getConfiguration().
+            getMetaDataRepositoryInstance().getMetaDatas());
+    }
+
+    /**
+     * Delete all instances of the given types using bulk delete queries.
+     * @param closeEMs TODO
+     */
+    private void clear(EntityManagerFactory emf, boolean closeEMs, ClassMetaData... types) {
+        if (emf == null || types.length == 0)
+            return;
+        
+        // prevent deadlock by closing the open entity managers 
+        // and rolling back any open transactions 
+        // before issuing delete statements on a new entity manager.
+        if (closeEMs)
+            closeAllOpenEMs(emf);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        for (ClassMetaData meta : types) {
+            if (!meta.isMapped() || meta.isEmbeddedOnly() 
+                || Modifier.isAbstract(meta.getDescribedType().getModifiers()))
+                continue;
+//            em.createQuery("DELETE FROM " + meta.getTypeAlias() + " o").
+//                executeUpdate();
+        }
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    /**
+     * Return the entity name for the given type.   
+     */
+    protected String entityName(EntityManagerFactory emf, Class c) {
+        ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c);
+        return (meta == null) ? null : meta.getTypeAlias();
+    }
+
+    public static void assertNotEquals(Object o1, Object o2) {
+        if (o1 == o2)
+            fail("expected args to be different; were the same instance.");
+        else if (o1 == null || o2 == null)
+            return;
+        else if (o1.equals(o2))
+            fail("expected args to be different; compared equal.");
+    }
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/Person.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/Person.java
index 36a87d2..8a06c08 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/Person.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/Person.java
@@ -1,73 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import javax.persistence.*;
-
-@Entity
-public class Person {
-	@Id
-	@GeneratedValue
-	private long id;
-
-	private String name;
-	
-	@Version
-	private long version;
-
-	@OneToOne(cascade=CascadeType.ALL)
-	private Address address;
-
-	public Person() {
-		this("?");
-	}
-	
-	public Person(String name) {
-		setName(name);
-	}
-	
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public Address getAddress() {
-		return address;
-	}
-
-	public void setAddress(Address address) {
-		this.address = address;
-		address.setOwner(this);
-	}
-
-	public long getId() {
-		return id;
-	}
-	
-	public String toString() {
-		return name;
-	}
-
-    public long getVersion() {
-        return version;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import javax.persistence.*;
+
+@Entity
+public class Person {
+	@Id
+	@GeneratedValue
+	private long id;
+
+	private String name;
+	
+	@Version
+	private long version;
+
+	@OneToOne(cascade=CascadeType.ALL)
+	private Address address;
+
+	public Person() {
+		this("?");
+	}
+	
+	public Person(String name) {
+		setName(name);
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Address getAddress() {
+		return address;
+	}
+
+	public void setAddress(Address address) {
+		this.address = address;
+		address.setOwner(this);
+	}
+
+	public long getId() {
+		return id;
+	}
+	
+	public String toString() {
+		return name;
+	}
+
+    public long getVersion() {
+        return version;
+    }
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/SingleEMFTestCase.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/SingleEMFTestCase.java
index 417edc7..7f895e2 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/SingleEMFTestCase.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/SingleEMFTestCase.java
@@ -1,76 +1,76 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import org.apache.openjpa.jdbc.meta.ClassMapping;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-public abstract class SingleEMFTestCase
-    extends PersistenceTestCase {
-
-    protected OpenJPAEntityManagerFactorySPI emf;
-
-    /**
-     * Call {@link #setUp(Object...)} with no arguments so that the emf
-     * set-up happens even if <code>setUp()</code> is not called from the
-     * subclass.
-     */
-    public void setUp() throws Exception {
-        setUp(new Object[0]);
-    }
-
-    /**
-     * Initialize entity manager factory. Put {@link #CLEAR_TABLES} in
-     * this list to tell the test framework to delete all table contents
-     * before running the tests.
-     *
-     * @param props list of persistent types used in testing and/or 
-     * configuration values in the form key,value,key,value...
-     */
-    protected void setUp(Object... props) {
-        emf = createEMF(props);
-    }
-
-    /**
-     * Closes the entity manager factory.
-     */
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        if (emf == null)
-            return;
-
-        try {
-            clear(emf);
-        } catch (Exception e) {
-            // if a test failed, swallow any exceptions that happen
-            // during tear-down, as these just mask the original problem.
-            if (testResult.wasSuccessful())
-                throw e;
-        } finally {
-            closeEMF(emf);
-        }
-    }
-    
-    protected ClassMapping getMapping(String name) {
-        return (ClassMapping) emf.getConfiguration()
-                .getMetaDataRepositoryInstance().getMetaData(name,
-                        getClass().getClassLoader(), true);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public abstract class SingleEMFTestCase
+    extends PersistenceTestCase {
+
+    protected OpenJPAEntityManagerFactorySPI emf;
+
+    /**
+     * Call {@link #setUp(Object...)} with no arguments so that the emf
+     * set-up happens even if <code>setUp()</code> is not called from the
+     * subclass.
+     */
+    public void setUp() throws Exception {
+        setUp(new Object[0]);
+    }
+
+    /**
+     * Initialize entity manager factory. Put {@link #CLEAR_TABLES} in
+     * this list to tell the test framework to delete all table contents
+     * before running the tests.
+     *
+     * @param props list of persistent types used in testing and/or 
+     * configuration values in the form key,value,key,value...
+     */
+    protected void setUp(Object... props) {
+        emf = createEMF(props);
+    }
+
+    /**
+     * Closes the entity manager factory.
+     */
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        if (emf == null)
+            return;
+
+        try {
+            clear(emf);
+        } catch (Exception e) {
+            // if a test failed, swallow any exceptions that happen
+            // during tear-down, as these just mask the original problem.
+            if (testResult.wasSuccessful())
+                throw e;
+        } finally {
+            closeEMF(emf);
+        }
+    }
+    
+    protected ClassMapping getMapping(String name) {
+        return (ClassMapping) emf.getConfiguration()
+                .getMetaDataRepositoryInstance().getMetaData(name,
+                        getClass().getClassLoader(), true);
+    }
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/SliceTestCase.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/SliceTestCase.java
index 4697ef8..a70dd3b 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/SliceTestCase.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/SliceTestCase.java
@@ -1,41 +1,41 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import javax.persistence.EntityManager;
-
-import org.apache.openjpa.slice.jdbc.DistributedJDBCConfiguration;
-
-public abstract class SliceTestCase extends SingleEMFTestCase {
-    protected void setUp(Object... props) {
-        super.setUp(props);
-        assertTrue(emf.getClass() + " is not a slice configuration. Check" +
-            " that BrokerFactory for the persistence unit is set to slice",
-             emf.getConfiguration() instanceof DistributedJDBCConfiguration);
-        
-    }
-    
-    int count(Class<?> type) {
-        EntityManager em = emf.createEntityManager();
-        String query = "SELECT COUNT(p) FROM " + type.getSimpleName() + " p";
-        Number number = (Number) em.createQuery(query).getSingleResult();
-        return number.intValue();
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.slice.jdbc.DistributedJDBCConfiguration;
+
+public abstract class SliceTestCase extends SingleEMFTestCase {
+    protected void setUp(Object... props) {
+        super.setUp(props);
+        assertTrue(emf.getClass() + " is not a slice configuration. Check" +
+            " that BrokerFactory for the persistence unit is set to slice",
+             emf.getConfiguration() instanceof DistributedJDBCConfiguration);
+        
+    }
+    
+    int count(Class<?> type) {
+        EntityManager em = emf.createEntityManager();
+        String query = "SELECT COUNT(p) FROM " + type.getSimpleName() + " p";
+        Number number = (Number) em.createQuery(query).getSingleResult();
+        return number.intValue();
+    }
+    
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
index 6bde7d8..235df36 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
@@ -1,189 +1,189 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-
-/**
- * Tests basic create, read, update and delete operations.
- * 
- * @author Pinaki Poddar 
- *
- */
-public class TestBasic extends SliceTestCase {
-    
-    protected String getPersistenceUnitName() {
-        return "slice";
-    }
-
-
-    public void setUp() throws Exception {
-        super.setUp(PObject.class, Person.class, Address.class, CLEAR_TABLES);
-    }
-
-    /**
-     * Persist N objects.
-     */
-    List<PObject> create(int N) {
-        List<PObject> pcs = new ArrayList<PObject>();
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        for (int i = 0; i < N; i++) {
-            PObject pc = new PObject();
-            pcs.add(pc);
-            em.persist(pc);
-            pc.setValue(i);
-        }
-        em.getTransaction().commit();
-        em.clear();
-        return pcs;
-    }
-
-    /**
-     * Create a single object.
-     */
-    PObject create() {
-        return create(1).get(0);
-    }
-
-    /**
-     * Delete a single object by EntityManager.remove()
-     */
-    public void testDelete() {
-        int N = 10;
-        create(N);
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        int before = count(PObject.class);
-        List all = em.createQuery("SELECT p FROM PObject p").getResultList();
-        assertFalse(all.isEmpty());
-        em.remove(all.get(0));
-        em.getTransaction().commit();
-
-        int after = count(PObject.class);
-        assertEquals(before - 1, after);
-    }
-
-    /**
-     * Delete in bulk by query.
-     */
-    public void testBulkDelete() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        int c = count(PObject.class);
-        int d = em.createQuery("DELETE FROM PObject p").executeUpdate();
-        assertEquals(c, d);
-        em.getTransaction().commit();
-        c = count(PObject.class);
-        assertEquals(0, c);
-
-    }
-
-    /**
-     * Store and find the same object.
-     */
-    public void testFind() {
-        PObject pc = create();
-        int value = pc.getValue();
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        PObject pc2 = em.find(PObject.class, pc.getId());
-        assertNotNull(pc2);
-        assertNotEquals(pc, pc2);
-        assertEquals(pc.getId(), pc2.getId());
-        assertEquals(value, pc2.getValue());
-    }
-
-    public void testPersistIndependentObjects() {
-        int before = count(PObject.class);
-        EntityManager em = emf.createEntityManager();
-        int N = 2;
-        em.getTransaction().begin();
-        for (int i = 0; i < N; i++)
-            em.persist(new PObject());
-        em.getTransaction().commit();
-        em.clear();
-        int after = count(PObject.class);
-        assertEquals(before + N, after);
-    }
-
-    public void testPersistConnectedObjectGraph() {
-        Person p1 = new Person("A");
-        Person p2 = new Person("B");
-        Person p3 = new Person("C");
-        Address a1 = new Address("Rome", 12345);
-        Address a2 = new Address("San Francisco", 23456);
-        Address a3 = new Address("New York", 34567);
-        p1.setAddress(a1);
-        p2.setAddress(a2);
-        p3.setAddress(a3);
-
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.persist(p1);
-        em.persist(p2);
-        em.persist(p3);
-        em.getTransaction().commit();
-
-        em.clear();
-
-        em = emf.createEntityManager();
-        em.getTransaction().begin();
-        List<Person> persons =
-                em.createQuery("SELECT p FROM Person p WHERE p.name=?1")
-                        .setParameter(1, "A").getResultList();
-        List<Address> addresses =
-                em.createQuery("SELECT a FROM Address a").getResultList();
-        for (Address pc : addresses) {
-            assertNotNull(pc.getCity());
-            assertNotNull(pc.getOwner().getName());
-        }
-        for (Person pc : persons) {
-            assertNotNull(pc.getName());
-            assertNotNull(pc.getAddress().getCity());
-        }
-        em.getTransaction().rollback();
-    }
-
-    /**
-     * Merge only works if the distribution policy assigns the correct slice
-     * from which the instance was fetched.
-     */
-    public void testMerge() {
-        PObject pc = create(1).get(0);
-        int value = pc.getValue();
-        pc.setValue(value + 1);
-        assertNotNull(pc);
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        PObject pc2 = em.merge(pc);
-        em.getTransaction().commit();
-        em.clear();
-
-        assertNotNull(pc2);
-        assertNotEquals(pc, pc2);
-        assertEquals(pc.getId(), pc2.getId());
-        assertEquals(value + 1, pc2.getValue());
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+/**
+ * Tests basic create, read, update and delete operations.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class TestBasic extends SliceTestCase {
+    
+    protected String getPersistenceUnitName() {
+        return "slice";
+    }
+
+
+    public void setUp() throws Exception {
+        super.setUp(PObject.class, Person.class, Address.class, CLEAR_TABLES);
+    }
+
+    /**
+     * Persist N objects.
+     */
+    List<PObject> create(int N) {
+        List<PObject> pcs = new ArrayList<PObject>();
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        for (int i = 0; i < N; i++) {
+            PObject pc = new PObject();
+            pcs.add(pc);
+            em.persist(pc);
+            pc.setValue(i);
+        }
+        em.getTransaction().commit();
+        em.clear();
+        return pcs;
+    }
+
+    /**
+     * Create a single object.
+     */
+    PObject create() {
+        return create(1).get(0);
+    }
+
+    /**
+     * Delete a single object by EntityManager.remove()
+     */
+    public void testDelete() {
+        int N = 10;
+        create(N);
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        int before = count(PObject.class);
+        List all = em.createQuery("SELECT p FROM PObject p").getResultList();
+        assertFalse(all.isEmpty());
+        em.remove(all.get(0));
+        em.getTransaction().commit();
+
+        int after = count(PObject.class);
+        assertEquals(before - 1, after);
+    }
+
+    /**
+     * Delete in bulk by query.
+     */
+    public void testBulkDelete() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        int c = count(PObject.class);
+        int d = em.createQuery("DELETE FROM PObject p").executeUpdate();
+        assertEquals(c, d);
+        em.getTransaction().commit();
+        c = count(PObject.class);
+        assertEquals(0, c);
+
+    }
+
+    /**
+     * Store and find the same object.
+     */
+    public void testFind() {
+        PObject pc = create();
+        int value = pc.getValue();
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        PObject pc2 = em.find(PObject.class, pc.getId());
+        assertNotNull(pc2);
+        assertNotEquals(pc, pc2);
+        assertEquals(pc.getId(), pc2.getId());
+        assertEquals(value, pc2.getValue());
+    }
+
+    public void testPersistIndependentObjects() {
+        int before = count(PObject.class);
+        EntityManager em = emf.createEntityManager();
+        int N = 2;
+        em.getTransaction().begin();
+        for (int i = 0; i < N; i++)
+            em.persist(new PObject());
+        em.getTransaction().commit();
+        em.clear();
+        int after = count(PObject.class);
+        assertEquals(before + N, after);
+    }
+
+    public void testPersistConnectedObjectGraph() {
+        Person p1 = new Person("A");
+        Person p2 = new Person("B");
+        Person p3 = new Person("C");
+        Address a1 = new Address("Rome", 12345);
+        Address a2 = new Address("San Francisco", 23456);
+        Address a3 = new Address("New York", 34567);
+        p1.setAddress(a1);
+        p2.setAddress(a2);
+        p3.setAddress(a3);
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(p1);
+        em.persist(p2);
+        em.persist(p3);
+        em.getTransaction().commit();
+
+        em.clear();
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        List<Person> persons =
+                em.createQuery("SELECT p FROM Person p WHERE p.name=?1")
+                        .setParameter(1, "A").getResultList();
+        List<Address> addresses =
+                em.createQuery("SELECT a FROM Address a").getResultList();
+        for (Address pc : addresses) {
+            assertNotNull(pc.getCity());
+            assertNotNull(pc.getOwner().getName());
+        }
+        for (Person pc : persons) {
+            assertNotNull(pc.getName());
+            assertNotNull(pc.getAddress().getCity());
+        }
+        em.getTransaction().rollback();
+    }
+
+    /**
+     * Merge only works if the distribution policy assigns the correct slice
+     * from which the instance was fetched.
+     */
+    public void testMerge() {
+        PObject pc = create(1).get(0);
+        int value = pc.getValue();
+        pc.setValue(value + 1);
+        assertNotNull(pc);
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        PObject pc2 = em.merge(pc);
+        em.getTransaction().commit();
+        em.clear();
+
+        assertNotNull(pc2);
+        assertNotEquals(pc, pc2);
+        assertEquals(pc.getId(), pc2.getId());
+        assertEquals(value + 1, pc2.getValue());
+    }
+
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java
index 77f5718..aa70891 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java
@@ -1,63 +1,63 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.List;
-
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
-import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
-import org.apache.openjpa.slice.jdbc.DistributedJDBCConfiguration;
-
-/**
- * Tests user-level configuration is set on per-slice basis.
- * 
- * @author Pinaki Poddar
- * 
- */
-public class TestConfiguration extends SliceTestCase {
-    protected String getPersistenceUnitName() {
-        return "per-slice";
-    }
-
-    public void testConfig() {
-        assertTrue(emf.getConfiguration() instanceof DistributedConfiguration);
-        DistributedJDBCConfiguration conf =
-                (DistributedJDBCConfiguration) emf.getConfiguration();
-        List<String> slices = conf.getAvailableSliceNames();
-        assertTrue(slices.size() > 1);
-        assertTrue(slices.contains("One"));
-        assertTrue(slices.contains("Two"));
-        assertTrue(slices.contains("Three"));
-        BrokerFactory bf = ((EntityManagerFactoryImpl) emf).getBrokerFactory();
-        Broker broker = bf.newBroker();
-        assertEquals(DistributedJDBCBrokerFactory.class, bf.getClass());
-        assertEquals(DistributedBrokerImpl.class, broker.getClass());
-        assertNotNull(conf.getDistributionPolicyInstance());
-
-        emf.createEntityManager();
-
-        slices = conf.getActiveSliceNames();
-        assertTrue(slices.size() > 1);
-        assertTrue(slices.contains("One"));
-        assertTrue(slices.contains("Two"));
-        assertFalse(slices.contains("Three"));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.List;
+
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
+import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
+import org.apache.openjpa.slice.jdbc.DistributedJDBCConfiguration;
+
+/**
+ * Tests user-level configuration is set on per-slice basis.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class TestConfiguration extends SliceTestCase {
+    protected String getPersistenceUnitName() {
+        return "per-slice";
+    }
+
+    public void testConfig() {
+        assertTrue(emf.getConfiguration() instanceof DistributedConfiguration);
+        DistributedJDBCConfiguration conf =
+                (DistributedJDBCConfiguration) emf.getConfiguration();
+        List<String> slices = conf.getAvailableSliceNames();
+        assertTrue(slices.size() > 1);
+        assertTrue(slices.contains("One"));
+        assertTrue(slices.contains("Two"));
+        assertTrue(slices.contains("Three"));
+        BrokerFactory bf = ((EntityManagerFactoryImpl) emf).getBrokerFactory();
+        Broker broker = bf.newBroker();
+        assertEquals(DistributedJDBCBrokerFactory.class, bf.getClass());
+        assertEquals(DistributedBrokerImpl.class, broker.getClass());
+        assertNotNull(conf.getDistributionPolicyInstance());
+
+        emf.createEntityManager();
+
+        slices = conf.getActiveSliceNames();
+        assertTrue(slices.size() > 1);
+        assertTrue(slices.contains("One"));
+        assertTrue(slices.contains("Two"));
+        assertFalse(slices.contains("Three"));
+    }
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java
index 1c08753..7b7c6bf 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestQuery.java
@@ -1,128 +1,128 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-/**
- * Tests query ordering.
- * 
- * @author Pinaki Poddar 
- *
- */
-public class TestQuery extends SliceTestCase {
-    private int POBJECT_COUNT = 25;
-    private int VALUE_MIN = 100;
-    private int VALUE_MAX = VALUE_MIN + POBJECT_COUNT - 1;
-    
-    protected String getPersistenceUnitName() {
-        return "ordering";
-    }
-
-    public void setUp() throws Exception {
-        super.setUp(PObject.class, Person.class, Address.class, CLEAR_TABLES);
-        int count = count(PObject.class);
-        if (count == 0) {
-            create(POBJECT_COUNT);
-        }
-    }
-    
-    void create(int N) {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        for (int i=0;i<POBJECT_COUNT;i++) {
-            PObject pc = new PObject();
-            pc.setValue(VALUE_MIN + i);
-            em.persist(pc);
-            String slice = SlicePersistence.getSlice(pc);
-            String expected = (pc.getValue()%2 == 0) ? "Even" : "Odd";
-            assertEquals(expected, slice);
-        }
-        em.getTransaction().commit();
-    }
-    
-    public void testQueryResultIsOrderedAcrossSlice() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Query query = em.createQuery("SELECT p.value,p FROM PObject p ORDER BY p.value ASC");
-        List result = query.getResultList();
-        Integer old = Integer.MIN_VALUE;
-        for (Object row : result) {
-            Object[] line = (Object[])row;
-            int value = ((Integer)line[0]).intValue();
-            PObject pc = (PObject)line[1];
-            assertTrue(value >= old);
-            old = value;
-            assertEquals(value, pc.getValue());
-        }
-        em.getTransaction().rollback();
-    }
-    
-    public void testAggregateQuery() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Object count = em.createQuery("SELECT COUNT(p) FROM PObject p").getSingleResult();
-        Object max   = em.createQuery("SELECT MAX(p.value) FROM PObject p").getSingleResult();
-        Object min   = em.createQuery("SELECT MIN(p.value) FROM PObject p").getSingleResult();
-        Object sum   = em.createQuery("SELECT SUM(p.value) FROM PObject p").getSingleResult();
-        em.getTransaction().rollback();
-        
-        assertEquals(POBJECT_COUNT, ((Number)count).intValue());
-        assertEquals(VALUE_MAX, ((Number)max).intValue());
-        assertEquals(VALUE_MIN, ((Number)min).intValue());
-        assertEquals((VALUE_MIN+VALUE_MAX)*POBJECT_COUNT, 2*((Number)sum).intValue());
-    }
-    
-    public void testSetMaxResult() {
-        EntityManager em = emf.createEntityManager();
-        int limit = 3;
-        em.getTransaction().begin();
-        List result = em.createQuery("SELECT p.value,p FROM PObject p ORDER BY p.value ASC")
-            .setMaxResults(limit).getResultList();
-        int i = 0;
-        for (Object row : result) {
-            Object[] line = (Object[])row;
-            int value = ((Integer)line[0]).intValue();
-            PObject pc = (PObject)line[1];
-            System.err.println(++i + "." + SlicePersistence.getSlice(pc) + ":" 
-                    + pc.getId() + "," + pc.getValue());
-        }
-        assertEquals(limit, result.size());
-        em.getTransaction().rollback();
-    }
-    
-    public void testHint() {
-        List<String> targets = new ArrayList<String>();
-        targets.add("Even");
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        Query query = em.createQuery("SELECT p FROM PObject p");
-        query.setHint(ProductDerivation.HINT_TARGET, "Even");
-        List result = query.getResultList();
-        for (Object pc : result) {
-            String slice = SlicePersistence.getSlice(pc);
-            assertTrue(targets.contains(slice));
-        }
-        em.getTransaction().rollback();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+/**
+ * Tests query ordering.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class TestQuery extends SliceTestCase {
+    private int POBJECT_COUNT = 25;
+    private int VALUE_MIN = 100;
+    private int VALUE_MAX = VALUE_MIN + POBJECT_COUNT - 1;
+    
+    protected String getPersistenceUnitName() {
+        return "ordering";
+    }
+
+    public void setUp() throws Exception {
+        super.setUp(PObject.class, Person.class, Address.class, CLEAR_TABLES);
+        int count = count(PObject.class);
+        if (count == 0) {
+            create(POBJECT_COUNT);
+        }
+    }
+    
+    void create(int N) {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        for (int i=0;i<POBJECT_COUNT;i++) {
+            PObject pc = new PObject();
+            pc.setValue(VALUE_MIN + i);
+            em.persist(pc);
+            String slice = SlicePersistence.getSlice(pc);
+            String expected = (pc.getValue()%2 == 0) ? "Even" : "Odd";
+            assertEquals(expected, slice);
+        }
+        em.getTransaction().commit();
+    }
+    
+    public void testQueryResultIsOrderedAcrossSlice() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query query = em.createQuery("SELECT p.value,p FROM PObject p ORDER BY p.value ASC");
+        List result = query.getResultList();
+        Integer old = Integer.MIN_VALUE;
+        for (Object row : result) {
+            Object[] line = (Object[])row;
+            int value = ((Integer)line[0]).intValue();
+            PObject pc = (PObject)line[1];
+            assertTrue(value >= old);
+            old = value;
+            assertEquals(value, pc.getValue());
+        }
+        em.getTransaction().rollback();
+    }
+    
+    public void testAggregateQuery() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Object count = em.createQuery("SELECT COUNT(p) FROM PObject p").getSingleResult();
+        Object max   = em.createQuery("SELECT MAX(p.value) FROM PObject p").getSingleResult();
+        Object min   = em.createQuery("SELECT MIN(p.value) FROM PObject p").getSingleResult();
+        Object sum   = em.createQuery("SELECT SUM(p.value) FROM PObject p").getSingleResult();
+        em.getTransaction().rollback();
+        
+        assertEquals(POBJECT_COUNT, ((Number)count).intValue());
+        assertEquals(VALUE_MAX, ((Number)max).intValue());
+        assertEquals(VALUE_MIN, ((Number)min).intValue());
+        assertEquals((VALUE_MIN+VALUE_MAX)*POBJECT_COUNT, 2*((Number)sum).intValue());
+    }
+    
+    public void testSetMaxResult() {
+        EntityManager em = emf.createEntityManager();
+        int limit = 3;
+        em.getTransaction().begin();
+        List result = em.createQuery("SELECT p.value,p FROM PObject p ORDER BY p.value ASC")
+            .setMaxResults(limit).getResultList();
+        int i = 0;
+        for (Object row : result) {
+            Object[] line = (Object[])row;
+            int value = ((Integer)line[0]).intValue();
+            PObject pc = (PObject)line[1];
+            System.err.println(++i + "." + SlicePersistence.getSlice(pc) + ":" 
+                    + pc.getId() + "," + pc.getValue());
+        }
+        assertEquals(limit, result.size());
+        em.getTransaction().rollback();
+    }
+    
+    public void testHint() {
+        List<String> targets = new ArrayList<String>();
+        targets.add("Even");
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query query = em.createQuery("SELECT p FROM PObject p");
+        query.setHint(ProductDerivation.HINT_TARGET, "Even");
+        List result = query.getResultList();
+        for (Object pc : result) {
+            String slice = SlicePersistence.getSlice(pc);
+            assertTrue(targets.contains(slice));
+        }
+        em.getTransaction().rollback();
+    }
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestXA.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestXA.java
index 4d71f2d..8b047b6 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestXA.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestXA.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice;
-
-import javax.persistence.*;
-
-public class TestXA extends SliceTestCase {
-    public void setUp() throws Exception {
-        super.setUp(PObject.class, Person.class, Address.class, CLEAR_TABLES);
-    }
-    public void testEmptyCommit() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.getTransaction().commit();
-    }
-    public void testEmptyRollback() {
-        EntityManager em = emf.createEntityManager();
-        em.getTransaction().begin();
-        em.getTransaction().rollback();
-    }
-    
-	public void testPersistIndependentObjects() {
-		EntityManager em = emf.createEntityManager();
-        int before = count(PObject.class);
-		int N = 2;
-		em.getTransaction().begin();
-		for (int i=0; i<N; i++)
-			em.persist(new PObject());
-		em.getTransaction().commit();
-		em.clear();
-		int after = count(PObject.class);
-		assertEquals(before+N, after);
-	}
-	
-    protected String getPersistenceUnitName() {
-        return "XA";
-    }
-    
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import javax.persistence.*;
+
+public class TestXA extends SliceTestCase {
+    public void setUp() throws Exception {
+        super.setUp(PObject.class, Person.class, Address.class, CLEAR_TABLES);
+    }
+    public void testEmptyCommit() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.getTransaction().commit();
+    }
+    public void testEmptyRollback() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.getTransaction().rollback();
+    }
+    
+	public void testPersistIndependentObjects() {
+		EntityManager em = emf.createEntityManager();
+        int before = count(PObject.class);
+		int N = 2;
+		em.getTransaction().begin();
+		for (int i=0; i<N; i++)
+			em.persist(new PObject());
+		em.getTransaction().commit();
+		em.clear();
+		int after = count(PObject.class);
+		assertEquals(before+N, after);
+	}
+	
+    protected String getPersistenceUnitName() {
+        return "XA";
+    }
+    
+
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/EvenOddDistributionPolicy.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/EvenOddDistributionPolicy.java
index 5cb7970..cb5104a 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/EvenOddDistributionPolicy.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/EvenOddDistributionPolicy.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.policy;
-
-import java.util.List;
-
-import org.apache.openjpa.slice.DistributionPolicy;
-
-import org.apache.openjpa.slice.*;
-
-public class EvenOddDistributionPolicy implements DistributionPolicy {
-    public String distribute(Object pc, List<String> slices, Object context) {
-        if (pc instanceof PObject) {
-            int v = ((PObject)pc).getValue();
-            return (v%2 == 0) ? "Even" : "Odd";
-        }
-        return null;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.policy;
+
+import java.util.List;
+
+import org.apache.openjpa.slice.DistributionPolicy;
+
+import org.apache.openjpa.slice.*;
+
+public class EvenOddDistributionPolicy implements DistributionPolicy {
+    public String distribute(Object pc, List<String> slices, Object context) {
+        if (pc instanceof PObject) {
+            int v = ((PObject)pc).getValue();
+            return (v%2 == 0) ? "Even" : "Odd";
+        }
+        return null;
+    }
+
+}
diff --git a/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/UserDistributionPolicy.java b/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/UserDistributionPolicy.java
index d19dd71..fe7a54e 100644
--- a/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/UserDistributionPolicy.java
+++ b/openjpa-slice/src/test/java/org/apache/openjpa/slice/policy/UserDistributionPolicy.java
@@ -1,78 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.slice.policy;
-
-import java.util.List;
-
-import org.apache.openjpa.slice.DistributionPolicy;
-
-import org.apache.openjpa.slice.PObject;
-import org.apache.openjpa.slice.Person;
-
-
-/**
- * Exemplar {@link DistributionPolicy} that maintains closure and distributes
- * based on attributes of the given instance. 
- * 
- * @author Pinaki Poddar 
- *
- */
-public class UserDistributionPolicy implements DistributionPolicy {
-
-	/**
-	 * Distribute the given instance.
-	 * Assumes that two configured slices are named as <em>One</em> and 
-	 * <em>Two</em>.<br>
-	 * The policy is only implemented for PObject and Person i.e. two of three 
-	 * known classes. No policy is implemented for Address because Address is
-	 * persisted always by cascade and hence Slice should assign automatically
-	 * the same slice as its owner Person. 
-	 * 
-	 */
-	public String distribute(Object pc, List<String> slices, Object context) {
-		assertValidSlices(slices);
-		if (pc instanceof PObject)
-			return distribute((PObject)pc);
-		if (pc instanceof Person) {
-			return distribute((Person)pc);
-		}
-		throw new RuntimeException("No policy for " + pc.getClass());
-	}
-	
-	void assertValidSlices(List<String> slices) {
-		if (slices.contains("One") && slices.contains("Two"))
-			return;
-		throw new RuntimeException("This policy assumes two slices named " +
-				"One and Two. But configured slices are " + slices); 
-	}
-	
-	/**
-	 * Distribute PObject based on odd-even value of its id.
-	 */
-	String distribute(PObject pc) {
-		return (pc.getId()%2 == 0) ? "One" : "Two";
-	}
-	
-	/**
-	 * Distribute Person based on first character of its name.
-	 */
-	String distribute(Person pc) {
-		return (pc.getName().startsWith("A")) ? "One" : "Two";
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice.policy;
+
+import java.util.List;
+
+import org.apache.openjpa.slice.DistributionPolicy;
+
+import org.apache.openjpa.slice.PObject;
+import org.apache.openjpa.slice.Person;
+
+
+/**
+ * Exemplar {@link DistributionPolicy} that maintains closure and distributes
+ * based on attributes of the given instance. 
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class UserDistributionPolicy implements DistributionPolicy {
+
+	/**
+	 * Distribute the given instance.
+	 * Assumes that two configured slices are named as <em>One</em> and 
+	 * <em>Two</em>.<br>
+	 * The policy is only implemented for PObject and Person i.e. two of three 
+	 * known classes. No policy is implemented for Address because Address is
+	 * persisted always by cascade and hence Slice should assign automatically
+	 * the same slice as its owner Person. 
+	 * 
+	 */
+	public String distribute(Object pc, List<String> slices, Object context) {
+		assertValidSlices(slices);
+		if (pc instanceof PObject)
+			return distribute((PObject)pc);
+		if (pc instanceof Person) {
+			return distribute((Person)pc);
+		}
+		throw new RuntimeException("No policy for " + pc.getClass());
+	}
+	
+	void assertValidSlices(List<String> slices) {
+		if (slices.contains("One") && slices.contains("Two"))
+			return;
+		throw new RuntimeException("This policy assumes two slices named " +
+				"One and Two. But configured slices are " + slices); 
+	}
+	
+	/**
+	 * Distribute PObject based on odd-even value of its id.
+	 */
+	String distribute(PObject pc) {
+		return (pc.getId()%2 == 0) ? "One" : "Two";
+	}
+	
+	/**
+	 * Distribute Person based on first character of its name.
+	 */
+	String distribute(Person pc) {
+		return (pc.getName().startsWith("A")) ? "One" : "Two";
+	}
+}
diff --git a/openjpa-slice/src/test/resources/META-INF/persistence.xml b/openjpa-slice/src/test/resources/META-INF/persistence.xml
index b4509b3..9338928 100644
--- a/openjpa-slice/src/test/resources/META-INF/persistence.xml
+++ b/openjpa-slice/src/test/resources/META-INF/persistence.xml
@@ -1,125 +1,125 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
-    <persistence-unit name="enhance">
-        <class>org.apache.openjpa.slice.PObject</class>
-        <class>org.apache.openjpa.slice.Person</class>
-        <class>org.apache.openjpa.slice.Address</class>
-        <properties>
-         <property name="openjpa.Log" value="DefaultLevel=WARN, Enhance=TRACE"/>
-        </properties>
-    </persistence-unit>
-    
-    
-   <!-- ==================================================================== -->
-   <!-- Configuration for testing basic per-slice configuration              -->
-   <!-- ==================================================================== -->
-   <persistence-unit name="per-slice">
-      <properties>
-         <property name="openjpa.BrokerFactory"        value="slice"/>
-         <property name="openjpa.slice.Names"          value="One,Two, Three"/>
-         <property name="openjpa.slice.Master"         value="One"/>
-         <property name="openjpa.slice.Lenient"        value="true"/>
-         
-         <property name="openjpa.slice.DistributionPolicy"  value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
-         <property name="openjpa.slice.ThreadingPolicy"     value="fixed"/>
-
-         <property name="openjpa.Log"                       value="DefaultLevel=INFO, Enhance=TRACE, SQL=TRACE"/>
-         <property name="openjpa.ConnectionDriverName"      value="org.apache.derby.jdbc.EmbeddedDriver"/>
-         <property name="openjpa.ConnectionUserName"        value=""/>
-         <property name="openjpa.ConnectionPassword"        value=""/>
-         <property name="openjpa.slice.One.ConnectionURL"   value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
-         <property name="openjpa.slice.Two.ConnectionURL"   value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
-         <property name="openjpa.slice.Three.ConnectionURL" value="jdbc:some-bad-url"/>
-         
-      </properties>
-   </persistence-unit>
-
-   <persistence-unit name="XA">
-      <class>org.apache.openjpa.slice.PObject</class>
-      <properties>
-         <property name="openjpa.BrokerFactory" value="slice"/>
-         <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
-
-         <property name="openjpa.slice.Names" value="One,Two"/>
-         <property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
-         
-         <property name="openjpa.ConnectionUserName"        value=""/>
-         <property name="openjpa.ConnectionPassword"        value=""/>
-         <property name="openjpa.slice.One.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
-         <property name="openjpa.slice.One.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
-         <property name="openjpa.slice.Two.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
-         <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
-         
-         <property name="openjpa.Multithreaded" value="false"/>
-         <property name="openjpa.Log" value="DefaultLevel=INFO, Enhance=TRACE, SQL=TRACE"/>
-         <property name="openjpa.jdbc.SynchronizeMappings" value="refresh"/>
-         <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
-         <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
-      </properties>
-   </persistence-unit>
-   
-   <!-- ==================================================================== -->
-   <!-- Configuration for testing basic CRUD operations                      -->
-   <!-- ==================================================================== -->
-   <persistence-unit name="slice">
-        <class>org.apache.openjpa.slice.PObject</class>
-        <class>org.apache.openjpa.slice.Person</class>
-        <class>org.apache.openjpa.slice.Address</class>
-		<properties>
-            <property name="openjpa.BrokerFactory" value="slice"/>
-            <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
-            <property name="openjpa.slice.Names" value="One,Two"/>
-            <property name="openjpa.slice.Master" value="Two"/>
-            <property name="openjpa.slice.One.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
-            <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
-            <property name="openjpa.ConnectionUserName" value=""/>
-            <property name="openjpa.ConnectionPassword" value=""/>
-            <property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
-            <property name="openjpa.slice.Lenient" value="false"/>
-            
-            <property name="openjpa.Connection2URL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
-	        <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
-            <property name="openjpa.QueryCompilationCache" value="false"/>
-   	        <property name="openjpa.Log" value="DefaultLevel=WARN, Enhance=TRACE, SQL=TRACE"/>
-            <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
-            <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
-      	</properties>
-   </persistence-unit>
-   
-      <persistence-unit name="ordering">
-        <class>org.apache.openjpa.slice.PObject</class>
-        <properties>
-            <property name="openjpa.BrokerFactory" value="slice"/>
-            <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
-            <property name="openjpa.slice.Even.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
-            <property name="openjpa.slice.Odd.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
-            <property name="openjpa.ConnectionUserName" value=""/>
-            <property name="openjpa.ConnectionPassword" value=""/>
-            <property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.EvenOddDistributionPolicy"/>
-            <property name="openjpa.slice.Lenient" value="false"/>
-            
-            <property name="openjpa.Connection2URL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
-            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
-            <property name="openjpa.Log" value="DefaultLevel=WARN, Enhance=TRACE, SQL=TRACE"/>
-            <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
-        </properties>
-   </persistence-unit>
-</persistence>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
+    <persistence-unit name="enhance">
+        <class>org.apache.openjpa.slice.PObject</class>
+        <class>org.apache.openjpa.slice.Person</class>
+        <class>org.apache.openjpa.slice.Address</class>
+        <properties>
+         <property name="openjpa.Log" value="DefaultLevel=WARN, Enhance=TRACE"/>
+        </properties>
+    </persistence-unit>
+    
+    
+   <!-- ==================================================================== -->
+   <!-- Configuration for testing basic per-slice configuration              -->
+   <!-- ==================================================================== -->
+   <persistence-unit name="per-slice">
+      <properties>
+         <property name="openjpa.BrokerFactory"        value="slice"/>
+         <property name="openjpa.slice.Names"          value="One,Two, Three"/>
+         <property name="openjpa.slice.Master"         value="One"/>
+         <property name="openjpa.slice.Lenient"        value="true"/>
+         
+         <property name="openjpa.slice.DistributionPolicy"  value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
+         <property name="openjpa.slice.ThreadingPolicy"     value="fixed"/>
+
+         <property name="openjpa.Log"                       value="DefaultLevel=INFO, Enhance=TRACE, SQL=TRACE"/>
+         <property name="openjpa.ConnectionDriverName"      value="org.apache.derby.jdbc.EmbeddedDriver"/>
+         <property name="openjpa.ConnectionUserName"        value=""/>
+         <property name="openjpa.ConnectionPassword"        value=""/>
+         <property name="openjpa.slice.One.ConnectionURL"   value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
+         <property name="openjpa.slice.Two.ConnectionURL"   value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
+         <property name="openjpa.slice.Three.ConnectionURL" value="jdbc:some-bad-url"/>
+         
+      </properties>
+   </persistence-unit>
+
+   <persistence-unit name="XA">
+      <class>org.apache.openjpa.slice.PObject</class>
+      <properties>
+         <property name="openjpa.BrokerFactory" value="slice"/>
+         <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+
+         <property name="openjpa.slice.Names" value="One,Two"/>
+         <property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
+         
+         <property name="openjpa.ConnectionUserName"        value=""/>
+         <property name="openjpa.ConnectionPassword"        value=""/>
+         <property name="openjpa.slice.One.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+         <property name="openjpa.slice.One.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
+         <property name="openjpa.slice.Two.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+         <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
+         
+         <property name="openjpa.Multithreaded" value="false"/>
+         <property name="openjpa.Log" value="DefaultLevel=INFO, Enhance=TRACE, SQL=TRACE"/>
+         <property name="openjpa.jdbc.SynchronizeMappings" value="refresh"/>
+         <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
+         <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
+      </properties>
+   </persistence-unit>
+   
+   <!-- ==================================================================== -->
+   <!-- Configuration for testing basic CRUD operations                      -->
+   <!-- ==================================================================== -->
+   <persistence-unit name="slice">
+        <class>org.apache.openjpa.slice.PObject</class>
+        <class>org.apache.openjpa.slice.Person</class>
+        <class>org.apache.openjpa.slice.Address</class>
+		<properties>
+            <property name="openjpa.BrokerFactory" value="slice"/>
+            <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+            <property name="openjpa.slice.Names" value="One,Two"/>
+            <property name="openjpa.slice.Master" value="Two"/>
+            <property name="openjpa.slice.One.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
+            <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
+            <property name="openjpa.ConnectionUserName" value=""/>
+            <property name="openjpa.ConnectionPassword" value=""/>
+            <property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
+            <property name="openjpa.slice.Lenient" value="false"/>
+            
+            <property name="openjpa.Connection2URL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
+	        <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
+            <property name="openjpa.QueryCompilationCache" value="false"/>
+   	        <property name="openjpa.Log" value="DefaultLevel=WARN, Enhance=TRACE, SQL=TRACE"/>
+            <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
+            <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
+      	</properties>
+   </persistence-unit>
+   
+      <persistence-unit name="ordering">
+        <class>org.apache.openjpa.slice.PObject</class>
+        <properties>
+            <property name="openjpa.BrokerFactory" value="slice"/>
+            <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+            <property name="openjpa.slice.Even.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
+            <property name="openjpa.slice.Odd.ConnectionURL" value="jdbc:derby:target/database/openjpa-slice2;create=true"/>
+            <property name="openjpa.ConnectionUserName" value=""/>
+            <property name="openjpa.ConnectionPassword" value=""/>
+            <property name="openjpa.slice.DistributionPolicy" value="org.apache.openjpa.slice.policy.EvenOddDistributionPolicy"/>
+            <property name="openjpa.slice.Lenient" value="false"/>
+            
+            <property name="openjpa.Connection2URL" value="jdbc:derby:target/database/openjpa-slice1;create=true"/>
+            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
+            <property name="openjpa.Log" value="DefaultLevel=WARN, Enhance=TRACE, SQL=TRACE"/>
+            <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
+        </properties>
+   </persistence-unit>
+</persistence>
diff --git a/openjpa-xmlstore/pom.xml b/openjpa-xmlstore/pom.xml
index b176333..552e0e5 100644
--- a/openjpa-xmlstore/pom.xml
+++ b/openjpa-xmlstore/pom.xml
@@ -31,7 +31,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>1.2.1</version>
+        <version>1.2.2</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/pom.xml b/pom.xml
index 3efd794..759769d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,7 +40,7 @@
         Changing this version needs to also be done in all children poms
         See: http://jira.codehaus.org/browse/MNG-624
     -->
-    <version>1.2.1</version>
+    <version>1.2.2</version>
     <url>http://openjpa.apache.org</url>
     <issueManagement>
         <system>jira</system>
@@ -241,6 +241,7 @@
                                     <exclude>**/org.apache.openjpa.revision.properties</exclude>
                                     <exclude>**/target/**/*</exclude>
                                     <exclude>release.properties</exclude>
+                                    <exclude>**/.*/**</exclude>
 
                                     <!--
                                         Exclude internal repository. These files are 
@@ -371,6 +372,7 @@
                                 <exclude>**/org.apache.openjpa.revision.properties</exclude>
                                 <exclude>**/target/**/*</exclude>
                                 <exclude>release.properties</exclude>
+                                <exclude>**/.*/**</exclude>
 
                                 <!--
                                     Exclude internal repository. These files are 
@@ -610,7 +612,7 @@
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-release-plugin</artifactId>
-                    <version>2.0-beta-7</version>
+                    <version>2.0-beta-9</version>
                 </plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
@@ -703,8 +705,8 @@
       </site>
     </distributionManagement>
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/openjpa/tags/1.2.1</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/openjpa/tags/1.2.1</developerConnection>
-        <url>http://svn.apache.org/repos/asf/openjpa/tags/1.2.1</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/openjpa/tags/1.2.2</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/openjpa/tags/1.2.2</developerConnection>
+        <url>http://svn.apache.org/repos/asf/openjpa/tags/1.2.2</url>
     </scm>
 </project>
